SYS/BIOS是一个可扩展的实时内核(或者说是操作系统),其提供了许多模块化的APIs(应用程序接口),支持抢占式多线程,硬件抽象,实时分析和配置工具,其设计目的是为了最大限度地减少对内存和CPU的要求。其拥有很多实时嵌入式操作系统的功能,如任务的调度,任务间的同步和通信,内存管理,实时时钟管理,中断服务管理等。有了它,用户可以编写复杂的多线程程序,并且会占用更少的CPU和内存资源。
SYS/BIOS的早期版本是DSP/BIOS,更名的原因,是因为SYS/BIOS不仅可以用于DSP,而且也可以嵌入到ARM等其他Soc中去。SYS/BIOS是一个可用于实时调度、同步,主机和目标机通信,以及实时分析系统上的一个可裁减实时内核,它提供了抢占式的多任务调度,对硬件的及时反应,实时分析和配置工具等。同时也提供标准的API接口,易于使用。它是TI的eXpressDSP实时软件技术的的一个关键部分。
CCS支持SYS/BIOS的开发,用户单独下载安装bios组件即可运行,能够大大方便用户编写多任务应用程序。
RTOS分为32个中断等级,可设定范围是0-31,其中0优先级最低,31优先级最高,这与28335和stm32中的优先级相反; 在优先级上,硬件中断优先于软件中断,软件中断优先于任务;
如果有其他中断打断了当前执行的任务,则会使用中断堆栈来保存相关寄存器,使用中断调度技术有许多好处,首先调度程序是面向所有中断处理的公用代码,有利于节省系统中代码所占用的空间,每个任务线程都具有独立的堆栈,意味着调度程序为每个中断单独使用的堆栈可以更小,可以在高优先级程序正在执行过程时准确进入较低优先级线程,此外,高优先级可以正确的抢断较低优先级线程的运行而运行。中断调度程序还允许启用用户观察程序,以便在发生中断时跟踪这些中断的执行(不要求强制使用)。
为提高中断响应的实时性,RTOS中可配置不受中断管理的中断,这些一般应用于高优先级的中断,实现此功能就是寄存器basepri,这个寄存器最多有 9 位(由表达优先级的位数决定),它定义了被屏蔽优先级的阈值。当它被设成某个值后,所有优先级号大于等于此值的中断都被关(优先级号越大,优先级越低)。但若被设成 0,则不关闭任何中断, 0 也是缺省值。在ucos中使用的是primask,这是个只有 1 个 bit 的寄存器。 在它被置 1 后,就关掉所有可屏蔽的异常,只剩下NMI 和硬 fault 可以响应。它的缺省值是 0,表示没有关中断。
Hwi中断调度执行原理:
Swi模块特点概括:
sysbios软件中断,swi一般伴随hwi的发生而发生,以便更容易也更灵活的完成中断事务,软件中断可以指定优先级,高优先级swi将优先于低优先级swi运行,sysbios的调度程序会根据优先级进行调度,并在切换时处理所有寄存器的保存和恢复操作;
与任务的不同,swi是在单个堆栈上运行,这能使得swi能以一个低的内存消耗来运行,但也使他们不允许被挂起,换句话说,swi要一直运行到结束,这与硬件中断十分类似,并且以硬件中断的处理模式来处理,swi使用的堆栈和hwi使用的堆栈是同一个堆栈,每次swi进行抢断中断时,都需要先将相应的寄存器保存到堆栈中,因此需要分配的堆栈大小与系统所需要的swi的数量成正比;
swi的典型应用场合是这样的,系统产生了一个外设中断,从而触发了hwi线程,而在hwi内的线程都是用于处理紧急需要实时响应的,实时的响应外设的需求,hwi内的线程需要尽可能快的处理完毕,并且处理hwi时是禁止其他中断的,因此为了让hwi处理尽量少的处理操作,一些不是那么紧急和需要实时处理的事务将放在软件中断去处理,当hwi发布swi时软件中断会立即准备好运行,由于swi的优先级比hwi的优先级低,并且是可以被抢断的,因此被运行对实时性不是特别高的事件,那么swi的执行是常态和平稳的,而不是突发的执行;
较高优先级的hwi完成后,调度程序会立即启动软件中断,在软件中断中可以对收集到的外设中断信息进行处理,但当下个hwi响应时,软件中断会立即被抢断,系统转而去执行新的hwi,而swi被恢复时可以继续运行,对收集到的信息去处理,以保证不会有外设数据因为不被响应而丢失。在swi执行完毕,而hwi没有被触发时,调度程序将运行最低优先级的空闲任务。缩短进入中断的窗口区;
通常swi中处理的事务是以毫秒来计时的,而hwi中处理的事务是以微秒计时;
swi与hwi类似,一旦运行就不能停止,不能被挂起或者中途停止,只能由更高优先级的中断抢断,swi和hwi都只会运行一次,不管在执行之前被发布了多少次,hwi可以设置在被触发多少次后发布软件中断;
相同优先级的swia和swib,如果swia先被触发,则swib要等swia执行完成之后才会被调用,如果中断出现hwi中断,则在hwi执行之后继续返回到swia中断;
在创建的每个swi的数据结构中都有Trigger(触发器)的变量用于有条件的发布,在Trigger为0的时刻中断才被触发。一般来说,在初始配置为0即可;
Swi主要包括以下常用API:
Swi_inc():API的调用将无条件的发布swi,将会使swi的值自加1,这个API可用于知道在swi在运行前被发布了多少次。
Swi_dec() 如果需要设置swi被发布了多少次才被执行一次,则可以调用此API,每次Swi_dec()的发布都会使swi的值自减1,直至为0,才会正式开始运行swi。
Swi_or() API有一个野码参数,在swi发布前,这个野码参数需要与触发器的数值进行位或运算,并将新的运算结果作为新的触发器值,而在Swi执行完毕后,触发器的值将会被复原。
Swi_and() API同样有一个野码参数,在swi发布前,这个野码参数需要与触发器的数值进行位与运算,并将新的运算结果作为新的触发器值,只有在运算结果为0时,才会正式运行swi,同样在Swi执行完毕后,触发器的值将会被复原。
Swi_gettrigger() API,将返回被锁存的触发器数值,这个数值会被锁存是因为swi执行完毕后trigger数值将会被复原。
注意:
sys/bios可以处理几乎无数多个定时器,时钟模块可以创建很多实例,创建时始终标志为true则立马启动,在同一个线程中启动或停止时钟。
线程的确切定义随着所使用的处理器,架构,操作系统的不同而不同,线程的一个关键特性是具有优先级,决定在哪一时刻先执行的任务,与硬件中断和软件中断不同,任务是可能被挂起的,会在等待某些事件发生时允许执行其他线程,或者只是因为另一个线程优先级更高(包括硬件中断和软件中断)而发生挂起。
创建任务可以选择在应用程序中配置已静态方式创建任务或是在程序执行中动态创建任务,任务具有优先级,为任务分配的优先级是可以在运行时根据应用程序的实际需求而进行更改的,bios的任务调度程序会判断在任意的给定时间去执行哪一线程,调度的判断是根据任务线程的优先级以及任务线程是否挂起以等待某一事件的发生。
任务与软件中断线程的不同之处,每个任务实例都有自己独立的堆栈,使得任务更加有效并且易于使用,但在内存使用率方面,任务会使用更多资源,对系统容量有一定要求。
死锁:
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。例:如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。
优先级翻转:
是当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。解决优先级翻转问题有优先级天花板(priority ceiling)和优先级继承(priority nheritance)两种办法。
优先级天花板:当任务申请某资源时,把该任务的优先级提升到可访问这个资源的所有任务中的最高优先级,这个优先级称为该资源的优先级天花板。这种方法简单易行, 不必进行复杂的判断, 不管任务是否阻塞了高优先级任务的运行, 只要任务访问共享资源都会提升任务的优先级。
优先级继承:当任务A 申请共享资源S 时, 如果S正在被任务C 使用,通过比较任务C 与自身的优先级,如发现任务C 的优先级小于自身的优先级, 则将任务C的优先级提升到自身的优先级, 任务C 释放资源S 后,再恢复任务C 的原优先级。这种方法只在占有资源的低优先级任务阻塞了高优先级任务时才动态的改变任务的优先级,如果过程较复杂, 则需要进行判断。
信号量用于实现任务挂起,信号量的计数值始终≥0。对信号量采用原子操作是十分重要的,这能保证信号量的发布和挂起不会被中断,以保证操作的连贯性和安全性。信号量分为两类,一类为计数型,一类为二进制型,二进制的只能为0和1,计数型可以是≥0的任意数,创建信号量时,参数之一就是信号量的计数模式配置。信号量的挂起和信号量的发布都会修改信号量的值,其中信号量的发布将使计数值递增,信号量的挂起将使计数值递减。无论是哪一类计数模式,只有在信号量计数为0时,才会导致任务被挂起。二进制型的信号量,在信号量为1时,调用信号量发布API时,不会改变信号量的值。
多个任务可以使用同一个信号量来实现挂起,如果同时有两个任务a和b已经被挂起,在发布信号量时,将会允许一个且仅有一个任务解除挂起,并准备好运行,这里被解除的任务是之前最先被挂起的任务,与优先级无关。
信号量在使用中常见的两个API:
Semaphore_pend() :此API被调用一次,信号量递减1。
Semaphore_post() API:发布信号量,允许其他任务使用共享资源。
创建SYS/BIOS工程实例:SYS/BIOS工程实例
附录:关于SYS/BIOS的官方视频学习资料
一、概览 http://www.eeworld.com.cn/training/TI_study/2013/0503/257.html
二、定时器和时钟模块 http://www.eeworld.com.cn/training/TI_study/2013/0503/258.html
三、硬件中断和空闲线程_1 http://www.eeworld.com.cn/training/TI_study/2013/0503/259.html
四、硬件中断和空闲线程_2 http://www.eeworld.com.cn/training/TI_study/2013/0503/266.html
五、软件中断_1 http://www.eeworld.com.cn/training/TI_study/2013/0503/260.html
六、软件中断_2 http://www.eeworld.com.cn/training/TI_study/2013/0503/261.html
七、任务 http://www.eeworld.com.cn/training/TI_study/2013/0503/262.html
八、信号量 http://www.eeworld.com.cn/training/TI_study/2013/0503/263.html
九、对MSP430的支持_1 http://www.eeworld.com.cn/training/TI_study/2013/0503/264.html
十、对MSP430的支持_2 http://www.eeworld.com.cn/training/TI_study/2013/0503/265.html