I am attempting to write a SafeRTOS application for the LM3S9D96, beginning with the safeRTOS_demo, (The one with the spiders)
What I have attempted to do is to add two stubbed tasks with a structure as follows:
void basicMasterRunTask(void *pvParameters) { printf("Basic MasterTask Running.\n");
while(1) { //Block this task for some number of clock ticks if( xTaskDelay(50) == errSCHEDULER_IS_SUSPENDED ) { printf("Basic MasterTask: scheduler is suspended!\n"); } } }
As I mentioned, I have two functions stubbed in this manner. Each of them appears to function on it's own if I disable one by not creating it. If both tasks are created, FaultISR is triggered. What could be going wrong? I have tried varying the number of ticks passed to xTaskDelay, but It seems to have no effect.
How can I go about tracking this down? Is there something in the structure of SafeRTOS that I can look at to get some direction?
I changed one of the tasks to use xTaskDelayUntil(). behavior is similar with the exception that when I pause execution, I no longer go to the FaultISR. Instead I get "No source available for "0x20000ce" If I am interpreting the memory map correctly, That appears to be an unused portion of flash.
MEMORY CONFIGURATION name origin length used unused attr fill---------------------- -------- --------- -------- -------- ---- -------- FLASH 00000000 00080000 0002b174 00054e8c R X SRAM 20000210 00017df0 0000fc96 0000815a RW X
Hi Andrew,
Normally, in the case of a FaultISR being triggered, I would recommend taking a look at the FAULTSTAT register. The bits in this register (whose meanings can be found in the datasheet) can give you details about what caused the fault. In this case, however, it seems like you might be suffering from stack corruption or stack overflow issues. This can cause variables in SRAM to have corrupted values, and may cause the program counter to jump to unusual places. This is especially true in RTOS situations, where several tasks have SRAM space allocated in adjacent memory locations.
How much memory do you have allocated for your overall system stack, and how much is each task in your system allocated? If there is a task that doesn't quite fit, you may want to increase the overall stack size.
If size isn't the problem, this may be more difficult to track down. If you just have a bad pointer somewhere, or some sort of resource mismanagement is causing stack corruption without overflow, you will need to either step through the code and watch it happen, or set up a way to periodically read variables in SRAM to figure out when the corruption is happening.
If none of these options seem to help, let me know, and we can try to come up with a different debugging approach.
Regards,Christian
Thank you for your response, and please forgive my ignorance:
I have set what I think is the overall stack size (Build->TMS40 Linker->Basic Options - "Set C system stack size...) to 0x800 as recommended for use with console output in the Getting Started guide for the DK-LM3S9D96. For the tasks existing in the safertos_demo, I have not changed the individual stack sizes, copying the form of the stack array from led_task for my new task, like this:
unsigned long _taskStack[128];
This seems like it should be adequate for the task, as there is almost nothing in it.
One of the things that I am curious about, is whether the task stack is actually where the task is executed, or if the stack is from/to this buffer when a context switch occurs, and whether adding more tasks with this size increases the demand on the size of the "overall" stack.
I have attempted to increase the size of the overall stack to 0xF00. There was no change in behavior. I can still initialize either of my stubbed functions, but if I do both, the program appears to deadlock. One interesting thing to note is that although the program appears to lock when both of my stubbed tasks are enabled, The programs seems to go to the mystery section in the neighborhood of 0x200.0000 with only one task enabled. I think perhaps this may be a piece of ROM containing a SafeRTOS function. With both tasks enabled, I can still catch myself going to the same location. Trying the original safertos_demo...Yes, that seems to be what is calling SafeRTOSIdleHook()
After the Idle Task returns, execution loops between 0x0200.0c16 and 0x0200.0c22, so now I have convinced myself that this is a ROM safeRTOS function, but it would be neat to see a map of the ROM to know what it is. Going back to my application, I'm seeing breaks take me mainly to the IdleHook. I'm getting the idea that all of my tasks are blocked. I wonder if there is some way to inspect task status.
The last thing I'll wonder out loud about is whether the counting of tasks is of any consequence. I have not incremented the task number when adding tasks, as it appears at my superficial inspection to be cosmetic to the safertos_demo.
Thank you for any insights you can offer me, feel free to wax verbose on the basics of which I may be clueless.
I've acquired the ebook "Using the FreeRTOS real-time kernel a Practical guide" Which had a section on troubleshooting a demo program which crashes when a simple task is added. I had already increased my heap size to 0x800 in order to make use of printf, so I decided to increase it again, this time to 0xF00. The result was that I have gone from apparently stalling in the idle task to generating a fault interrupt. At Christians recommendation, I tried to look at the FAULTSTAT register. Eclipse's register browser did not seem to line up precisely with the one in the LM3S9D96 datasheet. There was so SystemControlBlock(SCB) appearant among the peripherals. The datasheet does state the base address and offset for FAULTSTAT, HFAULTSTAT, MMADR, and FAULTADDR:
Perifial Base Address: 0xE000.E000
FAULTSTAT: 0xD28
HFAULTSTAT: 0xD2C
MMADDR: 0xD34
FAULTADDR: 0xD38
Using the Memory browser I looked up the locations manually.
FAULTSTAT, and HFAULTSTAT appear to be clear. Since there is no MMARV bit set high, the value E000EDF8 in MMADDR(0xE000ED34) should not be valid. Apparently the same value is in FAULTADDR(0xE000.EDF8). I don't know what significance the value 00000002 in the register betwen HFAULTSTAT and MMADDR might be.
I have repeated this process with the slight variation that 0x80000000 shows up in HFAULTSTAT (0xE000ED2c) corresponding to the DBG bit (I don't know what that means. And the mystery register (0xE000ED30) showing a value of 0x00000003.
I still don't know what this register is, or how surprised I should be that I am entering the FaultISR with nothing in FAULTSTAT.
I seem to have fixed the problem (at long last) I was using printf to let myself know that I had indeed entered new tasks. The new tasks have stack buffers composed of an array of unsigned long with 128 elements. It seems that was enough to overwhelm the already increased stack/heap allocations. The problem was fixed when I further increased them to 0x1000 each. I'll take this as the answer, although I don't know what considerations need to come into play when allocating stack and heap space.