bamos-cic wrote on Thursday, April 27, 2017:
Hi,
I’ve recently noticed some issues in my projects where mutex’s no longer seemed to provide mutual exclusion?
I created a small test application with two tasks that exemplifies the issue i’m seeing. This is running with freeRTOS 9.0.0
#include <FreeRTOS.h>
#include <platform.h>
#include <VirtualSerialPort.h>
#include <SEGGER_SYSVIEW.h>
VirtualSerialPort serial(0);
static void HighPriorityTask( void* Params);
static void LowPriorityTask( void* Params);
xSemaphoreHandle mutexPtr = NULL;
int main(void)
{
SystemClock_Config();
serial.Init();
mutexPtr = xSemaphoreCreateMutex();
if(mutexPtr == NULL)
{
while(1);
}
SEGGER_SYSVIEW_Conf();
if (xTaskCreate( HighPriorityTask, ( const char * ) "HPT", 256, NULL, tskIDLE_PRIORITY + 2, NULL ) == pdTRUE)
{
if(xTaskCreate( LowPriorityTask, ( const char * ) "LPT", 256, NULL, tskIDLE_PRIORITY + 1, NULL ) == pdTRUE)
vTaskStartScheduler();
}
while (1);//shouldn't get here
}
static void HighPriorityTask( void* Params)
{
volatile uint32_t temp = 0;
while(1)
{
printf("HPT\t mutex addr 0x%p\n", mutexPtr);
for(int numItr = 0; numItr < 10; numItr++)
{
uint32_t sleepTime = rand() %500;
printf("HPT\t sleeping for %i ms\n", sleepTime);
vTaskDelay(sleepTime);
printf("HPT\t take mutex, wait indefinitely\n");
if(xSemaphoreTake(mutexPtr,portMAX_DELAY) == pdTRUE)
{
printf("HPT\t mutex taken\n");
uint32_t sleepTime = rand() %500;
printf("HPT\t sleeping for %i ms\n", sleepTime);
vTaskDelay(sleepTime);
for(int i = 0; i < 20000; i++)
{
temp += i;
}
if(xSemaphoreGive(mutexPtr) == pdTRUE)
{
printf("HPT\t mutex given\n");
}
else
{
printf("HPT\t mutex give failed\n");
}
}
else
{
printf("HPT\t mutex take failed!\n");
}
}
printf("HPT DONE, sleep for 2 sec\n");
vTaskDelay(100);
}
}
static void LowPriorityTask( void* Params)
{
volatile uint32_t temp = 0;
uint32_t num;
while(1)
{
printf("\t\t\t\t\tLPT\tmutex addr 0x%p\n", mutexPtr);
vTaskDelay(rand() %500);
for(int numItr = 0; numItr < 10; numItr++)
{
printf("\t\t\t\t\tLPT\t take mutex, wait indefinitely\n");
if(xSemaphoreTake(mutexPtr,portMAX_DELAY) == pdTRUE)
{
printf("\t\t\t\t\tLPT\t mutex taken\n");
uint32_t sleepTime = rand() %500;
printf("\t\t\t\t\tLPT\t sleeping for %i ms\n", sleepTime);
vTaskDelay(sleepTime);
if(xSemaphoreGive(mutexPtr) == pdTRUE)
{
printf("\t\t\t\t\tLPT\t mutex given\n");
}
else
{
printf("\t\t\t\t\tLPT\t mutex give failed\n");
}
}
else
{
printf("\t\t\t\t\tLPT\t mutex take failed!\n");
}
}
printf("\t\t\t\t\tLPT DONE, sleep for 2 sec\n");
vTaskDelay(2000);
}
}
Here’s an example of some output, with the problematic section in bold.
HPT mutex addr 0x20021e50
HPT sleeping for 432 ms
HPT take mutex, wait indefinitely
HPT mutex taken
HPT sleeping for 5 ms
HPT mutex given
HPT sleeping for 490 ms
HPT take mutex, wait indefinitely
HPT mutex taken
HPT sleeping for 29 ms
HPT mutex given
HPT sleeping for 104 ms
HPT take mutex, wait indefinitely
HPT mutex taken
HPT sleeping for 492 ms
HPT mutex given
HPT sleeping for 497 ms
LPT mutex addr 0x20021e50
HPT take mutex, wait indefinitely
HPT mutex taken
HPT sleeping for 172 ms
LPT take mutex, wait indefinitely
HPT mutex given
HPT sleeping for 235 ms
LPT mutex taken
LPT sleeping for 268 ms
HPT take mutex, wait indefinitely
HPT mutex taken
HPT sleeping for 341 ms
LPT mutex given
LPT take mutex, wait indefinitely
HPT mutex given
HPT DONE, sleep for 2 sec
LPT mutex taken
LPT sleeping for 476 ms
HPT mutex addr 0x20021e50
HPT sleeping for 258 ms
HPT take mutex, wait indefinitely
HPT mutex taken
HPT sleeping for 489 ms
LPT mutex given
LPT take mutex, wait indefinitely
HPT mutex given
HPT sleeping for 451 ms
Am I making an incorrected assumption or setting/using something incorrectly? I’m guessing there’s a stupid mistake in there somewhere that I’m not seeing.
This is on a Cortex M7 port compiled with Keil (RVDS).
Any suggestions are greately appriciated.
thanks!