Hello,
I have to finish a software based on TMS5730LS3137 + HALCOGEN (TI Software Generation Tool) + FreeRTOS. This software was started by someone else which left the company.
I do not have any experience with this CPU, so it takes me many weeks to understand how it works!
I finally found the root cause of the application spurious crashes, it was a DABT on address 0xFFFFFFB0 (SSIR1 Register).
In my application, MPU is disabled.
After further research, I saw that this error was raised in FreeRTOS xTaskResumeAll() function. Sometimes, when taskYIELD_IF_USING_PREEMPTION() is called, the CPU is still in user mode!
This happens, when calling vPortMalloc()/vPortFree().
What I cannot understand, is why sometimes CPU is in user mode at this moment.
Is this a known issue?
TI uses FreeRTOS 9.0.0, as workaround for this issue I changed portYIELD_WITHIN_API()to enable privileged mode when required:
A better solution would be find out why the CPU is in user mode while inside the xTaskResumeAll API. You can try to put a breakpoint at prvRaisePrivilege in your modified portYIELD_WITHIN_API. This would give us a callstack to analyze when CPU is in the user mode inside a FreeRTOS API.
This is obvious to me, when calling vPortMalloc() from a Task, there is no switch into privileged mode, in heap_4.c, the MPU wrappers are disabled (MPU_WRAPPERS_INCLUDED_FROM_API_FILE).
So, it look like vPortMalloc()/vPortFree() may not work in user mode… But is this really wanted like this?
As I wrote before, I have to finish this project, started from another developer.
I had a hard time to understand how CortexR4 works, and have not spend too much time to analyse the TI FreeRTOS implementation.
MPU usage is disabled in TI-HALCOGEN, I supposed this suffisant:
Can you put a breakpoint in any other FreeRTOS API in your application which is not coming from logging (something like queue send/receive, semaphore give/take) etc?
When pvPortMalloc()/vPortFree() are called from other API function, like xQueueGenericSend(), the corresponding MPU routine is used. This way the privilege mode is enabled, and no Data Abort Interrupt is generated!
With all FreeRTOS API routines, MPU “variants” are used, only for pvPortMalloc() and pPortFree() it is not the case!
I agree with you, this is very confusing!
adding MPU_pvPortMalloc() and MPU_vPortFree() solve my issue in a much cleaner way!
To complete my reply, I had to change a little bit the implementation of prvRaisePrivilege(). Because the implementation done by TI always force the switching into System mode!
I added a simple check, to only switch into System mode when CPU is in User mode (as MPU_vPortFree() / MPU_pvPortMalloc() may be called for IRQ mode)
Have you made sure that vPortMalloc/vPortFree are safe to use in an ISR? That would generally require that the functions do their work inside a big critical section, which would add a lot of possible latency to ISR responce.