Hi,
I think I found a bug in the mpu_wrappers.c
of the TI Hercules FreeRTOS port.
Context
I’m trying to use Tracealyzer in snapshot mode with the FreeRTOS Kernel 10.3.1 and a TI Hercules TMS570LS1224 microcontroller. Please note that this microcontroller has an MPU on it.
While doing so I encountered an unhandled prefetchEntry exception. Using the CP15 (AMR) register, I was able to conclude it was a permission fault that caused the exception.
Using my debugger, I was able to reproduce the bug.
Here’s the call stack that is causing the problem:
TO MPU_ucQueueGetQueueType(struct QueueDefinition *)()
prvTraceGetQueueType(void *)()
prvInitialiseNewQueue(unsigned long, unsigned long, unsigned char *, int, struct QueueDefinition *)()
xQueueGenericCreate(unsigned long, unsigned long, int)()
MPU_xQueueGenericCreate(unsigned long, unsigned long, int)()
FROM my_freertos_task(void *)()
As you can see, there are 2 calls to MPU_*
API, which switch from user mode to privileged mode.
Problem (bug?)
When in privileged mode, the xPortRaisePrivilege()
function returns 15
instead of pdTRUE
(1).
This can cause problem when trying to reset to the correct mode.
As the vPortResetPrivilege()
function is implemented has follows:
void vPortResetPrivilege( BaseType_t xRunningPrivileged )
{
if( xRunningPrivileged != pdTRUE )
{
portSWITCH_TO_USER_MODE();
}
}
The nested MPU function will switch to user mode.
The expected behaviour would be to stay in a privileged mode, as we are in a nested MPU call.
Fix
I’m not good enough with assembly to explain why the function was not designed to return a bool, but here’s my quick fix:
void vPortResetPrivilege( BaseType_t xRunningPrivileged )
{
if( xRunningPrivileged == pdFALSE)
{
portSWITCH_TO_USER_MODE();
}
}
With this, I don’t get any exception.
Closing
I would like to have yours thought on this bug and how to fix it.
Also, I’m not sure if this forum is the correct place to post this kind of bug, but I hope it’s helpful to somebody else.
Regards,
Gabriel