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.
Code: Untitled.cpp Select all
#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 );
}