GPIO Interrupt on specific core is not working

opcode_x64
Posts: 34
Joined: Sun Jan 13, 2019 5:39 pm

GPIO Interrupt on specific core is not working

Postby opcode_x64 » Sun Dec 08, 2019 10:08 am

Hello everybody,

I am trying to raise a GPIO Interrupt Service Routine on Core 1, but it doesn't working... I just tried like this:

1.) Creating a Task which is pinned to Core 1
2.) executing gpio_install_isr_service(0); and gpio_isr_handler_add(...) in the task pinned to core 1

In the doc's I have just read that the GPIO ISR is executing on that core where the ISR was registered ?!

To verify on which the current code is running I am using xPortGetCoreID()

When I launch my code, then Task is running on Core 1, but the ISR is running on Core 0.... so it does not working...

So what I am doing wrong ?


Below is my "minimal example code":

Code: Select all

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define GPIO_INT_PIN    GPIO_NUM_35
#define ESP_INTR_FLAG_DEFAULT   0

static void IRAM_ATTR GPIO_INT_HANDLER(void* arg){ 
    ets_printf("Core ID of DRDY ISR: %d\n",xPortGetCoreID());
}

void TASK_config_DRDY_INT_HANDLER(void * pvParameters){
  gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);

  gpio_set_intr_type(GPIO_INT_PIN, GPIO_INTR_NEGEDGE);
  gpio_isr_handler_add(GPIO_INT_PIN, GPIO_INT_HANDLER, NULL);
 
  ets_printf("Core ID of DRDY_ISR_CONFIG TASK: %d\n",xPortGetCoreID());

  while(1){
      vTaskDelay(1);
  }
}

void app_main(){

  gpio_config_t GPIO_INT_PIN_CONFIG={
    .intr_type=GPIO_INTR_NEGEDGE,
    .pin_bit_mask=(1ULL<< GPIO_INT_PIN),
    .mode=GPIO_MODE_INPUT,
    .pull_up_en=GPIO_PULLUP_DISABLE,
    .pull_down_en=GPIO_PULLDOWN_DISABLE,
  };
  ESP_ERROR_CHECK(gpio_config(& GPIO_INT_PIN_CONFIG));

vTaskDelay(1000/portTICK_PERIOD_MS);

xTaskCreatePinnedToCore(TASK_config_DRDY_INT_HANDLER,
                          "TASK_config_DRDY_INT_HANDLER",
                          2048, NULL, 1, NULL, 1);

    while(1){
        vTaskDelay(1);
    }
}
Best regards.
opcode_x64

Ritesh
Posts: 1128
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: GPIO Interrupt on specific core is not working

Postby Ritesh » Sun Dec 08, 2019 6:28 pm

opcode_x64 wrote:
Sun Dec 08, 2019 10:08 am
Hello everybody,

I am trying to raise a GPIO Interrupt Service Routine on Core 1, but it doesn't working... I just tried like this:

1.) Creating a Task which is pinned to Core 1
2.) executing gpio_install_isr_service(0); and gpio_isr_handler_add(...) in the task pinned to core 1

In the doc's I have just read that the GPIO ISR is executing on that core where the ISR was registered ?!

To verify on which the current code is running I am using xPortGetCoreID()

When I launch my code, then Task is running on Core 1, but the ISR is running on Core 0.... so it does not working...

So what I am doing wrong ?


Below is my "minimal example code":

Code: Select all

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define GPIO_INT_PIN    GPIO_NUM_35
#define ESP_INTR_FLAG_DEFAULT   0

static void IRAM_ATTR GPIO_INT_HANDLER(void* arg){ 
    ets_printf("Core ID of DRDY ISR: %d\n",xPortGetCoreID());
}

void TASK_config_DRDY_INT_HANDLER(void * pvParameters){
  gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);

  gpio_set_intr_type(GPIO_INT_PIN, GPIO_INTR_NEGEDGE);
  gpio_isr_handler_add(GPIO_INT_PIN, GPIO_INT_HANDLER, NULL);
 
  ets_printf("Core ID of DRDY_ISR_CONFIG TASK: %d\n",xPortGetCoreID());

  while(1){
      vTaskDelay(1);
  }
}

void app_main(){

  gpio_config_t GPIO_INT_PIN_CONFIG={
    .intr_type=GPIO_INTR_NEGEDGE,
    .pin_bit_mask=(1ULL<< GPIO_INT_PIN),
    .mode=GPIO_MODE_INPUT,
    .pull_up_en=GPIO_PULLUP_DISABLE,
    .pull_down_en=GPIO_PULLDOWN_DISABLE,
  };
  ESP_ERROR_CHECK(gpio_config(& GPIO_INT_PIN_CONFIG));

vTaskDelay(1000/portTICK_PERIOD_MS);

xTaskCreatePinnedToCore(TASK_config_DRDY_INT_HANDLER,
                          "TASK_config_DRDY_INT_HANDLER",
                          2048, NULL, 1, NULL, 1);

    while(1){
        vTaskDelay(1);
    }
}
Best regards.
opcode_x64
Hello,

How you have verified that task is running in core 1 but ISR is running on core 0?

Because I believe ISR is highest priority which can be executed first on core 0 if available otherwise on core 1 if no any room is available.
Regards,
Ritesh Prajapati

opcode_x64
Posts: 34
Joined: Sun Jan 13, 2019 5:39 pm

Re: GPIO Interrupt on specific core is not working

Postby opcode_x64 » Wed Apr 08, 2020 9:46 pm

Hello Ritesh,

I solved the problem, but I forgot to post the solution here.. Sorry for that ! :( .

Solution is easy: it is necessary to run the gpio config for the desired interrupt pin also in the task which is pinned to the desired core and is allocating the interrupt pin.

Solutions should looks like this:

Code: Select all

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define GPIO_INT_PIN    GPIO_NUM_35
#define ESP_INTR_FLAG_DEFAULT   0

static void IRAM_ATTR GPIO_INT_HANDLER(void* arg){ 
    ets_printf("Core ID of DRDY ISR: %d\n",xPortGetCoreID());
}

void TASK_config_DRDY_INT_HANDLER(void * pvParameters){
    /* GPIO config procedure */
    gpio_config_t GPIO_INT_PIN_CONFIG={
    .intr_type=GPIO_INTR_NEGEDGE,
    .pin_bit_mask=(1ULL<< GPIO_INT_PIN),
    .mode=GPIO_MODE_INPUT,
    .pull_up_en=GPIO_PULLUP_DISABLE,
    .pull_down_en=GPIO_PULLDOWN_DISABLE,
  };
  ESP_ERROR_CHECK(gpio_config(& GPIO_INT_PIN_CONFIG));
  /* GPIO config procedure END*/
  
  gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
  gpio_set_intr_type(GPIO_INT_PIN, GPIO_INTR_NEGEDGE);
  gpio_isr_handler_add(GPIO_INT_PIN, GPIO_INT_HANDLER, NULL);
 
  ets_printf("Core ID of DRDY_ISR_CONFIG TASK: %d\n",xPortGetCoreID());

  while(1){
      vTaskDelay(1);
  }
}

void app_main(){

vTaskDelay(1000/portTICK_PERIOD_MS);

xTaskCreatePinnedToCore(TASK_config_DRDY_INT_HANDLER,
                          "TASK_config_DRDY_INT_HANDLER",
                          2048, NULL, 1, NULL, 1);

    while(1){
        vTaskDelay(1);
    }
}
The strange thing is, this behavior/error just occurred after an update of the ESP-IDF Framework. I can't tell you when exactly, cause I hade a "long" break in working on this. In previous version of ESP-IDF it did not matter, where you executed the gpio config procedure of the desired pin (refer to /*...*/ comment in the code), meaning core 0 oder core 1... but now it seems that the gpio config procedure must also be goes with the desired core when pinning gpio interrupt to desired core is needed.

Hope this will be helpful for someone..

Best regards,
opcode_x64

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

Re: GPIO Interrupt on specific core is not working

Postby ESP_Sprite » Thu Apr 09, 2020 4:57 am

Ritesh wrote:
Sun Dec 08, 2019 6:28 pm
Because I believe ISR is highest priority which can be executed first on core 0 if available otherwise on core 1 if no any room is available.

Just to correct this: No, ISRs are always executed on the core where they are allocated/initialized. However ISRs can wake up a task (using semaphores, queues, ....) that can run on any core.

Ritesh
Posts: 1128
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: GPIO Interrupt on specific core is not working

Postby Ritesh » Sun Apr 19, 2020 10:44 am

ESP_Sprite wrote:
Thu Apr 09, 2020 4:57 am
Ritesh wrote:
Sun Dec 08, 2019 6:28 pm
Because I believe ISR is highest priority which can be executed first on core 0 if available otherwise on core 1 if no any room is available.

Just to correct this: No, ISRs are always executed on the core where they are allocated/initialized. However ISRs can wake up a task (using semaphores, queues, ....) that can run on any core.
Thanks for providing updates and details for same
Regards,
Ritesh Prajapati

Who is online

Users browsing this forum: No registered users and 27 guests