FreeRTOS stack issue, program variables getting stepped on during FreeRTOS background processing.

pblase wrote on Thursday, November 22, 2018:

Working on an Atmel ATSAMC21N-XPRO demo board (ATSAMC21N18A processor), using Atmel Studio with the GNU tools, FreeRTOS rev 10.0.0 as per the Atmel START web utility. The main program is written in C++, with the files copied over from a separate project created by the START utility (which uses ASF 4 and only works with C; however all files have the proper

#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus

surrounding them and compile fine. I’ve had similar code running before, without FreeRTOS, and it seems to work fine.

In the main program file, there’s the instantiation of a class
Heartbeat_LED_task_t Heartbeat_LED_timer;

In the .map file, this ends up right below the FreeRTOS stuff:

 .bss           0x200004d0       0x20 ProElec_R2_ATSAMC21N.o
                0x200004d0                ErrorInfo
                0x200004d4                retval
                0x200004d8                Heartbeat_LED_timer <===
 .bss           0x200004f0      0x968 thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang/heap_1.o
 .bss           0x20000e58       0xec thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/tasks.o
                0x20000e58                pxCurrentTCB
 .bss           0x20000f44       0x3c thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.o

So far so good.

The task that uses Heartbeat_LED_timer executes its loop once every 10th second and then uses
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(HEARTBEAT_LOOP_ms)); //tenth second
to delay until the next .1 second mark.

While the program is sleeping, between calls, the FreeRTOS steps on it; pretty much any time that FreeRTOS uses a local variable, it ends up located inside of the above variables.

For instance, I used the data-change breakpoint to trace it and found:

Line 2016 of tasks.c is

	UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */

which is in xTaskResumeAll(void).

When this executes, uxPendedCounts is located in the middle of Heartbeat_LED_timer!

Looking at the disassembly, uxPendedCounts is found at R7 + 4
(" 000063FC str r3, [r7, #4]")
Sure enough, R7 is pointing right to the middle of Heartbeat_LED_timer. R7 is set somehow in the setup for xTaskResumeAll().
( put a screenshot in the attached .zip file)
Obviously there’s a setting wrong somewhere, but I have no clue what it could be.

rtel wrote on Thursday, November 22, 2018:

On the assumption you have checked your stack sizes, and have stack
overflow protection set to 2
( this
would, on first reading, seem to be some kind of linker script problem
as FreeRTOS doesn’t decide where variable are allocated. Maybe related
to the use of C++ but I can’t be sure? When C++ is used its best to get
that into the subject of the thread so others that use C++ themselves
see it.

pblase wrote on Friday, November 23, 2018:

Is this code executing in the task stack, or is there a separate stack for the kernal itself?

rtel wrote on Saturday, November 24, 2018:

I’m not sure what is meant by executing in the task stack. Do you mean using the task stack? FreeRTOS applications are just normal C application (C++ in this case) so how the stack is used is completly up to the compiler while tasks are running. When an interrupt executes then the stack is swtich, but everything else uses the task’s own stacks.

pblase wrote on Saturday, November 24, 2018:

The code in tasks.c executes in the background, independent of any task. Ok, so it’s an application problem, either the entire application is overflowing the stack, not likely, or some memory parameter is set wrong.

richarddamon wrote on Saturday, November 24, 2018:

Paul, ALL code that executes once the scheduler starts MUST run either in the context of a task, or the context of an interrupt. There isn’t a ‘the task stack’, but each task is given its own stack, and the scheduler switches tasks by changing which stack is being used.

pblase wrote on Saturday, November 24, 2018:

Just as a note, several people have used FreeRTOS with C++ with few problems.

richarddamon wrote on Saturday, November 24, 2018:

Yes, C++ is not generally the issue. C++ problems tend to give errors at compile/link time, unless you make the big mistake of putting a non-POD type into a queue. The basic problem sounds to be memory overruns or memory map issues which are about as easy to create with C code as C++ code.

pblase wrote on Saturday, November 24, 2018:

Ok. The problem was that the stack wasn’t quite big enough. The Process Stack Pointer must be used to point to the thread stack, the Main Stack Pointer to the application stack (at the far end of memory). Since the PSP is decremented during pushes, it simply went past the end of the allocated FreeRTOS tasks.o area (where the task stacks are).