STM32L152RC (eval board) and FreeRTOS

dminikol wrote on Friday, December 13, 2013:


I have some weird problems with mentioned configuration of HW and SW. I’m trying to build a working binary in ar-none-eabi-gcc v. 4.8.2 and everything seems to be OK (linker script works correctly, map file shows that every single bit is on its own place, the idle-task can be run successfully). The problems actually starts, when I’m trying to run the second task with priority 1 - it will not run and the Memory management exception is the last thing what OS does on its own. The address in the pc is pointing to the function that implements the task’s functionality. If the tasks priority is below zero, then task will be run (which is a very wrong according to the FreeRTOS documentation). The OS heap size is 10K. Used heap size is 3K all the time. The msp size is 4K and it’s allocated in the end of the RAM. Moreover, any privileged data is not initialized properly for some very strange reasons. Memset (the one from the C’s string header - the app will crash) doesn’t work either.
You can find a project’s code here

My question is: Where can be a possible error?

P.S. I removed from my project every header with copyrights (I’ll add them later back) for my own convenience and it doesn’t mean that I’m stealing FreeRTOS’s code.

rtel wrote on Friday, December 13, 2013:

If the tasks priority is below zero, then task will be run (which is a very wrong according
to the FreeRTOS documentation

The priority is passed into the xTaskCreate() function as an unsigned value - therefore passing a negative number is the same as passing a really massive positive number.

The top bit of the priority is used to determine if the task will run in a privileged mode or not. So, when you attempt to pass in a negative number you are inadvertently creating a privileged mode task. When you pass in a small positive number you are creating an unprivileged task. You can see this by stepping through the first line of the xTaskCreate() function.


dminikol wrote on Friday, December 13, 2013:

Thank you for your answer. Yes, it’s true. I checked it. So, on practice that means, I can create only privileged tasks, am I right? But why FreeRTOS does crash, if none-privileged task is created? And why memset doesn’t work? Why it’s even included if it doesn’t work? Is my linker script(my very first ld script) written correctly?

rtel wrote on Friday, December 13, 2013:

Please read the description of the priority parameter on the xTaskCreate() API documentation page:

Presumably your application (hopefully not FreeRTOS) is generating a memory fault in the MCU when you access memory outside of the memory allocated to the unprivileged task. That won’t happen when the task is running with privileges because then it will be able to access what it likes.

Are you sure you want to be using the MPU port?


dminikol wrote on Friday, December 13, 2013:

Yes, I’m quite sure, I want to use this port. Otherwise I won’t learn anything new.
OK. I see. Yes, an unprivileged task generates memory management fault. So in case of two blinking lights, when I’m accessing a memory mapped peripherals it’s an OK to get a memory fault, am I right? (I’m trying to understand it, so I know that question is a bit stupid, but still…). But then, why it does work in unprivileged mode without FreeRTOS… Your operating system is great and that is the only reason I’m trying to understand it.

ADDED 1: error was found in the ld script. Doesn’t affect a lot on the memory allocation, but still…

ADDED 2: OK. I see… I read about the xTaskCreateRestricted and it seems the only solution in current situation. And for the privileged tasks I still can use good old xTaskCreate.

ADDED 3: guys, thank you for your help and OS.

dminikol wrote on Saturday, December 14, 2013:

May be it’s not broken, but could anybody, please, explain me, why memset doesn’t work with heap_4.c (FreeRTOS 7.6.0 MPU for ARM Cortex M3 stm32l152rc evaluation board)? Even if I’m not creating any task, but IDLE, it will result in a Hard fault. The program counter points to the memset-function, which is in line 2442 (or very close to it, tasks.c). Memcmp doesn’t work either. I still can’t create a task without any privileged rights with xTaskCreate (yes in documentation you told me to use xTaskCreateRestricted). xTaskCreate creates a new task in non-privileged memory area, let’s say this task’s stack starts from the address 0x20001860 (trust me, it’s not privileged memory area, system privileged data’s last address is 0x20000180) and the task simply does nothing(it has only an infinite loop). Still the system will end up with memory fault. More interesting thing, same behavior was seen with port without MPU - system is crashing with memory fault. Also memset and another mem* -functions don’t work either.
It might be that I misunderstand something, but in this case, please, point it out to me. I’ll be glad to hear it.

rtel wrote on Saturday, December 14, 2013:

Only when you are using the MPU port (which is not the normal thing to do):

The only RAM a non-privileged task has access to by default is its own stack. If it attempts to access anything other RAM the MCU (not FreeRTOS) will generate a protection fault. You can manually allocate other RAM regions to it using the provided API. Then it will have access to its stack and the RAM regions specifically allocated to it.

As already noted, by default a task only has access to its own stack. When you call pvPortMalloc() (or whichever memory allocation function you are using) you are forcing the task to attempt to access memory from the heap - which it does not have access to, and the MCU will generate a protection fault. That is expected behaviour, and why normally in MPU ports all memory is statically allocated so the allocated regions can be manually allocated to the tasks that can legitimately access them. If it didn’t do this then it would not be an MPU aware port. If this is not the behaviour you are expecting I would ask again - are you sure you actually want to be using the MPU port?

same behavior was seen with port without MPU - system is crashing with memory fault

Ports without the MPU to not enable either the MPU or the memory protection fault, so that cannot be the case (unless you are manually enabling the MPU in your application code). The fault you are seeing must be something other than a memory protection fault.


dminikol wrote on Saturday, December 14, 2013:

Yes, I’m still sure, I’d like to use an MPU.
Thank you for a such comprehensive explanation.
p.s. It seems I broke some rules of MPU regions, which are well explained in your book and ARM Cortex M3 manual (Start address and the size of the region in bytes).

dminikol wrote on Sunday, December 15, 2013:

Once again thank you for your help and FreeRTOS. BTW, I’m sorry about a memset. It’s basically was my fault, I understood it later. You see, the reason, why it didn’t work was in toolchain - it linked wrong libraries. If you have a look at Makefile I posted, you notice that I’m using a -mthumb option. That way, when the memset called the bl instruction should be used to branch, but in my binary a blx-instruction was used. That means, the MCU was in arm state, which is very wrong. On practice that means, the linker messed up with libraries. After rebuilding a toolchain, I was able to use a memset. Apparently this issue is well-known one. You can find a lot of posts on stackoverflow of that. Typically people are using ld instead of gcc (big mistake) or they forgot to include architecture information into the linker flags.

I also re-wrote a linker script and now kernel’s functions are located to the beginning of the FLASH, right after the interrupt vectors.