I’ve got the usual large program, configuration controlled by include files abusing #ifdef structures.
This is running on an STMicro STML562 with 512K flash and 256K of internal RAM. The QSPI memory interface runs a 32 MBit memory mapped into the processor address space as 2 MB of 32 bit words (32 bit ARM processor).
I have a number of queues in the system, which is packet oriented, has numerous communications, mesh networking, and supports multiple displays, so not quite simple.
My previous architecture was to use the skeleton generated by CubeMXIDE, which uses FreeRTOS 10.3.1 (takes them forever to upgrade RTOS since they prefer Azure), add a call to a setup program (CPP_LINK) after the default task has been created. CPP_LINK creates the main application task.
CPP_LINK was called from the default task before the loop, and then called the main application setup, creating the application task. This returned to the default task which was a 10 second loop since I never used it. (and CubeMXIDE always creates this task).
The IOC configurator has the ability to set up tasks and the like outside of the main task, but has no awareness of conditionals, so the way I configure the system won’t work.
What it looks like to me (and first question) is that the code needed to create a task takes a lot of FreeRTOS heap (I use 4.c). The FreeRTOS stack was set to user supplied, and is maxed out at 256K in the QSPI memory.
I kept having to increase the size of the default task as I added more and more program features, to the point where I was running out of that heap memory. The program kept crashing, or performing unreliably (overwriting things and returning bad results from the scans of queues, semaphores, and tasks).
I moved the creation routine (CPP_LINK) out of the task, and put it into the main program before the oskernelstart, so no task creation inside a task. I have just finished putting the rest of the main program loop into a similar situation, with the main task created, but not actively running. All the setups are not in the main program loop, so that seems to be working properly.
So, design wise, is FreeRTOS really intended to create tasks gracefully from within another task? Is that task creation a temporary memory hog which requires one-time use of the default task’s heap?
Question 2: I noticed that the debugger was erratic until I increased some task heap sizes, but I’m not sure if FreeRTOS has the capability to figure this out. I do have a modified “malloc failed” hook that tells me how much memory I needed and what the shortfall was, but that just came back with zero. So: no task overrun catching? I do have checkforstackoverflow set to option 2, but I may not be using it properly since it doesn’t seem to trip.
I got a lot of hard fault memory accesses, some of which were my fault in the graphics object tree, some of which were caused by memory pointers being corrupted.
Somewhat long, but the devil is in these details. Have I guessed correctly about the design intent of task creation? Things seem to be working better now.
in summary, FreeRTOS heap is in a dedicated memory area per program configuration. Graphics tree, graphics programs, and things not in FreeRTOS are generally in XHEAP (separate memory manager) memory, and should be well behaved. Actual graphics display memories are in yet another area of memory, so everything should be nicely partitioned