版权声明:本文为本文为博主原创文章,转载请注明出处。如有错误,欢迎指正。

@

一、添加系统调用

下面给xenomai添加一个系统调用get_timer_hits(),用于获取应用程序运行CPU的定时器中断产生的次数,类似于VxWorks里的tickGet()。需要说明一下VxWorks是采用周期tick的方式来驱动系统运作,tickGet()获取的也就是tick定时器中断的次数,但xenomai使用的tickless,即定时器不是周期产生tick的。所以get_timer_hits()用于获取定时器中断次数,get_timer_hits()没有具体用途,这里主要用来举例怎么为xenomai添加一个实时系统调用。

在前两篇文中说到,xenomai每个系统的系统系统调用号在\cobalt\uapi\syscall.h中:

  1. #define sc_cobalt_bind 0
  2. #define sc_cobalt_thread_create 1
  3. #define sc_cobalt_thread_getpid 2
  4. ......
  5. #define sc_cobalt_extend 96

在此添加sc_cobalt_get_timer_hits的系统,为了避免与xenomai系统调用冲突(xenomai官方添加的系统调用号从小到大),那我们就从最后一个系统调用添加,即127号系统调用,如下。

  1. #define sc_cobalt_bind 0
  2. #define sc_cobalt_thread_create 1
  3. #define sc_cobalt_thread_getpid 2
  4. ......
  5. #define sc_cobalt_extend 96
  6. #define sc_cobalt_ftrace_puts 97
  7. #define sc_cobalt_recvmmsg 98
  8. #define sc_cobalt_sendmmsg 99
  9. #define sc_cobalt_clock_adjtime 100
  10. #define sc_cobalt_thread_setschedprio 101
  11. #define sc_cobalt_get_timer_hits 127
  12. #define __NR_COBALT_SYSCALLS 128 /* Power of 2 */

先确定一下我们这个函数的API形式,由于是一个非标准的形式,这里表示如下:

  1. int get_timer_hits(unsigned long *u_tick);

参数为保存hits的变量地址;

返回值:成功0;出错 <0;

系统调用的头文件,然后添加一个系统调用的声明,觉得它和clock相关,那就放在kernel\xenomai\posix\clock.h中吧。

  1. #include <linux/ipipe_tickdev.h>
  2. COBALT_SYSCALL_DECL(get_timer_hits,
  3. (unsigned long __user *u_tick));

然后是该函数的内核实现,放在/kernel\xenomai\posix\clock.c,如下:

  1. COBALT_SYSCALL(get_timer_hits, primary,
  2. (unsigned long __user *u_tick))
  3. {
  4. struct xnthread *thread;
  5. unsigned long tick;
  6. int cpu;
  7. int ret = 0;
  8. unsigned int irq;
  9. thread = xnthread_current();
  10. if (thread == NULL)
  11. return -EPERM;
  12. /*得到当前任务CPU号*/
  13. cpu = xnsched_cpu(thread->sched);
  14. irq = per_cpu(ipipe_percpu.hrtimer_irq, cpu);
  15. /*读取该CPU中断计数*/
  16. tick = __ipipe_cpudata_irq_hits(&xnsched_realtime_domain, cpu,
  17. irq);
  18. if (cobalt_copy_to_user(u_tick, &tick, sizeof(tick)))
  19. return -EFAULT;
  20. return ret;
  21. }

需要注意的是该系统调用的权限,这里使用primary,表示只有cobalt上下文(实时线程)才能调用。

修改完成后重新编译内核并安装。

二、Cobalt库添加接口

在前两篇文中说到,xenomai系统调用由libcobalt发起,所以修改应用库来添加该函数接口,添加声明include\cobalt\time.h

  1. COBALT_DECL(int, get_timer_hits(unsigned long tick));

xenomai3.x.x\lib\cobalt\clock.c添加该接口定义:

  1. COBALT_IMPL(int, get_timer_hits, (unsigned long * tick))
  2. {
  3. int ret;
  4. ret = -XENOMAI_SYSCALL1(sc_cobalt_get_tick,
  5. tick);
  6. return ret;
  7. }

重新编译并安装xenomai库,详见本博客其他文章。

三、应用使用

由于我们添加get_timer_hits()系统调用时,指定了系统调用的权限为primary,这里创建一个实时任务,使用宏__RT()指定链接到libcobalt库。

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sched.h>
  6. #include <time.h>
  7. #include <unistd.h>
  8. #include <signal.h>
  9. #include <alchemy/task.h>
  10. #include <alchemy/timer.h>
  11. #include <alchemy/sem.h>
  12. #include <boilerplate/trace.h>
  13. #include <xenomai/init.h>
  14. #define PRIO 50
  15. void test(void *cookie)
  16. {
  17. unsigned long tick;
  18. int ret;
  19. ret = __RT(get_timer_hits(&tick));
  20. if (ret){
  21. fprintf(stderr,
  22. "%s: failed to get_tick,%s\n",
  23. __func__,strerror(-ret));
  24. return ret;
  25. }
  26. fprintf(stdout,"timer_hits:%ld\n",tick);
  27. /*....*/
  28. return 0;
  29. }
  30. int main(int argc, char *const *argv)
  31. {
  32. struct sigaction sa __attribute__((unused));
  33. int sig, cpu = 0;
  34. char sem_name[16];
  35. sigset_t mask;
  36. RT_TASK task;
  37. int ret;
  38. sigemptyset(&mask);
  39. sigaddset(&mask, SIGINT);
  40. sigaddset(&mask, SIGTERM);
  41. sigaddset(&mask, SIGHUP);
  42. sigaddset(&mask, SIGALRM);
  43. pthread_sigmask(SIG_BLOCK, &mask, NULL);
  44. setlinebuf(stdout);
  45. ret = rt_task_spawn(&task, "test_task", 0, PRIO,
  46. T_JOINABLE, test, NULL);
  47. if (ret){
  48. fprintf(stderr,
  49. "%s: failed to create task,%s\n",
  50. __func__,strerror(-ret));
  51. return ret;
  52. }
  53. __STD(sigwait(&mask, &sig));
  54. rt_task_join(&task);
  55. rt_task_delete(&task);
  56. return 0;
  57. }

编译Makefile:

  1. XENO_CONFIG := /usr/xenomai/bin/xeno-config
  2. PROJPATH = .
  3. CFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --cflags)
  4. LDFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --ldflags)
  5. INCFLAGS= -I$(PROJPATH)/include/
  6. EXECUTABLE := get-timer-hits
  7. src = $(wildcard ./*.c)
  8. obj = $(patsubst %.c, %.o, $(src))
  9. all: $(EXECUTABLE)
  10. $(EXECUTABLE): $(obj)
  11. $(CC) -g -o $@ $^ $(INCFLAGS) $(CFLAGS) $(LDFLAGS)
  12. %.o:%.c
  13. $(CC) -g -o $@ -c $< $(INCFLAGS) $(CFLAGS) $(LDFLAGS)
  14. .PHONY: clean
  15. clean:
  16. rm -f $(EXECUTABLE) $(obj)

运行结果:

  1. $./get-timer-hits
  2. timer_hits:3

可以看到,虽然系统已经启动十几分钟了,但一直没有运行xenomai应用,xenomai tick相关中断才产生了3次,这就是tickless,后面会出xenomai调度及时间子系统相关文章,敬请关注。

xenomai内核解析--双核系统调用(三)--如何为xenomai添加一个系统调用的更多相关文章

  1. 【原创】xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. 1. 引出问题 上一篇文章xenomai内核解析--双核系统调用(一)以X86处理器为例,分析了xenomai内核调用的流程, ...

  2. 【原创】xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 1.概述 上篇文章xenomai内核解析--实时IP ...

  3. 【xenomai内核解析】系列文章大纲

    xenomai内核解析 本博客为本人学习linux实时操作系统框架xenomai的一些记录,主要剖析xenomai内核实现,以及与linux相关的知识.方便读者定位具体文章,现列出本博客大纲,后续会陆 ...

  4. 【原创】xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1.概述 1.概述 [原创]实时IPC概述 [ ...

  5. xenomai内核解析之信号signal(二)---xenomai信号处理机制

    xenomai信号 上篇文章讲了linux的信号在内核的发送与处理流程,现在加入了cobalt核,Cobalt内核为xenomai线程提供了信号机制.下面一一解析xenomai内核的信号处理机制. 1 ...

  6. xenomai内核解析---内核对象注册表—xnregistry(重要组件)

    1. 概述 上篇文章xenomai内核解析--同步互斥机制(一)--优先级倒置讲到,对于所有内核对象: xnregistry:保存内核对象,提供内核对象存储和快速检索. xnsynch:资源抽象,提供 ...

  7. 【原创】xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(二)--实时与非实时关联(bind流程)

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 1.概述 上篇文章介绍了实时端socket创建和配置 ...

  8. [保姆级教程] 如何在 Linux Kernel (V5.17.7) 中添加一个系统调用(System call)

    最近在学习 <linux Kernel Development>,本书用的linux kernel 是v2.6 版本的.看完"系统调用"一节后,想尝试添加一个系统调用, ...

  9. xenomai内核解析之双核系统调用(一)

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 xenomai 内核系统调用 一.32位Lin ...

随机推荐

  1. android屏幕适配的全攻略--支持不同的屏幕尺寸适配平板和手机

    一. 核心概念与单位详解 1. 什么是屏幕尺寸.屏幕分辨率.屏幕像素密度? 屏幕分辨率越大,手机越清晰 dpi就是dot per inch dot意思是点,就是每英寸上面的像素点数 android原始 ...

  2. CentOS 7 Zookeeper 和 Kafka 集群搭建

    环境 CentOS 7.4 Zookeeper-3.6.1 Kafka_2.13-2.4.1 Kafka-manager-2.0.0.2 本次安装的软件全部在 /home/javateam 目录下. ...

  3. 2020/6/10 JavaScript高级程序设计 BOM

    BOM(浏览器对象模型):提供用于访问浏览器的对象. 8.1 window对象 window是BOM的核心对象,表示浏览器的一个实例. JavaScript访问浏览器窗口的接口 ECMAScript规 ...

  4. gdi和gdi+比较

    http://www.360doc.com/content/10/1013/17/1066008_60709410.shtmlhttp://www.360doc.com/content/10/1013 ...

  5. 什么是JSTL标签库?

    什么是JSTL? JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的. 有什么作用? ...

  6. Oracle查询dba_extents视图很慢

    Oracle查询dba_extents视图很慢 问题描述 下边这条SQL查询每次大概要花1分钟左右,实在是比较异常. select owner,tablespace_name from dba_ext ...

  7. Python必须知道的异常处理

    异常处理 把可能会发生的错误,提前在代码里进行捕捉(监测) try : code except Exception: 出错后要执行的代码 下面是常见的异常: attributeError 试图访问一个 ...

  8. js修改函数内部的this指向(bind,call,apply)

    js修改函数内部的this指向 在调用函数的时候偶尔在函数内部会使用到this,在使用this的时候发现并不是我们想要指向的对象.可以通过bind,call,apply来修改函数内部的this指向. ...

  9. 03-springboot整合elasticsearch-源码初识

        前面两个小节已经知道了spring boot怎么整合es,以及es的简单使用,但是springboot中是怎么和es服务器交互的.我们可以简单了解一下.要看一下源码 在看源码的同时,先要对sp ...

  10. Hadoop2.7.7 centos7 完全分布式 配置与问题随记

    Hadoop2.7.7 centos7 完全分布式 配置与问题随记 这里是当初在三个ECS节点上搭建hadoop+zookeeper+hbase+solr的主要步骤,文章内容未经过润色,请参考的同学搭 ...