binary semaphore doesn't work if created in task that uses it ?

pataga
Posts: 33
Joined: Sat Aug 12, 2017 5:53 am

binary semaphore doesn't work if created in task that uses it ?

Postby pataga » Mon Jan 15, 2018 5:21 am

I am using a binary semaphore given from an isr that notifies a task to read new data from a device. The device generates data ready interrupts at approximately 400Hz, so the task should be also getting notifications from the semaphore at the same rate.

If i create the global semaphore in the task that uses it, then the task gets notifications at roughly the FreeRTOS tick rate ( in this case, 500Hz ) with some gaps.

If i create the semaphore in app_main before creating the task that uses it, everything works as expected, the notifications are processed at the data ready interrupt rate (~400Hz) without missing any.

Not sure if this is correct behavior, in any case, it would be nice to have an explanation.

Code: Select all

volatile SemaphoreHandle_t imuSemaphore; void drdyHandler(void) { xSemaphoreGiveFromISR(imuSemaphore, NULL); } static void imu_task() { // does not work if created here ! //imuSemaphore = xSemaphoreCreateBinary(); //attachInterrupt(pinDRDYINT, drdyHandler, RISING); // initialize device to generate data and data ready interrupts ... while (1) { if (xSemaphoreTake(imuSemaphore, portMAX_DELAY)) { LED_ON(); // read the data from device LED_OFF(); } } } void app_main() { // init stuff ... // works if semaphore created here imuSemaphore = xSemaphoreCreateBinary(); attachInterrupt(pinDRDYINT, drdyHandler, RISING); xTaskCreatePinnedToCore(&imu_task, "imutask", 2048, NULL, 20, NULL, 1); while(1) { // do some stuff delayMs(30); } }
sem_good.png
sem_good.png (10.91 KiB) Viewed 835 times
sem_bad.png
sem_bad.png (15.8 KiB) Viewed 835 times

ESP_Sprite
Posts: 1986
Joined: Thu Nov 26, 2015 4:08 am

Re: binary semaphore doesn't work if created in task that uses it ?

Postby ESP_Sprite » Mon Jan 15, 2018 8:03 am

Do you get the same weird behaviour if you pin the task to CPU 0 instead of 1?

pataga
Posts: 33
Joined: Sat Aug 12, 2017 5:53 am

Re: binary semaphore doesn't work if created in task that uses it ?

Postby pataga » Mon Jan 15, 2018 11:16 am

Do you get the same weird behaviour if you pin the task to CPU 0 instead of 1?
OK, this is even stranger. If I pin the task to cpu 0, then the notification doesn't work correctly whether I create the semaphore and register the handler in app_main or in the task initialization code.

In both cases, I get the notifications at 500Hz with some skips every 3 or 4 notifications.

Went back to original configuration with task pinned to core 1 and semaphore/isr registration in app_main, and it works fine.
So at least my working configuration is repeatable :-D

Am using esp-idf downloaded on Jan 11.

ESP_igrr
Posts: 1182
Joined: Tue Dec 01, 2015 8:37 am

Re: binary semaphore doesn't work if created in task that uses it ?

Postby ESP_igrr » Mon Jan 15, 2018 12:44 pm

Please don't forget to pass 2nd BOOL* argument to xSemaphoreGiveFromISR and call portYIELD_FROM_ISR if it gets set to pdTRUE.
If you don't do that, preemption will only happen on the next FreeRTOS tick.

pataga
Posts: 33
Joined: Sat Aug 12, 2017 5:53 am

Re: binary semaphore doesn't work if created in task that uses it ?

Postby pataga » Mon Jan 15, 2018 1:55 pm

Please don't forget to pass 2nd BOOL* argument to xSemaphoreGiveFromISR and call portYIELD_FROM_ISR if it gets set to pdTRUE.
If you don't do that, preemption will only happen on the next FreeRTOS tick.
Ah ... so i was using it wrong all this time ! I found a correct example of semaphore usage, and fixed the ISR

Code: Select all

void drdyHandler(void) { static BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(imuSemaphore, &xHigherPriorityTaskWoken); if( xHigherPriorityTaskWoken == pdTRUE) { portYIELD_FROM_ISR(); // this wakes up imu_task immediately instead of on next FreeRTOS tick } }
and now it works fine. Thanks much ...

ESP_igrr
Posts: 1182
Joined: Tue Dec 01, 2015 8:37 am

Re: binary semaphore doesn't work if created in task that uses it ?

Postby ESP_igrr » Mon Jan 15, 2018 3:52 pm

Good to know. The variable does not need to be static, by the way.

Return to “Report Bugs”

Who is online

Users browsing this forum: No registered users and 2 guests