FreeRTOS along with Arduino

martinayotte
Tue Sep 22, 2015 12:48 am
I’m looking to use FreeRTOS on a new project, but I still want to keep the Arduino environment.
In other words, I want to keep the best of both worlds.

I’ve found the FreeRTOS from Bill Greiman, https://github.com/greiman/FreeRTOS-Arduino, but I didn’t make it work yet, although I’ve got it compile.
It is freezing at the first xTaskCreate(). I’m not sure why, but I presume that it somehow get problems with the stack management or something like that.

Reading before that some of you used FreeRTOS, can you tell me which flavours you have used ?
Is it possible to keep the best of both worlds with those flavours too ?

Probably I will move my tests from my Netduino2Plus onto my my STM32F4Stamp, because I can attach STLink on the first one without purchasing some 6 pins pogo, so on the Stamp, I will maybe found the issue thru debugging …


stevech
Tue Sep 22, 2015 2:33 am
There is a port of FreeRTOS for the Teensy 3 Freescale ARM with Arduino libraries. I ran it. Moving it to the ST shouldn’t be hard.
You can start with the Teensy 3 version download on their forum.

As you may know, ST’s CubeMX and HAL libraries have a FATFS and FreeRTOS port. Those use the HAL libraries which are a superset of the Arduino libraries except for specific Arduino projects, e.g., serial LED video walls.


martinayotte
Tue Sep 22, 2015 2:50 am
stevech wrote:There is a port of FreeRTOS for the Teensy 3 Freescale ARM with Arduino libraries.

victor_pv
Tue Sep 22, 2015 3:50 am
FreeRTOS was ported years ago for the Maple.
A few months back I compared the original STM32 files with that port, and then applied the changes over to the latest FreeRTOS available the the time, I think it was 8.2.1
Both versions are included in the main stm32duino repo, in the libraries folder.

I have tested both successfully, and Madias is doing a project right now with it, seems to work good.
If you are trying to use freeRTOS with an STM32 board, I recommend you use either the old or the new one with the rest of the stm32duino/libmaple core.


madias
Tue Sep 22, 2015 7:36 am
As Victor said, I’m working with RTOS from the stm32duino standard library. I think there is no reason using the old version, so please try:
FreeRTOS821
first!
(Maybe there are some more examples in the “FreeRTOS” library)

martinayotte
Tue Sep 22, 2015 12:44 pm
Oh !
I didn’t know it was already integrated as an Arduino style library like the one from Bill Greiman.
Thanks a lot for the info !
I will try it out, especially the Bill’s one was based on v8.0.1. Usually, the newer, the better.

martinayotte
Tue Sep 22, 2015 4:48 pm
Well ! it is working fine with this version. Thanks to all of you ! :)
I won’t care trying to debug the other one, since it is older.
But I had to increase heap size since it was set to only 8K, and STM32F405 has plenty of RAM.
Also I needed to add defines such as configNORMAL_STACK_SIZE, because there was only one as configMINIMAL_STACK_SIZE set to 120 bytes, which is really too small for tasks using SerialUSB or UIPEthernet. I’ve defined configNORMAL_STACK_SIZE at 2048.
I will also need to check the LD scripts, because I’ve just discovered that under STM32F4, even for the old discovery_f407, the ram.ld is set with length to 61K, far from what the chip is providing 192K. I don’t know yet if the heap is really using this value.

victor_pv
Wed Sep 23, 2015 1:47 am
martinayotte wrote:Well ! it is working fine with this version. Thanks to all of you ! :)
I won’t care trying to debug the other one, since it is older.
But I had to increase heap size since it was set to only 8K, and STM32F405 has plenty of RAM.
Also I needed to add defines such as configNORMAL_STACK_SIZE, because there was only one as configMINIMAL_STACK_SIZE set to 120 bytes, which is really too small for tasks using SerialUSB or UIPEthernet. I’ve defined configNORMAL_STACK_SIZE at 2048.
I will also need to check the LD scripts, because I’ve just discovered that under STM32F4, even for the old discovery_f407, the ram.ld is set with length to 61K, far from what the chip is providing 192K. I don’t know yet if the heap is really using this value.

martinayotte
Wed Sep 23, 2015 2:21 am
Thanks, Victor, for the hints !

Yes, I know that F405 doesn’t have linear 192K but, it is segmented. But at least, the main block is 112K with another 16K (I don’t remember for what) and finally 64K CCM (core coupled memory).

But it is kind of relief compare to LPC1768 with total of 64K (32K+16K+16K) … ;)

Yes, I think I have to tweak LD scripts by comparing them with other compiler, because the original Maple are maybe far from been optimized, even the comments still mentioned F103 due to copy/paste … :?

Thanks for links, it will be helpful !


stevech
Wed Sep 23, 2015 6:31 am
Beware the CCM memory region cannot be used for DMA based I/O. It’s core-coupled and not addressable by the DMA controllers.

Avoiding this is up to the programmer, not the compiler or linker.


martinayotte
Wed Sep 23, 2015 2:31 pm
What would be the best use for this CCM ?
I saw some threads where people place the FreeRTOS stacks in there.
Some others suggest generic buffers (without DMA), lookup tables, even some codes for fast handling.
But is there other possibilities without having to think twice before using any things there ?

stevech
Wed Sep 23, 2015 7:50 pm
martinayotte wrote:What would be the best use for this CCM ?
I saw some threads where people place the FreeRTOS stacks in there.
Some others suggest generic buffers (without DMA), lookup tables, even some codes for fast handling.
But is there other possibilities without having to think twice before using any things there ?

martinayotte
Wed Sep 23, 2015 9:00 pm
@stevech, if you have custom LD scripts, maybe it can be helpful to share them, since, as I described earlier, the ones under F4 are quite far from the best, they looks like copies of F1 probably a bit tweaked.
I wish to have the best of F4 been committed in our github.

stevech
Wed Sep 23, 2015 11:49 pm
My linker scripts are coded for IAR, not GCC. I’d have to study up on GCC ld scripts to translate.

martinayotte
Thu Sep 24, 2015 12:33 am
Then, if you work with any F4 boards with smt32duino, you can update the LD scripts directly to the ones are already present in Github, it will be very appreciated. If you need a QA tester, I will be there to help … ;)
Of course, all those people like me that are not fluent with those will need the be a bit briefed about which attribute to use if we wish to benefit from this.

stevech
Thu Sep 24, 2015 2:23 am
(this post is broader than FreeRTOS, the thread title).

Here’s a linker script for IAR’s linker. It’s fairly self-documenting and I can explain if needed.
A “guru” could set all this up and just document how the rank and file can use it.

Somone can adapt this for GCC’s ld script.
This is an STM32F415’s linker file. There’s a named section “CCMRAM” for the CCM space. Sections can be used to force variable(s) to go somwhere in that region. Such as a big array of bytes. Or RAM buffers for FATFS – if your SD card interface (SDIO, SPI) will not be DMA based.
GCC will have the same concept, different syntax.

You can declare an array of uint8_t in CCRAM. Then cast the byte pointer to other types’ pointers so simplify shared use of the buffer, so long as you don’t create a conflict. (A buffer ownership semaphore lock is an overkill in a single threaded MCU environment.)

Example linker file (IAR compiler’s syntax). The first part is auto-generated by the IAR IDE. The rest is custom coded.
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__];

define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };

initialize by copy { readwrite };
do not initialize { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
place in CCMRAM_region { section CCMRAM }; /* added Aug2015 SLC */


martinayotte
Thu Sep 24, 2015 1:43 pm
Thanks a lot, Stevech !
I will try to adapt this to GCC when I get chance.

Leave a Reply

Your email address will not be published. Required fields are marked *