330 likes | 453 Views
实时系统. 前后台系统. void main(void) { init_nrf2401(); init_uart(); init_misc(); while(1) { nrf2401_send_data(nrf2401_vehicle_address1,packet,3); delay_ms(5); If(cmd_ready) cmd_process(); } }. 代码临界段. 代码的临界段也称为临界区,指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。
E N D
void main(void) • { • init_nrf2401(); • init_uart(); • init_misc(); • while(1) • { • nrf2401_send_data(nrf2401_vehicle_address1,packet,3); • delay_ms(5); • If(cmd_ready) • cmd_process(); • } • }
代码临界段 • 代码的临界段也称为临界区,指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。 • 为确保临界段代码的执行,在进入临界段之前要关中断,而临界段代码执行完以后要立即开中断 • 对共享资源进行访问的代码通常是临界区
共享资源 • 可以被一个以上任务使用的资源叫做共享资源。为了防止数据被破坏,每个任务在与共享资源打交道时,必须独占该资源。这叫做互斥(mutual exclusion)。 • 所谓独占资源通常也就意味着这段代码一旦开始执行就不允许被打断.
MicroOS II中的任务 • 任务即是一个进程.UCOSII是多任务的可抢占操作系统.当然我们可以把一个复杂的事情分成多个简单的子任务,每个作为一个进程运行,这样可以简化复杂程序的设计. • 任务=程序代码+堆栈+使用的CPU寄存器+任务控制块 • 任务控制块保存着所有与进程相关的信息,包括堆栈的指针和优先级 • 任务的堆栈则用来保存任务分配的局部变量,此外,当任务被切换出去时,堆栈还保存当前寄存器的值
任务切换(上下文切换) • 当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(Context),即CPU寄存器中的全部内容。这些内容保存在任务的当前状况保存区(Task’s Context Storage area),也就是任务自己的栈区之中.入栈工作完成以后,就是把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行。这个过程叫做任务切换 • 任务切换一定要快,否则将严重影响系统性能
进程调度 • 操作系统内核中有一个称为调度器的模块,负责选择适合的进程(任务)运行. • 一旦选出适合的进程,调度器将进行任务切换. • UCOSII基于优先级进行调度.任何时候调度器都选择就绪的最高优先级任务来运行
不可抢占与可抢占内核 • 不可剥夺型内核:要求每个任务自我放弃CPU的所有权。不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。异步事件还是由中断服务来处理。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。 • 可抢占内核:当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。如果是中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的那个任务开始运行。
不可抢占内核的优点 • 响应中断快 • 任务级响应时间比前后台系统快得多 • 可以方便的调用非可重入性函数 • 几乎不需要使用信号量保护共享数据
不可抢占内核的缺点 • 不可剥夺型内核的最大缺陷在于其响应时间。高优先级的任务已经进入就绪态,但还不能运行,要等,也许要等很长时间,直到当前运行着的任务释放CPU。与前后系统一样, • 不可剥夺型内核的任务级响应时间是不确定的,不知道什么时候最高优先级的任务才能拿到CPU的控制权,完全取决于应用程序什么时候释放CPU。
可抢占内核的优缺点 • 优点:系统响应时间快 • 缺点:实现复杂,需要专门的同步机制和互斥机制;不可调用非重入函数
可重入函数 • 可以被一个以上的任务调用,而不必担心数据的破坏 • 应该尽量只使用局部变量 • 如果确实需要使用全局变量,则必须利用互斥机制来保护对全局变量的访问
MicroCOS-II的进程调度算法 • 只提供基于优先级的调度算法 • 每个任务的优先级必须不同 • 最多支持64个任务 • UCOS-II的调度算法很简单,每次选择处于就绪状态下的具有最高优先级的任务 • UCOS-II的任务优先级是创建任务时指定的,操作系统本身并不去动态调整,除非调用OSTaskChangePrio函数改变优先级
内核同步机制 • 常常碰到多个任务访问同一共享资源的问题,这个时候就必须保证相互之间的互斥性:即任何时刻该资源只能被一个任务占用,且一个任务在访问该共享资源时,保证不被打断 • Ucos-ii没有linux和windows nt那么复杂,它只是用在简单的微控制器系统中,不存在多处理器的问题 • UCOS-II提供的基本同步机制是:关中断,禁止任务切换,信号量
关中断 • void Function (void) • { • OS_ENTER_CRITICAL(); • . • . /*在这里处理共享数据*/ • . • OS_EXIT_CRITICAL(); • }
禁止任务切换 • void Function (void) • { • OSSchedLock(); • . • . /* You can access shared data in here (interrupts are recognized) */ • . /*在这里处理共享数据(中断是开着的)*/ • OSSchedUnlock(); • } • 注意:这种办法只能保证多个任务之间的互斥,不能保证任务与中断服务程序之间的互斥
信号量(Semaphores) • 什么是信号量:简单说就是为了保证互斥访问一共享资源的一个计数器。所有的任务要想访问该资源就必须先检查这个信号量,只有当信号量的值大于0才能访问资源 • 三个操作:初始化,down,up • down---就是将信号量的计数减1,如果信号量为0则该任务block(获取信号量) • up---相反操作,释放信号量
进程间通信(IPC) • UCOS-II提供两种IPC机制:消息邮箱和消息队列 • 消息邮箱:实际上就是个数据结构,里面有个成员变量是个指针,该指针指向一条消息,另外还有些成员变量表示有哪些任务正在等待接受该消息 • 消息队列:和消息邮箱基本相同,只是它可以放入多条消息,而邮箱通常只有一条消息
使用RTOS的得失 • 得:更方便开发复杂系统(通过将复杂任务分解为简单子任务,且每个任务的开发相对独立,逻辑关系简单);提供更好的实时性,更强大的功能 • 失:运行操作系统本身需要占用一定的RAM,操作系统代码也要占用一定程序ROM(flash);此外,运行内核也会需要一定的CPU时间
讨论:面向嵌入式的RTOS与通用OS的区别 • 如UCOS-II和FreeRTOS这类小型的RTOS和linux,solaris,windows nt这些通用OS的区别有哪些? • 又与uclinux,windows ce, vxworks,QNX等嵌入式操作系统有什么区别? • 这些区别导致了各自设计与实现的哪些不同?
通用操作系统主要用在PC和小型机,大型机上,他们最关心的是整体的效率和公平性,也即最大限度的利用CPU,榨干CPU的处理能力,使得在单位时间内干尽可能的多的事情,同时对于多个任务来说要尽可能的让大家公平,平均的分配处理器时间。另外就是用户的响应度要好。因为这类系统的资源(内存,硬盘)均较宽裕,操作系统要实现尽可能丰富的功能:网络,文件系统,各种设备,总线的支持通用操作系统主要用在PC和小型机,大型机上,他们最关心的是整体的效率和公平性,也即最大限度的利用CPU,榨干CPU的处理能力,使得在单位时间内干尽可能的多的事情,同时对于多个任务来说要尽可能的让大家公平,平均的分配处理器时间。另外就是用户的响应度要好。因为这类系统的资源(内存,硬盘)均较宽裕,操作系统要实现尽可能丰富的功能:网络,文件系统,各种设备,总线的支持 • UCOS-II这类小型RTOS主要是用在面向控制和功能有限资源受限的微控制器系统中。他们最关心的是按时完成任务和确定性。同时因为资源有限,OS应该尽可能的小,此外,通常无需文件系统等复杂的功能。
Wince, uclinux等嵌入式操作系统通常运行在较高性能的处理器上,而且内存等资源相对也还比较大(比如:16MB)。通常需要文件系统,网络等功能。因此他们适合用在需要完整较多计算,或者较多功能的场合,也常常需要用户交互。提供一个基础平台 • Ucos-ii则基本不需要用户交互,且几乎不需要文件系统等。内存等资源很小(几kB)。适合用在功能比较单一,处理器性能比较差(单片机)的场合
讨论:设计RTOS与设计通用OS的差别 • 硬件平台:小型RTOS通常运行在RISC处理器上;因为RISC比CISC更容易满足确定性的要求 • 内核结构:小型RTOS更适合采用微内核,而通用OS适合宏内核,单纯的微内核性能太差 • WHY?
RISC优点 • 指令系统小:指令集小+简单的指令 • 指令的格式相同,执行长度与寻址方式相同 • 几乎所有的指令都具有相同的长度,相同的寻址方式和相同的执行时间 • 大量的通用寄存器,没有特殊寄存器 • 能够更好的发挥流水线的性能 • 结构简单,开发容易,速度快,成本低
RISC的缺点 • 代码密度不高 • 与x86不兼容
MicroKernel的优点 • 内核很小,简单,容易维护 • 高度的可移植性与模块化 • 可定制,系统配置灵活 • 内核很小,从而CPU在内核中运行的时间很短,从而不可抢占的时间很短,天生的可抢占特性
MicroKernel的缺点 • 效率低 • BUT在嵌入式系统中这个缺点常常能得以克服 • Question:microkernel为什么效率低?