il-mix wrote on Wednesday, May 10, 2017:
Hi, everyone!
I have several task running and some ISR from GPIO. All these task/isr will use a printf function, and it is quite likely that output will be messed up by concurrent call to it (output of merged strings from different tasks).
To prevent this behavior, I tried using mutex/semaphore/critical sections, awfully without luck. Or better, with some luck (no more merged strings), but when an ISR kicks in, everything locks; the ISR hangs waiting for the mutex.
I think I have to better understand how things are heandled by FreeRTOS.
Here is an example of the code/flow:
int main()
{
gPrintfSemaphore = xSemaphoreCreteBinary(); // or xSemaphoreCreteMutex()
xTaskCreate(myTask, "my_task1", DEFAULT_STACK_SIZE, 1, NULL);
xTaskCreate(myTask, "my_task2", DEFAULT_STACK_SIZE, 2, NULL);
[...]
[enable some interrupts]
}
void myTask(void* handle)
{
for(;;)
{
myPrintf("hello\n");
vTaskDelay(rand()%100);
}
}
void GPIO_ISR()
{
myPrintf("GPIO ISR\n");
}
void myPrintf(const char* msg)
{
xSemaphoreTake(gPrintfSemaphore, portMAX_DELAY(); // or taskENTER_CRITICAL()
[call actual printf]
// without semaphore/mutex control, it is likely that printf outputs something like "helhellolo\n\n"
xSemaphoreGive(gPrintfSemaphore);
// tried taskYIELD() here, but no luck (actually, locks at first printf...)
}
Thanks for your support!
MIX
EDIT:
Actually, I’m not really using printf, but I send couple of serial message data, that needs to be correctly decode on the other side (if two messages got merged, it becomes garbage). This is also an example of a more generic critical section that need to be accessed by a single task/ISR at a time.