Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Priority inheritance not working as expected

Posted by alexanderw2 on 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 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"); BSPLCDDisplayStringAtLine (i++, (uint8t *) "high before take mutex 1"); xSemaphoreTake( Mutex1, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t *) "high after take mutex 1"); for( int * ptr = (int)data; *ptr <= 4; ++ptr) { BSPLCDDisplayStringAtLine (i++, (uint8t *) "high before receive"); xQueueReceive( Queue1, ptr, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t *) "high before send"); xQueueSend( Queue2, ptr, portMAXDELAY); } vTaskSuspend(0); }

static void medium( void x) { BSPLCDDisplayStringAtLine (i++, (uint8t *) "medium"); char *c; uint32t 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++; BSPLCDDisplayStringAtLine (i++, (uint8t *) "medium before send queue 1"); xQueueSend( Queue1, tmp, portMAXDELAY); *tmp = *c++; BSPLCDDisplayStringAtLine (i++, (uint8t *) "medium before send queue 1"); xQueueSend( Queue1, tmp, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t *) "medium before take mutex 2"); xSemaphoreTake( Mutex2, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t *) "medium before give mutex 1"); xSemaphoreGive( Mutex1); BSPLCDDisplayStringAtLine (i++, (uint8t *) "medium before give mutex 2"); xSemaphoreGive( Mutex2); } } uint32t target[10]; static void low( void *x) { BSPLCDDisplayStringAtLine (i++, (uint8t *) "low"); for( uint32t *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( Mutex1); BSPLCDDisplayStringAtLine (i++, (uint8t *) "low after give mutex 1"); BSPLCDDisplayStringAtLine (i++, (uint8t *) "low before receive queue 2"); while(pdTRUE==xQueueReceive( Queue2, data++, portMAX_DELAY)) / donothing */; BSPLCDDisplayStringAtLine (i++, (uint8t *) "low before take mutex 1"); xSemaphoreTake( Mutex1, portMAXDELAY); BSPLCDDisplayStringAtLine (i++, (uint8t *) "low before give mutex 2"); xSemaphoreGive( Mutex2); } vTaskSuspend(0); } ~~~~


Priority inheritance not working as expected

Posted by rtel on January 28, 2016

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

Posted by alexanderw2 on January 30, 2016

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.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS