0
votes

I'm using FreeRTOS with STM32F407. I have problem with wrong context switch restoration. The code goes like this inside task code:

char *ptr = pvPortMalloc(sizeof(char) * size);
memcpy(ptr, buf, size);
...
log("Before:");
logItoa((int)ptr);

blockingFunction(); // Here preemption will occur

log("After:");
logItoa((int)ptr);

blockingFunction() does not use ptr. When I debug I can see, that the address pointed by the ptr is stored with instruction:

STR R0, [R7, #24]

so I check the value under the address (R7 + 24)(^1) in data memory and see that the address to dynamically allocated data is successfully saved.
After context restoration I check the variable ptr and see, that it isn't pointing on my newly allocated data, so I check the value under the address (^1) and see, that the value remains unchanged, but value in R7 register (used for address counting) isn't same as before preemption.
It leads to situation when each of my local variables aren't the same, because they're wrongly fetched from data memory.
If it's kind of stack overflow issues, how can I debug it?

2
The quickest way would be to increase the task stack size and see if the problem goes away. You could also try increasing the system stack size in case this is too small. What toolchain are you using? Also I assume the malloc is not inside the task loop? - Realtime Rik
I allocated almost whole RAM for FreeRTOS heap size and xPortGetMinimumEverFreeHeapSize() returns about 50MB free. I allocated also for each of my tasks two times more stack size. For each of my tasks uxTaskGetStackHighWaterMark returns value which shows that it is impossible to occur stack overflow. The only task, which I didn't check is LWiP thread, but I don't think that's making problems. I'm using gcc-arm-none-eabi-5_4-2016q3. It is inside task loop, but it the loop starts with: xQueueReceive() which is unblocked once an hour. Of course at the end the memory is freed. - K. Koovalsky
It does not sound like a stack overflow problem then. The storing and restoring of the registers is done in xPortPendSVHandler (apart from the automatically stored ones). You could debug here, however you come here for every context switch so it can be tricky to catch it when it is restoring your task. - Realtime Rik

2 Answers

1
votes

Most issues on Cortex-M come down to incorrect interrupt priority assignments and stack overflow, so later versions of FreeRTOS have lots of traps for both of these errors to let you know immediately if they occur - but you have to turn on the ability to trap these common errors, as per below:

Do you have configASSERT() defined, and which version of FreeRTOS are you using? The later the version the more helpful configASSERT() will be.

Do you have configCHECK_FOR_STACK_OVERFLOW set to 2 and a stack overflow hook defined?

0
votes

I found the source of problem. Inside the blockingFunction() there were buffer explicitly filled. The buffer was too small and overwrote my task's TCB.