点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-优快云博客
原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!
5.3.2 Xenomai3:使用xeno-config获取编译和链接参数
xeno-config是一个辅助脚本,用于为使用Xenomai库的应用程序提供正确的编译和链接标志。通过这个工具,开发者可以轻松获取所需的编译器选项和链接器参数,确保应用程序能够正确地集成到Xenomai环境中。对于不同的API或特性集,如Cobalt、POSIX、Alchemy等,xeno-config可以通过传递特定的参数来调整输出的编译和链接标志。
注意,如果是交叉编译环境,在执行xeno-config之前,需让DESTDIR指向xenomai的安装目录。下面的例子中,xenomai-v3.2.1编译后,通过make install安装到了~/ipipie-arm64/xenomai_install目录。
场景一:cobalt skin
应用程序直接调用libcobalt库中定义的__cobalt_pthread_create/__wrap_pthread_create类似的API。
当然为了方便,可以使用宏定义来更方便的编程:__COBALT(pthread_create)/__WRAP(pthread_create)展开之后就是__cobalt_pthread_create/__wrap_pthread_create。
在应用程序中直接使用cobalt skin比较少见!
获取编译参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=cobalt --cflags
-I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/cobalt -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include -march=armv8-a -D_GNU_SOURCE -D_REENTRANT -fasynchronous-unwind-tables -D__COBALT__
获取链接参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=cobalt --ldflags
-Wl,--no-as-needed -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/modechk.wrappers /root/ipipe-arm64/xenomai_install/usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/dynlist.ld -L/root/ipipe-arm64/xenomai_install/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt -march=armv8-a
场景二:posix skin
应用程序使用posix接口来编程,例如pthread_create。
获取编译参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=posix --cflags
-I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/cobalt -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include -march=armv8-a -D_GNU_SOURCE -D_REENTRANT -fasynchronous-unwind-tables -D__COBALT__ -D__COBALT_WRAP__
获取链接参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=posix --ldflags
-Wl,--no-as-needed -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/cobalt.wrappers -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/modechk.wrappers /root/ipipe-arm64/xenomai_install/usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/dynlist.ld -L/root/ipipe-arm64/xenomai_install/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt -march=armv8-a
与cobalt skin的区别是什么?来看最主要的区别,在链接参数中,多了一个标志:
-Wl,@/root/xenomai/xenomai-v3.2.1/lib/cobalt/cobalt.wrappers
-Wl,@/root/xenomai/xenomai-v3.2.1/lib/cobalt/cobalt.wrappers
//文件内容
# cat lib/cobalt/cobalt.wrappers
--wrap pthread_attr_init
--wrap pthread_create
--wrap pthread_setschedparam
--wrap pthread_getschedparam
--wrap pthread_setschedprio
--wrap pthread_yield
--wrap sched_yield
--wrap sched_get_priority_min
--wrap sched_get_priority_max
--wrap sched_setscheduler
--wrap sched_getscheduler
--wrap pthread_kill
--wrap pthread_join
--wrap pthread_setname_np
--wrap sem_init
--wrap sem_destroy
--wrap sem_post
--wrap sem_timedwait
--wrap sem_wait
--wrap sem_trywait
--wrap sem_getvalue
--wrap sem_open
--wrap sem_close
--wrap sem_unlink
--wrap clock_getres
--wrap clock_gettime
--wrap clock_settime
--wrap clock_adjtime
--wrap clock_nanosleep
--wrap nanosleep
--wrap pthread_mutex_init
--wrap pthread_mutex_destroy
--wrap pthread_mutex_lock
--wrap pthread_mutex_trylock
--wrap pthread_mutex_timedlock
--wrap pthread_mutex_unlock
--wrap pthread_mutex_setprioceiling
--wrap pthread_mutex_getprioceiling
--wrap pthread_cond_init
--wrap pthread_cond_destroy
--wrap pthread_cond_wait
--wrap pthread_cond_timedwait
--wrap pthread_cond_signal
--wrap pthread_cond_broadcast
--wrap mq_open
--wrap mq_close
--wrap mq_unlink
--wrap mq_getattr
--wrap mq_setattr
--wrap mq_send
--wrap mq_timedsend
--wrap mq_receive
--wrap mq_timedreceive
--wrap mq_notify
--wrap open
--wrap open64
--wrap __open_2
--wrap __open64_2
--wrap socket
--wrap close
--wrap ioctl
--wrap read
--wrap write
--wrap recvmsg
--wrap recvmmsg
--wrap sendmsg
--wrap sendmmsg
--wrap recvfrom
--wrap sendto
--wrap recv
--wrap send
--wrap getsockopt
--wrap setsockopt
--wrap bind
--wrap connect
--wrap listen
--wrap accept
--wrap getsockname
--wrap getpeername
--wrap shutdown
--wrap timer_create
--wrap timer_delete
--wrap timer_settime
--wrap timer_getoverrun
--wrap timer_gettime
--wrap timerfd_create
--wrap timerfd_gettime
--wrap timerfd_settime
--wrap select
--wrap vfprintf
--wrap vprintf
--wrap fprintf
--wrap printf
--wrap puts
--wrap fputs
--wrap fputc
--wrap putchar
--wrap fwrite
--wrap fclose
--wrap syslog
--wrap vsyslog
--wrap gettimeofday
--wrap __vfprintf_chk
--wrap __vprintf_chk
--wrap __fprintf_chk
--wrap __printf_chk
--wrap __vsyslog_chk
--wrap __syslog_chk
--wrap sigwait
--wrap sigwaitinfo
--wrap sigtimedwait
--wrap sigpending
--wrap sigqueue
--wrap kill
--wrap sleep
--wrap usleep
--wrap mmap
--wrap mmap64
--wrap time
--wrap fcntl
查看cobalt.wrappers的内容,以--wrap pthread_create为例,将应用程序中对 pthread_create函数的所有引用重定向到名为 __wrap_pthread_create 的函数,并将 pthread_create函数本身重命名或重新定义为 __real_pthread_create。最终的调用堆栈为:
Application->pthread_create
->重定向到__wrap_pthread_create //lib/cobalt/thread.c
->pthread_create_ex //lib/cobalt/thread.c
->__real_pthread_create //lib/cobalt/wrappers.c
->pthread_create //回归到标准libpthread库函数
上述例子涉及到复用Linux线程创建的逻辑,非常复杂。并不是所有的库函数都会回归到标准库函数。例如clock_getres函数,直接调用Xenomai系统调用sc_cobalt_clock_getres,完事!
Application->clock_getres
->重定向到__wrap_clock_getres // lib/cobalt/clock.c
->XENOMAI_SYSCALL2(sc_cobalt_clock_getres, clock_id, tp)
场景三:Alchemy skin
获取编译参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=alchemy --cflags
-I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/cobalt -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include -march=armv8-a -D_GNU_SOURCE -D_REENTRANT -fasynchronous-unwind-tables -D__COBALT__ -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/alchemy
获取链接参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=alchemy --ldflags
-Wl,--no-as-needed -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/modechk.wrappers -lalchemy -lcopperplate /root/ipipe-arm64/xenomai_install/usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/dynlist.ld -L/root/ipipe-arm64/xenomai_install/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt -march=armv8-a
在posix skin的基础上,链接时新增了-lalchemy -lcopperplate:链接Alchemy库和Copperplate库。Alchemy库提供了alchemy skin,copperplate库可以把alchemy skin转换为对posix skin的调用!
xeno-config工具默认启用了Copperplate的自动初始化功能。为了禁用自动初始化,可以在编译或配置阶段传递--no-auto-init选项给xeno-config工具,这样做的结果是,在程序启动时将不会自动调用copperplate_init()函数。不是很常用的用法,不建议!
场景四:兼容Xenomai2/native接口
参考Migrating to Xenomai 3 :: Xenomai 3,如果应用程序是使用Xenomai2/native接口编写的,现在想要运行在Xenomai3,不能简单的使用alchemy skin,需要加上--compat,或者直接使用natvie skin.
获取编译参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=native --cflags
-I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/trank -D__XENO_COMPAT__ -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/cobalt -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include -march=armv8-a -D_GNU_SOURCE -D_REENTRANT -fasynchronous-unwind-tables -D__COBALT__ -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/alchemy
获取链接参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=native --ldflags
-Wl,--no-as-needed -ltrank -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/modechk.wrappers -lalchemy -lcopperplate /root/ipipe-arm64/xenomai_install/usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/dynlist.ld -L/root/ipipe-arm64/xenomai_install/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt -march=armv8-a
主要变化是增加了-ltrank,引入了trank库。
trank是啥意思呢?
在源码中翻到了解释,是Transition Kit的缩写。它包含了一系列的包装器和服务,帮助开发者更轻松地将使用Xenomai 2.x开发的应用程序迁移到Xenomai 3.x。这个工具包提供了源代码级别的兼容性,使得原本依赖于Xenomai 2.x的POSIX和原生API的应用程序能够在Xenomai 3.x环境中继续运行。
场景五:兼容Xenomai2/posix接口
获取编译参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=posix --compat --cflags
-I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/trank/posix -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/trank -D__XENO_COMPAT__ -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include/cobalt -I/root/ipipe-arm64/xenomai_install/usr/xenomai/include -march=armv8-a -D_GNU_SOURCE -D_REENTRANT -fasynchronous-unwind-tables -D__COBALT__ -D__COBALT_WRAP__
获取链接参数
root@u2204:~/ipipe-arm64/xenomai_install# DESTDIR=$(pwd) usr/xenomai/bin/xeno-config --skin=posix --compat --ldflags
-Wl,--no-as-needed -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/cobalt.wrappers -ltrank -Wl,@/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/modechk.wrappers /root/ipipe-arm64/xenomai_install/usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/root/ipipe-arm64/xenomai_install/usr/xenomai/lib/dynlist.ld -L/root/ipipe-arm64/xenomai_install/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt -march=armv8-a
相比场景二,主要变化是增加了-ltrank,引入了trank库。原理与场景四兼容Xenomai2/native接口的原理完全相同。
点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-优快云博客
原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!