Priority inheritance not working as expected

Hi, I’m using a STM32F429I-DISCO board with FreeRTOS V8.2.1 and am trying to understand how scheduling and priority inheritance work when using mutexes and queues. I’m using the BSPLCDDisplayStringAtLine() function to ouput what line just got executed or will get executed next. The output: high high before take mutex 1 high after take mutex 1 high before receive medium medium before take mutex 1 low low before take mutex 2 low before give mutex 1 There’s no more output, but I’d expect the next lines to be medium after take mutex 1 medium before send queue 1 high before send Why doesn’t FreeRTOS switch back to the medium priority task, after it got blocked by the xSemaphoreTake( Mutex1, portMAXDELAY) call and the Mutex_1 was given in the low priority task? Thanks ~~~~ int i = 0; uint32t data[]={1,2,3,4}; static void high (void *) { BSPLCDDisplayStringAtLine (i++, (uint8t ) “high”); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “high before take mutex 1”); xSemaphoreTake( Mutex_1, portMAX_DELAY); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “high after take mutex 1”); for( int * ptr = (int)data; *ptr <= 4; ++ptr) { BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “high before receive”); xQueueReceive( Queue_1, ptr, portMAX_DELAY); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “high before send”); xQueueSend( Queue_2, ptr, portMAX_DELAY); } vTaskSuspend(0); } static void medium( void x) { BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “medium”); char *c; uint32_t tmp[1]; for( c=”012345″;c != 0 ;++c) { BSPLCDDisplayStringAtLine (i++, (uint8t *) “medium before take mutex 1”); xSemaphoreTake( Mutex1, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t ) “medium after take mutex 1”); *tmp = *c++; BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “medium before send queue 1”); xQueueSend( Queue_1, tmp, portMAX_DELAY); *tmp = *c++; BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “medium before send queue 1”); xQueueSend( Queue_1, tmp, portMAX_DELAY); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “medium before take mutex 2”); xSemaphoreTake( Mutex_2, portMAX_DELAY); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “medium before give mutex 1”); xSemaphoreGive( Mutex_1); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “medium before give mutex 2”); xSemaphoreGive( Mutex_2); } } uint32_t target[10]; static void low( void *x) { BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “low”); for( uint32_t *data = target;data <= 9;data++) { BSPLCDDisplayStringAtLine (i++, (uint8t *) “low before take mutex 2”); xSemaphoreTake( Mutex2, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t ) “low before give mutex 1”); xSemaphoreGive( Mutex_1); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “low after give mutex 1”); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “low before receive queue 2”); while(pdTRUE==xQueueReceive( Queue_2, data++, portMAX_DELAY)) / donothing */; BSPLCDDisplayStringAtLine (i++, (uint8t *) “low before take mutex 1”); xSemaphoreTake( Mutex_1, portMAX_DELAY); BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) “low before give mutex 2”); xSemaphoreGive( Mutex_2); } vTaskSuspend(0); } ~~~~

Priority inheritance not working as expected

As far as I can see – and its not that easy to follow – your low priority task is attempting to give mutex 1 when mutex 1 is being held by the high priority task. Stepping into the code, or pausing the debugger, will probably show you stopped on the following line: ~~~~ /* A task can only have an inherited priority if it holds the mutex. If the mutex is held by a task then it cannot be given from an interrupt, and if a mutex is given by the holding task then it must be the running state task. */ configASSERT( pxTCB == pxCurrentTCB ); ~~~~

Priority inheritance not working as expected

Thanks for the quick response. It was assumed that Mutexes could be given back by a task other than the one that took it. Commenting out the configASSERT() “fixes” it, as well as switching to a binary semaphore. I’ll have to ask in class why this unsupported way of using mutexes was used.