一、为什么要学习实时操作系统(rtos)
随着嵌入式系统要处理的任务越来越复杂,对任务时时性要求越来越高。我们往往需要花比较大的精力用在任务间的调度处理上,比如我们想要设计一个行列键盘按键输入并用数码管动态显示的系统,单纯的行列键盘按键输入和数码管动态显示都很简单,但把他们放到一起就会出现问题,数码管动态显示内部需要延迟和定时刷新才能保证数码管的亮度和显示的实时性,而键盘的输入往往也需要按键消抖的延迟,当两个任务放在一起就会彼此间产生影响。
实时操作系统的优势在这时候就很明显了,他让编程人员更加关注任务本身而非任务间的调度关系。在众多的实时操作系统中,ucos的资料是最丰富的,无论是教程还是代码网上一搜就可以搜到,作为嵌入式实时操作系统的入门非常合适。
二、UCOSIII中任务的五种状态和相互切换
ucosiii中任务共有五种状态,他们分别是:
1. 休眠状态:表示任务代码已经保存在程序存储器中,但任务并没有被创建或已经被删除。
2. 就绪状态:当多个任务同时需要被执行时,能运行的只有其中优先级最高的一个因为CPU只有一个,此时其余的任务就处于就绪状态,等待高优先级任务执行完毕后释放CPU资源。
3. 运行状态:顾名思义表示任务当前正在运行。
4. 挂起/等待状态:任务脱离就绪和运行两种状态,强行被暂停,但又不同于休眠状态的被删除,任务仍然可以被恢复后继续运行。
5. 中断服务状态:当发送中断,当前正在运行的任务会被挂起,CPU转而去执行中断服务函数,此时任务的任务状态叫做中断服务态。
任务状态间的切换如下图所示
三、任务的创建、挂起、恢复与删除
1、任务创建函数
每一个任务的创建都要有对应的任务栈大小、任务函数、及任务优先级(数字越小越优先)有五个系统任务默认优先级不可被使用。
任务创建要在临界区内进行,临界区的特点是1禁止中断、2 调度器锁定
void OSTaskCreate (OS_TCB *p_tcb, //p_tcb指向任务控制块起始地址
CPU_CHAR *p_name, //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, //任务最大的消息接收数目,0时表示禁止
OS_TICK time_quanta, //时间片轮转长度 0时表示默认长度
void *p_ext, //用户补充存储区
OS_OPT opt, //任务选项
OS_ERR *p_err) //任务出错返回值
2、挂起任务
OSTaskSuspend (OS_TCB *p_tcb,
OS_ERR *p_err)
3、恢复任务
OSTaskResume (OS_TCB *p_tcb,
OS_ERR *p_err)
4、删除任务
OSTaskDel (OS_TCB *p_tcb,
OS_ERR *p_err)