您的位置:首页 > 其它

uCOS-II 学习笔记之事件管理--------信号量管理的学习

2014-01-08 21:47 567 查看
  今天将卢有亮老师基于VC的信号量管理的代码移植到STM32中,并通过串口打印在串口终端。

  假设有共享资源R,允许2个任务分时访问R,那么信号量应该设置为2,系统中有三个任务(A、B、C)分别访问资源R,任务的优先级分别为7、6、5. 3个任务在操作系统的初始化和启动多任务之前被创建。任务A运行后创建信号量,并访问R,访问完成后任务将自己阻塞1000个时钟周期。任务B先阻塞自己300个时钟周期,任何操作步骤同任务A。任务C先阻塞400个时钟周期,然后操作步骤同任务A。

//=========================================================================================
//uCOS-II 学习例子
//=========================================================================================
//信号量管理的例子
void UserTaskSemA(void *pParam)
{
/*任务SemA创建信号量,然后周期性访问资源R*/
/*创建信号量*/
INT8U     *perr;
INT8U err;
//INT8U i;
OS_SEM_DATA mySemData;
err=0;
perr=&err;
MyEventSem=OSSemCreate(2);
if (MyEventSem==(OS_EVENT *)0)
{
printf("任务A创建信号量失败!\r\n");
OSTaskDel(OS_PRIO_SELF);
return;
}
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d, 任务A创建信号量。当前信号量值=%d\r\n",OSTimeGet(),mySemData.OSCnt);
while(1)
{
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务A开始请求信号量!当前信号量值=%d\r\n",OSTimeGet(),mySemData.OSCnt);
OSSemPend(MyEventSem,0,perr);
if (err!=OS_ERR_NONE)
{
printf("任务A请求信号量失败\r\n");
printf("错误号%d\n",err);
continue;
}
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务A获得信号量。当前信号量值=%d,任务A开始对R操作\r\n",OSTimeGet(),mySemData.OSCnt);
OSTimeDly(1000); /*模拟操作资源,需要10秒,1000个时钟嘀嗒*/
printf("时间:%d,任务A结束资源操作,提交信号量!\r\n",OSTimeGet());
OSSemPost(MyEventSem);
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务A提交信号量完成,当前信号量值=%d,任务A将延时阻塞1000嘀嗒\r\n",OSTimeGet(),mySemData.OSCnt);
OSTimeDly(1000);
}
}
void UserTaskSemB(void *pParam)
{
/*任务SemA创建信号量,然后周期性访问资源R*/
INT8U     *perr;
INT8U err;
OS_SEM_DATA mySemData;
err=0;
perr=&err;
printf("时间:%d,任务B开始延时300个时钟嘀嗒",OSTimeGet());
OSTimeDly(300);/*任务B先延时3秒*/
if (MyEventSem==(OS_EVENT *)0)
{
printf("任务A创建信号量失败!\r\n");
OSTaskDel(OS_PRIO_SELF);
return;
}
while(1)
{
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务B开始请求信号量!当前信号量值=%d\r\n",OSTimeGet(),mySemData.OSCnt);
OSSemPend(MyEventSem,0,perr);
if (err!=OS_ERR_NONE)
{
printf("任务B请求信号量失败\r\n");
printf("错误号%d\n",err);
continue;
}
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务B获得信号量。当前信号量值=%d,任务B开始对R操作,需1000个时钟嘀嗒\r\n",OSTimeGet(),mySemData.OSCnt);
OSTimeDly(1000); /*模拟操作资源,需要10秒,1000个时钟嘀嗒*/
printf("时间:%d,任务B结束资源操作,提交信号量!\n",OSTimeGet());
OSSemPost(MyEventSem);
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务B提交信号量完成,当前信号量值=%d,任务B将延时阻塞1000嘀嗒\r\n",OSTimeGet(),mySemData.OSCnt);
OSTimeDly(1000);
}
}

void UserTaskSemC(void *pParam)
{
/*任务SemA创建信号量,然后周期性访问资源R*/
INT8U     *perr;
INT8U err;
//INT8U i;
OS_SEM_DATA mySemData;
err=0;
perr=&err;
printf("时间:%d,任务C开始延时400个时钟嘀嗒",OSTimeGet());
OSTimeDly(400);/*任务C先延时4秒*/
if (MyEventSem==(OS_EVENT *)0)
{
printf("任务A创建信号量失败!\r\n");
OSTaskDel(OS_PRIO_SELF);
return;
}
while(1)
{
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务C开始请求信号量!当前信号量值=%d\r\n",OSTimeGet(),mySemData.OSCnt);
OSSemPend(MyEventSem,0,perr);
if (err!=OS_ERR_NONE)
{
printf("任务C请求信号量失败\r\n");
printf("错误号%d\n",err);
continue;
}
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务C获得信号量。当前信号量值=%d,任务C开始对R操作,需1000个时钟嘀嗒\r\n",OSTimeGet(),mySemData.OSCnt);
OSTimeDly(1000); /*模拟操作资源,需要10秒,1000个时钟嘀嗒*/
printf("时间:%d,任务C结束资源操作,提交信号量!\r\n",OSTimeGet());
OSSemPost(MyEventSem);
OSSemQuery(MyEventSem,&mySemData);
printf("时间:%d,任务C提交信号量完成,当前信号量值=%d,任务C将延时阻塞1000嘀嗒\r\n",OSTimeGet(),mySemData.OSCnt);
OSTimeDly(1000);
}
}


运行结果如下所示:

时间:0,任务C开始延时400个时钟嘀嗒时间:0,任务B开始延时300个时钟嘀嗒时间:0, 任务A创建信号量。当前信号量值=2
时间:1,任务A开始请求信号量!当前信号量值=2
时间:1,任务A获得信号量。当前信号量值=1,任务A开始对R操作
时间:300,任务B开始请求信号量!当前信号量值=1
时间:300,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
时间:400,任务C开始请求信号量!当前信号量值=0
时间:1002,任务A结束资源操作,提交信号量!
时间:1002,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
时间:1003,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
时间:1301,任务B结束资源操作,提交信号量!
时间:1301,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
时间:2003,任务C结束资源操作,提交信号量!
时间:2003,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
时间:2004,任务A开始请求信号量!当前信号量值=2
时间:2004,任务A获得信号量。当前信号量值=1,任务A开始对R操作
时间:2302,任务B开始请求信号量!当前信号量值=1
时间:2302,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
时间:3004,任务C开始请求信号量!当前信号量值=0
时间:3005,任务A结束资源操作,提交信号量!
时间:3005,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
时间:3006,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
时间:3303,任务B结束资源操作,提交信号量!
时间:3303,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
时间:4006,任务C结束资源操作,提交信号量!
时间:4006,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
时间:4007,任务A开始请求信号量!当前信号量值=2
时间:4007,任务A获得信号量。当前信号量值=1,任务A开始对R操作
时间:4304,任务B开始请求信号量!当前信号量值=1
时间:4304,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
时间:5007,任务C开始请求信号量!当前信号量值=0
时间:5008,任务A结束资源操作,提交信号量!
时间:5008,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
时间:5009,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
时间:5305,任务B结束资源操作,提交信号量!
时间:5305,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
时间:6009,任务C结束资源操作,提交信号量!
时间:6009,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
时间:6010,任务A开始请求信号量!当前信号量值=2
时间:6010,任务A获得信号量。当前信号量值=1,任务A开始对R操作
时间:6306,任务B开始请求信号量!当前信号量值=1
时间:6306,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
时间:7010,任务C开始请求信号量!当前信号量值=0
时间:7011,任务A结束资源操作,提交信号量!
时间:7011,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
时间:7012,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
时间:7307,任务B结束资源操作,提交信号量!
时间:7307,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒
时间:8012,任务C结束资源操作,提交信号量!
时间:8012,任务C提交信号量完成,当前信号量值=2,任务C将延时阻塞1000嘀嗒
时间:8013,任务A开始请求信号量!当前信号量值=2
时间:8013,任务A获得信号量。当前信号量值=1,任务A开始对R操作
时间:8308,任务B开始请求信号量!当前信号量值=1
时间:8308,任务B获得信号量。当前信号量值=0,任务B开始对R操作,需1000个时钟嘀嗒
时间:9013,任务C开始请求信号量!当前信号量值=0
时间:9014,任务A结束资源操作,提交信号量!
时间:9014,任务C获得信号量。当前信号量值=0,任务C开始对R操作,需1000个时钟嘀嗒
时间:9015,任务A提交信号量完成,当前信号量值=0,任务A将延时阻塞1000嘀嗒
时间:9309,任务B结束资源操作,提交信号量!
时间:9309,任务B提交信号量完成,当前信号量值=1,任务B将延时阻塞1000嘀嗒


由于串口打印函数需要一定的时间,显示结果未能像PC机运行那样,细看打印结果,基本上都是根据设计来的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: