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。
运行结果如下所示:
由于串口打印函数需要一定的时间,显示结果未能像PC机运行那样,细看打印结果,基本上都是根据设计来的。
假设有共享资源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机运行那样,细看打印结果,基本上都是根据设计来的。
相关文章推荐
- C/C++易错小记录
- nyoj 32-组合数(DFS)
- 有理数类
- Class.newInstance()学习
- 【一些事晚报】薪资大比拼 12306的互联网思维 京东和腾讯在一起
- AJAX和form表单提交的中文转码问题全面解决,encoderURL两次转码的真相
- vim代码补全
- 黑马程序员_09_多态的演变过程
- How to Defeat Windows 8 ASLR in Getting the Address of KPCR
- WIFI基本知识
- 程序员面试题精选100题(27)-二元树的深度[数据结构]
- db file sequential read等待事件
- android libaray的创建和使用
- SB新态
- 面试题:求最小的K个数。
- Opencv2.1+vs2008生成不依赖编译环境的exe文件
- typedef int (init_fnc_t) (void)和typedef int (*init_fnc_t) (void) 区别
- 概要设计说明书——机房收费系统
- 黑马程序员-------第一天
- MCU封装简介