Page 1 of 1

help with understandig freeRTOS code

Posted: Fri Jan 08, 2021 8:42 pm
by sebasdt
dear espressif forum,

I have used a bit of code but i don't understand fully how it works and what the variables do.
This code is used for reading a encoder value and so it needed to be an interupt.

Code: Select all

void ESP_ISR callBack(Encoder & enc) {
  BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
  static int16_t lastReading = 0;

  int16_t currentReading = enc;
  if (currentReading != lastReading) {
    lastReading = currentReading;
    xQueueSendToBackFromISR(encoderQueue, &currentReading, &pxHigherPriorityTaskWoken);
    if (pxHigherPriorityTaskWoken) {
      portYIELD_FROM_ISR();
    }
  }
}
what i don't understand are these 2 things:

Code: Select all

 BaseType_t pxHigherPriorityTaskWoken = pdFALSE;

Code: Select all

if (pxHigherPriorityTaskWoken) {
      portYIELD_FROM_ISR();
    }
I know what xQueueSendToBackFromISR does.

Code: Select all

xQueueSendToBackFromISR(encoderQueue, &currentReading, &pxHigherPriorityTaskWoken);
It sends the value that's in currentReading to encoderQueue back to code that isn't part of the ISR. The last bit is how long it should wait.
what does &pxHigherPriorityTaskWoken mean or do?

Re: help with understandig freeRTOS code

Posted: Sat Jan 09, 2021 5:09 am
by ESP_Sprite
It's a low-latency thing.

Say, the ESP32 is running some background task (I dunno, some WiFi housekeeping task or something) and your interrupt hits. Without the pxHigherPriorityTaskWoken logic, as soon as your interrupt finishes, FreeRTOS would return control to that task up till the next FreeRTOS timer tick, which may still be a few milliseconds away. It will do this even if the task waiting for the interrupt queue is super-high priority! However, by checking if the queue would wake up a high-priority task, you can tell FreeRTOS to switch to that task as soon as the interrupt is done, so it can read out the queue without any delay.

Re: help with understandig freeRTOS code

Posted: Sat Jan 09, 2021 8:47 am
by sebasdt
WOW thanks for your reply!
now I understand what's happening!
here below is code for a button ISR but isn't this the same? (wait or is this just for synching between isr task?)
The only thing it's without pxHigherPriorityTaskWoken.

Code: Select all

void IRAM_ATTR isr() {
  portENTER_CRITICAL(&synch);
  //Serial.println("interupt called");
  if ((micros() - LastMicros) >= 25 * 1000UL) {
    if (digitalRead(encoderButton) == LOW) {
      buttonPressed = true;
      //   xQueueSendFromISR(buttonQueue, &buttonPressed, NULL);
    }
    LastMicros = micros();
  }
  portEXIT_CRITICAL(&synch);
}