portYIELD_FROM_ISR() is not working
Posted: Tue Feb 18, 2020 12:16 am
Hi anyone,
I have trouble with portYIELD_FROM_ISR(). I expect it to block the current running task2 so that the main loop task can immdiately process the data from External Input ISR.
Thank you,
Michael
Yellow wave : External Input (GPIO16)
Blue wave: Main Task Output Signal (GPIO17)
Black wave: Task 2 Output Signal (GPIO27)
Task 2 is not yielding to the main loop task as expected. portYIELD_FROM_ISR() seems to be not working.
I have trouble with portYIELD_FROM_ISR(). I expect it to block the current running task2 so that the main loop task can immdiately process the data from External Input ISR.
Thank you,
Michael
Yellow wave : External Input (GPIO16)
Blue wave: Main Task Output Signal (GPIO17)
Black wave: Task 2 Output Signal (GPIO27)
Task 2 is not yielding to the main loop task as expected. portYIELD_FROM_ISR() seems to be not working.
- #define LED 27 // task led
- #define LED2 17 // task 2 led
- const byte interruptPin = 16;
- volatile int interruptCounter = 0;
- int numberOfInterrupts = 0;
- volatile SemaphoreHandle_t extSemaphore;
- portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
- void IRAM_ATTR handleInterrupt() {
- BaseType_t xHigherPriorityTaskWoken;
- xHigherPriorityTaskWoken = pdFALSE;
- portENTER_CRITICAL_ISR(&mux);
- interruptCounter++;
- portEXIT_CRITICAL_ISR(&mux);
- // Give a semaphore that we can check in the loop
- xSemaphoreGiveFromISR(extSemaphore, &xHigherPriorityTaskWoken);
- // It is safe to use digitalRead/Write here if you want to toggle an output
- //portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR();
- /*
- if (xHigherPriorityTaskWoken) {
- portYIELD_FROM_ISR();
- }
- */
- }
- void setup() {
- pinMode(LED, OUTPUT);
- digitalWrite(LED, LOW);
- pinMode(LED2, OUTPUT);
- digitalWrite(LED2, LOW);
- Serial.begin(115200);
- // Create semaphore to inform us when the external input trigger has been detected.
- extSemaphore = xSemaphoreCreateBinary();
- Serial.println("Monitoring interrupts: ");
- pinMode(interruptPin, INPUT_PULLUP);
- attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
- #define ESP32_RUNNING_CORE 1 /* Core 1 required for OLED display */
- xTaskCreatePinnedToCore(
- task2, /* Task function. */
- "task2", /* name of task. */
- 10000, /* Stack size of task */
- NULL, /* parameter of the task */
- 2, /* priority of the task */
- NULL, /* Task handle to keep track of created task */
- ESP32_RUNNING_CORE // Fix
- );
- }
- void loop() {
- // If Timer has fired
- if (xSemaphoreTake(extSemaphore, 0) == pdTRUE){
- uint32_t isrCount = 0;
- // Read the interrupt count
- portENTER_CRITICAL(&mux);
- isrCount = interruptCounter;
- portEXIT_CRITICAL(&mux);
- if (isrCount % 2 == 0)
- digitalWrite(LED, LOW);
- else
- digitalWrite(LED, HIGH);
- Serial.print("An interrupt has occurred. Total: ");
- Serial.println(isrCount);
- }
- }
- /* this function will be invoked when additionalTask was created */
- void task2( void * parameter )
- {
- /* loop forever */
- for(;;){
- for (int i=0; i<500000; i++) { // short active time
- digitalWrite(LED2, HIGH); // LED2 =1 (Task2 is running.
- }
- digitalWrite(LED2, LOW);
- delay(10);
- }
- /* delete a task when finish,
- this will never happen because this is infinity loop */
- vTaskDelete( NULL );
- }