⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task_example.c

📁 uCOS-II多任务移植范例
💻 C
字号:
/*****************************************************************
*文件名: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); 即可
**实验效果和用信号量的一样。 
*******************************************************************************************************/






















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -