ucos任务管理

一、操作系统的初始化与启动

1.操作系统初始化,初始化各种内核对象和全局变量......


它是第一个执行的函数

void  OSInit (OS_ERR  *p_err)
参数:
p_err,返回错误码
返回值:无
......
OS_SemInit(p_err);
OS_TaskInit(p_err);  
OS_IntQTaskInit(p_err);                                 
OS_IdleTaskInit(p_err);
OS_TickTaskInit(p_err);  
......                           

2.启动操作系统,创建任务后调用

void  OSStart (OS_ERR  *p_err)
参数:
p_err,返回错误码

二、任务的管理

1.任务状态


UCOSIII任务状态转换图。

在这里插入图片描述
在这里插入图片描述

2.创建任务


```c

```c
void  OSTaskCreate (OS_TCB        *p_tcb,
                    CPU_CHAR      *p_name,
                    OS_TASK_PTR    p_task,
                    void          *p_arg,
                    OS_PRIO        prio,
                    CPU_STK       *p_stk_base,
                    CPU_STK_SIZE   stk_limit,
                    CPU_STK_SIZE   stk_size,
                    OS_MSG_QTY     q_size,
                    OS_TICK        time_quanta,
                    void          *p_ext,
                    OS_OPT         opt,
                    OS_ERR        *p_err)
参数:
p_tcb,类似于线程id,控制任务
p_name,任务的名字,自定义
p_task,类似于线程函数,任务函数
p_arg,类似于线程参数传递,任务参数传递
prio,任务的优先级
p_stk_base,任务栈的基址,提供一个数组基址
stk_limit,腾出10%的栈空间给到堆栈检测函数使用,反过来说,当前任务只能使用90%栈空间
stk_size,任务栈的大小,以字(32bit)为单位
q_size,任务内消息队列的大小,若不使用,写0
time_quanta,与其它任务处在同一个优先级,内核允许一个任务运行一定的时间(又叫时间片),然后轮到下一
             个任务,即所谓的互相“礼让”执行。默认为0,时间片由内核决定。
p_ext,提供额外存储空间用于存储浮点运算单元寄存器,若不提供,写NULL
opt,在创建任务的时候,提供额外操作,如果不使用,写OS_OPT_TASK_NONE
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:无

#栈大小
创建任务特别检查传递的数组的大小是否空间充足,因为它是作为任务的栈空间使用,若空间不足,会导致程序不能执行,直接跑到HardFault_Handler这个函数。
原因如下:
1)任务里申请大空间的局部变量,例如数组、结构体…,将会占用大量的栈空间
2)任务里包含很多复杂的函数,将会占用大量的栈空间

解决方法:
1)该局部变量变为全局变量
2)该局部变量变为静态的局部变量
3)创建当前任务的时候,决定更大的栈空间

#UCOSIII优先级
优先级 0:中断服务管理任务 OS_IntQTask()
优先级 1:时钟节拍任务 OS_TickTask() 滴答定时器任务
优先级 2:定时任务 OS_TmrTask()
优先级 3:开始任务 OS_start_task()
优先级OS_CFG_PRIO_MAX-2 : 统计任务 OS_StatTask()
优先级OS_CFG_PRIO_MAX-1 : 空闲任务 OS_IdleTask()

其他自己设定的任务可以根据重要性从4开始设定。

#轮转调度算法
时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。每个任务被分配一时间段,称作它的时间片,即该任务允许运行的时间。时间片轮转调度算法是面向于多个同级的任务。
在这里插入图片描述

轮转调度算法在实际使用中,时间片长度该设为多少需要好好调试,因为有时候时间片太短,任务还没来得及做事情,就被调度了;时间片太长,又会造成让其它任务等太久,所以实际编程中需要好好调试。

1)使用时间片轮转调度,需要将系统中的宏定义:“OS_CFG_SCHED_ROUND_ROBIN_EN”设为真,这样才能启用时间片轮转调度,具体位置在os_cfg.h。

2)在执行OSInit函数后添加如下代码:

#if OS_CFG_SCHED_ROUND_ROBIN_EN     
    //使能时间片轮转调度功能,时间片长度为:1*5=5ms
    OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
#endif

OSSchedRoundRobinCfg 函数分析

void  OSSchedRoundRobinCfg (CPU_BOOLEAN   en,
                            OS_TICK       dflt_time_quanta,
                            OS_ERR       *p_err)

参数说明:
en,使能,填写为"DEF_ENABLED"才能使能时间片轮转调度;
dflt_time_quanta,时间片长度,就是每个任务每次获得CPU使用权后执行的时间。若参数为0,时间片长度=OS_CFG_TICK_RATE_HZ/10。
p_err,错误码。

3)当一个任务想要放弃本次时间片的时候,就可以调用该函数,函数原型如下:

void  OSSchedRoundRobinYield (OS_ERR  *p_err)

4)任务创建示例

//创建任务1
OSTaskCreate((OS_TCB *)&Task1_TCB,		        //任务控制块
			(CPU_CHAR *)"Task1",		//任务的名字
			(OS_TASK_PTR)task1,		//任务函数
			(void *)0,			//传递参数
			(OS_PRIO)6,			//任务的优先级		
			(CPU_STK *)task1_stk,		//任务堆栈基地址
			(CPU_STK_SIZE)128/10,		//任务堆栈深度限位
			(CPU_STK_SIZE)128,		//任务堆栈大小			
			(OS_MSG_QTY)0,			//禁止任务消息队列
			(OS_TICK)10,			//默认时间片长度为10*1ms=100ms																
			(void  *)0,			//不需要补充用户存储区
			(OS_OPT)OS_OPT_TASK_NONE,	//没有任何选项
			&err				//返回的错误码
			);

3.任务挂起

暂停任务的执行

void   OSTaskSuspend (OS_TCB  *p_tcb,
                      OS_ERR  *p_err)

参数:
p_tcb,类似于线程id,控制任务

p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:无

项目用途:
1)如果当前任务不是经常要执行的,可以挂起。类似于手机APP的管理机制,如果app进入后台就冻结其执行,也就是挂起app,有利于提高系统响应,降低资源占用。
2)保护共享资源,可以挂起。

4.任务恢复执行

void  OSTaskResume (OS_TCB  *p_tcb,
                    OS_ERR  *p_err)

参数:
p_tcb,类似于线程id,控制任务
p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:无

5.任务的删除

void  OSTaskDel (OS_TCB  *p_tcb,
                 OS_ERR  *p_err)

参数:
p_tcb,类似于线程id,控制任务;若是删除自己的话,就填写NULL。

p_err,返回错误码,没有错误的就返回OS_ERR_NONE

返回值:无

项目用途:
专门用于初始化硬件,一般来说,硬件只做一次初始化,完毕后可将该任务删除,该任务的删除是不会释放资源,只是通过任务列表去掉而已。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值