几类常用的Xenomai 原生API:
1、任务管理
Xenomai 本身提供的一系列多任务调度机制,主要有以下一些函数:
intrt_task_create (RT_TASK *task, const char *name, int stksize, int prio, intmode) ; 任务的创建;
int rt_task_start(RT_TASK *task, void(*entry)(void *cookie), void *cookie) ; 开始任务调度;
intrt_task_suspend (RT_TASK *task); 挂起任务;
intrt_task_delete (RT_TASK *task) ; 删除任务;
intrt_task_set_periodic (RT_TASK *task, RTIME idate, RTIME period) ;设置任务运行周期;
intrt_task_wait_period (unsigned long *overruns_r) ;挂起任务到下个周期再运行;
intrt_task_set_priority (RT_TASK *task, int prio);设置任务优先级;
2、内存堆服务
intrt_heap_create (RT_HEAP *heap, const char *name, size_t heapsize, int mode) 创建一个内存堆空间或一个共享内存片段;
intrt_heap_delete (RT_HEAP *heap) 删除一个内存堆空间或一个共享内存片段;
int rt_heap_bind(RT_HEAP *heap, const char *name, RTIME timeout) 绑定共享内存空间;
intrt_heap_unbind (RT_HEAP *heap) 接触共享内存空间的绑定;
3、信息管道服务
intrt_pipe_create (RT_PIPE *pipe, const char *name, int minor, size_t poolsize) 创建通讯管道;
intrt_pipe_delete (RT_PIPE *pipe) 删除通讯管道;
ssize_t rt_pipe_receive (RT_PIPE *pipe, RT_PIPE_MSG **msgp, RTIME timeout) 从管道接受一条信息;
ssize_trt_pipe_send (RT_PIPE *pipe, RT_PIPE_MSG *msg, size_t size, int mode) 向管道发送一条信息;
Xenomai 在实时内核之上还提供了多组API 模拟多种不同的实时操作系统和编程规范,包括POSIX、VxWorks 和RTAI 等。这使得实时应用系统的开发和移植变得非常方便。
Xenomai 的移植
Xenomai 提供了一个与 Linux 无缝结合地实时子系统,所以首先要做的是将Xenomai 作为目标内核的一部分进行编译。Xenomai 提供了一个脚本文件scripts/prepare-kernel.sh 用来进行目标内核的编译。这个脚本文件同样能够应用于Adeos 对于内核的补丁。脚本文件使用方法如下:
$scripts/preparekernel.sh
–linux=[adeos=][arch=]
–linux 选项指定了目标内核源代码树路径。
–adeos 选项指定了与目标内核版本很相匹配的Adeos补丁的路径。如果Adeos已经安装在目标内核中,这个参数选项可以忽略。如果系统侦测到以前安装过Adeos补丁,将不再安装。
–arch 选项给脚本文件指定了目标板的结构。如果没有说明该选项,编译系统将会侦测并推荐一个合理的默认值。
下面以x86 和linux2.6.15 架构为例说明配置命令的使用:
cd
scripts/preparekernel.sh
–linux=/usr/src/linux2.6.15ipipe–arch=x86
adeos=ksrc/arch/i386/patches/adeosipipe2.6.15i3861.201.patch
建立实时子系统后,需要对Xenomai 内核选项进行配置,其方法与通常Linux 内核的配置方法类似。
如图3.2 所示,标准内核结合了实时子内核后,将会在内核配置选项中多出一条“Real-time sub-system”选项。用户可在子选项的子菜单中选择或去除相应的功能。
配置内核选项后,直接配置Xenomai 部分并编译、安装Linux 内核就成功安装了Xenomai 实时子内核。命令如下:
mkdir && cd./configure enablex86sep
$ makeinstall
以上是以x86 架构为例说明Xenomai 实时子系统的安装,本文中的基于ARM 的目标板实时子系统的安装基本步骤相同,只需在安装后,将生成的库文件即宿主机/usr/Xenomai 目录拷贝至目标板的/usr/目录下,以供应用程序使用。
3.2.2.3 移植的注意点
通过以上章节的分析,移植Xenomai 至Linux 内核的步骤就清晰了,但在其过程中会有很多莫名其妙的错误,大部分都是因为在配置Linux 内核选项时有些选项是必须安装却没有安装,有些选项选择后会对 Xenomai 的编译产生一些致命的错误而导致实时子系统安装的失败,特别是与时间有关的选项。所以,移植 Xenomai 需要仔细阅读相关文档,遇到问题时逐步排除可能产生问题的选项,才能正确安装子系统。
3.2.2.4 移植正确性验证
Xenomai 子系统移植完成后,如系统没有报错即可编写实时程序对系统移植的正确性进行验证。
验证程序不需要实现十分复杂的功能,本文中编写的测试程序,使用了Xenomai实时子系统的原生API,该程序创建了任务,指定了任务的优先级,对任务的实体部分进行了简单地实现,部分源代码如下所示:
#include <native/task.h>
#include <native/timer.h>
#define TASK_PRIO 99 /* Highest RT priority */
#define TASK_MODE 0 /* No flags */
#define TASK_STKSZ 0 /* Stack size (use default one) */
#define TASK_PERIOD 100000 /* 100 usc period */
RT_TASK task_desc;
void sampling_task (void *cookie)
{
unsigned long overruns;
int err;
/* The task will undergo a 100 uscperiodic timeline. */
err = rt_task_set_periodic(NULL,TM_NOW,TASK_PERIOD);
...
for (;;) {
err =rt_task_wait_period(&overruns);
if (err)
break;
/* Work for the current period*/
}
}
int main (int argc, char *argv[])
{
int err;
/* Disable paging for this program'smemory. */
...
/* Create a real-time task */
err =rt_task_create(&task_desc,
"MyTaskName",
TASK_STKSZ,
TASK_PRIO,
TASK_MODE);
if (!err)
/* If successfully created, start thetask. */
rt_task_start(&task_desc,&sampling_task,NULL);
...
}
该测试程序编译后运行无误,实时子系统Xenomai 安装正确,用户可进行实时任务的设计和开发。
3.2.3 实时性能测试
实时系统最为重要的特性在于能够在限定的时间内完成指定功能并对外部事件作出正确响应。这一特性要求系统任务响应时间足够少,中断响应足够快。其中,任务响应时间更是主要指标,所以选用任务响应时间作为测试的时间指标。其含义为: 任务响应时间:自中断发出处理请求到相应程序即将执行的时间间隔;
中断响应时间:从中断触发到完成响应并开始执行中断服务例程(interrupt service routine,ISR)第一条指令的时间间隔。
Xenomai 提供了很多高精度的时间函数,可以获取系统时钟值,测试任务响应时间正是利用了这些函数,关键伪代码如下:
while(1){
…
start = gettime();
wait_np();
//理论延时period;
end=gettime();
response=end – start – period;
//response 可近似认为是任务响应时间;
…
}
中断响应时间测试思路为:编写一个发生时机可以预知的中断,可以在中断发生前捕获系统当前时间 start,中断发生并调用 ISR 时再次捕获系统当前时间 end,则end-start 的值可近似认为是中断响应时间。
经测试,Xenomai实时子系统的实时性能达到微秒级的响应,能够很好的满足实时应用的要求。