|
功能:任务一和任务二都可以调用函数Fun(),但不能同时调用
目的:熟悉信号量的使用
代码:#include "includes.h"
#define TASK_STK_SIZE 512
#define Task_Hold 0x01
#define Task_Post 0x00
OS_STK DispCharMStk[TASK_STK_SIZE]; /*任务堆栈*/
OS_STK DispCharYStk[TASK_STK_SIZE];
OS_STK StartTaskStk[TASK_STK_SIZE];
INT16S key;
INT8U y1 = 0;
INT8U y2 = 0;
INT8U TaskID = 0;
INT8U err;
INT8U Flag; /*信号量是否放开标志*/
OS_EVENT *Fun_Sem;
void DispCharM(void *data); /*函数声明*/
void DispCharY(void *data);
void StartTask(void *data);
void Fun(INT8U *id);
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /*清屏*/
OSInit(); /* 初始化 uC/OS-II */
Fun_Sem = OSSemCreate(1); /*建立只有一个资源的信号量*/
PC_DOSSaveReturn(); /*保存DOS的返回环境*/
PC_VectSet(uCOS, OSCtxSw); /*安装ucos的任务切换向量*/
OSTaskCreate(StartTask, (void *)0, &StartTaskStk[TASK_STK_SIZE - 1], 0);
OSStart(); /*多任务开始*/
}
void StartTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata; /*防止编译警告*/
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); /*安装ucos的时钟向量*/
PC_SetTickRate(OS_TICKS_PER_SEC); /*设置时钟频率*/
OS_EXIT_CRITICAL();
OSStatInit(); /*初始化 uC/OS-II's 统计任务 */
OSTaskCreate(DispCharM,(void *)0, &DispCharMStk[TASK_STK_SIZE - 1], 2);
OSTaskCreate(DispCharY,(void *)0, &DispCharYStk[TASK_STK_SIZE - 1], 3); /*建立两个任务*/
for(;;)
{
if( Flag == Task_Hold) /*信号量是否被 hold 住*/
{
if( TaskID == 2 ) /*是否被2#任务 hold 住*/
{
PC_DispStr(10,12,"Warning: DispCharM hold the semaphore for 15s",DISP_BGND_BLACK + DISP_FGND_WHITE); /* 显示警告信息:2#任务 hold 住信号量 15s*/
}else if( TaskID == 3 )
{
PC_DispStr(10,12,"Warning: DispCharY hold the semaphore for 6s ",DISP_BGND_BLACK + DISP_FGND_WHITE); /* 显示警告信息:3#任务 hold 住信号量 6s*/
}
}else{
PC_DispStr(10,12," ",DISP_BGND_BLACK + DISP_FGND_WHITE);
} /*清除警告信息*/
if( PC_GetKey(&key) == TRUE )
{
if( key == 0x1B )
{
PC_DOSReturn();
}
}
OSTimeDly(5);
}
}
void DispCharM (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
for (;;)
{
OSSemPend(Fun_Sem,0,&err);
PC_DispStr(10,0,"DispCharM have got the semaphore",DISP_BGND_BLACK + DISP_FGND_WHITE); /*显示已得到信号量*/
PC_DispStr(10,8," ",DISP_BGND_BLACK + DISP_FGND_WHITE);
TaskID = OSPrioCur; /*传送任务优先级号*/
Fun(&TaskID); /*调用 Fun() 函数*/
Flag = Task_Hold;
OSTimeDlyHMSM(0,0,15,0); /* hold 住信号量 15s */
Flag = Task_Post; /*释放*/
OSSemPost(Fun_Sem);
if( PC_GetKey(&key) == TRUE )
{
if( key == 0x1B )
{
PC_DOSReturn();
}
}
OSTimeDlyHMSM(0,0,2,0);
}
}
void DispCharY(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
for (;;)
{
OSSemPend(Fun_Sem,0,&err);
PC_DispStr(10,8,"DispCharY have got the semaphore",DISP_BGND_BLACK + DISP_FGND_WHITE);
PC_DispStr(10,0," ",DISP_BGND_BLACK + DISP_FGND_WHITE);
TaskID = OSPrioCur;
Fun(&TaskID);
Flag = Task_Hold;
OSTimeDlyHMSM(0,0,6,0);
Flag = Task_Post;
OSSemPost(Fun_Sem);
if( PC_GetKey(&key) == TRUE )
{
if( key == 0x1B )
{
PC_DOSReturn();
}
}
OSTimeDlyHMSM(0,0,1,0);
}
}
void Fun(INT8U *id)
{
char *S_Fun = "# task is calling the Fun()";
char s[50];
sprintf(s, "%d", *id);
strcat(s,S_Fun);
if(*id == 2)
{
PC_DispStr(10,1,s,DISP_BGND_BLACK + DISP_FGND_WHITE);
PC_DispStr(10,7," ",DISP_BGND_BLACK + DISP_FGND_WHITE);
}else if( *id == 3 ){
PC_DispStr(10,7,s,DISP_BGND_BLACK + DISP_FGND_WHITE);
PC_DispStr(10,1," ",DISP_BGND_BLACK + DISP_FGND_WHITE);
}
} 注:程序在 windows 的虚拟环境下有时会产生错误,可能是和某些驱动程序相冲突了。在纯DOS环境下可以稳定运行。运行效果图:
|
|