【uTenux实验】事件标志

【uTenux实验】事件标志

事件标志是一个用来实现同步的对象,由多个位组成,用作指示对应事件存在的标志。事件标志由用来指示对应事件存在的位模式(bitpattern)和一个等待事件标志的任务队列组成。

uTenux提供了一组API用于处理事件标志:创建、删除、设置、等待、清除。

1、创建事件标志:tk_cre_flg

为建立的事件标志分配一个控制块

事件结构体:

typedef struct t_cflg {VPexinf;ATRflgatr;UINTiflgptn;UBdsname[} T_CFLG;

其中事件属性flgatr,可设置为以下的一个或多个值:

TA_TFIFO 任务按FIFO的顺序排队

TA_TPRI 任务按优先级顺序排队

TA_WSGL 不允许等待多个任务(等待一个任务)

TA_WMUL 允许等待多个任务(等待多个任务)

TA_DSNME 设定DS对象名

OS根据事件标志的属性对使用这个事件标志的任务进行调度。

或等待:等待任意一个条件满足,与等待:等待所有条件满足

我的理解,事件标志就是一个二进制数。因为事件标志本身就是个UINT类型的数字。设置事件标志就是将这个数的某一位置位,清除事件标志就是将这个数的某一位清零。同一个事件标志有多个位,多个任务可以同时使用一个事件标志。

创建事件标志,OS会建立一个事件标志的控制块,用于调度。创建事件标志的时候,会为这个时间标志设置个初始值:iflgtn。与任务和信号量相同,FlgID只是这个事件标志的代表,并不是事件标志的值。

事件标志的属性中如果TA_WMUL设置为1,那么就允许多个任务同时等待一个事件标志。当一个事件标志被设置时,如果多个任务都满足条件,此时这些任务都会被释放。进入等待状态,虚拟主机,有系统调度决定哪个先执行哪个后执行。

2、设置和清除时间标志

ER ercd= tk_set_flg(ID flgid,UINT setptn) ;ER ercd= tk_clr_flg(ID flgid,UINT clrptn);

给出事件标志的ID,香港服务器,和要设置的位,即可设置或清除事件标志。

如果一个调用tk_wai_flg的任务的等待状态释放条件满足,则该任务的等待状态被清除。即此时OS的事件分派器工作了。

3、等待事件标志:

ERercd= tk_wai_flg(ID flgid,UINT waiptn,UINT wfmode,UINT* p_flgptn,TMO tmout);

等待flgid的某些位被置位。如果条件不满足,则进入等待状态。

关于API的详细描述,虚拟主机,uTenux内核规范有详细介绍。

【实验描述】

1、创建一个事件标志:FlgID,FlgID事件标志的初始值设置为1. 如果初始值iflgtn被设置为0x02,那么TaskB将先执行一遍循环,然后进入等待后TaskA开始执行。

2、创建两个优先级相同的任务:EventflagSampleTaskA(TaskA)EventflagSampleTaskB(TaskB)

3、创建任务后启动TaskB,在TaskB中启动TaskA。此时由于TaskB的优先权较大,TaskB继续执行,遇到等待事件标志时候停止执行。此时TaskA开始执行。

4、TaskA首先为TaskB设置事件标志(0x02),然后申请事件标志Flag的0x01。条件满足,继续执行清除这个事件标志(0x01)。循环执行,重新等待事件标志,此时事件标志没有被设置,所以TaskA进入休眠状态。TaskB继续执行。

5、TaskB获得优先权开始执行,完成FlagID(0x02)的清除,之后继续等待资格事件。当然,同样没等到进入休眠,任务A继续。

6、如此往复。。。

【实验代码】

#include EventflagSampleTaskA(W stacd,VP exinf);void EventflagSampleTaskB(W stacd,VP exinf);void EventflagSamplePutFlg(void);static ID TaskID_A;static ID TaskID_B;static ID FlgID;EXPORT ER EventflagSample( void ){ T_CTSK ctsk; T_CFLG cflg;cflg.exinf = (VP) NULL; //没有额外信息 cflg.flgatr = TA_WMUL | TA_TPRI; //事件标志的属性 cflg.iflgptn = 0x01; //事件标志的初始值 FlgID = tk_cre_flg(&cflg); if(FlgID < E_OK) {return FlgID; } else{tm_putstring((UB*)); }ctsk.bufptr = (VP)NULL; ctsk.exinf = (VP) NULL; ctsk.task = EventflagSampleTaskA; ctsk.stksz = 512; ctsk.itskpri = 24; ctsk.tskatr = TA_HLNG | TA_RNG0; TaskID_A = tk_cre_tsk(&ctsk); if(TaskID_A < E_OK) {return TaskID_A; } else {tm_putstring(); }ctsk.task = EventflagSampleTaskB; ctsk.itskpri = 24; TaskID_B = tk_cre_tsk(&ctsk); if(TaskID_B < E_OK) {tm_putstring((UB*));return TaskID_B; } else {tm_putstring(); } tm_putstring(); tk_sta_tsk(TaskID_B,5);return E_OK;}void EventflagSampleTaskA(W stacd,VP exinf){ UINT flgptn; while(1) {tm_putstring((UB*));tk_set_flg(FlgID,0x02); //为任务B设置事件标志tk_wai_flg(FlgID,0x01,TWF_ANDW,&flgptn,-1);EventflagSamplePutFlg();tm_putstring((UB*));tk_clr_flg(FlgID,0x01); //清除任务A自己的事件标志EventflagSamplePutFlg(); //输出任务信息:3:两个事件标志都被设置,2:任务B事件标志被设置,1:任务A事件标志被设置tm_putstring((UB*)); }}void EventflagSampleTaskB(W stacd,VP exinf){ UINT flgptn; tm_putstring((UB*)); tk_sta_tsk(TaskID_A,0); while(1) {tm_putstring((UB*));tk_set_flg(FlgID,0x01); //为任务A设置事件标志tk_wai_flg(FlgID,0x02,TWF_ANDW,&flgptn,-1);EventflagSamplePutFlg();tm_putstring((UB*));tk_clr_flg(FlgID,0x02); //清除自己的事件标志 EventflagSamplePutFlg();tm_putstring((UB*));} while(1);}void EventflagSamplePutFlg(void){B flgptn[10];T_RFLG rflg;tm_putstring((UB*));tk_ref_flg(FlgID, &rflg);ltostr(rflg.flgptn,flgptn,16,10);tm_putstring((UB*)flgptn);tm_putstring((UB*));}

【实验输出】 这里的风景美不胜收,真让人流连忘返。

【uTenux实验】事件标志

相关文章:

你感兴趣的文章:

标签云: