Hello !
I'd like to use Chibios in my application, the chip will be a LPC4330. I have a LPC4330 Xplorer board.
I know it isn't officially supported...
Right now I only need a kernel and stuff like message passing and queues, no need for a HAL. I'm using FreeRTOS at the moment but I'd prefer Chibios for various reasons (static allocation, speed, RAM use, seems simpler, the code looks much better, etc).
So, where do I start ? Is it supported in svn ? Do I need to make a port (or if there is a port in beta I'd be interested to test it)...
I've seen projects which seem to match, you guys know about this ?
http://ehc.ac/p/chibios/svn/6746/tree/t ... 0-SBC-RAM/
https://github.com/marcinj/ChibiOS-RT/tree/lpc_dev
Thanks for any info, and keep up the good work !
LPC4330
- Giovanni
- Site Admin
- Posts: 14565
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1112 times
- Been thanked: 937 times
- Contact:
Re: LPC4330
Hi,
You can use ChibiOS exactly as-is, you just need to create 3 very simple files that are specific of the platform.
For example look at the STM32 files here in ./os/ports/GCC/ARMCMx/STM32F4xx, copy them into a directory named ./os/ports/GCC/ARMCMx/LPC43xx and do the small changes required, if in trouble just post here.
Note that there is a demo with the kernel only: ARMCM3-GENERIC-KERNEL. You may start from this one if you don't need an HAL.
Giovanni
You can use ChibiOS exactly as-is, you just need to create 3 very simple files that are specific of the platform.
For example look at the STM32 files here in ./os/ports/GCC/ARMCMx/STM32F4xx, copy them into a directory named ./os/ports/GCC/ARMCMx/LPC43xx and do the small changes required, if in trouble just post here.
Note that there is a demo with the kernel only: ARMCM3-GENERIC-KERNEL. You may start from this one if you don't need an HAL.
Giovanni
Re: LPC4330
OK !
The application is a multichannel audio interface. It has USB2 high-speed, ethernet, and lots of IO.
It can act as a USB soundcard with digital audio IO. With two identical boards linked through ethernet, it will also be able to send the digital audio through ethernet, which is nice, since it can go longer than the 5 meters limit of USB, be routed through a PC for DSP/EQ, and provides isolation.
So, this application is kind of married to LPC43xx series from NXP, since they're the only chips out there with Ethernet, USB2 highspeed, and proper multichannel audio IO capability. Therefors, I don't feel too bad about non-portable code !...
The CPU is Cortex-M4. I also use the other core (Cortex-M0) but the OS doesn't have to know about it, no need for multicore OS here. The M0 just runs a single interrupt.
I've got most of the code done, the ethernet hardware in this chip kicks ass, it can handle full 100Mbps both ways with something like 25% cpu load ; the USB hardware isn't too bad either, 8 channel playback uses like 5% cpu load.
I have reached a point where the code is going to be a horrible mess if I don't use a RTOS
FreeRTOS needs 10µs for task switching... I have measured it with my scope... on a 200MHz CPU, that's ridiculous. With USB2 sending 8k packets/s, this means all stuff like audio packet and buffering code would need to be outside the OS.
I am using LPCXPresso which is the official NXP IDE.
It is compatible with my debug probe, kind of works not too bad (although being based on Eclipse, it is prone to suck in many subtle ways)...
I'm using LPCOpen (the NXP sort-of-HAL), which provides hardware drivers for most of the stuff. It replaces CMSIS, so I don't use it.
The C runtime is redlib (provided by LPCXpresso), which has its own startup code, which copies everything from SPI flash to RAM, does the setup, etc.
I'm going to keep those, they works well, so I'll probably end up removint some of the chibios initcode.
I think I will also use the functions from LPCOpen in the chibios port file. They're here... no need for duplication.
So...
I have simply looked at the chibios makefiles and copied the needed chibios files into a directory which is shared between my IDE projects.
And right from the start, boom, gcc complains about something :
chcore_v7m.h:385:25: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'asm'
register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL;
Actually, it is because it wants __asm and not "asm", I searched for a "#define asm __asm" in chibios source code, did not find anything. So I just searched and replaced.
It compiles without error now....
Todo :
- modify the config includes to use existing #defines like cpu type, interrupt bitmasks, etc.
- hack the startup code to integrate it with LPCOpen/Redlib (Chibios and Redlib both want to own the interrupt vectors... hm...)
- linker script (everyone's favorite)
The application is a multichannel audio interface. It has USB2 high-speed, ethernet, and lots of IO.
It can act as a USB soundcard with digital audio IO. With two identical boards linked through ethernet, it will also be able to send the digital audio through ethernet, which is nice, since it can go longer than the 5 meters limit of USB, be routed through a PC for DSP/EQ, and provides isolation.
So, this application is kind of married to LPC43xx series from NXP, since they're the only chips out there with Ethernet, USB2 highspeed, and proper multichannel audio IO capability. Therefors, I don't feel too bad about non-portable code !...
The CPU is Cortex-M4. I also use the other core (Cortex-M0) but the OS doesn't have to know about it, no need for multicore OS here. The M0 just runs a single interrupt.
I've got most of the code done, the ethernet hardware in this chip kicks ass, it can handle full 100Mbps both ways with something like 25% cpu load ; the USB hardware isn't too bad either, 8 channel playback uses like 5% cpu load.
I have reached a point where the code is going to be a horrible mess if I don't use a RTOS

FreeRTOS needs 10µs for task switching... I have measured it with my scope... on a 200MHz CPU, that's ridiculous. With USB2 sending 8k packets/s, this means all stuff like audio packet and buffering code would need to be outside the OS.
I am using LPCXPresso which is the official NXP IDE.
It is compatible with my debug probe, kind of works not too bad (although being based on Eclipse, it is prone to suck in many subtle ways)...
I'm using LPCOpen (the NXP sort-of-HAL), which provides hardware drivers for most of the stuff. It replaces CMSIS, so I don't use it.
The C runtime is redlib (provided by LPCXpresso), which has its own startup code, which copies everything from SPI flash to RAM, does the setup, etc.
I'm going to keep those, they works well, so I'll probably end up removint some of the chibios initcode.
I think I will also use the functions from LPCOpen in the chibios port file. They're here... no need for duplication.
So...
I have simply looked at the chibios makefiles and copied the needed chibios files into a directory which is shared between my IDE projects.
And right from the start, boom, gcc complains about something :
chcore_v7m.h:385:25: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'asm'
register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL;
Actually, it is because it wants __asm and not "asm", I searched for a "#define asm __asm" in chibios source code, did not find anything. So I just searched and replaced.
It compiles without error now....
Todo :
- modify the config includes to use existing #defines like cpu type, interrupt bitmasks, etc.
- hack the startup code to integrate it with LPCOpen/Redlib (Chibios and Redlib both want to own the interrupt vectors... hm...)
- linker script (everyone's favorite)
- Giovanni
- Site Admin
- Posts: 14565
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1112 times
- Been thanked: 937 times
- Contact:
Re: LPC4330
Hi,
"asm" is a valid GCC keyword, it should work as-is if you provide the same options you can see in the Makefile. If you are not using the ChibiOS startup files please make sure to fulfill all the startup requirements.
ChibiOS does not need to own the vectors table but usually it is a good idea to use what it is provided in order to avoid integration problems. You can rename default names using -DvectorXX=mynewname.
About context switch, our license allows benchmarking and encourages publishing results
Giovanni
"asm" is a valid GCC keyword, it should work as-is if you provide the same options you can see in the Makefile. If you are not using the ChibiOS startup files please make sure to fulfill all the startup requirements.
ChibiOS does not need to own the vectors table but usually it is a good idea to use what it is provided in order to avoid integration problems. You can rename default names using -DvectorXX=mynewname.
About context switch, our license allows benchmarking and encourages publishing results

Giovanni
Re: LPC4330
The project was set to std=c99, I set it to gnu99 which allows "asm" keyword.
Here's another funny one.
LPCOpen has : typedef enum {FALSE = 0, TRUE = !FALSE} Bool; (why not !)
ChibiOS uses #defines and #ifs as usual...
However...
This displays "TRUE is false", like you'd expect from any properly behaving PHP application
I modified the LPCOpen header...
Here's another funny one.
LPCOpen has : typedef enum {FALSE = 0, TRUE = !FALSE} Bool; (why not !)
ChibiOS uses #defines and #ifs as usual...
However...
Code: Select all
typedef enum {F=0, T=1} foo;
#if T
#error TRUE is true
#else
#error TRUE is false
#endif
This displays "TRUE is false", like you'd expect from any properly behaving PHP application

I modified the LPCOpen header...
- Giovanni
- Site Admin
- Posts: 14565
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1112 times
- Been thanked: 937 times
- Contact:
Re: LPC4330
The definitions in chtypes.h try to play nice with redefining macros but cannot perform a check on an enum.
There is not much I can do there, enums are bad in that role. Using an enum you cannot do:
for the same reason it would be wrong to do:
The best thing would be everybody aligning to C99 but this is taking a while apparently.
Giovanni
Code: Select all
/**
* @brief Generic 'false' boolean constant.
*/
#if !defined(FALSE) || defined(__DOXYGEN__)
#define FALSE 0
#endif
/**
* @brief Generic 'true' boolean constant.
*/
#if !defined(TRUE) || defined(__DOXYGEN__)
#define TRUE (!FALSE)
#endif
There is not much I can do there, enums are bad in that role. Using an enum you cannot do:
Code: Select all
#define MY_SWITCH TRUE
#if MY_SWITCH
....
#endif
for the same reason it would be wrong to do:
Code: Select all
#define TRUE true
#define FALSE false
The best thing would be everybody aligning to C99 but this is taking a while apparently.
Giovanni
Re: LPC4330
Yeah, I know. I've modified the LPCOpen headers to use proper defines.
I have also checked on my FreeRTOS numbers, they seem correct, asserts are not enabled etc, I don't see anything wrong in the config. A more precise measurement gives 11.4µs per context switch, and I can get it down to 10.9µs if I put the code and data in separate RAM areas that the CPU can access in parallel... not much of a change.
I have reorganized the LPC libraries startup code and linker scripts more to my liking, for example relocating the vector table in RAM instead of SPI Flash to make it faster.
ChibiOS now compiles and links with my app, but I have not run it yet. I need to make sure the init code sets the interrupts, etc, as ChibiOS needs.
I have a doubt...
LPC libraries : #define __NVIC_PRIO_BITS 3
ChibiOS' cmparams.h sets : #define CORTEX_PRIORITY_BITS 4
The LPC43xx manual says "Eight programmable interrupt priority levels with hardware priority level masking" which means 3 bits...
So, the "#define CORTEX_PRIORITY_BITS 4" worries me a bit... what do you think ?
I have also checked on my FreeRTOS numbers, they seem correct, asserts are not enabled etc, I don't see anything wrong in the config. A more precise measurement gives 11.4µs per context switch, and I can get it down to 10.9µs if I put the code and data in separate RAM areas that the CPU can access in parallel... not much of a change.
I have reorganized the LPC libraries startup code and linker scripts more to my liking, for example relocating the vector table in RAM instead of SPI Flash to make it faster.
ChibiOS now compiles and links with my app, but I have not run it yet. I need to make sure the init code sets the interrupts, etc, as ChibiOS needs.
I have a doubt...
LPC libraries : #define __NVIC_PRIO_BITS 3
ChibiOS' cmparams.h sets : #define CORTEX_PRIORITY_BITS 4
The LPC43xx manual says "Eight programmable interrupt priority levels with hardware priority level masking" which means 3 bits...
So, the "#define CORTEX_PRIORITY_BITS 4" worries me a bit... what do you think ?
- Giovanni
- Site Admin
- Posts: 14565
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1112 times
- Been thanked: 937 times
- Contact:
Re: LPC4330
Well ! It seems to work now !
I had to modify chcore_v7m.c, in _port_init() :
SCB_VTOR = CORTEX_VTOR_INIT;
The vectors are set by my startup code, so _port_init() was setting them back to 0... after commenting this line, it works.
I did the same benchmark as FreeRTOS, except I used mailboxes instead of queues.
Main thread sends incrementing integers in a mailbox of size 1, the other thread fetches them from the mailbox and outputs the lowest bit of the integer on a GPIO.
So, in release mode, no asserts, etc :
- FreeRTOS outputs 45kHz
- ChibiOS outputs 186 kHz ... WHOA
Each period means 2 ints were transmitted through the mailbox, so the mailbox throughput is double that.
And I just realized that each period has 4 context switches and not 2, so my previous FreeRTOS numbers were actually wrong. My bad.
- FreeRTOS 4x45kHz = 180kHz => 5.5 µs
- ChibiOS 4x186kHz = 744kHz => 1.34 µs
This isn't a very accurate "context switch only" measurement since it includes the MBox overhead, but it is more meaningful for me, as my threads will be using MBoxes to communicate.
The FPU is enabled also.
If I use a larger size mbox, I measure about 560ns to insert or extract a message in it (without context switch, but with locking).
It's extremely fast... Is this in the right ballpark for a 204 Mhz cortex M4 ?
Many thanks for your help !
I had to modify chcore_v7m.c, in _port_init() :
SCB_VTOR = CORTEX_VTOR_INIT;
The vectors are set by my startup code, so _port_init() was setting them back to 0... after commenting this line, it works.
I did the same benchmark as FreeRTOS, except I used mailboxes instead of queues.
Main thread sends incrementing integers in a mailbox of size 1, the other thread fetches them from the mailbox and outputs the lowest bit of the integer on a GPIO.
So, in release mode, no asserts, etc :
- FreeRTOS outputs 45kHz
- ChibiOS outputs 186 kHz ... WHOA
Each period means 2 ints were transmitted through the mailbox, so the mailbox throughput is double that.
And I just realized that each period has 4 context switches and not 2, so my previous FreeRTOS numbers were actually wrong. My bad.
- FreeRTOS 4x45kHz = 180kHz => 5.5 µs
- ChibiOS 4x186kHz = 744kHz => 1.34 µs
This isn't a very accurate "context switch only" measurement since it includes the MBox overhead, but it is more meaningful for me, as my threads will be using MBoxes to communicate.
The FPU is enabled also.
If I use a larger size mbox, I measure about 560ns to insert or extract a message in it (without context switch, but with locking).
It's extremely fast... Is this in the right ballpark for a 204 Mhz cortex M4 ?
Many thanks for your help !
- Giovanni
- Site Admin
- Posts: 14565
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1112 times
- Been thanked: 937 times
- Contact:
Re: LPC4330
Hi,
This is consistent with my data, it is about right, thanks for sharing
Synchronous messages are even faster (no buffering, pure context switch) but only allow for thread to thread communication, not ISR to thread.
Giovanni
This is consistent with my data, it is about right, thanks for sharing

Synchronous messages are even faster (no buffering, pure context switch) but only allow for thread to thread communication, not ISR to thread.
Giovanni
Who is online
Users browsing this forum: No registered users and 1 guest