Xenomai3 练习一:Getting started
练习网址链接:http://www.cs.ru.nl/J.Hooman/DES/XenomaiExercises/
目标
下面是这个练习的主要目标:
▪ 学习如何编译和执行一个Xenomai程序
▪ 能够使用错误代码
▪ 这些练习基于Xenomai3 , 使用Alchemy API
▪ 示例程序包括创建和开始一个任务,查看Alchemy API中的task management services
创建一个任务
当你在Xenomai中创建一个实时任务时,RT_TASK结构被用作描述符来引用这个任务。
RT_TASK数据结构用于保存关于任务的所有信息:
▪ 实时任务执行的任务功能
▪ 传递给它的初始参数
▪ 分配给变量的堆栈大小
▪ 它的优先级
▪ 不管它是否使用浮点数学
▪ 以及一个“signal handler”信号处理程序,当任务变为活动时将被调用
通过 rt_task_create 创建实时任务
int rt_task_create (RT_TASK *task, const char *name, int stack_size, int priority, int mode)
‘task’ 是一个指向RT_TASK类型结构体的指针,该结构体必须在之前声明并填充。
‘name’ 是一个ASCII字符串,表示任务的符号名称。这个符号名可以通过调用rt_task_bind()函数来检索代码中任何地方的任务结构。
'stack_size’是新任务要使用的堆栈大小。
‘priority’ 是给予任务的优先级。优先级最高为99,最低为0。
'mode’是一组影响任务的标志,例如:
▪ T_JOINABLE允许其他任务等待新任务的终止。这意味着这个任务实际上调用了rt_task_join(),以便在终 止后清理任何位于用户空间的资源。
开始一个任务
通过 rt_task_start 开始一个任务
int rt_task_start (RT_TASK *task, void(*)(void *arg) entry, void *arg)
'task’是一个指向RT_TASK类型结构体的指针,该结构体必须已经通过调用rt_task_create()函数初始化。
'entry’是这个实时任务要执行的任务函数的地址。
'arg’是指定给任务函数的空指针参数
示例程序
下面的“ex01a.c”C代码演示了创建和启动编写消息的“demo”任务。
注意,在"main"中,字符数组"str"被用作任务的名称。这个数组必须足够长,以存储sprintf中使用的字符串加上一个额外的空字符。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <alchemy/task.h> //alchemy是xenomai自带的api
RT_TASK hello_task; //创建一个RT_TASK类型结构体,结构体名称为 hello_task
// function to be executed by task
void helloWorld(void *arg) //结构体中创建helloWorld函数,传入空指针参数arg
{
RT_TASK_INFO curtaskinfo;
//该结构体报告关于实时任务的各种静态和运行时信息,这些信息由调用rt_task_inquire()返回。
//报告信息 curtaskinfo
printf("Hello World!\n");
//inquire current task 查询当前任务
//用法:int rt_task_inquire(RT_TASK * task, RT_TASK_INFO *info)
//task:任务描述符。如果task为NULL,则返回当前任务的信息。
//info:任务信息将被写入的结构体的地址。传递NULL是有效的,在这种情况下,系统只探测指定任务的存在。
rt_task_inquire(NULL,&curtaskinfo);
// print task name
printf("Task name : %s \n", curtaskinfo.name);
}
int main(int argc, char* argv[])
{
char str[10]; //创建名字字符数组,存储10个字符
printf("start task\n"); //start task
sprintf(str,"hello"); //把hello打印成字符串保存在str中
/* Create task
* Arguments: &task,
* name,
* stack size (0=default), 堆栈大小0=默认
* priority,
* mode (FPU, start suspended, ...)
*/
rt_task_create(&hello_task, str, 0, 50, 0); //任务名称为str中存放的hello
/* Start task
* Arguments: &task,
* task function,
* function argument
*/
rt_task_start(&hello_task, &helloWorld, 0);
}
编译xenomai程序
要编译ex01.c程序,我们使用以下Makefile
XENO_CONFIG := /usr/xenomai/bin/xeno-config
CFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --cflags)
LDFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --ldflags)
CC := gcc
EXECUTABLE := ex01a
all: $(EXECUTABLE)
%: %.c
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
clean:
rm -f $(EXECUTABLE)
然后使用命令
$ make
将构建可以执行的可执行ex01a使用
$ ./ex01a
Error:
会出现无法编译的error,需要在/etc/ld.so.conf.d下配置xenomai.conf文件
xenomai.conf文件中加入xenomai的库路径
/usr/xenomai/lib
执行使其生效
$sudo /sbin/ldconfig -v