vladdo
Posts: 21
Joined: Fri Jul 29, 2022 11:08 pm

Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Mon Aug 15, 2022 12:52 pm

Hello everyone!
I am having some issues using and understanding interrupts while using FreeRTOS as an operating system on the pi pico. I have the following scenario:

I have a task that prints temperatures and other text to an LCD (LCD task),
a task getting temperature information from some temperature sensor (temperature task);
and some buttons that are supposed to make changes to what appears on the LCD screen (it is supposed to be like a menu with buttons for navigation basically).

The situations is as follows:
I created the tasks for LCD and temperature gathering and I had them run as independent tasks with the temperature task sending the temperatures to the LCD task in a queue. And this worked great.
But then i wanted to add the buttons and I decided to use interrupts. So i initialized the interrupts like this in main:

Code: Select all

gpio_set_irq_enabled_with_callback(BUTTON_UP_PIN, GPIO_IRQ_EDGE_RISE, 1, button_ISR);
gpio_set_irq_enabled(BUTTON_LEFT_PIN, GPIO_IRQ_EDGE_RISE, 1);   //left
gpio_set_irq_enabled(BUTTON_RIGHT_PIN, GPIO_IRQ_EDGE_RISE, 1);  //right
gpio_set_irq_enabled(BUTTON_MID_PIN, GPIO_IRQ_EDGE_RISE, 1);     //middle
gpio_set_irq_enabled(BUTTON_DOWN_PIN, GPIO_IRQ_EDGE_RISE, 1);   //down
And then I created the callback function:

Code: Select all

void button_ISR(uint gpio, uint32_t events) {
    xQueueSendToBackFromISR(irq_queue, &gpio, 0);
}
That sends the interrupt in the queue to the LCD task where I do a Receive:

Code: Select all

//code that is supposed to run even if no buttons were pushed 1

if (xQueueReceive(irq_queue, &passed_value_buffer, portMAX_DELAY) == pdPASS){
	// check the value of passed_value_buffer see whitch of the buttons was presses and change what is shown on screen accordingly 
}

//code that is supposed to run even if no buttons were pushed 2

The receive works fine, but not totally. My problem is that even though LCD is supposed to be a tasks that runs 'all the time', if I add that xQueueReceive in LCD task, the code in the LCD task runs only when a button is pushed. But the problem is that I want some parts of the code in LCD task to run continuously. Actually I want the whole task to run continuously and only the parts in the if to be executed exclusively when a button is pushed.

My question is why does the whole LCD task stop running when no button is pushed and why does it only run when a button is pushed, and what solutions are there to my problem.

Thank you!

(P.S. I am new to this stuff)

fivdi
Posts: 577
Joined: Sun Sep 23, 2012 8:09 pm

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Mon Aug 15, 2022 1:37 pm

Code: Select all

if (xQueueReceive(irq_queue, &passed_value_buffer, portMAX_DELAY) == pdPASS){
	// check the value of passed_value_buffer see whitch of the buttons was presses and change what is shown on screen accordingly 
}
This code blocks until there is something in the queue for it to process. In other words, it block until a button is pressed. It blocks because the third parameter (xTicksToWait) is set to portMAX_DELAY. Setting xTicksToWait to 0 will cause the function to return immediately if the queue is empty. xQueueReceive returns pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.

See https://www.freertos.org/a00118.html for more information.

Code: Select all

void button_ISR(uint gpio, uint32_t events) {
    xQueueSendToBackFromISR(irq_queue, &gpio, 0);
}
There is also bug here as the address of a variable on the stack is being posted to the back of the queue. I would imagine you wanted to post the gpio number to the back of the queue rather than the address of the gpio number on the stack.
https://github.com/fivdi

alastairpatrick
Posts: 348
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Mon Aug 15, 2022 3:01 pm

fivdi wrote:
Mon Aug 15, 2022 1:37 pm
There is also bug here as the address of a variable on the stack is being posted to the back of the queue. I would imagine you wanted to post the gpio number to the back of the queue rather than the address of the gpio number on the stack.
That's actually okay; xQueueSendToBackFromISR copies the item referenced by pvItemToQueue.

fivdi
Posts: 577
Joined: Sun Sep 23, 2012 8:09 pm

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Mon Aug 15, 2022 3:58 pm

alastairpatrick wrote:
Mon Aug 15, 2022 3:01 pm
fivdi wrote:
Mon Aug 15, 2022 1:37 pm
There is also bug here as the address of a variable on the stack is being posted to the back of the queue. I would imagine you wanted to post the gpio number to the back of the queue rather than the address of the gpio number on the stack.
That's actually okay; xQueueSendToBackFromISR copies the item referenced by pvItemToQueue.
It does indeed. https://www.freertos.org/xQueueSendToBackFromISR.html
https://github.com/fivdi

vladdo
Posts: 21
Joined: Fri Jul 29, 2022 11:08 pm

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Tue Aug 16, 2022 8:47 am

fivdi wrote:
Mon Aug 15, 2022 3:58 pm
alastairpatrick wrote:
Mon Aug 15, 2022 3:01 pm
fivdi wrote:
Mon Aug 15, 2022 1:37 pm
There is also bug here as the address of a variable on the stack is being posted to the back of the queue. I would imagine you wanted to post the gpio number to the back of the queue rather than the address of the gpio number on the stack.
That's actually okay; xQueueSendToBackFromISR copies the item referenced by pvItemToQueue.
It does indeed. https://www.freertos.org/xQueueSendToBackFromISR.html
Thank you so much for your answers. You fixed my problem

vladdo
Posts: 21
Joined: Fri Jul 29, 2022 11:08 pm

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Tue Aug 16, 2022 9:03 am

fivdi wrote:
Mon Aug 15, 2022 1:37 pm

Code: Select all

if (xQueueReceive(irq_queue, &passed_value_buffer, portMAX_DELAY) == pdPASS){
	// check the value of passed_value_buffer see whitch of the buttons was presses and change what is shown on screen accordingly 
}
This code blocks until there is something in the queue for it to process. In other words, it block until a button is pressed. It blocks because the third parameter (xTicksToWait) is set to portMAX_DELAY. Setting xTicksToWait to 0 will cause the function to return immediately if the queue is empty. xQueueReceive returns pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.

See https://www.freertos.org/a00118.html for more information.

Code: Select all

void button_ISR(uint gpio, uint32_t events) {
    xQueueSendToBackFromISR(irq_queue, &gpio, 0);
}
There is also bug here as the address of a variable on the stack is being posted to the back of the queue. I would imagine you wanted to post the gpio number to the back of the queue rather than the address of the gpio number on the stack.
Thank you for your answer. This fixed it. But while I was playing with this code I discovered another issue I have. Sometime, randomly, when I press one of the buttons, another button will be registered. I checked where the "switch" was happening and it seems to come as far up as the callback function (button_ISR()). To give you an example sometimes if I press the mid button (gpio pin 12), the down button gpio pin number (gpio pin 13) will actually be send from the interrupt. Do you know also what might be causing this?

fivdi
Posts: 577
Joined: Sun Sep 23, 2012 8:09 pm

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Tue Aug 16, 2022 12:21 pm

vladdo wrote:
Tue Aug 16, 2022 9:03 am
But while I was playing with this code I discovered another issue I have. Sometime, randomly, when I press one of the buttons, another button will be registered. I checked where the "switch" was happening and it seems to come as far up as the callback function (button_ISR()). To give you an example sometimes if I press the mid button (gpio pin 12), the down button gpio pin number (gpio pin 13) will actually be send from the interrupt. Do you know also what might be causing this?
My best guess here would be that the buttons are poorly connected to the GPIOs. Are you working with buttons on a breadboard with long connection wires? If so, the long wires could be the source of the problem. Does each button have an external pull-up or pull-down resistors? If not, that could be the source of the problem.
https://github.com/fivdi

vladdo
Posts: 21
Joined: Fri Jul 29, 2022 11:08 pm

Re: Pi pico interrupts and FreeRTOS tasks (C/C++ sdk)

Tue Aug 16, 2022 3:13 pm

fivdi wrote:
Tue Aug 16, 2022 12:21 pm
vladdo wrote:
Tue Aug 16, 2022 9:03 am
But while I was playing with this code I discovered another issue I have. Sometime, randomly, when I press one of the buttons, another button will be registered. I checked where the "switch" was happening and it seems to come as far up as the callback function (button_ISR()). To give you an example sometimes if I press the mid button (gpio pin 12), the down button gpio pin number (gpio pin 13) will actually be send from the interrupt. Do you know also what might be causing this?
My best guess here would be that the buttons are poorly connected to the GPIOs. Are you working with buttons on a breadboard with long connection wires? If so, the long wires could be the source of the problem. Does each button have an external pull-up or pull-down resistors? If not, that could be the source of the problem.
The wiring seems fine. I am using a breadboard but the wires are very short. Also, the problem appears just sometimes, and before trying the code with interrupts, I tried it with polling, and I had no problem with the polling method. But thank you for the guess. Maybe I will make another thread about this problem.

Return to “SDK”