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 558 times

sem_bad.png
sem_bad.png (15.8 KiB) Viewed 558 times

ESP_Sprite
Posts: 1770
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: 1060
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: 1060
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.

Who is online

Users browsing this forum: No registered users and 2 guests