alexanderw2 wrote on Thursday, January 28, 2016:
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 BSP_LCD_DisplayStringAtLine() 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( Mutex_1, portMAX_DELAY) call and the Mutex_1 was given in the low priority task?
Thanks
int i = 0;
uint32_t data[]={1,2,3,4};
static void high (void *)
{
BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) "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)
{
BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) "medium before take mutex 1");
xSemaphoreTake( Mutex_1, portMAX_DELAY);
BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) "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++)
{
BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) "low before take mutex 2");
xSemaphoreTake( Mutex_2, portMAX_DELAY);
BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) "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))
/* do_nothing */;
BSP_LCD_DisplayStringAtLine (i++, (uint8_t *) "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);
}