实例描述:
平台: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);
}
{
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_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_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_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");
}
}
}
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;
}
编译下载后,运行结果如下,在串口助手打印结果如下:
#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;
}
编译下载后,运行结果如下,在串口助手打印结果如下: