hmnewsteo wrote on Friday, October 27, 2017:
Hi
In a CortexM3 SiLabs EZR32, I use FreeRTOS (V7.5.2 provided with the IDE of my microcontroller) and a SPI port sharing five SPI devices : a SRAM, a FLASH, an accelerometer, an RF driver and a 3G Modem.
The firmware periodically accesses to all of those devices.
To protect access to the SPI port, I’ve used a mutex “xSPIMutex”.
So before each acces to an SPI device, I call xSemaphoreTake(xSPIMutex, portMAX_DELAY), and after each access I call xSemaphoreGive(xSPIMutex).
SPI port is never used in an interrupt subroutine, but only called from a task.
One of the tasks accessing to the PSI port has a higher priorty for the use of SPI. That’s why I added in this task :
xSemaphoreTake(xSPIMutex, portMAX_DELAY);
vTaskPrioritySet(xTaskGetCurrentTaskHandle(), TASK_USUAL_PRIORITY + 1);
before any access to the SPI port, and
vTaskPrioritySet(xTaskGetCurrentTaskHandle(), TASK_USUAL_PRIORITY);
xSemaphoreGive(xSPIMutex);
after each acces.
My problem is that after a few seconds and a few volleys of access to the SPI port, a xSemaphoreGive(xSPIMutex) ends with a uxMutexesHeld = 0 :
- xSemaphoreGive(xSPIMutex) calls xQueueGenericSend
- xQueueGenericSend calls prvCopyDataToQueue
- prvCopyDataToQueue calls xTaskPriorityDisinherit
- xTaskPriorityDisinherit finds a blank pxTCB->uxMutexesHeld so when it calls configASSERT it enters a while(1); loop.
The problem does not occurin the task in which the priority is higher.
Here’s a part of FreeRTOSConfig.h :
define configMAX_PRIORITIES ( 4 )
define configMINIMAL_STACK_SIZE (( unsigned short ) 140)
define configTOTAL_HEAP_SIZE (( size_t )(10000))
define configMAX_TASK_NAME_LEN ( 10 )
define configUSE_TRACE_FACILITY ( 0 )
define configUSE_16_BIT_TICKS ( 0 )
define configIDLE_SHOULD_YIELD ( 0 )
define configUSE_MUTEXES ( 1 )
define configUSE_RECURSIVE_MUTEXES ( 0 )
define configUSE_COUNTING_SEMAPHORES ( 0 )
define configUSE_ALTERNATIVE_API ( 0 )/* Deprecated! */
define configQUEUE_REGISTRY_SIZE ( 10 )
define configUSE_QUEUE_SETS ( 0 )
I’ve tried to increase “configQUEUE_REGISTRY_SIZE” and “configMINIMAL_STACK_SIZE” with no effect.
“configTOTAL_HEAP_SIZE” can not be higher, as all available RAM seems to be already used.
For each SPI device, I’ve written a device_select() and a device_unselect() function where I take then give the mutex.
Those functions are called before and after each access to SPI.
Could anyone help me ?
Thank you for any help.
Herve