/*****************************************************************
*文件名:Task_Example
*描述:点灯程序(LED1点亮1秒,熄灭;LED2点亮3秒,熄灭)
*平台:LP2104
*说明:uC/OS-II下优先级和信号量在调度中的应用
*时间:2008.11.9
*来源:互联网
******************************************************************/
#include "config.h"
#define TASK_STK_SIZE 64
OS_STK TaskStartStk[TASK_STK_SIZE];
OS_STK TaskStk[TASK_STK_SIZE];
OS_STK TaskStk5[TASK_STK_SIZE];
OS_STK TaskStk2[TASK_STK_SIZE];
#define LED1 (1<<10)
#define LED2 (1<<11)
void TaskStart(void *pdata);
void Task1(void *pdata);
void Task2(void *pdata);
void Task5(void *pdata);
OS_EVENT *Ledcon;
/*********************************************************************************************************
** 函数名称: main
** 功能描述: 主函数,由它启动多任务环境,创建第一个任务
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: OSInit,OSTaskCreate,OSStart
********************************************************************************************************/
int main(void)
{
OSInit(); /*uC/OS-II初始化*/
Ledcon = OSSemCreate(1); /*建立信号量Ledcon,主要是为了使两个管脚的高低电平不会相互干扰,且初始化为高电平,说明
同一时刻只有一个任务可以使用这个信号量*/
OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);
OSStart();
return 0;
}
/*********************************************************************************************************
** 函数名称: TaskStart
** 功能描述: uC/OS-II的第一个任务,通常由它初始化目标板和建立其它任务
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void TaskStart(void *pdata)
{
pdata = pdata; /*避免编译器警告*/
TargetInit(); /*目标板初始化*/
PINSEL0 = 0x00000000; /*管脚设置为GPIO*/
PINSEL1 = 0x00000000;
OSTaskCreate(Task1,(void*)0,&TaskStk[TASK_STK_SIZE-1],4); /*创建任务*/
OSTaskCreate(Task2,(void*)0,&TaskStk2[TASK_STK_SIZE-1],5); /*创建任务*/
OSTaskCreate(Task5,(void*)0,&TaskStk5[TASK_STK_SIZE-1],6); /*创建任务*/
/*由于Task1,Task2,Task5优先级都没有TaskStart高,所以TaskStart继续运行*/
for(;;)
{
OSTimeDlyHMSM(1,0,0,0); /*TaskStart挂起一个小时,主要是为了挂起内核。内核继续执行优先级最高的任务*/
}
}
/*********************************************************************************************************
** 函数名称: Task1
** 功能描述: uC/OS-II的其它任务,点亮LED1
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void Task1(void *pdata)
{
INT8U err;
pdata = pdata;
for(;;)
{
OSSemPend(Ledcon,0,&err); /*uC/OS-II检查信号量Ledcon的状态,没有任务占用,故Task1可以继续运行
同时信号量置0,否则无限期的等待该信号量,uC/OS-II将任务改挂起,
继续寻找就绪任务中优先级最高的 */
IODIR = LED1; /*设置LED1为输出*/
IOCLR = LED1; /*点亮LED1*/
OSTimeDlyHMSM(0,0,3,0); /*延时1秒,或者说挂起一秒。挂起后,uC/OS-II内核继续寻找下一个优先级
高的任务,会找到Task2。若没有这个延时,系统将继续向下执行,再把LED1
对应管脚输出高电平,因此LED1会闪一下,但是这个时间很短暂,观察不到*/
IOSET = LED1; /*LED1熄灭*/
OSSemPost(Ledcon); /*释放信号量,同时一直在等待该信号量的Task2从挂起处开始执行*/
}
}
/*********************************************************************************************************
** 函数名称: Task2
** 功能描述: uC/OS-II的其它任务,点亮LED2, 持续3秒
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void Task2(void *pdata)
{
INT8U err;
pdata = pdata;
for(;;)
{
OSSemPend(Ledcon,0,&err); /*uC/OS-II检查信号量Ledcon的状态,由于信号量已经被Task1置0,故不可用,
uC/OS-II将Task2挂起,继续寻找就绪任务中优先级最高的,发现Task5*/
IODIR = LED2; /*设置LED2为输出*/
IOCLR = LED2; /*点亮LED2*/
OSTimeDlyHMSM(0,0,8,0); /*延时3秒,寻找就绪任务中优先级最高的,找到Task1*/
IOSET = LED2; /*LED2熄灭*/
OSSemPost(Ledcon); /*释放信号量*/
}
}
/*********************************************************************************************************
** 函数名称: Task5
** 功能描述: 空闲任务。uC/OS-II在找到了Task5之后,Task5只是一个无限的循环,不会主动的让出内核使用
使用权,假如没有其他任务主动抢走使用权的话,它将一直占用。大概1秒后,Task1的挂起任务
OSTimeDlyHMSM(0,0,1,0); 到期,且Task1的优先级最高。将内核使用权抢走
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void Task5(void *pdata)
{
pdata = pdata;
for(;;)
{
}
}
/********************************************************************************************************
** End Of File
********************************************************************************************************/
/*******************************************************************************************************
**可以把消息邮箱用作二值信号量,在上面的实验中。
**把Ledcon=OSSemCreate(1);换成ledcon=OSMboxcreate((void *)1);
**把OSSemPend(Ledcon,0,&err);换成OSMboxPend(lecon,0,&err);
**把OSSemPost(Ledcon); 换成OSMboxPost(ledcon,(void *)1); 即可
**实验效果和用信号量的一样。
*******************************************************************************************************/