Queue with task and ISR

alexpetitfr wrote on Thursday, September 16, 2010:

Hello all,

1-I would like to know if we can do a task which wait for message in a queue (that is fill with the ISR, for exmple Uart Rx ISR)
with “uxQueueMessagesWaiting”. Or if I have to use a semaphore (waiting for semaphore activate in the task, and activate it in the Uart Rx ISR when i put a message in the queue?).

2-I fill the queue in a task, and the Uart Tx ISR take data in the queue and push them on the Tx Uart. Is it a problem if the ISR (for exemple Uart Tx ISR) is highter than configMAX_SYSCALL_INTERRUPT_PRIORITY? I think yes. So If it yes, is it possible to change Free Rtos in order to give the mask priority for the Queue?

So :
xQueueHandle xQueueCreate(
                            unsigned portBASE_TYPE uxQueueLength,
                            unsigned portBASE_TYPE uxItemSize
                          );
become :
xQueueHandle xQueueCreate(
                            unsigned portBASE_TYPE uxQueueLength,
                            unsigned portBASE_TYPE uxItemSize
                            unsigned portBASE_TYPE uxMaskPriority

                          );

Thanks

Alexander

rtel wrote on Thursday, September 16, 2010:

-I would like to know if we can do a task which wait for message in a queue (that is fill with the ISR, for exmple Uart Rx ISR)
with “uxQueueMessagesWaiting”. Or if I have to use a semaphore (waiting for semaphore activate in the task, and activate it in the Uart Rx ISR when i put a message in the queue?).

uxQueueMessagesWaiting() is only used to query how many messages a queue holds.  You cannot use it to wait for a message.  You can use xQueueReceive() to wait for a message to arrive - just specify a block time in the third parameter and you will block until either a message arrives or the block time expires.

Or if I have to use a semaphore (waiting for semaphore activate in the task, and activate it in the Uart Rx ISR when i put a message in the queue?)

That would be one way of doing it for sure, but I’m not sure it gives you any advantage over blocking on the queue itself.  If you want to post a lot of data before unblocking the task using a separate semaphore would be more efficient - however I would suggest using a fast circular buffer rather than a queue to store the data otherwise use get the queue overhead without getting any benefits.

2-I fill the queue in a task, and the Uart Tx ISR take data in the queue and push them on the Tx Uart. Is it a problem if the ISR (for exemple Uart Tx ISR) is highter than configMAX_SYSCALL_INTERRUPT_PRIORITY?

Two things about this statement - first using queues in this method is not efficient.  I know this is how the demo apps often do it, but they also state that they only do it as a convenient way of demonstrating how a task and queue can communication.  It would be much more efficient to use a DMA or other such fast mechanism.  Second - it is definitely not ok to have the interrupt above configMAX_SYSCALL_INTERRUPT_PRIORITY.  This too is stated clearly, in my opinion.  Please read the documentation for what this configuration parameter does.

I think yes.

I think no.

So If it yes, is it possible to change Free Rtos in order to give the mask priority for the Queue?

This last bit confuses me as I don’t know what you mean by the mask priority.  You can change your version of FreeRTOS in any way you like, but if I am guessing what you mean correctly then I suspect to keep the code portable the answer would also be no as far as changing the main line code is concerned.

Regards.

alexpetitfr wrote on Friday, September 17, 2010:

thank for all, all you explain is clear. I think too it’s more efficient to use  a circulare buffer.

So, to be clear for the last point : when we use the queue, at a moment, free rtos call
taskENTER_CRITICAL, the interrupt are masked from 255 to configMAX_SYSCALL_INTERRUPT_PRIORITY (for STM32).
I would like to mask just all priority (or level) of the ISR that use the queue.
For exemple UART use queue at priority 12 et ethernet is at priority 13 (under the UART on STM32) and configMAX_SYSCALL_INTERRUPT_PRIORITY = 11, so
when the queue in the task call taskENTER_CRITICAL, UART ISR and ethernet ISR are masked during. So it’s not necessary
to look ethernet ISR ; that why i would like to pass a parameter in the create queue in order to do
oldIP = taskENTER_CRITICAL(12) and after restore the level interrupt with taskEXIT_CRITICAL(oldIp).

I hope  it is more clear

thanks.

Alex

alexpetitfr wrote on Friday, September 17, 2010:

I understand the code must be portable.
So if it’s not possible, it’s not a problem.
I have write a circulare buffer that do this.

Thanks

Alex

rtel wrote on Friday, September 17, 2010:

Yes that is much clearer thank you.  I would recommend adding a feature request using the Source Forge feature request tracker (see the Tracker menu item at the top of this page).

That could be added in as a separate (new) API function because the old function would also have to be maintained for backward compatibility reasons.

Regards.

richard_damon wrote on Friday, September 17, 2010:

I would point out that the critical sections you mention protect not only data in that particular queue, but if the task gets suspended, also global information. To implement the sort of masking you are talking about, FreeRTOS would need to implement 2 different types of Critical Sections, one for global operations, and a second one for “local” information that is more limited. Note that for the second type to be useful, the objects that use it must only be referenced by a single task and an interrupt, as you are allowing other interrupts to occur which may cause a task switch.

My guess is that if you look at what the critical section is guarding, it is only for a short time that you would be using the limited critical section (just the time to check/adjust the data pointers) and the full critical section would be needed for the longer operations (task switching) so there isn’t that much gain for the work.

alexpetitfr wrote on Friday, September 17, 2010:

Yes you are right so I will kept my circular buffer beetween the task and my ISR.

Thanks a lot

zouzman wrote on Monday, October 31, 2016:

Hi all,

I’m new to freertos and I want to implement circular buffer for the same usage too, but I didn’t find an example on how to implement it correctly.

Could you provide me with useful links ?

Thanks ! :))

rtel wrote on Monday, October 31, 2016:

This is not really a FreeRTOS question, just a C programming question.

Did you Google “circular buffer C”, or “thread safe circular buffer”, or
“thread safe circular queue”, or “circular buffer implementations in C”,
or some such like, I’m sure you will come up with lots of implementations.