UC/OS II事件管理之信号量管理实例

实例描述:

平台:MDK4.7+UCOSII+STM32F103

系统移植:http://blog.csdn.net/mcu_tian/article/details/48224361

UC/OS II事件管理之信号量管理实例工程:http://download.csdn.net/detail/mcu_tian/9102763

任务A、任务B、任务C 3个任务   这3个任务都需要访问资源R,允许2个任务同时访问R,信号量设置为2。
三个任务的优先级分别为 9、8、 7。
三个任务在得到信号量之后,都会通过串口在串口助手上打印相关信息。

任务A创建信号量,信号量的设置为2,并通过信号量访问R,然后阻塞1000个时钟周期
任务B先阻塞自己200个时钟周期  访问R,然后自己阻塞自己1000个时钟周期
任务C先阻塞自己200个时钟周期  访问R,然后自己阻塞自己1000个时钟周期



实验步骤:
1:重定向标准输出到USART1
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return (ch);
}
2:修改os_cfg.h的宏定义关于事件管理、信号量管理、时间管理的配置
#define OS_SEM_EN                 1    /* Enable (1) or Disable (0) code generation for SEMAPHORES     */
#define OS_SEM_ACCEPT_EN          1    /*    Include code for OSSemAccept()                            */
#define OS_SEM_DEL_EN             1    /*    Include code for OSSemDel()                               */
#define OS_SEM_PEND_ABORT_EN      1    /*    Include code for OSSemPendAbort()                         */
#define OS_SEM_QUERY_EN           1    /*    Include code for OSSemQuery()                             */
#define OS_SEM_SET_EN             1    /*    Include code for OSSemSet()                               */
 
#define OS_TIME_DLY_HMSM_EN       1    /*     Include code for OSTimeDlyHMSM()                         */
#define OS_TIME_DLY_RESUME_EN     1    /*     Include code for OSTimeDlyResume()                       */
#define OS_TIME_GET_SET_EN        1    /*     Include code for OSTimeGet() and OSTime

#define OS_TIME_DLY_HMSM_EN       1    /*     Include code for OSTimeDlyHMSM()                         */
#define OS_TIME_DLY_RESUME_EN     1    /*     Include code for OSTimeDlyResume()                       */
#define OS_TIME_GET_SET_EN        1    /*     Include code for OSTimeGet() and OSTimeSet()             */
#define OS_TIME_TICK_HOOK_EN      1    /*     Include code for OSTimeTickHook()  
3:编写任务函数:
OS_EVENT *R_Sem;
OS_SEM_DATA R_Infor;


void Sem_TaskA(void *p)
{
INT8U perr;
R_Sem = OSSemCreate(2);
if(R_Sem == (OS_EVENT *)0)
{
printf("Crete failed\n");
return;
}
OSSemQuery(R_Sem,&R_Infor);
printf("TaskA Crete Successfully\n Time:%d \nThe SemNumber: %d\n",OSTimeGet(),R_Infor.OSCnt);
while(1)
{
OSSemPend(R_Sem,0,&perr);
if(perr == OS_ERR_NONE)
{
printf("TaskA get the Sem\n");
OSSemQuery(R_Sem,&R_Infor);
printf("TaskA is the prio:%d \nTime:%d \nThe SemNumber: %d\n",OSPrioCur,OSTimeGet(),R_Infor.OSCnt);
}
OSTimeDly(1000);
if(OSSemPost(R_Sem) == OS_ERR_NONE)
{
printf("Task A post the Sem\n");
}
}


};
void Sem_TaskB(void *p)
{
INT8U perr;
OSTimeDly(200);
while(1)
{
OSSemPend(R_Sem,0,&perr);
if(perr == OS_ERR_NONE)
{
printf("TaskB get the Sem\n");
OSSemQuery(R_Sem,&R_Infor);
printf("TaskB is the prio:%d \nTime:%d \nThe SemNumber: %d\n",OSPrioCur,OSTimeGet(),R_Infor.OSCnt);
}
OSTimeDly(1000);
if(OSSemPost(R_Sem) == OS_ERR_NONE)
{
printf("Task B post the Sem\n");
}
}
}


void Sem_TaskC(void *p)
{
INT8U perr;
OSTimeDly(200);
while(1)
{
OSSemPend(R_Sem,0,&perr);
if(perr == OS_ERR_NONE)
{
printf("TaskC get the Sem\n");
OSSemQuery(R_Sem,&R_Infor);
printf("TaskC is the prio:%d \nTime:%d \nThe SemNumber: %d\n",OSPrioCur,OSTimeGet(),R_Infor.OSCnt);
}
OSTimeDly(1000);
if(OSSemPost(R_Sem) == OS_ERR_NONE)
{
printf("Task C post the Sem\n");
}
}
}
4:编写主函数:
#include "app.h"

#define TASK_STK_SIZE 512
#define TaskStart_Prio 1

OS_STK TaskStk[5][TASK_STK_SIZE];//用户任务堆栈

int main(void)
{
USART1_Init();
OSInit();
printf("The OS begin\n");
OSTaskCreate(Sem_TaskA,0,&TaskStk[1][TASK_STK_SIZE-1],9);
OSTaskCreate(Sem_TaskB,0 ,&TaskStk[2][TASK_STK_SIZE-1],8);
OSTaskCreate(Sem_TaskC,0 ,&TaskStk[3][TASK_STK_SIZE-1],7);
OS_CPU_SysTickInit();  //注意,要在系统开始前必须初始化系统时钟,不然延时等系统功能不能运行。
OSStart();

while(1);
return 0;
}

编译下载后,运行结果如下,在串口助手打印结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值