江 韬,季爱明,毛凌峰
(苏州大学,江苏 苏州 215021)
SAFERTOS是近年来欧美极为流行的实时操作系统,本文设计的新型智能负荷检测仪中已将其内嵌于主控芯片LM3S9B96中免费使用。SAFERTOS是从一款开源实时操作系统FREERTOS演化而来的,并且在安全性方面做了很多优化。最重要的是,SAFERTOS通过了欧洲的一个安全认证,使其能够用于医疗、工业等高安全系数领域。
实时系统的正确性不仅依赖于系统计算的逻辑结果,还依赖于产生这些结果的时间。因此,实时操作系统的调度机制和通信机制对于整个系统来说都是至关重要的[1]。SAFERTOS如大多数实时操作系统一样支持任务调度、中断管理、消息队列等功能,而且内核本身精简安全,是本应用的理想选择。
SAFERTOS任务有运行、阻塞、挂起和就绪4个状态,被划分为11(10~0)个优先级,其中等级10优先级最高。SAFERTOS的状态转换如图1所示。任务被创建后处于就绪状态,一旦调度器被开启,系统就会根据调度算法,找出投入运行的就绪任务,使该任务获得CPU和硬件资源后即开始运行。运行中的任务可能会由于等待某个事件而被阻塞一段时间,或者被一个例程挂起而由另一个例程恢复,此时调度器会重新进行调度[2]。
SAFERTOS采用抢占式和合作式任务调度,即基于优先级的抢占式调度与时间轮转调度相结合的算法。SAFERTOS确保了CPU总是被具有最高优先级的就绪任务所控制,当系统中出现两个或两个以上就绪任务拥有相同的当前最高优先级时,调度器会使用时间片轮转算法,将CPU时间平均分配给这些任务。系统至少应该有一个任务处于就绪状态,因此优先级最低的空闲任务不会被阻塞或挂起。
多任务多个中断处理过程有机地构成了嵌入式实时多任务应用程序,它们之间相互竞争CPU、共享内存和硬件等资源。任务间通信机制协调彼此运行的步调、彼此间传递的数据或信息,保证协同运行的各个任务具有正确的执行次序,协同完成某项工作。SAFERTOS提供的通信机制有临界区和消息队列两种。
SAFERTOS采用传统的实现临界区的方法,即关中断进入临界区,开中断出临界区。SAFERTOS提供了队列,用于任务间、任务与中断服务程序之间安全地传递数据。队列的基本元素为项目(item),每个队列可以包含0个或多个项目,每个项目占内存空间的大小以及队列包含项目的个数在队列创建时可任意配置。基于这种结构,队列使用灵活,以此为基础可以开发出实时操作系统常见的邮箱和信号量。
μC/OS-II(Micro-Control Operation System Version2)是一款源代码开放的实时操作系统内核,由LABROSSE J J开发。μC/OS-II最大的特点是源代码开放,移植性强。μC/OS-II是完全抢占式的内核,它总是运行优先级最高的就绪任务,并且提供了许多系统调用,如邮箱、信号量、动态内存分配、时间管理等[3]。μC/OS-II与SAFERTOS的功能比较如表1所示。
从表 1可以看出,SAFERTOS与μC/OS-II的功能差异不大,两者皆支持中断嵌套,有类似的任务间通信机制。受任务位图的影响,μC/OS-II能建立的任务数目不超过56个,而SAFERTOS能够创建的任务数目只受内存大小限制。SAFERTOS支持同等优先级的轮转调度,这比μC/OS-II能更好地支持多任务后台计算。出于安全考虑,SAFERTOS不支持动态内存分配。
邮箱用于任务、任务与中断服务程序之间传递结构化数据或事件标志。邮箱实质上是消息的中转站,一个任务或一个中断服务程序通过内核服务可以把一个消息(即一段结构化数据)放到邮箱里去。每个邮箱有相应的正在等待消息的任务列表,要得到消息的任务会因为邮箱是空的而被挂起,直到收到消息[4]。
虽然SAFERTOS没有直接提供邮箱机制,仅仅提供了一种配置灵活的队列,但从本质上,SAFERTOS的队列是一种未结构化的邮箱。而通过结构化队列项目的内存缓存区,可以实现收发特定数据结构的邮箱机制。创建邮箱函数为mbox_create,其中参数mptr为邮箱内存缓存区首地址,msgcnt为队列项目个数,msgsz为每个项目的大小,mboxptr为邮箱的句柄(邮箱的标志,供收发函数使用),则函数定义如下:
邮箱接收函数为 mbox_get,发送函数为 mbox_put。其中:参数mptr为邮箱句柄,msg为收发的结构化数据的地址,接收函数中的waitopt为获取消息失败,任务等待时间。函数定义如下:
某些软硬件资源(例如Flash、串行总线、数据缓冲区等)会被不同任务同时访问,使用信号量可以实现资源的互斥访问。每种资源用一个信号量描述,当任务访问该资源时,必须先成功获取该信号量。
信号量由计数器和等待队列组成,计数器描述可用信号量的个数,等待队列用来挂起等待获取信号量的任务。释放信号量(V操作)计数器加1;获取信号量(P操作)计数器减 1。如果计数器值小于 0,则获取失败,请求获取信号量的任务被阻塞固定长时间,等待其他任务释放信号量。从本质上来看,信号量是项目长度为零的队列。定义的信号量数据结构如下:
创建信号量函数为SemaphoreCreate,需要的参数是信号量结构指针和计数器初始值。函数定义如下:
表1 μC/OS-II与SAFERTOS系统服务比较
获取信号量函数为sem_p,释放信号量函数为sem_v,其中,参数s为信号量指针,waitopt为获取失败等待时间。则函数定义如下:
负荷检测仪是一种广泛应用于配电变压器运行状态监测、运行管理、电能计量、无功补偿和远程通信的智能监测控制装置[5]。其系统硬件结构图如图2所示。检测仪采用LM3S9B96芯片作为主控芯片,控制整个系统运行;高速高精度电能计量专用芯片ADE7878采集计算电网参数;大容量片外Flash芯片存储突发事件与电网历史数据;GPRS通信模块MC52i用于远程通信;高精度时钟芯片FM33256用于精确计时。
图2 系统硬件结构
检测仪软件功能比较复杂,如果采用传统的前后台系统架构,则无法实现任务的优先级执行,任务的响应时间与后台应用程序主循环执行时间有关,再加上前台中断程序的影响,任务的运行时间无法预测,这是实时系统难以容忍的[6]。所以需要一个实时操作系统来保证任务执行和执行时间的确定性。
根据系统各功能的内聚性、时间紧迫程度以及周期性执行原则,将系统划分为九大任务,如图3所示(图中箭头表示利用邮箱机制发送的事件标志或数据)。
电能累加任务最为紧急,它以非常短的周期读取缓存中的电能数值并累加。该任务完成累加操作后调用 xTaskDelay函数,将CPU让出一段时间后继续执行累加操作。参数计算和无功补偿任务以精确秒数周期运行,待定时时间到,由定时器中断服务程序发送消息唤醒执行。远程通信任务负责GPRS模块数据收发,当接收到数据时,由UART中断服务程序唤醒,并将数据传递给规约协议栈,唤醒规约任务。外部I/O事件(包括按键)发生时,I/O检测任务唤醒用户界面任务,改变用户界面内容。数据库用于电网历史数据和突发事件的存储,数据库任务由产生相关数据和事件的任务唤醒。
基于SAFERTOS系统的启动关键是配置调度器。调度器是SAFERTOS的核心,它负责管理任务状态转换、选择就绪态任务运行、实现任务上下文切换。系统启动步骤:(1)初始化最小系统,建立C运行环境。(2)设置初始化调度器所需的系统运行环境参数,包括CPU频率、系统滴答频率、系统堆栈位置和大小、中断向量表地址。这些参数包含在结构体xPORT_INIT_PARAMETERS中。(3)建立空闲任务运行环境,调用vTaskInitializeScheduler函数初始化调度器。(4)建立任务。SAFERTOS创建任务采用xTaskCreate函数,创建任务需要指明任务的名称、优先级、堆栈位置及大小等信息。(5)初始化系统硬件设备。(6)调用startScheduler函数启动调度器。
调度器启动后,优先级最高的任务被调度运行,系统启动完毕。
以上介绍了实时操作系统SAFERTOS在新型智能负荷检测仪中的应用,经测试,该负荷检测仪体现了较强的实时性、精确的参数计算、稳定的数据存储与远程通信。
[1]魏军华.嵌入式实时操作系统概述[J].科技广场,2011(1):254-256.
[2]Texas Instruments.SAFERTOS user’s manual.2009.
[3]LABROSSE J J.嵌入式实时操作系统 μC/OS-II[M].邵贝贝译.北京:北京航空航天大学出版社,2001:178-185.
[4]郭鹏,罗浩,廖明宏.实时操作系统中任务间通信的一种方法[J].哈尔滨商业大学学报,2003,19(5):561-564.
[5]高璞,高永华,郝建红.基于ARM和 GPRS的变压器负荷检测仪[J].仪器仪表用户,2010,17(2):36-37.
[6]罗蕾.嵌入式实时操作系统及应用开发[M].北京:北京航空航天大学出版社,2011:73-75.