ucos-ii学习笔记1 创建任务&&任务调度

2023-05-16

	最近在学习嵌入式系统,听说ucos-ii是使用最广,也是最经典的嵌入式系统,也就跟随大众从这个系统入手了,用的stm32F407开发板。

借用百度的一段介绍:

μC/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中)。同时,该系统源代码开放、整洁、一致,注释详尽,适合系统开发。 μC/OS-II已经通过联邦航空局(FAA)商用航行器认证,符合航空无线电技术委员会(RTCA)DO-178B标准。

uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。
uC/OS-II以源代码的形式发布,是开源软件, 但并不意味着它是免费软件。你可以将其用于教学和私下研究(peaceful research);但是如果你将其用于商业用途,那么你必须通过Micrium获得商用许可。

在没学操作系统之前,平时写的程序都是在单片机上裸奔,就是一个大循环,一堆函数怼进去,然后循环着调用,现在正在努力脱离裸奔。

ucos ii操作系统的基础是要有一个时钟节拍,这个时钟节拍来自滴答定时器,时间一般为几毫秒,而且不可以被打断。我使用的时钟节拍选择了HCLK的8分频,因为外设为8MHz,然后倍频到168MHz,也就是说SYSTick的时钟为21MHz。

ucos ii是依靠任务优先级和通过调度任务来执行函数的,每一个任务都相当于以前程序的那个大循环,只要没有释放CPU就会一直执行下去。释放CPU的直接代码就是把当前任务挂起或者调用ucos ii里面的延时函数(强调:不要自己写for延时什么的,这样虽然也是延时,但是这是占用CPU的延时,不会切换任务的)。

接下来介绍ucos ii第一批函数:

1.建立任务函数OSTaskCreate(void (* task)(void *pd),void *pada,OS_STK * ptos,INTU prio);

这个函数有4个参数,

task是指向任务的指针,说白了就是任务的名字,后面的那个pd不用理,干嘛用的暂时没搞清楚;

pdata是任务开始的时候传递给任务的参数的指针,就是一个参数,一般都是0;

ptos是分配给任务的堆栈的栈顶指针,也就是这个任务拥有的存储空间大小,任务越复杂,这个空间需要的越大;

prio是任务的优先级,优先级的数值越低,任务的优先级越高(优先级是唯一的,在ii中一个优先级只能对应一个任务)。

2.任务删除函数OSTaskDel(INT8U prio);

这个函数不用怎么说了,prio就是要删除的任务的优先级,但是,任务不能随便删,在删除之前要先释放这个任务占用的资源。

3.请求任务删除函数OSTaskDelReq(INT8U prio);

前面说到要删除任务就必须保证资源释放完毕,这个函数的作用就是通过向 被删除任务 发送请求来实现任务释放自身占用资源后再删除。

4.改变任务优先级任务OSTaskChangPrio(INT8U oldprio,INT8U newprio);

这函数一看就知道用来改任务的优先级的,不多说。

5.任务挂起函数OSTaskSuspend(INT8U prio);

这个函数用来挂起当前任务,让这个任务不再参与调度直到被恢复。挂起和删除不同,挂起并不需要先释放资源,而且挂起的认为可以恢复,删 除的任务无法恢复。这个挂起函数一般用在开始任务中,学了几天ucos ii后发现套路都是先初始化硬件,然后初始化ucos ii,然后就创建一个 开始任务,再在这个任务里面创建其它任务,并不是一口气都在main()里面都把任务创建好,main里面只创建一个任务,然后在开始任务执行完后就可以把开始任务挂起了,不需要再参与任务调度了。

6.任务恢复函数OSTaskResume(INT8U prio);

这个函数就是可以把挂起的任务恢复,让调度器可以重新调度该任务。

7.任务查询信息OSTaskQuery(INT8I prio.OS_TCB *pdata);

这个用来了解任务信息的,不太懂,书上说是获得对应任务的OS_TCB中的内容拷贝。


接下来上几个例子,也就是套路(省略了头文件什么的)

先定义任务的优先级、堆栈大小、任务名称等

//START 任务
#define START_TASK_PRIO      			10 //开始任务的优先级设置为最低
#define START_STK_SIZE  				64
OS_STK START_TASK_STK[START_STK_SIZE];
void start_task(void *pdata);	
//LED任务
#define LED_TASK_PRIO					8
#define LED_STK_SIZE					64
OS_STK LED_TASK_STK[LED_STK_SIZE];
void led_task(void *pdata);
//主任务
#define MAIN_TASK_PRIO					4
#define MAIN_STK_SIZE					128
OS_STK MAIN_TASK_STK[MAIN_STK_SIZE];
void main_task(void *pdata);
//按键任务
#define KEY_TASK_PRIO					3
#define KEY_STK_SIZE					64
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
void key_task(void *pdata);

如上,这就创建了4个任务,优先级从低到高,然后再在main里面创建开始任务

int main(void)
{ 

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        .......//初始化各种模块
	
	OSInit();  	 				//初始化UCOSII
  	OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
	OSStart();	    
}
起始任务就是开始任务,,一个意思一个意思,OSStart()是用来启动任务调度了。然后就进入开始任务了

void start_task(void *pdata)
{
    OS_CPU_SR cpu_sr=0; 	    
	pdata = pdata; 	

	OSStatInit();					//初始化统计任务.这里会延时1秒钟左右	
 	OS_ENTER_CRITICAL();		//进入临界区(无法被中断打断) 
 	OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);
	OSTaskCreate(key_task,(void *)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);
	OSTaskCreate(main_task,(void *)0,(OS_STK*)&MAIN_TASK_STK[MAIN_STK_SIZE-1],MAIN_TASK_PRIO);
 	OSTaskSuspend(START_TASK_PRIO);	//挂起起始任务.
	OS_EXIT_CRITICAL();				//退出临界区(可以被中断打断)
}

这个OSStaInit();据说是用来统计运行时间的,原文在这:

如果用户将系统定义常数OS_TASK_STAT_EN(见文件OS_CFG.H)设为1,这个任务就会建立。一旦得到了允许,OS_TaskStat()每秒钟运行一次(见文件OS_CORE.C),计算当前的CPU利用率。换句话说,OS_TaskStat()告诉用户应用程序使用了多少CPU时间,用百分比表示,这个值放在一个有符号8位整数OSCPUsage中,精读度是1个百分点。

 如果用户应用程序打算使用统计任务,用户必须在初始化时建立一个唯一的任务,在这个任务中调用OSStatInit()。换句话说,在调用系统启动函数OSStart()之前,用户初始代码必须先建立一个任务,在这个任务中调用系统统计初始化函数OSStatInit(),然后再建立应用程序中的其它任务。

临界区什么的就是为了一些不能受干扰的代码段设置的,必须连续运行,不能被中断的代码段,敞开了说临界区就是把中断全都关了,一条线的执行程序。

最后就是各个任务的内容了

void led_task(void *pdata)
{
	while(1)
	{
	}
}
void main_task(void *pdata)
{
	while(1)
	{
	}
}
void key_task(void *pdata)
{
	while(1)
	{
	}
}
这里需要注意的是每个任务的while循环里都要有个延时,前面也说过ucos ii是通过延时来释放CPU占用的,没有延时的话当前任务会一直占着CPU不放,其它任务没法执行。

第一次的笔记就这样了,虽然本意上这是写来自己看的,但有错误欢迎指出。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ucos-ii学习笔记1 创建任务&&任务调度 的相关文章

随机推荐