linux内核关闭网络巨帧xenomai,xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务...

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

1. 引出问题

上一篇文章xenomai内核解析--双核系统调用(一)以X86处理器为例,分析了xenomai内核调用的流程,读了以后可能会觉得缺了点什么,你可能会有以下疑问:

系统中的两个内核都是POSIX接口实现系统调用,那么我写一个POSIX接口的应用程序,怎样知道它调用的内核,或者说怎样成为运行在cobalt内核的RT应用,而不是普通linux应用?

对于同一个POSIX接口,可能我的程序中,既需要xenomai内核提供服务(xenomai 系统调用),又需要调用linux内核提供服务(linux内核系统调用),或者说既有libcobalt,又有glibc库,他们是如何实现或区分的?

2. 编译链接

对于问题1,答案是:由编译时链接的库决定,如果普通的编译,则该应用编译后是一个普通linux运用。如果要编译为xenomai应用,则需要链接到xenomai库,那如何设置编译链接参数?编译安装xenomai库后,可通过执行/usr/bin/xeno-config来获取。

$/usr/bin/xeno-config --help

xeno-config --verbose

--core=cobalt

--version="3.1"

--cc="gcc"

--ccld="/usr/bin/wrap-link.sh gcc"

--arch="x86"

--prefix="/usr"

--library-dir="/usr/lib"

Usage xeno-config OPTIONS

Options :

--help

--v,--verbose

--version

--cc

--ccld

--arch

--prefix

--[skin=]posix|vxworks|psos|alchemy|rtdm|smokey|cobalt

--auto-init|auto-init-solib|no-auto-init

--mode-check|no-mode-check

--cflags

--ldflags

--lib*-dir|libdir|user-libdir

--core

--info

--compat

复制代码

例如编译一个POSIX接口的实时应用,参数--cflags表示编译,指定接口(skin)--posix,就能得到编译该程序的gcc参数了:

$/usr/bin/xeno-config --posix --cflags

-I/usr/include/xenomai/cobalt -I/usr/include/xenomai -D_GNU_SOURCE -D_REENTRANT -fasynchronous-unwind-tables -D__COBALT__ -D__COBALT_WRAP__

复制代码

再看链接,--ldflags表示链接,如下得到链接参数:

$/usr/bin/xeno-config --ldflags --posix

-Wl,--no-as-needed -Wl,@/usr/lib/cobalt.wrappers -Wl,@/usr/lib/modechk.wrappers /usr/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/usr/lib/dynlist.ld -L/usr/lib -lcobalt -lmodechk -lpthread -lrt

复制代码

这样就将POSIX接口源码编译成一个xenomai可执行程序了。通常我们会将获取编译参数的操作直接放到Makefile里,编译时直接执行获取使用,这里给一个简单的Makefile示例如下:

XENO_CONFIG := /usr/xenomai/bin/xeno-config

PROJPATH = .

CFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --cflags)

LDFLAGS := $(shell $(XENO_CONFIG) --posix --alchemy --ldflags)

INCFLAGS= -I$(PROJPATH)/include/

EXECUTABLE := rt-task

src = $(wildcard ./*.c)

obj = $(patsubst %.c, %.o, $(src))

all: $(EXECUTABLE)

$(EXECUTABLE): $(obj)

$(CC) -g -o $@ $^ $(INCFLAGS) $(CFLAGS) $(LDFLAGS)

%.o:%.c

$(CC) -g -o $@ -c $< $(INCFLAGS) $(CFLAGS) $(LDFLAGS)

.PHONY: clean

clean:

rm -f $(EXECUTABLE) $(obj)

复制代码

3. libcobalt中的实现

下面来看问题2,既然我们已将一个接口链接到实时内核库libcobalt,当然由实时内核库libcobalt来区分该发起linux内核调用还是xenomai内核系统。与上一篇文章一样,以一个POSIX接口pthread_cretate()来解析libcobalt中的实现。

xenomai线程的创建流程比较复杂,需要先让linux创建普通线程,然后再由xenomai创建该线程的shadow 线程,即xenomai调度的实时线程,很符合我们上面的提出的问题2。 说到这先简答介绍一下xenomai实时线程的创建,详细的创建流程后面会写专门写一篇文章解析,敬请期待。

pthread_cretate()不是一个系统调用,由NPTL(Native POSIX Threads Library)实现(NPTL是Linux 线程实现的现代版,由UlrichDrepper 和Ingo Molnar 开发,以取代LinuxThreads),NPTL负责一个用户线程的用户空间栈创建、内存分配、初始化等工作,与linux内核配合完成线程的创建。每一线程映射一个单独的内核调度实体(KSE,Kernel Scheduling Entity)。内核分别对每个线程做调度处理。线程同步操作通过内核系统调用实现。

xenomai coblat作为实时任务的调度器,每个实时线程需要对应到 coblat调度实体,如果要创建实时线程就需要像linux那样NPTL与linux 内核深度结合,那么coblat与libcoblat实现将会变得很复杂。在这里,xenomai使用了一种方式,由NPTL方式去完成实时线程实体的创建(linux部分),在普通线程的基础上附加一些属性,对应到xenomai cobalt内核实体时能被实时内核cobalt调度。

所以libcoblat库中的实时线程创建函数pthread_cretate最后还是需要使用 glibc的pthread_cretate函数,xenomai只是去扩展glibc pthread_cretate创建的线程,使这个线程可以在实时内核cobalt调度。

pthread_cretate()在libcobalt中pthread.h文件中定义如下:

COBALT_DECL(int, pthread_create(pthread_t *ptid_r,

const pthread_attr_t *attr,

void *(*start) (void *),

void *arg));

复制代码

COBALT_DECL宏在wrappers.h中如下,展开上面宏,会为pthread_create()生成三个类型函数:

#define __WRAP(call)__wrap_ ## call

#define __STD(call)__real_ ## call

#define __COBALT(call)__cobalt_ ## call

#define __RT(call)__COBALT(call)

#define COBALT_DECL(T, P)\

__typeof__(T) __RT(P);\

__typeof__(T) __STD(P); \

__typeof__(T) __WRAP(P)

int __cobalt_pthread_create(pthread_t *ptid_r,

const pthread_attr_t *attr,

void *(*start) (void *),

void *arg);

int __wrap_pthread_create(pthread_t *ptid_r,

const pthread_attr_t *attr,

void *(*start) (void *),

void *arg);

int __real_pthread_create(pthread_t *ptid_r,

const pthread_attr_t *attr,

void *(*start) (void *),

void *arg);

复制代码

声明pthread_create()函数的这三个宏意思为:

__RT(P):__cobalt_pthread_create 表示Cobalt实现的POSIX函数

__STD(P):__real_pthread_create表示原始的POSIX函数(Linux glibc实现),cobalt库内部通过它来表示调用原始的POSIX函数(glibc NPTL).

__WRAP(P):__wrap_pthread_create是__cobalt_pthread_create 的弱别名,如果编译器编译时知道有该函数其它的实现,该函数就会被覆盖。

主要关注前面两个,对于最后一个宏,如果外部库想覆盖已有的函数,应提供其自己的__wrap_pthread_create()实现,来覆盖Cobalt实现的pthread_create()版本。 原始的Cobalt实现仍可以引用为__COBALT(pthread_create)。由宏COBALT_IMPL来定义:

#define COBALT_IMPL(T, I, A)\

__typeof__(T) __wrap_ ## I A __attribute__((alias("__cobalt_" __stringify(I)), weak));\

__typeof__(T) __cobalt_ ## I A

复制代码

最后cobalt库函数pthread_create实现主体为(xenomai3.x.x\lib\cobalt\thread.c):

COBALT_IMPL(int, pthread_create, (pthread_t *ptid_r,

const pthread_attr_t *attr,

void *(*start) (void *), void *arg))

{

pthread_attr_ex_t attr_ex;

......

return pthread_create_ex(ptid_r, &attr_ex, start, arg);

}

复制代码

COBALT_IMPL定义了__cobalt_pthread_create函数及该函数的一个弱别名__wrap_pthread_create,调用这两个函数执行的是同一个函数体。

对于 NPTL函数pthread_create,在Cobalt库里使用__STD()修饰,展开后即__real_pthread_create(),其实只是NPTL pthread_create()的封装,__real_pthread_create()会直接调用 NPTL pthread_create,在lib\cobalt\wrappers.c实现如下:

/* pthread */

__weak

int __real_pthread_create(pthread_t *ptid_r,

const pthread_attr_t * attr,

void *(*start) (void *), void *arg)

{

return pthread_create(ptid_r, attr, start, arg);

}

复制代码

它调用的就是glibc中的pthread_create函数.同样我们接着__cobalt_pthread_create()看哪里调用的.

int pthread_create_ex(pthread_t *ptid_r,

const pthread_attr_ex_t *attr_ex,

void *(*start) (void *), void *arg)

{

......

__STD(sem_init(&iargs.sync, 0, 0));

ret = __STD(pthread_create(&lptid, &attr, cobalt_thread_trampoline, &iargs));/*__STD 调用标准库的函数*/

if (ret) {

__STD(sem_destroy(&iargs.sync));

return ret;

}

__STD(clock_gettime(CLOCK_REALTIME, &timeout));

.....

}

复制代码

下面再看另一个例子,实时任务在代码中使用了linux的网络套接字(xenomai任务也是一个linux任务,也可以使用linux来提供服务,只不过会影响实时性),有以下代码,:

....

int sockfd,ret;

struct sockaddr_in addr;

sockfd = socket(PF_INET, SOCK_STREAM, 0);

.....

bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr_in));

....

复制代码

该代码编译时链接到了libcobalt,socket()函数即libcobalt中的__cobalt_socket(),其定义在xenomai-3.x.x\lib\cobalt\rtdm.c,如下:

COBALT_IMPL(int, socket, (int protocol_family, int socket_type, int protocol))

{

int s;

s = XENOMAI_SYSCALL3(sc_cobalt_socket, protocol_family,

socket_type, protocol);

if (s < 0) {

s = __STD(socket(protocol_family, socket_type, protocol));

}

return s;

}

复制代码

可以看到,libcobalt中的函数会先尝试调用实时内核cobalt的系统调用, 当cobalt系统调用不成功的时候才继续尝试通过__STD()宏来调用linux系统调用(cobalt内核根据socket协议类型参数PF_INET,SOCK_STREAM判断),这样就有效的分清了是linux系统调用还是xenomai系统调用。

一般情况下,可以直接在代码中使用__STD()宏指明我们调用的linux内核的服务,修改如下:

....

int sockfd,ret;

struct sockaddr_in addr;

sockfd = __STD(socket(PF_INET, SOCK_STREAM, 0));

.....

__STD(bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr_in)));

....

复制代码

现在一切都明了了,一个函数编译时通过参数链接到xenomai库后,通过__STD()宏来表示使用linux接口。

4. 总结

在实时程序或实时库libcobalt中,通过__STD()宏来表示使用linux接口。

对于一个未指明的接口,libcobalt会先尝试发起xenomai系统调用,不成功会接着尝试linux内核系统调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python怎么导入os模块_python之os模块

在自动化测试中&#xff0c;经常需要查找操作文件&#xff0c;比如说查找配置文件&#xff08;从而读取配置文件的信息&#xff09;&#xff0c;查找测试报告&#xff08;从而发送测试报告邮件&#xff09;&#xff0c;经常要对大量文件和大量路径进行操作&#xff0c;这就依赖…

linux7配置网卡绑定,CentOS7双网卡绑定配置

step1:创建绑定文件[rootnode-1 ~]# vi /etc/sysconfig/network-scripts/ifcfg-bond0TYPE"bond"BOOTPROTO"none"NAME"bond0"DEVICE"bond0"IPADDR"192.168.1.20"NETMASK"255.255.255.0"GATEWAY"192.168.1.1&q…

ubuntu复制文件到另一个文件夹_简单介绍一下电脑中的文件或文件夹的复制、移动及删除的操作方式...

大家好&#xff0c;我是波仔&#xff0c;今天又来跟各位学电脑基础的朋友们分享知识&#xff0c;让我们一起来学习吧。复制文件或文件夹在我们日常操作文件或文件夹的过程中&#xff0c;经常会遇到需要复制一些文件或文件夹什么的&#xff0c;下面我们就一起来分享一下常用的几…

Windows和linux提权方法,Windows与Linux本地用户提权体验(一)

无论是Windows系统还是linux系统都是基于权限控制的&#xff0c;其严格的用户等级和权限是系统安全的有力保证。这么严密的用户权限是否不可逾越呢?下面笔者反其道而行之进行Windows及Linux下的提权测试。一、windows下获取至高权限大家知道&#xff0c;在Windows系统中SYSTEM…

三相逆变器双pi控制器参数如何调节_光伏逆变器短路特性简析

1前言短路故障相对于其他故障类型来说是比较常见的&#xff0c;不同的设备的短路故障&#xff0c;大了讲都一样&#xff0c;细了说各有千秋&#xff0c;今天我们主要聊聊光伏逆变器的短路特征。电力系统中的电源&#xff0c;传统意义是指的是并入电力系统的同步发电机。但随着分…

linux安装多路径报错,Linux操作系统配置多路径通用教程(适用于(RHEL,CentOS,SuSE等)...

Linux操作系统配置多路径通用教程(适用于(RHEL,CentOS,SuSE等)猫先生 • 2019 年 06 月 01 日一&#xff0c;安装软件1&#xff0c;执行以下命令&#xff0c;检查当前系统中是否已经安装多路径工具&#xff1a;rpm -qa | grep device-mapper-multipathSuSE 系统 multipath 相关…

python脚本根据cookies自动登录网站_python实现带验证码网站的自动登陆实现代码...

早听说用python做网络爬虫非常方便&#xff0c;正好这几天单位也有这样的需求&#xff0c;需要登陆XX网站下载部分文档&#xff0c;于是自己亲身试验了一番&#xff0c;效果还不错。 本例所登录的某网站需要提供用户名&#xff0c;密码和验证码&#xff0c;在此使用了python的u…

鸟叔linux私房菜基础篇简体,鸟叔的Linux私房菜基础篇-学习笔记(一)

鸟叔的Linux私房菜基础篇-学习笔记(一)开机进入命令行模式:ctrlalt[F1-F6]的任意键进入命令行编辑界面ctrlaltF7进入图形界面模式开始下达指令[dmtsaistudy ~]$ command [-options] parameter1 parameter2 …一行指令中第一个输入的部分绝对是“指令(command)”或“可可执行文件…

net framework 3.5 安装错误_PageAdmin CMS建站系统报http403错误的解决方案

pageadmin CMS目前已经是国内用户最多的网站内容管理系统&#xff0c;但是很多新手第一次安装时候最常见的错误就是http403错误。针对这个错误&#xff0c;小编我整理出了常见的原因及解决方法原因1、后台站点绑定的域名和当前打开的域名不一致。解决办法&#xff1a;重装PageA…

linux怎么配置svn形式访问,linux服务器svn访问地址

弹性云服务器 ECS弹性云服务器(Elastic Cloud Server)是一种可随时自助获取、可弹性伸缩的云服务器&#xff0c;帮助用户打造可靠、安全、灵活、高效的应用环境&#xff0c;确保服务持久稳定运行&#xff0c;提升运维效率三年低至5折&#xff0c;多种配置可选了解详情什么是弹性…

java进程内存一直没释放_五分钟彻底搞懂你一直没明白的Linux内存管理

现在的服务器大部分都是运行在Linux上面的&#xff0c;所以&#xff0c;作为一个程序员有必要简单地了解一下系统是如何运行的。对于内存部分需要知道&#xff1a;地址映射内存管理的方式缺页异常先来看一些基本的知识&#xff0c;在进程看来&#xff0c;内存分为内核态和用户态…

c语言basic解释器,要理解解释器,做一个小解释器----小话c语言(20)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼}list->tail->next obj;list->tail obj;return obj;}void cc_arg_list_free(cc_arg_list *list){cc_arg_obj *head list->head;while(head){cc_arg_obj *next head->next;cc_arg_obj_free(head);head next;}}v…

ehcache使用_Mybatis整合(Redis、Ehcache)实现二级缓存,恕我直言,你不会

目的&#xff1a;Mybatis整合Ehcache实现二级缓存Mybatis整合Redis实现二级缓存Mybatis整合ehcache实现二级缓存ssm中整合ehcache在POM中导入相关依赖org.springframework spring-context-support ${spring.version}org.mybatis.caches mybatis-ehcache 1.1.0net.s…

c语言利用栈将字符串逆序输出,【C语言】利用栈将数组中字符串逆序

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include"stdio.h"#include"stdlib.h"#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef struct{char *base;char *top;int stacksize;}SqStack;main(){SqStack S;char a[4];int i;InitStack(&…

取证 c语言实现日志导出_日志与日志不一样:五种不能忽略的日志源

给日志源分出主次大有利于开展有效事件响应。就像分诊护士一样&#xff0c;安全人员也必须给数据分出个优先主次&#xff0c;以帮助他们更好地识别问题&#xff0c;使公司企业及其数据和设备能够避免入侵者和网络攻击的伤害。但是&#xff0c;记录和监视IT环境中的所有相关事件…

c语言 多文件 学生系统,编的学生成绩管理系统 从文件中读取保存数据总会多读入一组乱码数据...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼getch();return L;}}void SearchData(Stu L){Stu p;int num;pL->next;printf("Input the ID of the student you want to search:");scanf("%d",&num);while(p!NULL){if(p->numnum) { printf("…

codesoft指定打印机打印_巧用win32print来控制windows系统打印机并推送打印任务

小爬最近接到的一个需求是&#xff1a;将windows系统下的打印任务批量有序传输给网络打印机&#xff0c;实现批量有序打印。用户先从公司的OA(B/S模式)系统下 打印指定内容的表单以及表单中的附件内容。这个问题可以这样分解&#xff1a;1、抓包&#xff0c;得到OA对应的任务接…

c语言磁盘文件只有写没读,C语言的磁盘文件问题

匿名用户1级2010-04-06 回答C语言文件操作函数1,两种文件存取方式(输入,输出方式)顺序存取直接存取2,数据的两种存放形式文本文件二进制文件13.2文件指针定义文件类型指针变量的一般形式:FILE *指针变量名;例如:FILE *fp1,*fp2;13.3打开文件在使用文件之前,需打开文件.在C里使用…

crmeb pc端模板下载_PC端人人影视下载速度如何提高

首先下载最新版本的人人影视我的是这个&#xff0c;右下角版本号1022然后在下载设置那里把连接数调高一点大致就这样我的就是调了一下然后下载速度高了许多&#xff0c;刚开始只有1M左右的速度&#xff0c;现在4&#xff0c;5M每秒

android 编辑自定义可编辑表格,smart 框架 列表 可编辑表格

可编辑表格常用属性colModel: [{label: "主键ID", name: "hellop1",hidden:true},{label: "列明", name: "hellop2",align: "center", editable: true, edittype: text, editrules: { required: true } }editable&#xff1…