Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

wait for a signal

Posted by ggerla on January 7, 2008
hi,
I have an application that run under an operating system wich implements the following feature:

-----------------------
2.4.1. Signals
Signals represent the simplest and fastest form of task communication. These can always be
used when a pure task synchronization is required without data exchange.
Each active task contains its own signal flag with which the following operations can be
executed:
Wait for a signal
Send signal
Clear signal
The task handle of the receiver task is used for identifying the signals for the individual
operations.
2.4.1.1. Wait for a Signal
Each task can wait for its signal flag (system function "os_wait_signal" and "os_wait"). It
waits until its signal flag is set by another task (system function "os_send_signal"). After a
signal is received, the waiting task clears its signal flag again and enters the task state
READY or RUNNING, depending on priority relationships.
If the signal flag is already set when the task calls the wait function (when the signal flag was
previously set by another task), then it immediately receives the signal. The task does not
first enter the WAIT state (BLOCKED).
The waiting time for a signal can be restricted. If the specified time has expired without
receiving the signal, the waiting task is made READY again with the return status "time-out"
(see system function "os_wait_signal" and "os_wait").
2.4.1.2. Send Signal
Each task and each interrupt procedure can set the signal flag of any other task (send a
signal to this task). Only one signal which has been sent can be stored per task (signal flag).
As long as a task has not received a signal, each additional signal sent is lost.
2.4.1.3. Clear Signal
A task can clear the signal flag of any other task (even it's own). This allows defined signal
states in the system at any time.
-----------------------

Do you thing it will be possible to develop the same feature with FRTOS? If yes, how can I do?

Thanks in advance

RE: wait for a signal

Posted by Dave on January 7, 2008
I think you could just use the existing binary semaphore of mutex implementation. Its called a semaphore rather than signal but in effect does the same thing. The binary semaphore is good as a pure synchronization mechanism as it does not actually pass any data and as it does not use priority inheritance (unlike the mutex) it can be a one way communication if you like.

For example, an interrupt can "signal" a task by using the SemaphoreGiveFromISR() function.
A task can block on a "signal" by using the SeamphoreTake() function and if the signal is already there is will not block but just return immediately.

RE: wait for a signal

Posted by ggerla on January 8, 2008
Thank you Dave.
Your idea is pretty good. I'm afraid that it's difficult to implement this feature: as you suggest the signal is sent is sent to semaphore, while in the other OS the signal is sent to the task. So I have to assign one semaphore to only one task.
I tought that I can declare an array of configMAX_NUM_TASK semaphores. When a task is going to be in wait assign its Handle to a semaphore. When an interrupt "signal" a task, I search the Handle in the array and if I find it I use SemaphoreTake for that semaphore.
Instead, if the task for wich I send the signal is not waiting, assign the Handle to semaphore and when the task try to go in waiting, search its handle inside the array and if it found it don't wait.
So, what do you think about this idea? Have you got some more suggestions about this thread?

RE: wait for a signal

Posted by ggerla on January 10, 2008
Starting from Dave's suggestion, I put down this piece of code:

static xSemaphoreHandle xSemphrList[configMAX_NUM_TASK];

unsigned portBASE_TYPE usTaskWait(unsigned portBASE_TYPE event_selector, unsigned portBASE_TYPE timeout)
{
unsigned portBASE_TYPE retval=1;

if( (event_selector & W_SIG) == W_SIG )
{
unsigned char i=pxCurrentTCB->uxTCBNumber;
unsigned portLONG timeFirst;
unsigned portLONG timeAfter;

portDISABLE_INTERRUPTS();

if(xSemphrList==NULL)
{
vSemaphoreCreateBinary(xSemphrList);
}
timeFirst=usTaskGetTickElapsed();
if( xSemphrList != NULL )
{
xSemaphoreTake( xSemphrList, timeout );
}
timeAfter=usTaskGetTickElapsed();

portENABLE_INTERRUPTS();

if( (timeFirst+timeout) <= timeAfter )
retval=E_TMO;
else
retval=E_SIG;
}
else
{
if( (event_selector & W_TMO) == W_TMO )
{
vTaskDelay(timeout);
retval=E_TMO;
}
}
return retval;
}

/*!

\brief Manda un segnale ad un task

La funzione manda un segnale ad un task

\param *task Handle del task a cui deve essere mandato il segnale

\return 1 se l'operazione e' andata a buon fine, 0 se il puntatore
del TCB fornito e' NULL

*/
unsigned portBASE_TYPE usTaskSendSignal(void * task)
{
tskTCB *pxUnblockedTCB;
unsigned portBASE_TYPE retval=pdFALSE;

if(task!=NULL)
{
unsigned char i;

portDISABLE_INTERRUPTS();

pxUnblockedTCB=(tskTCB *)task;
i=pxUnblockedTCB->uxTCBNumber;

if(xSemphrList==NULL)
{
vSemaphoreCreateBinary(xSemphrList);
}
if( xSemphrList != NULL )
{
retval=xSemaphoreGive(xSemphrList);
}
portENABLE_INTERRUPTS();
}
return retval;
}

/*!

\brief Manda un segnale ad un task

La funzione manda un segnale ad un task

\param *task Handle del task a cui deve essere mandato il segnale

\return 1 se l'operazione e' andata a buon fine, 0 se il puntatore
del TCB fornito e' NULL

*/
unsigned portBASE_TYPE usTaskSendSignalFromISR(void * task)
{
tskTCB *pxUnblockedTCB;
unsigned portBASE_TYPE retval=pdFALSE;

if(task!=NULL)
{
unsigned char i;

portDISABLE_INTERRUPTS();

pxUnblockedTCB=(tskTCB *)task;
i=pxUnblockedTCB->uxTCBNumber;

if(xSemphrList==NULL)
{
vSemaphoreCreateBinary(xSemphrList);
}
if( xSemphrList != NULL )
{
retval=xSemaphoreGiveFromISR(xSemphrList,pdFALSE);
}
portENABLE_INTERRUPTS();
}
return retval;
}


/*!

\brief Cancella un segnale ad un task

La funzione cancella un segnale ad un task

\param *task Handle del task a cui deve essere mandato il segnale

\return 1 se l'operazione e' andata a buon fine, 0 se il puntatore
del TCB fornito e' NULL

*/
unsigned portBASE_TYPE usTaskClearSignal(void * task)
{
unsigned portBASE_TYPE retval=1;
tskTCB * pxUnblockedTCB;

if(task!=NULL)
{
unsigned char i;

portDISABLE_INTERRUPTS();

pxUnblockedTCB=(tskTCB *)task;
i=pxUnblockedTCB->uxTCBNumber;

if(xSemphrList!=NULL)
{
vQueueDelete(xSemphrList);
xSemphrList=NULL;
}

retval=0;

portENABLE_INTERRUPTS();
}
return retval;
}

/*!

\brief Cancella un segnale ad un task

La funzione cancella un segnale ad un task

\param *task Handle del task a cui deve essere mandato il segnale

\return 1 se l'operazione e' andata a buon fine, 0 se il puntatore
del TCB fornito e' NULL

*/
unsigned portBASE_TYPE usTaskClearSignalFromISR(void * task)
{
unsigned portBASE_TYPE retval=1;
tskTCB * pxUnblockedTCB;

if(task!=NULL)
{
unsigned char i;

portDISABLE_INTERRUPTS();

pxUnblockedTCB=(tskTCB *)task;
i=pxUnblockedTCB->uxTCBNumber;

if(xSemphrList!=NULL)
{
vQueueDelete(xSemphrList);
xSemphrList=NULL;
}

retval=0;

portENABLE_INTERRUPTS();
}
return retval;
}

Is it right to use the vQueueDelete to clear signal?
Even if the asynchronous serial seem to work, the synchronous serial does not. I think this could be due to the timing. Should I add a forced switch context at the end of send signal even if I can not explicitly find out in the datasheet?
I have another idea: if an ISR send signal to task and the scheduler is suspended, the task is insert in the pending list. Should I write a vApplicationTickHook function that remove the task from the pending list and insert it in the ready list? In this way the task will be processed more fastly.

Best regards

RE: wait for a signal

Posted by sotd on January 10, 2008
I have not been following this thread and have only scanned the code but I would definitely say that you are using critical sections where I dont think any are needed. The queue and semaphore functions take care of the mutual exclusion of the queues themselves.

I also dont think you need to ever delete a queue or semaphore but just use it to pass data. The data is transitory in the system not the queue or semaphore.

To wait for a message can you not just wait on a queue with the data that is sent on the queue being the event type. This would be normal.

xQueueHandle queue;

xQueueCreate(); // whatever

if( xQueueReceive( queue, &event, portMAX_DELAY ) ) // or what ever delay
{
switch( event ) {
case W_SIG : //do something
break;
case W_TMO : // do something
break;
}
}


RE: wait for a signal

Posted by saiberion on January 10, 2008
Alone from your description I think you misunderstood something.

To wait for a Queue/Semaphore you use xQueueReceive/xSemaphoreTake with
To send to a Queue/Semaphore you use xQueueSend(FromISR)/xSemaphoreGive(FromISR)

Deleting a queue means you free memory used by the queue, not "releasing" the signal
As soon as data are sent to a queue the waiting tasks reads the one piece of data from the queue. If a queue already has stored data the task will return immediately and if a queue is empty it waits until the block time is reached.
There is no need to release the signal manually because it is done somehow automatically.

For more information refer to the API documentation on the website and the example codes for different MCUs

RE: wait for a signal

Posted by ggerla on January 10, 2008
ok. I've undertsand what you said. But if a queue already has stored data, I want remove this data in order to the task will not return but wait a new data on the queue. Is this possible?

RE: wait for a signal

Posted by sotd on January 10, 2008
only while(pdPASS==xQueueReceive( queue, &var, 0 ));


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists