Values in argument struct change after xQueueReceive
Posted: Tue Sep 03, 2024 7:42 pm
I'm working on a project involving timing button presses of a button attached to GPIO pin 23 of an ESP32 board. In my project, I need to be able to pass some state to my interrupt handler, as well as to my debounce timers. According to the FreeRTOS documentation:
https://github.com/FreeRTOS/FreeRTOS-Ke ... v1.1.0.pdf and https://www.freertos.org/media/2018/Fr ... 0.0.0.pdf ; the void * type arguments to xTaskCreate are intended for this purpose.
The problem I'm having is that after `xQueueReceive` is called in my interrupt handling function, the values in the struct pointed to by my argument pointer get corrupted.
Here is the smallest code I could write to replicate the problem:
Here is the output that I get monitoring the code running on my esp32:
Why are my parameter values being overwritten?
Thanks.
https://github.com/FreeRTOS/FreeRTOS-Ke ... v1.1.0.pdf and https://www.freertos.org/media/2018/Fr ... 0.0.0.pdf ; the void * type arguments to xTaskCreate are intended for this purpose.
The problem I'm having is that after `xQueueReceive` is called in my interrupt handling function, the values in the struct pointed to by my argument pointer get corrupted.
Here is the smallest code I could write to replicate the problem:
Code: Select all
#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "hal/gpio_types.h"
#define GPIO_INPUT_PIN 23
#define GPIO_INPUT_PIN_SEL (1ULL<<GPIO_INPUT_PIN)
#define ESP_INTR_FLAG_DEFAULT 0
static QueueHandle_t gpio_evt_queue = NULL;
typedef struct {
uint8_t foo;
uint32_t bar;
} my_t;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
static void gpioTask(void * args)
{
my_t *B = (my_t *)args;
uint32_t io_num;
printf("in gpioTask, outside of queue\n");
printf(" B->foo = %d\n", (int)B->foo);
printf(" B->bar = %d\n", (int)B->bar);
printf("\n");
for (;;) {
if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
printf("in gpioTask, inside loop, inside queue\n");
printf(" B->foo = %d\n", (int)B->foo);
printf(" B->bar = %d\n", (int)B->bar);
gpio_isr_handler_remove(GPIO_INPUT_PIN);
}
}
}
void app_main(void)
{
my_t baz;
baz.foo = 3;
baz.bar = 2;
gpio_evt_queue = xQueueCreate(8, sizeof(uint32_t));
if (gpio_evt_queue == NULL){
printf("ERROR: xQueueCreate failed!");
}
gpio_config_t ioConf = {};
ioConf.intr_type = GPIO_INTR_POSEDGE;
ioConf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
ioConf.mode = GPIO_MODE_INPUT;
ioConf.pull_up_en = 0;
ioConf.pull_down_en = 1;
gpio_config(&ioConf);
printf("Hello world!\n");
if (xTaskCreate(
gpioTask,
"gpioTask",
2048,
&baz,
10, //configMAX_PRIORITIES - 5,
NULL) != pdPASS) {
printf("Failed to create task!");}
if(gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT) != ESP_OK){
printf("ERROR: gpio_install_isr_service failed!\n");
}
if(gpio_isr_handler_add(
GPIO_INPUT_PIN, gpio_isr_handler, (void*) GPIO_INPUT_PIN) != ESP_OK){
printf("ERROR: hpio_isr_handler_add failed!\n");
}
}
Code: Select all
Hello world!
in gpioTask, outside of queue
B->foo = 3
B->bar = 2
I (328) main_task: Returned from app_main()
in gpioTask, inside loop, inside queue
B->foo = 108
B->bar = 393507
in gpioTask, inside loop, inside queue
B->foo = 108
B->bar = 393507
Thanks.