介绍
几前的一个项目,使用Boost Asio重构了下:使用CMake统一编译,集成了一些开源第三方库的源码,比如googletest,gtest, zmq(弃用)及其他一些小的高性能开源代码,用于线程通讯。
项目源起于做汽车新能源相关工作时,希望能使用多个客户端(如终端)连接到一路CAN通讯上,可以支持局域网(比如可以方便工作电脑连接到CAN通讯测试专用电脑)。
要做的第一步,就是按照周立功can test工具里面的ControlCan.dll接口,实现一个同名DLL,用于替换原有ControlCan.dll,按照配置文件尝试读取远程can agent的IP地址及端口,can agent实现真正的CAN收发。这个时候,can test工具也可以作为一个客户端连接到can agent了。
这次改造,希望使用CMake来替换原有Visual Studio工程,项目结构更加简介清晰,没有那么多工程文件。由于更加习惯使用vscode remote ssh,所以干脆在Ubuntu下开发编译,支持跨系统编译及运行了(再测试调整下项目编译脚本,也可以支持ARM),编译操作也统一了。
项目目录结构
├── 3rd ├── asio_example ├── bin ├── build ├── can_agent ├── cmake ├── CMakeLists.txt ├── CMakePresets.json ├── config_file ├── doc ├── git_ver_src_in ├── include ├── libControlCAN ├── libzmq ├── README.md ├── test ├── test_asio_server └── test_zmq
libControlCan的实现
Boost库被编译成了静态库,libControlCan静态链接到boost,所以使用就不依赖boost了。libControlCan除了支持can test中原有的接口,通过桥接方式,导出了CAN及TCP两个类,支持分别与CAN设备直接通讯,及TCP通讯。
由于需要支持终端terminal,所以can agent及libControlCan收发数据采用文本,即把CAN帧转换为文本发送,收到后再解析回二进制。专门写了个高性能的template class转换二进制/文本,目前支持POD类型及char指针,好像也支持std::string,忘了懒得查源码了。
测试及性能
工程带有一个can agent,原本是作为测试libControlCAN用的,后来直接转正了。针对can agent,测试及优化了若干次。
笔记本CPU型号为AMD Ryzen 5 PRO 4650U,在每秒1000帧的情况下(10ms发送10帧本文帧),can agent及TCP client的CPU占用大致为2%,以后有空把实测结果补上吧(使用Ubuntu模拟CAN,及Windows使用周立功USBCANII连接CAN设备)。
最终优化之后,Ubuntu下使用gperftools测试can agent的主要时间分布:
?结语
创建了个C++群 768560256,欢迎加入讨论交流 C++ / Boost / template 等技术,也欢迎讨论其他技术 Linux / ARM,工业软件,职场交流。
|