Real-Time Executive (REX)
使用手册
第一章
序言
1.1
目的
本文描述了基于
ARM
平台的
Real-Time Executive
(
REX
)操作系统特性及使用方法。
REX
是专为小型嵌入式系统设计的简单高效的抢占式多任务实时操作系统(
RTOS
)。该系统最初是为
Intel80186
处理器设计的,随后被移植到
ARM
处理器。本文提供了
REX
的指南,第
7
章为编程参考。
1.2
适用范围
本手册适用于需要在
REX
系统上编写应用程序的读者。
1.3
内容组织
本文按以下结构编写:
n
第
2
章
REX
概述
n
第
3-6
章
REX
的详细叙述及内部工作机制
n
第
7
章
编程指南
1.4
字形习惯
函数声明,函数名,类型声明,示例代码使用特殊的字体,例如:
#include
程序变量用尖括号包围,例如
<number>
1.5
版本历史
版本 |
日期 |
说明 |
|
1999 |
初始版本 |
Rev.A |
1999 |
内容更新 |
Rev.B |
2001 |
删除了与 |
Rev.C |
2001 |
删除了成型信息 |
1.6
参考资料
1 |
REX Portation Guide |
80-24880-1 X1 |
1999 |
2 |
REX++ REX Extensions Users Guide |
80-V3083-1 X1 |
2001 |
1.7
技术支持
如需要求了解本文未详细说明的信息可通过高通的
CDMA
技术支持邮箱联系:
1.8
术语及习惯用语
本文使用以下术语及习惯用语
APCS
ARM
调用规范。为了支持不同厂家编译系统及汇编语言混合编程,
ARM
规定了程序调用的入口、出口处理及寄存器的使用规范。
API
应用程序接口。
ARM
Advanced
RISC Machines Limited
,
ARM
系列处理器制造商,通常也指
ARM
系列微处理器。
ARM7TDMI
ARM7
系列处理器中的一款。
CPSR
当前程序状态寄存器,该寄存器保存了旗语,中断控制位和处理器当前操作模式。
critical section
临界区,代码中访问共享资源的部分。
FIQ
快速中断,由
ARM
支持的中断之一,
FIQ
中断服务程序正在进行时也可用来标志处理器工作模式。
IRQ
普通中断,由
ARM
支持的中断之一,
IRQ
中断服务程序正在进行时也可用来标志处理器工作模式。
ISR
中断服务程序,也称为
interrupt trampoline
function
。
Idle Task
操作系统中的优先级最低的任务,空闲任务的优先级为
0
,为一个空等待循环,只能由中断抢夺其
CPU
控制权。
PC
程序当前指令寄存器
PSR
程序状态寄存器
REX
高通的实时操作系统
RTOS
实时操作系统
SPSR
受保护的程序状态寄存器,每一个处理器模式提供一个
SPSR
用以保存处理器切换到其它模式前的
CPSR
。
TCB
任务控制块,
REX
内部的数据结构,用于存放任务的信息。
timer block
定时器的别名。
trampoline function
REX
之外的中断服务函数,同
ISR
。
第二章
REX
概述
REX
是一个抢先的多任务实时操作系统,为任务的控制,同步,互斥,定时和中断控制提供了相应的
API
,所有的函数在调用它们的任务提供的设备环境下运行。
2.1
任务
REX
将每个任务视为独立的实体句柄,有独享的堆栈和优先级并共同组成任务的设备环境,每个任务有一组数据组成的结构,称为任务控制块(
TCB
),
REX
通过任务控制块记录任务运行的设备环境。
REX
运行期间允许在任何时候动态创建任意数量的任务,尽管更多的任务造成了遍历任务链表的时间延长,但新增任务对
REX
性能造成的损失是微乎其微的。不过仍要注意尽量使任务的数量保持最小。
REX
所能负担的任务最终取决于处理器种类,时钟速率以及特定应用下的中断响应指标。
2.2
堆栈
前一节提到过每个任务有独立的堆栈空间,任务处于运行状态时,该堆栈被激活,当任务挂起时,任务的设备环境被保存于堆栈顶部,堆栈指针则存放于该任务的
TCB
中。任务可能由于阻塞,等待信号量,等待中断服务而挂起。
如果任务被重新激活到运行状态,调度程序从
TCB
中恢复堆栈指针,任务的设备环境就可从堆栈中弹出,任务即可恢复运行。任务调度处理对于任务来讲是透明的。
2.3
优先级和调度
每一个任务都有一个优先级,优先级存放于任务的
TCB
中,优先级可以是任何的非零的
32
位数,数值越小则优先级越低,
REX
占用了优先级
0
用于空闲任务,旧版本的
REX
要求每个任务独占优先级,新的版本已经没有这个限制了。
REX
的调度策略为放行优先级最高的就绪态任务,即激活不等待任何事件的最高优先级任务。如果满足条件的同优先级任务不只一个,则
REX
会任选其中的一个任务。被激活的任务会一直运行到主动挂起或中断程序使另一个更高优先级的任务恢复运行。
一个任务等待的事件到达后,该任务进入就绪态,如果所有的任务都处于挂起状态,则空闲任务被激活。
REX
支持任务动态修改优先级,一个任务可以提升或降低自己或其他任务的优先级。
2.4
中断
REX
为抢占式内核,当中断返回时,控制会交给优先级最高的就绪任务而不是被中断的任务。
2.5
互斥
当两个任务需要共享一个资源时,需要有一个访问互斥机制,访问共享资源部分的代码成为临界区。
通过关中断可以简单的实现临界区,
REX
还提供一种不太彻底的方式,导出函数可用于锁定或释放公共资源。
2.6
禁用中断后的挂起
只有正在运行的任务可以禁止中断,一旦某个任务禁止中断后挂起,中断状态则一直由该任务保存,任务重新激活后可以恢复中断状态。有一种潜在的危险是中断被下一个激活的任务允许,这一特性在以后的版本中可能被修改,但是程序员不能依赖这一点。
2.7
信号量
通用信号量集与每一个任务关联,这些信号量集作为相关任务的设备环境保存在任务的
TCB
里,用来表示与任务有关的某类事件发生了。一个任务的信号量可以被所有任务及中断服务程序设置或清除。
关于信号量需要注意的重点:
n
信号量是通用旗语,用户可以任意定义信号量的含义。
n
一个任务可以通过其他任务或中断任意设置一个特定的信号量挂起,需要强调的是任意,如果一个任务并没有因该信号量挂起,则设置的信号量不会对该任务的运行状态产生影响。
2.8
定时器
定时器用来确定某个时间间隔,任务通过定时器来实现一段延时,延时时间到了以后会有一个信号量时标,任务可以查询该时标,或者任务可以挂起自己等待该信号量时标。
定时器可以和其他事件联合使用,这样就可以确定事件是否超时。
REX
通过维护定时器链表的方式管理所有正在计时的定时器。对定时器的数量没有限制,定时器越多则每次遍历链表耗时越长,但是新增一个定时器对性能的影响是微弱的。已经到期的计数器不会产生管理开销。
2.9
扩展接口
REX
提供了一些扩展接口以增强可操作性,例如异步进程调用,延迟进程调用,内存管理。详情参考
REX+
+
—
REX
扩展用户使用手册(
80-V3083-1
)。
第三章
任务
本章详细描述了
REX
的调度及设备环境调度机制。
3.1
任务的创建
创建新任务使用
REX
提供的函数
rex_def_task()
。
REX
并不为任务堆栈和
TCB
分配空间。这一工作由调用创建任务函数的程序负责。不过
REX
要求避免用户直接操作
TCB
的数据结构。
任务创建函数
rex_def_task()
完成以下工作:
1.
将设备环境数据入栈
2.
设置
TCB
3.
将要创建的任务加入任务列表
4.
调度处理
如果新建任务优先级高于当前任务,则新任务取得控制权,否则,调度直接返回而不发生任务切换。新建的任务直到成为优先级最高的就绪任务时开始执行。
任务的入口由
rex_def_task()
指定为
rex_task_preamble()
,任务
在第一次获得控制权时初始化堆栈。
任务永远不会返回,因此
rex_task_preamble()
在调用了任务函数之后,会调用
rex_kill_task()
,这样的话一旦任务异常返回,则该任务会被
REX
终止。
3.1.1
调度
任务的调度由函数实现,调度函数为
REX
保留的内部函数,不能被应用程序直接调用。调用该函数时必须禁止中断,调用函数
rex_sched()
之前必须先设置全局变量
rex_best_task
并将该变量指向优先级最高的就绪任务的
TCB
。
调度算法的基本规则为:
1.
调度器检查
rex_best_task
是否指向当前正运行的任务
rex_curr_task
。
2.
如果
rex_best_task
与
rex_curr_task
相同,则调度器直接返回。
3.
如果
rex_best_task
与
rex_curr_task
不同,将
rex_best_task
的值赋给
rex_curr_task
,然后调度器检查是否在中断服务程序,如果在中断服务程序,则调度器返回。
4.
如果系统未在中断服务,则调度器开始执行设备环境切换,将当前的设备环境入栈,栈顶指针存入当前运行任务的
TCB
,并从
rex_curr_task
指向的任务的
TCB
中恢复