Basic queue help please

Lancsrick
Posts: 30
Joined: Mon Apr 10, 2023 5:48 pm

Basic queue help please

Postby Lancsrick » Sat Jul 08, 2023 8:50 am

Hi all,

I'm missing something fundamental here and could do with some help please.

The aim is to get an interrupt writing the current elapsed time to a queue. To do that I'm using xQueueSendFromISR and esp_timer_get_time(). I've included the relevant lines of code below. Any help would be greatly appreciated, thanks.

Code: Select all

#include "freertos/queue.h"
#include "esp_timer.h"

QueueHandle_t red_line_queue;

void IRAM_ATTR isr_function( void *arg) 
{
    xQueueSendFromISR(red_line_queue,esp_timer_get_time(),(TickType_t(0));
}
I'm currently getting errors of:
src/main.c:125:2: error: unterminated argument list invoking macro "xQueueSendFromISR"
src/main.c:39:5: error: 'xQueueSendFromISR' undeclared (first use in this function); did you mean 'xQueueCRSendFromISR'? (This is the xQueueSendFromISR line)


I can't for the life of me see why the argument list is unterminated!

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Basic queue help please

Postby MicroController » Sat Jul 08, 2023 10:44 am

The first problem is the missing ")" after (TickType_t(0)).

Then, you need to pass in a pointer to the data to enqueue, and you should also use pxHigherPriorityTaskWoken (which also must be a pointer, but may be NULL).

like so

Code: Select all

void IRAM_ATTR isr_function( void *arg) 
{
   const int64_t time = esp_timer_get_time(); // store the "data" we want to enqueue into a local variable
   BaseType_t shouldYield = pdFALSE; // declare and initialize another local variable for the pxHigherPriorityTaskWoken argument
   
   xQueueSendFromISR(
       red_line_queue,
       &time, // pass a *pointer* to our data (local variable) to the function; the data pointed-to will be *copied* into the queue
       &shouldYield); // pass a *pointer* to the shouldYield local variable (= shouldYield is used as an output parameter)

   // If some task was waiting on our queue and should now be switched to,
   // xQueueSendFromISR will have set our shouldYield variable to pdTRUE       
   if(shouldYield != pdFALSE) {
       // let FreeRTOS know that we want it to switch tasks now
       portYIELD_FROM_ISR();
   }
}
Last edited by MicroController on Sat Jul 08, 2023 3:37 pm, edited 1 time in total.

Lancsrick
Posts: 30
Joined: Mon Apr 10, 2023 5:48 pm

Re: Basic queue help please

Postby Lancsrick » Sat Jul 08, 2023 1:09 pm

Great thank you :). I'll do some reading up to understand what those changes do. Appreciate the help :).

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Basic queue help please

Postby MicroController » Sat Jul 08, 2023 3:44 pm

Added some explanatory comments :)

The shouldYield and portYIELD_FROM_ISR() part is not strictly required, but without it the task reading from the queue may not "see" the data before the next OS tick, which can cause a delay in processing of up to one OS tick (default: 10ms).

Lancsrick
Posts: 30
Joined: Mon Apr 10, 2023 5:48 pm

Re: Basic queue help please

Postby Lancsrick » Sat Jul 08, 2023 3:57 pm

That's brilliant thanks. I'm used to using pointers as a way of updating data at a fixed address for a later task to read, why is this being used as an intermediary in the ISR?

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Basic queue help please

Postby MicroController » Sat Jul 08, 2023 11:04 pm

Arbitrary data types:
The FreeRTOS queues are generic and can be used with arbitrary data items, from e.g. simple int's to structs to arrays which may all have different sizes from one byte to maybe tens or hundreds of bytes.
In order for a single C function to accept arbitrary kinds/types/sizes of data, a (void) pointer is basically the only option the language provides. (In C++ you could use templates and references instead.)

"Output" parameter:
The pxHigherPriorityTaskWoken is meant to serve as an output of the function, i.e. a place where the function can store a value for the caller. Again, in C, the only way to achieve this is to pass a pointer to a variable into the function so that the function can write a value to the (caller's) variable.
Notice that xQueueSendFromISR actually already has a return value (for indicating success/failure) and uses the "output parameter" to give an additional, second output back to the caller.

Btw, here is the relevant FreeRTOS documentation.

Who is online

Users browsing this forum: No registered users and 89 guests