前言
在CP Autosar开发中,客户使用的接口以及这个接口的行为,虽然可以通过RTE定义清楚,但是RTE接口本身需要供应商和客户双方约定好。
然而,到了SoC端开发AP Autosar,情况就变得不一样了。很多名词我们经常会提到,这个代码是跨平台的,这个代码符合POSIX标准,这个代码能在Like-Unix系统上正常运行,这个代码可以兼容安卓内核。
我们不经疑惑,在汽车电子中,AP该如何去写代码?在ADAS控制器领域,真正去使用的操作系统有打过RT patch的Linux系统和商业版本的QNX系统。安卓和mac更多的应用在车机系统。
对于QNX系统和Linux系统的内核差异,我们抛开宏内核、微内核之类的争议不谈。单纯从开发应用的角度而言,QNX和Linux系统的差异到底有多大,在开发的时候需要注意哪些细节问题?本文将尝试盘点接口/应用层级的差异。
作者前前后后花了几个月时间尝试去研究QNX系统下的编程与调试,在这边做个总结,也给大家做个汇报。
QNX与Linux基础差异对比
QNX是微内核、Linux是宏内核
QNX是硬实时操作系统、Linux是软实时操作系统
QNX和Linux均是类Unix操作系统
QNX支持POSIX PSE54标准,Linux支持POSIX标准,但不一定支持PSE54标准。
就调度策略而言,Linux支持Fifo,RR,other,deadline,batch策略。而QNX支持Sporadic、RR、FIFO策略。两者有差异。
就IPC通讯机制(Socket、Signal、MessageQueue、Pipe、Shared Memory、信号量)而言,Linux支持POSIX相关标准之外,还额外支持System V相关接口。QNX支持POSIX标准,也有独有的Message Passing机制。总的来说,从功能角度来讲,大差不差。
就性能优化而言,各有各的特点,如果做到性能的极致,同时还要兼顾跨平台,需要对Linux、QNX做一些抽象。
文件系统两者不一样。
QNX与Linux应用差异对比
根目录下的差异
QNX和Linux在根目录这个层级上是有差异的,在Linux系统根目录有如下差异:
bin、dev、home、lib、opt、sbin、sys、usr、data、etc、lib、proc、tmp、var等文件夹。重要的命令行程序存放于bin目录下,库文件存放于lib目录下,系统库的索引环境变量为lib和usr/lib。tmp目录每次重启均会清零,etc目录会存放配置文件。proc目录存放程序运行的相关信息。dev目录会将内核相关的设备以文件的形式映射出来。
QNX系统根目录下有debug、dev、etc、lib、opt、proc、bin、sbin、tmp、usr、var目录。命令行相关程序存放于debug文件夹内,同时相关库也会存放在debug文件夹中。QNX系统中的proc文件夹内容与Linux系统中的内容相差较大,QNX内容更少,如果有软件是基于proc目录做策略的话,需要特别注意。QNX系统其他目录对比Linux系统,相差不大。
命令行的差异
在嵌入式系统中,我们会裁剪QNX和Linux系统,因此很多命令不一定会全部支持。对于我们经常需要用到的命令,例如ls,top等等,是否会有区别呢?就系统而言,两边到底有多大差距呢?这个问题值得我们去思考。我们从文件操作、性能调试、网络分析三个角度来对比两个系统的差异。
文件/文件系统操作命令:
ls,pwd,cd,cp,rm并无多大区别。
df -h查看文件分区情况两者并无区别。
mount/umount命令有区别,在QNX系统中,采用mount /dev/xxx /yyy的形式挂载文件系统。umount -f xxx取消挂载。
性能分析相关的命令:
top命令可以查看程序的状态,然后展示的内容有些许区别,命令的使用也有蛮大的区别。
QNX系统专有的hogs,pidin、ps命令对程序进行分析。
QNX系统无法使用strace命令来获取程序的系统调用,但是有tracelogger、traceprinter工具抓取相关信息,当然也可以抓取kernel event trace,而Linux系统可以直接使用strace、perf工具实现更多的功能。
QNX系统可以使用Valgrind进行内存相关的分析,而Linux系统需要额外按照这个命令。
QNX系统可以使用类似gdb的方式进行远程调试,也可以生成coredump文件,这个机制与Linux系统上有差异,但是功能上类似的。QNX系统还支持优先级反转的检测,Linux系统上没遇见过相关的成熟方案。
代码覆盖率相关的功能,应用的方式感觉大差不差,需要额外确认gtest是不是支持QNX系统,以便于完成工具链的闭环。
网络分析:
首先,QNX系统没有tcpdump工具(文档中是有的,实际在环境中并没有),真是非常可惜,Linux系统支持tcpdump,支持libpcap库所提供的相关特性。Linux系统常用的网络工具:tcpdump、iperf,ss,netstat、ifconfig、ping、ip、lsof、arp等等。一般网路工具需要覆盖1.网卡诊断查看相关功能 2.网卡性能检测 3.网络抓包 4.端口查看 5.网络连接查看 6.流量分析等等。
QNX系统上网络分析工具比较缺乏。Ifconfig、ping功能是类似的,sockstat是list所有socket信息含UDS相关的socket。netstat命令可以查看网络状态,可以看到丢包相关的数据。iperf3工具也可以正常使用。arp命令可以正常查看路由表。
就工具而言,QNX系统有一点让我无法容忍,响应一个命令需要半天、半天、半天、重要的事情说三遍!!!!!!
系统编程的差异
本节从创建进程、创建线程、锁、共享内存、网络编程、定时器、信号几个角度来确认两者的差异。
创建进程:
Linux系统常用fork+execv函数族,QNX系统 不支持fork,须采用posix_spawn函数族,Linux系统也支持这个posix_spawn函数族,但是很多代码并不会调用这个函数。
创建线程:
QNX系统和Linux系统均采用pthread_xxx函数族,但是有一点必须特别注意,亲测QNX系统中pthread_setname_np接口并不起作用,但是程序可以正常运行,Linux系统中这个接口调用是正常的,也可能是我对QNX系统理解的不到位。
锁创建:
sem_xxx POSIX标准的函数族,QNX系统和Linux系统均支持,System V接口在QNX系统中不支持。
共享内存创建:
Shm_xxx函数族POSIX标准的函数族,QNX系统和Linux系统均支持。但是这两者还是有差异的,QNX系统会在/dev/shmem目录下生成相关的共享内存文件,而Linux系统会在/dev/shm目录下生成相关的文件。此外,亲测当设置文件名时,文件名带不带路径,例如“a/shm1.shm”在两个系统中的实际效果不一致,但是程序会正常运行。
网络编程:
Linux支持很多特殊的特性:bpf、libpcap、netfilter机制等等。QNX系统没有bpf、没有libpcap、没有netfilter。Linux可以对socket本身设置优先级,QNX系统不支持。因此像开源时间同步代码linuxptp大概率在QNX系统上无法正常编译(没试过,但是用了linuxptp用了一些bpf的机制)。如果是普通的UDP、TCP开发,接口还是兼容的,但是对raw socket开发或者需要利用kernel机制的一些优化,则无法兼容。
总的来说,网络编程这块,QNX系统和Linux系统还是蛮大的,虽然POSIX接口是统一的,但是很多特殊的操作系统设计特性真是不兼容。尤其是用到setsockopt这个接口时,需要特殊特别特意的关注!!!!!!
定时器创建:
Linux系统的定时器有很多方式:alarm、timer_create/ timer_settime函数族、setitimer接口等等。QNX系统的教程说是支持这几个接口,并没有实际应用过,暂定兼容的。
信号的创建:
signal接口两者是兼容的,更高级的用法没试过。
编译的差异对比
对Linux系统交叉编译时,不需要显示的指定glibc库,也不需要显示的初始化编译器的环境。
而对QNX系统交叉编译时,首先需要调用qnxxxx_env脚本初始化环境,必须要显示的用-l c指定c库的链接,同时需要指定std的语言,同时QNX系统支持qcc和gcc两套编译器,亲测均可生成在QNX系统上运行的可执行文件。C++程序需要指定std变量并使用-lc++链接c++库。QNX系统若需要支持gnu特性,需要显示的指明gnu++11标准。对于socket编程,需要使用-lsocket指令显示链接相关库。
总而言之,qnx系统的交叉编译还是有很多注意点的。
审核编辑:发货
评论
查看更多