您的位置 首页 应用

ucos-ii学习笔记——信号量的原理及运用

Createdon:2012-10-7Author:zhangbin学习笔记forucos-iiPCredesignedbyzhangbin2012-10-7versions:V-01AllRight

Createdon:2012-10-7

Author:zhangbin

学习笔记

forucos-iiPC

redesignedbyzhangbin

2012-10-7

versions:V-0.1

AllRightsReserved

#include“INCLUDES.h”

#defineTASK_STK_SIZE512

char*s1=”MyTask”;

char*s2=”YouTask”;

INT8Uerr;//界说一个错误信息

INT8Uy=0;

OS_EVENT*Fun_Semp;//声明信号量是事情操控块ECB类型的

//留意,前面有一个比如2界说了互斥信号量,界说如下

//BOOLEANac_key;//信号量,互斥信号量实质上便是一个标志位,是一个全局变量,来标志共享资源的拜访状况

//这样,当现已有使命拜访共享资源时,其他的使命就不能拜访,知道该资源未被拜访,其他的使命才干够进行拜访

//留意这两个信号量的差异和运用状况

OS_STKStartTaskStk[TASK_STK_SIZE];//界说使命仓库区

OS_STKMyTaskStk[TASK_STK_SIZE];

OS_STKYouTaskStk[TASK_STK_SIZE];

voidFun(INT8Ux,INT8Uy);

voidStartTask(void*data);

voidMyTask(void*data);

voidYouTask(void*data);

voidmain(void)

{

Fun_Semp=OSSemCreate(1);//在主函数中创立信号量返回值为创立的信号量指针,参数是信号量的计数器的值

//用该参数对信号量计数器OSEventCnt进行初始化

//1即代表只创立一个信号量,代表信号量用于对共享资源的拜访(例如,把它作为二值信号量运用),详见P166

OSInit();

PC_DOSSaveReturn();

PC_VectSet(uCOS,OSCtxSw);

OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE1],0);//创立开始函数

OSStart();

}

voidStartTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

INT16Skey;

pdata=pdata;

OS_ENTER_CRITICAL();

PC_VectSet(0x08,OSTickISR);

PC_SetTickRate(OS_TICKS_PER_SEC);

OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE1],1);//创立使命函数

OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE1],2);//创立使命函数

for(;;)

{

//假如恩下ESC键,则退出UC/OS-II

if(PC_GetKey(&key)==TRUE)

{

if(key==0x1B)

{

PC_DOSReturn();

}

}

OSTimeDlyHMSM(0,0,3,0);

}

}

//MyTask的函数代码

voidMyTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3

OS_CPU_SRcpu_sr;

#endif

pdata=pdata;

for(;;)

{

OSSemPend(Fun_Semp,0,&err);//恳求信号量参数Fun_Semp是信号量指针0那一项是等候时限timeout,0表明无限等候

//err表明错误信息

PC_DispStr(0,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);//显现MyTask字符串

Fun(7,y);//调用Fun函数

OSSemPost(Fun_Semp);//发送信号量开释信号量,函数的参数Fun_Semp代表信号量的指针

OSTimeDlyHMSM(0,0,1,0);

}

}

voidYouTask(void*pdata)

{

#ifOS_CRITICAL_METHOD==3//AllocatestorageforCPUstatusregister

OS_CPU_SRcpu_sr;

#endif

pdata=pdata;

for(;;)

{

OSSemPend(Fun_Semp,0,&err);//恳求信号量

PC_DispStr(0,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);

Fun(7,y);//调用FUN函数

OSSemPost(Fun_Semp);//开释信号量

OSTimeDlyHMSM(0,0,2,0);//等候2s

}

}

//公共的函数Fun的代码

voidFun(INT8Ux,INT8Uy)

{

PC_DispStr(x,y,”CallingFUN()”,DISP_BGND_BLACK+DISP_FGND_WHITE);//显现字符串,表明调用了Fun函数

}

//创立信号量时,用的参数为1,即Fun_Semp=OSSemCreate(1);,只创立了一个信号量,这种状况一般是信号量用于对

//共享资源的拜访(例如,能够把它作为二值信号量运用)

//在上面的程序中,当MyTask运转时,先恳求获得了信号量,对共享资源Fun函数进行拜访,因为只创立了一个信号量,

//所以在MyTask的拜访期间,即便使命YouTask也进行请求信号量,此刻OSEventCnt是值现已为0了,所以会把使命

//YouTask列入使命等代表OSEventTbl[]中,使使命处于等候状况。

//只要等MyTask对Fun函数拜访完成了,调用OSSemPost(Fun_Semp);开释了信号量,该开释信号量的函数会先查看使命等候

//表中是否还有等候信号量的使命,假如有,则使使命进入安排妥当态后,调用调度器OS_Sched()引发一次使命调度,去运转等候

//使命列表中优先级最高的使命。假如没有,则就把信号量计数器OSSemCnt加1.

//所以使命YouTask要想拜访Fun()函数,有必要比及使命MyTask对Fun拜访结束,开释了信号量之后,才干拜访,反之亦然

//所以由上面能够看出,只创立一个信号量,即OSSemCreate(1);,效果就相当于运用一个二值信号量,标志共享资源是否正在

//被拜访

//看懂了上面的剖析,也就能够解说试验现象了,因为YouTask等候2s,MyTask等候1s,所以有可能在MyTask拜访Fan函数期间,YouTask

//也来拜访(也有可能是反过来),可是因为信号量现已被MyTask占用了,所YouTask只好等候,MyTask运用完了,开释了信号量,YouTask才干正常运用Fun函数

//这样也就处理了多使命对共享资源的运用的问题,使使命之间得到了同步

//要仔细剖析信号量作业的原理,把上面的内容看懂了,基本上也就能够运用信号量了

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/256252.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部