[uTenux] signal

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

Signal (style= "semaphore") is a used to indicate the resources available and the number of available resources in numerical form object. When using a set of resources, to achieve mutual exclusion semaphore control and synchronization. uTenux provides signal out of the API, you can easily use the semaphore.

 

uTenux, signal contains a resource count (used to indicate the presence of the corresponding resources as well as the number of resources) and a queue of tasks waiting for the semaphore.

when a task to return to m resources, semaphore resource count and m< font face=",">. When a task is to obtain n resources, decreases the semaphore resource count by n. If the number of semaphore resources is not enough (to further reduce the semaphore count may cause it to become a negative value), the attempt to get the resources of the task in wait state until the next time, resources are returned. Waiting for the semaphore resource task is put in the semaphore queue.

1, create a semaphore: IDsemid=tk_cre_sem(T_CSEM*pk_csem);

T_CSEM for signal structure, defined as follows:

 

 

typedef    struct t_csem {
VP exinf;
/*Extended information, OS don't care */
ATR sematr;
/* Signal properties*/
INT isemcnt;
/* Semaphore initial count */
INT maxsem;
/* Maximum number of semaphores */
UB dsname[
8]; /* Object name */
} T_CSEM;

 

Property of signal can be obtained by using the following expressions:

sematr:=(TA_TFIFO||TA_TPRI)|(TA_FIRST||TA_CNT)| [TA_DSNAME]

TA_TFIFO

tasks according to the FIFO order line

TA_TPRI

tasks according to the order of priority queue

TA_FIRST

the queue in the first task of the first resources

TA_CNT

request fewer tasks more to obtain resources

TA_DSNAME

set DS object name

tasks waiting for the semaphore queue order can be set to TA_FIFO or TA_TPRI . TA_FIRST and TA_CNT settings to access the resource sequence

2,tk_sig_sem is used to release the semaphore

 

Provide a release signal quantity can be. If there are no more than the maximum semaphore count, after release, the signal technology to increase this number.

3,tk_wai_sem used to apply signal.

about the amount of signal for:

 

If one needs to obtain a plurality of signal, but the signal is not enough. For example, I need to 3 a signal, but the signal remaining amount of only 1. Then use tk_wai_sem for signal time, does not change the semaphore count, and then began to wait for the other signal.

experiment:

1,Create three tasks: task A,B,C. The task of A three signal, B 4 a semaphore. Task A priority than task B. Task C as the lowest priority of the idle task.

2, create task, First start the task B, Task B to apply for 4 a semaphore. And then start the task A.

3 A a higher priority than the task B, Task B was interrupted, Task A start execution. Since there is no available signal system, task A for signal failure " Enter wait state.

4, returned to the task B, task B release four signal. At this time, system semaphore enough for task A use, task A awakened. Continue to implement.

5, A executive once dormant, task B start execution. Task B apply for and obtain the 4 a semaphore, LED inversion. After entering dormancy release.

6, two task enters wait state, the task C start execution. Task C is a dead circulation. To prevent the OS no running tasks and exit.

 

experimental code as follows:

 

//In this experiment, the signal representing the development board is a LED
//Task B requires 4 signals at the same time, control LED light off
//Task A requires 3 signals at the same time, control LED1,2,3 light off

#include
"SemSample.h"
#include
<dev/ts_devdef.h>

void SemSampleTaskA(W stacd,VP exinf);
void SemSampleTaskB(W stacd,VP exinf);
void SemSampleTaskC(W stacd,VP exinf);
void SemSamplePutCnt(void);
static ID TaskID_A;
static ID TaskID_B;
static ID TaskID_C;
static ID semid;


ER SemSample(
void)
{
ER ercd
= E_OK;
T_CTSK ctsk;
T_CSEM csem;

ctsk.exinf
= NULL;
ctsk.task
= SemSampleTaskA;
ctsk.tskatr
= TA_HLNG | TA_RNG0;
ctsk.stksz
= 512;
ctsk.bufptr
= NULL;
ctsk.itskpri
= 24;
TaskID_A
= tk_cre_tsk(&ctsk);
if(TaskID_A< E_OK)
{
ercd
= TaskID_A;
return ercd;
}

ctsk.itskpri
= 26;
ctsk.stksz
= 256;
ctsk.task
= SemSampleTaskB;
TaskID_B
= tk_cre_tsk(&ctsk);
if(TaskID_B < E_OK)
{
ercd
= TaskID_B;
return ercd;
}

ctsk.itskpri
= 28;
ctsk.stksz
= 256;
ctsk.task
= SemSampleTaskC;
TaskID_C
= tk_cre_tsk(&ctsk);
if(TaskID_C < E_OK)
{
ercd
= TaskID_C;
return ercd;
}

//Create a semaphore
csem.exinf = NULL;
csem.isemcnt
= 4;
csem.maxsem
= 4;
csem.sematr
= TA_TFIFO | TA_FIRST;
semid
= tk_cre_sem(&csem);
if(semid < E_OK)
{
ercd
= semid;
return ercd;
}
SemSamplePutCnt();

//Start the task B
tk_sta_tsk(TaskID_B,5);

return TRUE;
}


void SemSampleTaskA(W stacd,VP exinf)
{
ER ercd
= E_OK;
T_RSEM rsem;
rsem
= rsem;
while(1)
{
tm_putstring((UB
*)"Task A began to apply for 3 signal \n");
SemSamplePutCnt();
ercd
= tk_wai_sem(semid,3,500);

SemSamplePutCnt();
if(ercd == E_OK)
{
LEDTog(LED1);
LEDTog(LED2);
LEDTog(LED3);
}

tm_putstring((UB
*)"Task A began to release the 3 signals \n");
tk_sig_sem(semid,
3);
SemSamplePutCnt();

tk_slp_tsk(
500);
}

}

void SemSampleTaskB(W stacd,VP exinf)
{
ER ercd
= E_OK;
T_RSEM rsem;

ercd
= tk_sta_tsk(TaskID_C,0);

SemSamplePutCnt();
tk_wai_sem(semid,
4,-1);
ercd
= tk_sta_tsk(TaskID_A,0);
if(E_OK == ercd)
{
tm_putstring((UB
*)"Start TaskA sucessfuly.\n");
}
else
{
tm_putstring((UB
*)"TaskB Failed start Task A.\n");
}
tk_sig_sem(semid,
4);
//Task cycle
while(1)
{
//Task B requires 4 signals

SemSamplePutCnt();
tm_putstring((UB
*)"Task B began to apply for 4 signal \n");

if(tk_wai_sem(semid,4,-1) == E_OK)
{
tm_putstring((UB
*)"Task B successfully the 4 signal of \n");
SemSamplePutCnt();
LEDTog(LED1);
LEDTog(LED2);
LEDTog(LED3);
LEDTog(LED4);
if(tk_sig_sem(semid,4) == E_OK)
{
tm_putstring((UB
*)"Task B successfully released 4 signals \n");
}
else
{
tm_putstring((UB
*)"Task B release signal failure \n");
}
}
else
{
tm_putstring((UB
*)"Task B acquisition signal failure \n");
}
tk_slp_tsk(
200);
}

}

//Prevent all dormant cause the OS to exit the idle task
void SemSampleTaskC(W stacd,VP exinf)
{
B b;
while(1)
{
tm_putstring((UB
*)"this is in Task C\n");
for(b = 0;b<200;b++);
}
}


void SemSamplePutCnt(void)
{
B semcnt[
10];
T_RSEM rsem;

tm_putstring((UB
*)"The available signal current number: ");
tk_ref_sem(semid,
&rsem);
ltostr(rsem.semcnt,semcnt,
10,10);
tm_putstring((UB
*)semcnt);
tm_putstring((UB
*)"\n");
}

 

the serial output information:

----------------------------------------------------

micro Tenux Version 1.6.00(build 0180)

Supported MCU is ST STM32F407VG

  Copyright(c) 2008-2013 by Dalian uLoong Co.,Ltd. 

----------------------------------------------------

The available signal current number: 4

The available signal current number: 4

Task A began to apply for 3 signal

The available signal current number: 0

Start TaskA sucessfuly.

The available signal current number: 1

Task A began to release the 3 signal

The available signal current number: 4

The available signal current number: 4

Task B began to apply for 4 signal

Task B is successfully obtained 4 signal

The available signal current number: 0

Task B successfully released 4 signal

this is in Task C

The available signal current number: 4

Task B began to apply for 4 signal

Task B is successfully obtained 4 signal

The available signal current number: 0

Task B successfully released 4 signal

The available signal current number: 4

Task B began to apply for 4 signal

Task B is successfully obtained 4 signal

The available signal current number: 0

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Lucine at November 16, 2013 - 2:15 PM