您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 以UCOSIII为例-嵌入式实时操作系统概述
嵌入式实时操作系统概述以μC/OS-III为例张宗哲概述的主要内容一.任务及其状态二.任务调度三.上下文切换四.临界段五.中断管理六.时间管理七.共享资源管理八.同步与消息传递九.内存管理典型的前后台嵌入式系统为什么要以μC/OS-III为例一、典型的操作系统。二、商业内核,品质可靠。三、源代码开放,书写规范。四、中文参考资料多,便于学习五、我不懂其它的系统。实时内核一.任务及其状态什么是任务任务(也叫做线程)是简单的程序。单CPU中,在任何时刻只能是一个任务被执行。任务看起来像C函数。在大多数嵌入式系统中,任务通常是无限循环的。任务不能像C函数那样,它是不能return的。任务的基本样子任务的创建一个简单的任务例子任务状态二.任务调度什么是调度调度器,决定了任务的运行顺序。uC/OS-III是一个可抢占的,基于优先级的内核。根据其重要性每个任务都被分配了一个优先级。uC/OS-III支持多个任务拥有相同的优先级。当多个任务有相同的优先级时,uC/OS-III允许每个任务运行规定的时间片。当任务没有用完分配给它的时间片时,它可以自愿地放弃CPU。“可抢占的”意味当事件发生时,如果事件让高优先级任务被就绪,uC/OS-III马上将CPU的控制权交给高优先级任务。循环轮转调度抢占式调度三.上下文切换什么是上下文切换当uC/OS-III转向执行另一个任务的时候,它保存了当前任务的CPU寄存器到堆栈。并从新任务的的堆栈中CPU寄存器载入CPU。这个过程叫做上下文切换。上下文切换的例子四.临界段什么是临界段临界段代码,也称作临界域,是一段不可分割的代码。uC/OS-III中包含了很多临界段代码。如果临界段可能被中断,那么就需要关中断以保护临界段。如果临界段可能被任务级代码打断,那么需要锁调度器保护临界段。关中断uC/OS-III定义了一个进入临界段的宏和两个出临界段的宏。OS_CRITICAL_ENTER()OS_CRITICAL_EXIT()OS_CRITICAL_EXIT_NO_SCHED()锁住调度器当设置OS_CFG_ISR_POST_DEFERRED_EN为1时,在进入临界段前uC/OS-III会锁住调度器,退出临界段后开启调度器。OS_CRITICAL_ENTER()给调度器加锁。OS_CRITICAL_EXIT()给调度器解锁。OS_CRITICAL_EXIT_NO_SCHED()不调用调度器。五.中断管理什么是中断中断是硬件机制,用于通知CPU有异步事件发生。当中断被响应时,CPU保存部分(或全部)寄存器值并跳转到中断服务程序(ISR)。ISR响应这个事件,当ISR处理完成后,程序会返回中断前的任务或更高优先级的任务。在实时系统中,关中断的时间越短越好。长时间关中断可能会导致中断来不及响应而重叠。CPU的中断处理短中断服务程序在很多情况下,ISR不需要发送通知任务,而是在ISR中直接完成需要的工作(假定需要完成的工作代码较短)短ISR程序,如上所定义,是一个例外。它不遵循uC/OS-III的规则,所以uC/OS-III不知道ISR中发生了什么。长中断服务程序直接提交和延迟提交中断服务程序uC/OS-III有两种方法处理来自于中断的时间;直接提交和延迟提交。通过OS_CFH.H中的OS_CFG_ISR_POST_DEFERRED_EN来选择。当设置为0时,uC/OS-III使用直接提交方法。当设置为1时,使用推迟提交方法。直接提交中断服务程序延迟提交中断服务程序六.时间管理函数名功能OSTimeTick()用于标记,表示发生了一个时基中断OSTimeDly()延时执行任务n个时基OSTimeDlyHMSM()延时执行任务HH:MM:SS.mmmOSTimeDlyResume()恢复处于延时状态的任务OSTimeGet()获得当前的时基计数值OSTimeSet()设置当前的时基计数值uC/OS-III提供了一些与时间相关的函数如表所示系统时基uC/OS-III需要一个能提供周期性时间的时基源,叫做系统时基。硬件定时器可以被设置为每秒产生10到1000Hz的中断提供系统时基。时基可以看做是系统的心跳。它的速率决定于时基源。然而,时基速率越快,系统的额外支出就越大。时基函数OSTimeTick()延迟函数OSTimeDly()任务调用这个函数后就会被挂起直到期满。这个函数可以有三种模式:相对延时模式,周期性延时模式,绝对定时模式。相对延迟周期性延迟设置当参数设置为了OT_OPT_TIME_PERIDSIC时,OSTimeDly()被设置为周期性延时模式。周期性延迟相对延时模式和周期性延时模式看起来是不一样的,但是它们类似的。它们都可能丢失一个时基当有高优先级任务被执行很长时间时。绝对延迟可以使用绝对时间模式处理对时间要求很高的任务。例如,必须产品在上电的第10秒关闭LED。在这种情况下,你就需要设置为绝对时间模式OS_OPT_TIME_MATCH。设置OSTickCtr值为10乘以时基频率。相对延迟函数OSTimeDlyHMSM()可以设置为小时,分钟,秒,毫秒(HMSM由此四个英文首字母得来)。这个函数只在相对延时模式下运行。延迟恢复函数OSTimeDlyResume()任务可以调用OSTimeDlyResume()恢复其它被OSTimeDly()或OSTimeDlyHMSM()延时的任务。OSTimeSet()和OSTimeGet()每个时基中断发生时uC/OS-III会递增时基计数值。通过这个计数值能大概看出系统上电后经过了多长时间。OSTimeGet()能获得时基计数值。OSTimeSet()允许用户设置时基计数值。虽然uC/OS-III允许这种操作,但调用这个函数时需慎重。七.共享资源管理什么是共享资源多个任务可能会同时要求占用资源:内存空间、全局变量、指针、缓冲区、列表、环形缓冲区等。通过共享资源,任务间通信将会比较简单。当然,避免任务间的竞争和防止资源被破坏是非常重要的。大部分独占资源的方法都是创建临界段。资源共享方式什么时候该用关中断方式能很快地结束访问共享资源,不推荐使用这种方法,因为会导致中断延迟锁调度器式访问共享资源比较久时信号量方式当该共享资源经常被多个任务使用时采用。但信号量可能会造出优先级倒置。然而,信号量方式的执行时间少于mutex方式mutex方式推荐使用这种方法访问共享资源,尤其当任务要访问的共享资源有截止时间。uC/OS-III的mutex有内置的优先级,这样可防止优先级倒置。然而,mutex方式慢于信号量方式,多了个操作:需改变信号量的优先级。uC/OS-III提供了一些保护临界段的机制采用哪种保护机制决定于访问共享资源的代码长度关中断CPU_CRITICAL_ENTER()CPU_CRITICAL_EXIT()经常成对地使用。关中断时间越短越好,不然会影响系统响应外部事件的及时性。当临界段很短时可以使用关中断方法。锁调度器使用OSSchedLock()和OSSchedUnlock(),只有调度器被锁,中断是使能的,如果在处理临界段时中断发生,ISR程序就会被执行。什么是信号量信号量是一个“锁定机构”,代码需要获得“钥匙”才可以访问共享资源。占用该资源的任务不再使用该资源并释放资源(钥匙)时,其它任务才能够访问这个资源。通常有两种类型的信号量:二值信号量和多值信号量。二值信号量的值只能是0或1.多值信号量计数值可以是0到4294967295(依赖于计数值是8位,16位或32位)只有任务才允许使用信号量,ISR是不允许的。二值信号量任务要访问共享资源就必须执行一个等待操作。如果信号量是有效的(信号量计数值大于0),信号量计数值递减,任务访问该共享资源。如果信号量计数值为0,任务会被放入挂起队列中等待该信号量有效。uC/OS-III允许设置等待的时限。如果等待超时,该挂起任务会被就绪,等待该信号量的pend函数会返回一个错误代号。任务通过post函数释放信号量。如果没有任务在等待这个信号量,信号量计数值会被递增。如果有任务在等待这个信号量,其中高优先级的挂起任务被就绪,但信号量计数值不会递增。二值信号量创建任务等待二值信号量在共享I/O时,信号量非常有用优先级反转优先级反转是实时系统中的一个常见问题,仅存在于基于优先级的抢占式内核中。图显示了一种优先级反转的情况。任务H的优先级高于任务M,任务M的优先级高于任务L。互斥信号量uC/OS-III支持一种特殊类型的二值信号量叫做mutex,用于解决优先级反转问题。互斥信号量使用死锁死锁,就是两个任务互相等待对方所占用的资源的情况。防止死锁的方法1)同一个时间不要申请多于一个mutex2)不要直接地申请mutex(该申请放到器件驱动中和可重入函数中)3)在处理之前先获得全部所需要的mutex4)任务间以同样的顺序申请资源八.同步与消息管理什么是同步任务与ISR或其它任务同步运行。uC/OS-III中用于同步的两种机制:信号量和事件标志组。信号量用于同步信号量是绝大多数多任务内核所提供的协议机制。信号量最初用于控制共享资源的访问。信号量可用于ISR与任务间、任务与任务间的同步。信号量单向同步图显示了通过信号量,任务可以与ISR或任务同步。通过信号量的传递,这表明了ISR或任务发生了。使用信号量实现同步叫做单向同步。单向同步例子单向同步例子多值信号量计数值多值信号量计数值中保存了它还能被分配多少次。换句话说,当ISR提交该信号量n次,那么该信号量计数值就会增加n。多个任务等待一个信号量多个任务可以同时等待同样的信号量,假设每个任务都被设置了定时期限。事件标志组当任务要与多个事件同步时可以使用事件标志。若其中的任意一个事件发生时任务被就绪,叫做逻辑或(OR)。若所有的事件都发生时任务被就绪,叫做逻辑与(AND)。用户可以创建任意个事件标志组(限制于RAM)。事件标志组示例使用事件标志组例子当任务或ISR提交标志到事件标志组,满足条件的任务会被就绪。事件标志组中位的含义由用户定义,应用中可以有多个事件标志组。在事件标志组中,可以定义位0表示温度过低(由温度传感器接收),位1表示电压过低,位2表示某个开关被按下等。任务或ISR检测这些传感器并调OSFlagPost()设置相应的标志位。任务可以调用OSFlagPend()检测相应的标志是否发生。使用事件标志组例子使用事件标志组例子多任务同步通过广播信号量实现多任务同步是通用的方法。显然的,在单CPU系统中,同一时间只能执行一个任务。然而,多个任务可以同时被就绪。这叫做多任务同步。多任务同步的例子什么是消息消息中包含一个指向数据的指针、该数据的大小、时间戳变量。该指针可以指向数据区域甚至是一个函数。当然,消息的发送方和消息的接收方都应该知道消息所包含的意义。换句话说,接收方知道接收发到消息的含义。消息的内容(即数据)通常保留在其作用域中因为发送的是数据的地址而不是数据。换句话说,数据不是被拷贝并发送给任务,而是告诉任务数据的地址,并让任务自己去访问。消息队列消息队列是先入先出模式(FIFO)。然而,uC/OS-III也可以将其设置为后入先出模式(LIFO)。若任务或ISR发送紧急消息给另一个任务时,后入先出模式是非常有用的,在这种情况下,该紧急消息绕过消息队列中的其他消息。消息队列的长度可以在运行时设置。使用消息队列使用消息队列使用消息队列九.内存管理什么是内存管理一个处理器,在不断地分配和释放内存的过程中,一整块连续的内存被分散为很多离散的小块内存,这些叫做内存碎片,内存碎片过多会导致内存的浪费。uC/OSIII的内存管理机制就是为了尽量减少内存碎片。大致的思路是一次性取出一个较大的内存分区,把这个内存分区分成若干个内存块,然后将内存块逐个串成单向链表。每次要用到内存块就从内存分区中取出一块,用完就放回去。这跟消息队列的消息池的使用原理是一样的。内存分区的结构获得内存分区中的内存块归还内存块给内存分区谢谢大家!
本文标题:以UCOSIII为例-嵌入式实时操作系统概述
链接地址:https://www.777doc.com/doc-5222414 .html