UCOSIII基础


1.RTOS概述

RTOS(Real Time OS)即实时操作系统,根据各个任务的要求,进行资源(包括存储器、外设等)管理、消息管理、任务调度、异常处理等工作。在RTOS支持的系统中,每个任务均有一个优先级(类似前面章节的中断抢占优先级),RTOS 根据各个任务的优先级,动态地切换各个任务,保证对实时性的要求。

使用实时操作系统还需要额外的ROM/RAM开销,2~5%的CPU额外负荷,以及内核的费用。

RTOS的优点:

  • 1.并发性
  • 2.模块化:高内聚、低耦合的原则
  • 3.生态:很多高级软件组件,必须依赖于操作系统来实现
  • 4.实时性:功能复杂的情况下,实时性无法保证
  • 5.可重用性:软件可重用性差,总是重复造轮子

2.UCOSIII基本概念

2.1.UCOSIII 代码框架

  • 1.一个任务管理一个硬件
  • 2.任务与任务或任务与中断涉及到数据传输使用消息队列
  • 3.任务间共享资源访问使用互斥锁
  • 4.任务的同步使用信号量
  • 5.标志位的管理使用事件标志组
  • 6.编写一个专门初始化硬件的任务,该任务可以包含创建任务的功能。

2.2.UCOSIII的任务状态

  • 休眠态:任务已经分配,存储在内部flash中,但并为调用
  • 就绪态:在ucosIII的就绪表中登记,拥有运行的条件
  • 运行态:正在运行的任务,拥有此时的cpu使用权
  • 等待态:由于轮转调度机制,此时任务处于等待态,CPU使用权在此时处于运行态的任务手中
  • 中断服务:当中断触发,当前运行任务被挂起,CPU执行中断服务函数。

ps:当任务使用调度器上锁时,当中断服务函数结束,CPU返回给中断前运行的函数

2.3.内核调度点

  • 释放信号量、释放互斥锁或者发送消息,也可通过配置相应的参数不发生任务调度。
  • 使用延时函数OSTimeDly()或者OSTimeDlyHMSM()。
  • 任务等待的事情还没发生(等待信号量,消息队列等)。
  • 任务取消等待。
  • 创建任务。
  • 删除任务。
  • 删除一个内核对象。
  • 任务改变自身的优先级或者其他任务的优先级。
  • 任务通过调用OSTaskSuspend()将自身挂起。
  • 任务解挂某个挂起的任务。
  • 退出所有的嵌套中断。
  • 通过OSSchedUnlock()给调度器解锁。
  • 任务调用OSSchedRoundRobinYield()放弃其执行时间片。
  • 用户调用OSSched()

2.4.UCOS 任务组成

  • 1.任务堆栈:内部寄存器开出的存储空间,用来保存各个任务的工作环境

  • 2.任务控制块:记录各个任务的状态

  • 3.任务函数:运行处理任务的代码,在轮转调度机制下不停运转

OS_TCB Task1_TCB;
void task1(void *parg);
//任务1的任务堆栈,大小为128字,也就是512字节
CPU_STK task1_stk[128];	

3.共享资源保护

  • 共享资源主要是指:全局区或堆区中的数据,临界区代码,RAM,寄存器等。
  • 对共享资源的保护就是相当于在访问共享资源的时候做PV操作

3.1.常见的共享资源保护方式

  • 关闭中断请求:当访问共享资源的速度比UCOS关闭中断时间小的时候,如:读取或写入极少量数据时如读取内部FLASH、需要和中断服务程序共享变量或数据结构、喂狗操作、或需要保证读写稳定的操作,可选用关闭中断的方式保护共享资源,但此方法会引起中断延时触发,影响系统的原子性。
  • 禁止任务调度:当访问共享资源的时间比UCOSIII的中断关闭时间长,但是却比UCOSIII给调度器上锁时间短时,如访问变量缓冲区数据,甚至变量值自加/自减,可选择此方法。但给任务调度器上锁之后,此任务就会成为最高优先级,破话UCOS原先设定好的调度机制
  • 信号量:当任务访问被保护的共享资源不需要高实时性时,选择信号量,其优点是速度比互斥锁要快,但也存在破坏任务调度优先级的影响。
  • 互斥锁(推荐):把握实操作系统时性的需求,同时有优先级继承机制,也因如此访问优先级需要占用CPU时间,比信号量稍慢。

3.2.临界区保护

临界区是指一旦开始就不允许被打断的代码段。

CPU_SR_ALLOC();//首先存 cpu 状态寄存器的值
  • case1: 按照这个逻辑我们首先想到的就是关闭中断服务函数,但在临界区结束后要及时打,但此类情况只能适用于临界区代码可以快速完成,避免中断延迟相应,如串口数据丢包的情况。
CPU_CRITICAL_ENTER();  //屏蔽除NMI和fault以外的所有异常和中断,即将进入临界区 
//临界区代码,该代码涉及中断访问
CPU_CRITICAL_EXIT() ;  //开启除NMI和fault以外的所有异常和中断,退出临界区
  • case2:在仅由任务访问的代码段中也可以通过调度器上锁的方式进行临界区的保护,一旦上锁,操作系统会禁止阻塞型调用。若调度器上锁,禁止在临界区调用各种引起任务调度的函数,如睡眠延时、阻塞等待信号量/互斥型信号量/事件标志组/消息队列/多个内核对象等,否则引起内核运行异常。
OS_CRITICAL_ENTER();  //锁定调度器,即将进入临界区 
//临界区代码,该代码不涉及中断访问
OS_CRITICAL_EXIT() ;  //解锁调度器,退出临界区

3.3.信号量与PV操作

  • 信号量大多用于资源管理,当多个任务对共享资源进行访问时,为了防止访问任务数量操作资源的最大数目,信号量会阻塞其他试图获取该信号量的任务,直到有任务释放了信号量。
  • 以上操作机制可称为PV操作。P表示申请一个资源,每次P操作使信号量减1,V是释放一个资源,每次V操作使信号量加1。信号量表示的是当前可用的资源个数,当信号量为负时,申请资源的进程(任务)就只能等待了。所以,信号量是负的多少,就表明有多少个进程(任务)申请了资源但无资源可用,只能处于等待状态。
  • 在操作系统进行PV操作的过程中,会导致优先级反转这一严重的问题,在任何实时操作系统中都应该优先考虑。

PS:97年美国火星探测车上出现重庆现象就是应为当时的RTLinux操作系统,在PV操作的过程中发生优先级反转

  • 优先级翻转是当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。

优先级反转的解决方法

  • 目前解决优先级反转的方法有两种,一种是优先级继承,另一种是优先级最高权限,在UCOSIII中默认使用的是优先级继承的方法,即将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级。当高优先级任务由于等待资源而被阻塞时,此时资源的拥有者的优先级将会临时自动被提升,以使该任务不被其他任务所打断,从而能尽快的使用完共享资源并释放,再恢复该任务原来的优先级别。

创建信号量

/*
函数说明:
	信号量创建
参数说明:
	p_sem:信号量对象
	p_name:信号量名字
	cnt:信号量的初值
	p_err:返回错误码,没有错误的就返回OS_ERR_NONE
*/
void  OSSemCreate(OS_SEM      *p_sem,
                  CPU_CHAR    *p_name,
                  OS_SEM_CTR   cnt,
                  OS_ERR      *
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值