UCOS III学习(二)

一、时间片轮转调度

1、时间片轮转

UCOS III支持同优先级任务下的时间片轮转调度,首先解释下什么是时间片轮转
时间片是指一个较小的时间间隔,通常为 10 ms~100 ms 。在简单的轮转算法中,系统将所有的就绪的任务进程按 FIFO 规则排成一个队列,将 CPU 分配给队首进程,且规定它最多只能连续执行若干个时间片,若时间片用完时进程仍未完成,也必须将其插入就绪队列末尾,并把 CPU 交给下一个进程。简单来说,就好像你(CPU)定了一个每天的计划表,以小时为单位(一小时就相当于一个时间片),吃饭、睡觉、工作就是你每天的任务,每个任务都会占用若干个时间片,比如现在第一个任务是吃饭并分配了一个时间片,那你就有一个小时时间可以吃饭,若你在一个小时内没有吃完,你也必须放弃当前的任务转而执行第二任务睡觉,经过一轮轮转后你又回到了吃饭这个任务时你就可以接着上次吃的位置继续吃。如此循环往复,每个任务按照规定的时间片个数X单个时间片长度运转。

2、UCOS中关于时间片轮状调度的的API函数

首先要让时间片轮转宏置1

#define OS_CFG_SCHED_ROUND_ROBIN_EN     1u   //定义为1时使能时允许使用时间片轮转功能                              

然后要使能时间片轮转功能

 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
	void  OSSchedRoundRobinCfg (CPU_BOOLEAN   en,						//en=1 使能
                             OS_TICK       dflt_time_quanta,			//设置单个时间片长度=n*5ms(默认值)
                             											//写0时表示一个时间片=200/10*5毫秒=100ms 
                             OS_ERR       *p_err)						//保存函数出错返回值	

创建任务时设置任务所需要的时间片数量

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,			//单个任务时间片个数 0时表示默认长度100ms
                    void          *p_ext,				
                    OS_OPT         opt,					
                    OS_ERR        *p_err)				

【注】单次任务执行时间=时间片个数*时间片长度

若需要放弃本次任务的时间片

void  OSSchedRoundRobinYield (OS_ERR  *p_err)

放弃本次时间片后会将CPU使用权限移交给同优先级下下一个任务。

二、UCOS III内部任务

在UCOS III内部共支持五个系统内部任务,分别是必须要有的空闲任务、时钟节拍任务与可原则是否开启的统计任务与、定时任务、中断服务管理任务。

1、空闲任务

空闲任务特点
1、空闲任务是UCOSIII创建的第一个任务。
2、空闲任务是UCOSIII必须创建的。
3、空闲任务优先级总是OS_CFG_PRIO_MAK-1(优先级最低)。
4、空闲任务中不能调用任何可使空闲任务进入等待态的函数!

空闲任务函数主要内容

void  OS_IdleTask (void  *p_arg)
{
    CPU_SR_ALLOC();
    (void)&p_arg;                                          /* Prevent compiler warning for not using 'p_arg'  */
    while (DEF_ON) {
        CPU_CRITICAL_ENTER();								//进入临界态防止被打断
        OSIdleTaskCtr++;									//空闲计数
#if OS_CFG_STAT_TASK_EN > 0u								//开启空闲统计
        OSStatTaskCtr++;									//空闲加一
#endif
        CPU_CRITICAL_EXIT();							    //退出临界状态

        OSIdleTaskHook();                                   /* Call user definable HOOK (空闲任务内部钩子函数) */
    }
}

2、时钟节拍任务

主要作用:
时钟节拍任务用来跟踪任务延时和任务等待超时,任务函数为OS_TickTask(),是UCOSIII必须创建的一个任务,任务优先级用宏OS_CFG_TICK_TASK_PRIO(默认优先级为1)来定义 ,一般时钟节拍任务的任务应该设置一个相对较高的优先级。时钟节拍任务会在系统初始化时被创建,他是为其他任务的延时与定时提供时钟服务,不需要我们太多的了解。

3、统计任务

在UCOSIII中统计任务可用来统计CPU的使用率、各个任务的CPU使用率和各任务的堆栈使用情况,默认情况下统计任务是不会创建的。如果要开启统计任务的话需要做如下步骤:
1、将宏OS_CFG_STAT_TASK_EN置1。
2、必须在main函数创建的以一个任务也是唯一的一个应用任务里面调用函数OSStatTaskCPUUsageInit()。
3、统计任务的优先级通过宏OS_CFG_STAT_TASK_PRIO来设置,一般设置OS_CFG_PRIO_MAX-2,也就是倒数第二个优先级。

4、定时任务

UCOSIII提供软件定时器功能,定时任务是可选的,将宏OS_CFG_TMR_EN设置为1就会使能定时任务,在OSInit()中将会调用函数OS_TmrInit()来创建定时任务。定时任务的优先级通过宏OS_CFG_TMR_TASK_PRIO定义,ALIENTEK默认将定时器任务优先级设置为2。

5、中断服务管理任务

当把os_cfg.h文件中的宏OS_CFG_ISR_POST_DEFERRED_EN置1就会使能中断服务管理任务,当ISR(中断服务函数)调用UCOSIII提供的“post”函数时,要发送的数据和发送的目的地都会存入一个特别的缓冲队列中,当所有嵌套的ISR都执行完成以后UCOSIII会做任务切换,运行中断服务管理任务,该任务会把缓存队列中存放的信息重发给相应的任务。这样做的好处就是可以减少中断关闭的时间,否则,在ISR中还需要把任务从等待列表中删除,并把任务放入就绪表,以及做一些其他的耗时操作。
中断服务管理任务的优先级永远为0,不可更改!

三、钩子函数与回调函数

在UCOS III内部预留了大量的钩子函数,所谓的钩子函数是好比找了个代理,监视事件是否发生,如果发生了这个代理就执行你的事件处理方法;在这个过程中,代理就是钩子函数,它的作用与回调函数类似,不同之处在于钩子函数是直接明确了在满足某种条件后所需要应对的方法即钩子函数,而回调函数是将某个解决方法(回调函数)的指针作为参数进行传递,当发生事件后再使用函数指针调用某个函数。简单来说就是,发生某一事件后调用的钩子函数是确定的,但函数执行的内容是可以自定义的;而回调函数恰好相反,函数本身执行的内容是确定的,但发生事件后调用哪一个回调函数是可以自己选择的

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值