基本情况介绍
在移植Xenomai并连接igh的工程中遇到了一些编译问题,但由于本人是这方面的小白,多番寻找之下仍未能解决问题,所以在这里贴出具体情况,希望有大佬能不吝赐教。
移植Xenomai和igh的流程是参考了这篇博客
版本
linux-dovetail-v5.10.76-dovetail3+xenomai-v3.2.1+ethercat-e1000e-5.10源码包
其中linux-dovetail-v5.10.76-dovetail3是Xenomai官方做好的内核源码。具体的连接如下:
linux
xenomai
igh
问题
在Xenomai的移植当中,按照教程的做法能够顺利完成Xenomai的移植, uname -a
和dmesg | grep -i xenomai
显示版本号已经发生改变,使用sudo /usr/xenomai/bin/latency
工具进行测试能够正常使用,但是在igh的安装过程中,经过./configure
之后运行sudo make -j4
就会出现错误。错误的部分内容如下(完整内容见文末):
/usr/xenomai/lib/xenomai/bootstrap.o: In function `xenomai_main':
bootstrap.c:(.text+0x0): multiple definition of `xenomai_main'
/usr/xenomai/lib/xenomai/bootstrap.o:bootstrap.c:(.text+0x0): first defined here
/usr/xenomai/lib/xenomai/bootstrap.o:(.rodata+0x0): multiple definition of `xenomai_auto_bootstrap'
/usr/xenomai/lib/xenomai/bootstrap.o:(.rodata+0x0): first defined here
/home/lzx/xenomai/ethercat-e1000e-5.10/lib/.libs/libethercat_rtdm.so: undefined reference to `rt_dev_ioctl'
/home/lzx/xenomai/ethercat-e1000e-5.10/lib/.libs/libethercat_rtdm.so: undefined reference to `rt_dev_open'
/home/lzx/xenomai/ethercat-e1000e-5.10/lib/.libs/libethercat_rtdm.so: undefined reference to `rt_dev_close'
collect2: error: ld returned 1 exit status
Xenomai和igh所使用的./configure
参数如下:
xenomai
sudo ./scripts/bootstrap
sudo ./configure --with-pic --with-core=cobalt --enable-smp --disable-tls --enable-dlopen-libs --disable-clock-monotonic-raw
igh
sudo ./bootstrap
sudo ./configure --with-module-dir=/lib/modules/5.10.76-xenomai --enable-generic --enable-8139too=no --enable-debug-if --enable-rtdm --enable-cycles --enable-hrtimer --with-xenomai-dir=/usr/xenomai --prefix=/opt/etherlab
这里虽然使用的是e1000的源码包,但是也曾尝试过master和stable-1.5的源码包,同样出现了上面的问题
分析
错误提示undefined reference to rt_dev_xxx
,似乎和rtdm接口有关,在igh的文档中有提到rtdm是作为与Xenomai连接的接口,并且出现了multiple definition of xenomai_main
的提示,在这篇博客中提到:
Xenomai 3 的rtdm驱动更像一般的Linux驱动,named device会在/dev/rtdm/xxx创建一个设备文件。而用户空间使用时,写得来也和Linux的一般char设备相似,open/close/read/write/ioctl,只不过实际上在link的时候这些函数都被做了手脚,替换成了libcobalt.so中的函数(参见 /usr/xenomai/lib/cobalt.wrappers)
以我粗陋的知识来推断(瞎猜),应该是编译过程中链接动态库时出现了问题。为了解决问题我又到Xenomai和igh的论坛寻找解决方法,在上面发现两篇分别是15、16年的文章与这里遇到的问题一致,里面提到问题之所以出现,可能是因为igh没有更新连接Xenomai的编译方法。最后我在igh的gitlab仓库询问了我所遇到的问题链接,得到的回复是:
We (the etherlab team ) mainly support ethercat under preempt rt kernel. We do not use the rtai or xenomai interface anymore in production enviroments.
Please feel free to fix it and create a merge request.
It seems there is a missing library at linking time, maybe the xenomai have splitted some libs
大概意思是igh团队主要支持preemptRT的实时内核,不再使用RTAI和Xenomai的接口。问题看起来似乎是链接过程中某个库没找到,可能Xenomai分割了某些库。
结论
igh团队可能不再更新对Xenomai的接口,Xenomai+igh的实时控制方案似乎没办法进行了,但是我还是想找到解决上面提到的编译错误的方法。毕竟我所参考的博客教程不到一年前才发布,而我使用的源码包与教程一致,在Xenomai和igh的gitlab仓库里也能看到最近的更新是一年以前,是在没道理这篇博客能够顺利安装上,到了我这就不行了。
在这里也求助各位路过的大佬能够解决我的问题。
make完整报错内容
make all-recursive
make[1]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10'
Making all in include
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/include'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/include'
Making all in script
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script'
Making all in init.d
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script/init.d'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script/init.d'
Making all in sysconfig
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script/sysconfig'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script/sysconfig'
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script'
make[3]: Nothing to be done for 'all-am'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script'
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/script'
Making all in devices
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices'
Making all in ccat
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/ccat'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/ccat'
Making all in e1000
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/e1000'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/e1000'
Making all in e1000e
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/e1000e'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/e1000e'
Making all in igb
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/igb'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices/igb'
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices'
make[3]: Nothing to be done for 'all-am'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices'
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/devices'
Making all in master
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/master'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/master'
Making all in tool
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/tool'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/tool'
Making all in lib
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/lib'
CC libethercat_rtdm_la-common.lo
CC libethercat_rtdm_la-domain.lo
CC libethercat_rtdm_la-master.lo
CC libethercat_rtdm_la-reg_request.lo
In file included from domain.c:42:0:
domain.c: In function ‘ecrt_domain_size’:
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
domain.c:83:11: note: in expansion of macro ‘ioctl’
ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_SIZE, domain->index);
^~~~~
common.c: In function ‘ecrt_open_master’:
In file included from master.c:36:0:
master.c: In function ‘ecrt_master_reserve’:
common.c:98:18: warning: implicit declaration of function ‘rt_dev_open’; did you mean ‘__real_open’? [-Wimplicit-function-declaration]
master->fd = rt_dev_open(path, O_RDWR);
^~~~~~~~~~~
__real_open
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
master.c:45:15: note: in expansion of macro ‘ioctl’
int ret = ioctl(master->fd, EC_IOCTL_REQUEST, NULL);
^~~~~
In file included from common.c:41:0:
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
common.c:108:11: note: in expansion of macro ‘ioctl’
ret = ioctl(master->fd, EC_IOCTL_MODULE, &module_data);
^~~~~
master.c: In function ‘ec_master_clear’:
master.c:94:9: warning: implicit declaration of function ‘rt_dev_close’; did you mean ‘__real_close’? [-Wimplicit-function-declaration]
rt_dev_close(master->fd);
^~~~~~~~~~~~
__real_close
In file included from reg_request.c:38:0:
reg_request.c: In function ‘ecrt_reg_request_state’:
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
reg_request.c:72:11: note: in expansion of macro ‘ioctl’
ret = ioctl(reg->config->master->fd, EC_IOCTL_REG_REQUEST_STATE, &io);
^~~~~
CC libethercat_rtdm_la-sdo_request.lo
CC libethercat_rtdm_la-slave_config.lo
CC libethercat_rtdm_la-voe_handler.lo
In file included from voe_handler.c:39:0:
voe_handler.c: In function ‘ecrt_voe_handler_send_header’:
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
voe_handler.c:67:11: note: in expansion of macro ‘ioctl’
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_SEND_HEADER, &data);
^~~~~
In file included from sdo_request.c:38:0:
sdo_request.c: In function ‘ecrt_sdo_request_index’:
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
sdo_request.c:68:11: note: in expansion of macro ‘ioctl’
ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_INDEX, &data);
^~~~~
In file included from slave_config.c:34:0:
slave_config.c: In function ‘ecrt_slave_config_sync_manager’:
ioctl.h:50:15: warning: implicit declaration of function ‘rt_dev_ioctl’; did you mean ‘__real_ioctl’? [-Wimplicit-function-declaration]
#define ioctl rt_dev_ioctl
^
slave_config.c:95:11: note: in expansion of macro ‘ioctl’
ret = ioctl(sc->master->fd, EC_IOCTL_SC_SYNC, &data);
^~~~~
/bin/sed -e 's,%libdir%,/opt/etherlab/lib,' -e 's,%includedir%,/opt/etherlab/include,' EtherCATConfig.cmake.in > EtherCATConfig.cmake
CCLD libethercat_rtdm.la
*** Warning: Linking the shared library libethercat_rtdm.la against the non-libtool
*** objects /usr/xenomai/lib/xenomai/bootstrap.o is not portable!
ar: `u' modifier ignored since `D' is the default (see `U')
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/lib'
Making all in examples
make[2]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples'
Making all in dc_user
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples/dc_user'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples/dc_user'
Making all in user
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples/user'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples/user'
Making all in xenomai
make[3]: Entering directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples/xenomai'
CC ec_xenomai_example-main.o
CCLD ec_xenomai_example
/usr/xenomai/lib/xenomai/bootstrap.o: In function `xenomai_main':
bootstrap.c:(.text+0x0): multiple definition of `xenomai_main'
/usr/xenomai/lib/xenomai/bootstrap.o:bootstrap.c:(.text+0x0): first defined here
/usr/xenomai/lib/xenomai/bootstrap.o:(.rodata+0x0): multiple definition of `xenomai_auto_bootstrap'
/usr/xenomai/lib/xenomai/bootstrap.o:(.rodata+0x0): first defined here
/home/lzx/xenomai/ethercat-e1000e-5.10/lib/.libs/libethercat_rtdm.so: undefined reference to `rt_dev_ioctl'
/home/lzx/xenomai/ethercat-e1000e-5.10/lib/.libs/libethercat_rtdm.so: undefined reference to `rt_dev_open'
/home/lzx/xenomai/ethercat-e1000e-5.10/lib/.libs/libethercat_rtdm.so: undefined reference to `rt_dev_close'
collect2: error: ld returned 1 exit status
Makefile:424: recipe for target 'ec_xenomai_example' failed
make[3]: *** [ec_xenomai_example] Error 1
make[3]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples/xenomai'
Makefile:462: recipe for target 'all-recursive' failed
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10/examples'
Makefile:519: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/lzx/xenomai/ethercat-e1000e-5.10'
Makefile:444: recipe for target 'all' failed
make: *** [all] Error 2