编写LXRT用户空间程序

上传人:s9****2 文档编号:512000751 上传时间:2023-08-29 格式:DOCX 页数:8 大小:19.27KB
返回 下载 相关 举报
编写LXRT用户空间程序_第1页
第1页 / 共8页
编写LXRT用户空间程序_第2页
第2页 / 共8页
编写LXRT用户空间程序_第3页
第3页 / 共8页
编写LXRT用户空间程序_第4页
第4页 / 共8页
编写LXRT用户空间程序_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《编写LXRT用户空间程序》由会员分享,可在线阅读,更多相关《编写LXRT用户空间程序(8页珍藏版)》请在金锄头文库上搜索。

1、编写LXRT (RTAI-LXRT)用户空间程序Asad Chan 2011-06-28此文档仅为那些刚涉猎RTAI Linux的爱好者编写。在用户空间下编写RTAI-LXRT程序 并不是一件困难的事,可以参考DIAPM RTAI Programming Guide 1.0和How to port your C+ GNU/Linux application to RTAI/LXRT。而这两个文档却没有一个完整在用户 空间能执行的例子,所以往往会造成看了遇到问题不知问题出在哪里。往往有的程序编写好 了,也编译好了,在控制台下执行却出现了 segmentation fault字样。RTAI Lin

2、ux 调度器(请参考 RTAI 3.3 User Manual rev0.2)RTAI分别在内核空间和用户空间提供了两个对等的任务调度器,一个为rtai_sched, 一个为rtai_lxrt,这两个调度器主要是他们所能调度的可调度任务有所差异,而这两个调 度器都能调度用户空间和内核空间的任务。rtai_sched能调度Linux下的各种任务,例如 process, thread, kthread,而同时它还能调度RTAI内核空间任务(请区分Linux内核和 RTAI内核)。而rtai_lxrt仅能调度process, thread, kthread,却不能调度RTAI内核 空间任务。此文档仅

3、介绍在用户空间执行的实时性任务,而要使用这两个调度器,需将 rtai_hal.ko,rtai_sched.ko,rtai_lxrt.ko三个模块加载进Linux内核,因为只有将这 些模块加载进内核才能使这两个调度器运行起来并且能为实时性进程/线程提供调度服务。 也即在用户空间编写的实时性进程/任务需要上述两个调度器中的一个提供调度服务才能正 常运行。现在开始吧!1、建立main.c文件内容如下:#include #include #include #include static int end = 1;void endHandler (int sig) /信号处理函数(end = 0;/使静态

4、变量为0,这将是主函数的死循环被breakint main (void)(RT_TASK *task = 0;定义实时任务指针,用于指向被创建的实时性任务int period = 0;/定义周期变量,用于存储定时器的周期signal (SIGKILL,endHandler);/连接几个主要关闭信号的信号处理函数signal (SIGTERM,endHandler);/包括KILL也即杀死进程信号,TERM关闭信号signal (SIGALRM,endHandler);/这些信号被收到时将会break主程序的循环if (!(task=rt_task_init_schmod (nam2num(TE

5、ST”),0,0,0,SCHED_FIFO,0x0f) /初始化本进程 /为实时性任务printf (Cant initial the taskn);exit (1);mlockall (MCL_CURRENT|MCL_FUTURE);/锁定本进程内存,防止本进程的内存页被换出/导致的实时性被破坏period = start_rt_timer (nano2count(10000);/启动定时器,设置其定时周期/频率,/根据定时器是否是oneshotrt_make_hard_real_time ();/使本任务为硬(hard)实时性任务rt_task_make_periodic (task, r

6、t_get_time ()+period*10,period*100); /设置本任务的周期while (end) 如果end为1则一直执行,end = =0,则说明接收到7kill/term/alrm三个信号 /中的一个,证明此进程被用户终止或alrm,贝break此循环,结束此任务printf(Hello World!n);打印字符,注意,此为syscall,会导致任务进入非实时性/状态,当此调用结束时将会重新返回到实时性状态/*在实际应用中如果你的任务是周期性执行的,请在此处填写需要执行的周期性过程。 如果你的任务是需要等待某个事件、者信号量或者某个消息的到来,请你建立相应 的事件、信号

7、量、消息邮箱,并在此处等待相应的量,相应的量到来时执行你需要的 操作。*/rt_task_wait_period (); /使当前任务进入休眠,知道下一次执行周期到达被唤醒, /如果execution time = deadline则此函数不会使 /任务进入休眠状态rt_make_soft_real_time ();/是任务进入软实时状态stop_rt_timer ();停止定时器rt_task_delete (task);删除实时性任务,此时控制权将交回Linuxprintf (End of the Application!n);return 0;返回 0 值2、建立Makefile文件在M

8、akefile文件内如下所写:CC = gccCFLAGS = -I/usr/realtime/include -oDFLAGS = -L/usr/realtime/lib -llxrt -lpthreadTARGET = mainSOURCE = main.c all:$(CC) $(SOURCE) $(CFLAGS) $(TARGET) $(DFLAGS)clean:rm main注释:CFLAGS宏用于设置编译选项,可以看到“-I/usr/realtime/include”这项,此项用于 设置包含rtai_lxrt.h的路径(path),其原因在于此路径不是Linux的标准头文件路径,

9、因此需要手动在编译选项里指定其路径,其选项为“-I”-o”选项用于告诉编译器编译 成可执行文件。DFLAGS宏用于设置连接选项,可以看到“-L/usr/realtime/lib”这项,这项用于指定 静态库“liblxrt.a”的路径,因为此文件不在Linux的标准库路径下,需要手动设置其路 径,其选项为“-L”。需要手动指定其静态库,可见“-llxrt” “-lpthread”两项,其中 “-llxrt”实为liblxrt.a的缩写,此实为GNU连接器的使用规则,由此可知“- lpthread”即为 libpthread.a 的缩写。“$()”符号用于对定义的宏进行解析,例如“$(CC)”在上

10、面的例子中等价为 “gcc”,$(SOURCE)”等价为“main.c”,其他各项亦按此种形式解析。3、编译main.c文件假设你的main.c、Makefile两个文件放在绝对路径/usr/root/workspace/main目录 里,那么在控制台下进入到此目录,执行以下命令即可:make /注:“/”为回车的意思。此时控制台上会显示gccmain.c -I/usr/realtime/include -o main -L/usr/realtime/lib -llxrt -lpthread”,同时在main目录下会生成可执行文件main。4、执行main此时,在上面步骤下在控制台下执行以下命

11、令:./main /此时,会返回一个错误,类似于“cant open file liblxrt.so.1 .”之类的字样, 其原因是文件liblxrt.so.1并不是在Linux系统设定的静态库路径下,那么要解决这个问 题需要将在第2步中设定路径“/usr/realtime/lib”加入到Linux系统能寻找的静态库的 路径中,此可以通过以下命令设定:ldconfig /usr/realtime/lib /注:ldconfig即为设置静态库查找路径命令,其参数即为你需要设置的静态库路径。此时,你再执行:./main /你又发现出问题了,其表现为控制台返回“segmentation fault”

12、,也即为段错误。还 记得在 “RTAI Linux 调度器”一节中曾提到过 rtai_hal.ko, rtai_sched.ko, rtai_lxrt.ko三个模块,根据该小节中的解释,需要运行main程序,必须要将这三个模块 加载到内核空间,以使其提供调度任务服务功能。首先要切换到目录 /usr/realtime/modules 下,也即如下命令:cd /usr/realtime/modules /继续执行以下命令:insmod rtai_hal.ko /insmod rtai_sched.ko /insmod rtailxrt.ko /此时,再重新执行以下命令:./main /此时,控制台

13、上将会不断打印“ Hello World!”。此时可以通过按下“Ctrl + C”来 终止程序,而更建议在任务管理器下将此进程杀死,因为程序里实现了信号kill的处理函 数。疑惑还是存在疑惑的存在主要是在main函数里的各个步骤还是难以让人理解。例如singal函数的调 用是一件比较难以明白的处理,里面连接了 kill信号,在kill的处理句柄里可以看到它将 end赋0,而end为0将会导致main函数里的循环结束。而在Linux系统里kill信号是有 默认的处理句柄的,那么我们为什么不用它的默认处理句柄呢?它同样可以使应用程序退出 并释放相应的内存。1、头文件首先,既然在用户空间编写RTAI

14、-LXRT可运行程序,那么意味着并且实际上是可以调用 Linux的系统调用,标准库等用户空间能运行的函数,那么可以包含stdio.h, stdlib.h, 这两个标准头文件,以使程序能调用标准的库函数,同时需要包含signal.h头文件,此头 文件主要是提供signal连接关闭程序句柄,而需要使用RTAI-LXRT提供的实时性功能,则 毫无疑问需要包含rtai_lxrt.h,请记得rtai_lxrt.h在/usr/realtime/include (假设是 按照RTAI安装的默认路径)目录里,因此需要在编译选项里指定这一路径,否则将不能找 到此头文件。头文件包含如下所示:#include #i

15、nclude #include #include 2、RT_TASK 指针可以看到在程序的开头声明了指针task,可以知道它为RT_TASK结构体指针,此结构 体指针用于指向需要设置为实时性的任务,需要这个指针的原因是当在程序中将一个 process (本文档例子中即为 main Process) /pthread/kthread 向 RTAI 内核注册后,task 将指向此prcess/pthread/kthread,在随后的过程中还需要设置task指向的任务的一些属 性,比如该任务的周期等属性,那么需要使用task作为设置该任务设置的链接口,并且在 程序结束时还要通过它来从RTAI内核中删除任务。请详细阅读代码。3、signal 函数在关闭一个进程时,进程将会收到kill信号,在Linux系统里,在收到kill信号后, 默认的kill句柄将会执行从Linux内核中删除任务的操作,这个操作包括关闭收到该信号 的进程所打开的所有文件,释放该进程所占的内存页,将该进程

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号