搜索
bottom↓
回复: 12

最近寫了個 CDIPC 實時進程間通訊庫(類似 ROS)

[复制链接]

出615入1076汤圆

发表于 2018-7-20 15:07:15 | 显示全部楼层 |阅读模式
本帖最后由 dukelec 于 2018-7-20 15:10 编辑

CD 系列相繼誕生了一系列作品,包括最早的 RS485 對等傳輸的協議 —— CDBUS、其上層協議 —— CDNET,模組免焊接裝配方式 —— CDBITE.

今天要介紹的是一個進程間通訊的庫 —— CDIPC, 其中還包含一個解析命令行參數的庫 —— CDARGS.

本來想找一個二進制版本的 JSON 序列化庫,譬如 BSON 這些,但都嫌實時性不夠、相關的解析庫龐大且複雜,準備自己再寫一個 CDSON, 不過暫時沒時間還是算了。

爲何 CDIPC
很多年前,入行機器人領域的前夕,就接觸到 ROS 這款機器人操作系統,它本質是一個 IPC 的通訊庫,然後很多第三方的程序使用其通訊, 因此構建成爲了一個系統。

ROS 的通訊有兩個核心:topic 和 service, 其中 topic 又是重中之重,它是 M-to-N 多對多的通訊方式,不同接收者收到相同的數據。 而 service 是 M-to-1 的 RPC, 類似遠程調用函數然後返回結果。

使用 IPC 的好處是便於模塊化編程,將一個大的系統劃分多個小模塊,有助於降低任務難度,且可以最大程度的復用已有模塊,而無需修改代碼。 同時,各模塊可以用不同的編程語言和技術來實現,譬如講究實時性的地方用 C/C++ 來寫,而界面部分可以用 Python、Javascript、HTML 等實現, 這樣開發效率遠遠比統一語言和庫要高的多。不同模塊是獨立的程序,可以隔離錯誤,否則類似 C/C++ 語言中用錯指針導致 bug 很難排查(除非是當時就報錯), 而且,不重要的模組出錯退出(譬如 UI 展示),不會影響到系統運作,降低事故風險。

然而,ROS 的通訊不是實時的,且十分臃腫,並不是很適合用做機器人控制。後來找了很久,找到一個實時的面向機器人的實時 IPC 庫, 叫做 ACH, 主頁:http://www.golems.org/projects/ach.html

然而 ACH 同樣不好用,首先,它不支持 service 功能,其次,它不是很穩定,譬如某個模塊程序意外退出,會導致 mutex 死鎖 (其實是 glibc 的 bug: https://sourceware.org/bugzilla/show_bug.cgi?id=21422 ). 雖然 ACH 使用的是共享內存交換數據,但是發佈數據和收取數據都要經過 memcpy 內存拷貝,很低效。

而且,無論是 ROS 還是 ACH, 它們的 topic 都不支持我想要的一款功能:可以分別爲不同接收者配置一個參數 —— 是否允許丟棄數據。 ROS 和 ACH 的 topic 所支持的模式都是發佈者可以不受限制的發佈數據,如果接收方處理不過來的話,最老的數據便會丟失。

然而有些場合我們希望當接收者處理不過來的時候,發送者予以等待。 這種情況,如果使用 ROS, 我們需要單獨再建一個 topic 或 service 讓發佈者查詢接收者是否過忙,會很麻煩。

ROS 還有一個不方便的地方是,只有 topic 支持錄製保存數據用於調試,而 service 卻不支持。

爲了解決以上種種問題,所以,我創建了 CDIPC 這個開源項目。

CDIPC 特點
1. 進程間交換數據通過內存直接共享,且無需拷貝。
1. 因爲實時任務不允許動態申請內存,所以 CDIPC 是創建時提前指定好最大支持的發佈和接收者數量、數據塊大小和數量等信息。
3. 支持 topic 和 service 功能,且都支持錄製調試。
4. 可以選擇是否允許丟棄數據,不同的接收者可以有不同設置,譬如爲核心接收者設置不允許丟棄數據,而爲錄製程序對應的接收者設置允許丟棄數據,因爲不能因爲調試這個輔助功能影響到核心功能的安全。
5. 和 ACH 一樣,不規定通訊數據格式,如有需要,用戶可以自行選擇第三方序列化的庫。
6. 因爲使用的是 PI-futex 做 mutex 和 cond, 效率非常高,且內核驅動可以通過 CDIPC 與用戶進程直接交換數據。(之前爲實時內核 PREEMT-RT 寫驅動的時候,一直在想用什麼接口好,/dev 接口、unix socket、sysfs 接口貌似都很低效,中間環節太多,實時性難以保障)
7. 已經通過 swig 提供了 Python 語言的接口,其它語言想訪問 CDIPC 就很簡單了,同樣的 swig 配置,改下編譯參數就可以。
8. 可以通過配套的小工具,把 CDIPC 導出爲 WebSocket 等接口,方便瀏覽器端程序直接訪問 CDIPC.
9. 就連 windows 都支持 futex, 所以將來可能可以移植到不同系統(然而支持實時的桌面系統只有 Linux)。

CDIPC 核心結構如下,topic 和 service 共用同一套,灰色部分是 service 僅有。



具體描述還請移步到項目頁面:https://github.com/dukelec/cdipc

配套有一個命令行工具,可以方便的用來測試 CDIPC, 和 dump 指定 topic 和 service 數據狀態。

CDARGS
最後提一下這個命令行參數解析庫,因爲使用 CDIPC 後,我準備再寫一個圖形化的工具(之前基於 ROS 寫過一款),方便配置模組、連線模組、監控模組運行狀態(譬如視覺算法模組可以實時顯示當前處理的畫面),連線信息通過命令行參數傳遞給不同的模塊程序,會涉及到動態參數,譬如我們希望某個模塊可以支持動態數量的輸入信號。

用法很簡單,例如:

  1. cd_args_t ca;
  2. cd_args_parse(&ca, argc, argv);

  3. // if --id not found, use default value "0"
  4. // --id 3, --id=3 are the same
  5. int id = atol(cd_arg_get_def(&ca, "--id", "0"));

  6. // -h is short version for --help, return not NULL if found of any
  7. // return NULL if arg not found, return empty string if arg has no value
  8. if (cd_arg_get2(&ca, "--help", "-h")) {
  9.     printf("%s", usage_dump);
  10.     exit(0);
  11. }

  12. // we could call cd_arg_get_left in a loop to report all left args
  13. const char *left = cd_arg_get_left(&ca);
  14. if (left) {
  15.     df_error("unknown arg: %s\n", left);
  16.     printf("%s", usage_dump);
  17.     exit(-1);
  18. }
复制代码

CDARGS 同時也有提供 Python 的版本,全部包含在 CDIPC 庫中。

造這個輪子之前,我同樣是苦苦找尋了很久,別人寫的都超複雜,且不滿足我的動態需求。。。

[原文來自我的博客:http://blog.dukelec.com/cdipc-zh ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)

出0入0汤圆

发表于 2018-7-20 17:00:45 | 显示全部楼层
楼主的想法和经历的确是很精彩,我觉得ROS的另外一个好处就是社区维护的比较好,有众多的开源模块可以直接参考甚至使用。也祝愿楼主这个开源项目能够顺利推进,早日出成果。

出0入0汤圆

发表于 2019-8-7 12:02:19 | 显示全部楼层
学习一下,跟着楼主学到了很多。

出0入0汤圆

发表于 2019-8-23 23:31:49 | 显示全部楼层
楼主这个框架用在什么场景下呢?是以守护进程运行,然后我自己写的不同的应用程序通过 cdipc 来通信吗?
感觉非常适合传感器采集然后集中处理这种应用。

出615入1076汤圆

 楼主| 发表于 2019-8-25 17:50:30 | 显示全部楼层
meirenai 发表于 2019-8-23 23:31
楼主这个框架用在什么场景下呢?是以守护进程运行,然后我自己写的不同的应用程序通过 cdipc 来通信吗?
感 ...

不需要守護進程,相當於一個存放在內存中的文件,相關進程各自按照規則讀寫該文件而已。

適合實時性高的應用,和希望減少數據拷貝的應用。

出0入0汤圆

发表于 2021-9-13 20:03:10 | 显示全部楼层
请问楼主有PCIe转CAN 的模块吗?或者此类的开发计划

出0入0汤圆

发表于 2021-9-14 08:51:30 | 显示全部楼层
楼主大能

出615入1076汤圆

 楼主| 发表于 2021-9-14 11:09:04 | 显示全部楼层
阿豪博士 发表于 2021-9-13 20:03
请问楼主有PCIe转CAN 的模块吗?或者此类的开发计划

暫時沒有搞 can 的意願,除非哪天被迫用 can,而且需要上 pcie 的 fpga

出0入42汤圆

发表于 2022-4-1 21:55:30 | 显示全部楼层
dukelec 发表于 2021-9-14 11:09
暫時沒有搞 can 的意願,除非哪天被迫用 can,而且需要上 pcie 的 fpga
(引用自8楼)

楼主,您好,最近封闭在家,在学习您的这个库,但是有个问题我不是特别理解,两个进程之间怎么联系上的呢?如果是socket通信,我还知道双方知道端口号就可以了,但是这里没有看到两个进程之间建立联系的地方,能指点一下吗,或者给个最简单的两个进程通信的例子可以吗,非常感谢!

出0入42汤圆

发表于 2022-4-1 23:49:11 来自手机 | 显示全部楼层
您好,我看到那个测试程序了,我再理解一下,还是非常感谢您的分享

出615入1076汤圆

 楼主| 发表于 2022-4-2 00:39:55 来自手机 | 显示全部楼层
我是一个大白菜 发表于 2022-4-1 21:55
楼主,您好,最近封闭在家,在学习您的这个库,但是有个问题我不是特别理解,两个进程之间怎么联系上的呢 ...
(引用自9楼)

共享內存
兩間程序可以訪問同一段內存數據,通過該共享內存傳遞數據

出0入0汤圆

发表于 2022-4-2 00:41:03 来自手机 | 显示全部楼层
好东西,看上去类似openwrt的ubus

出0入42汤圆

发表于 2022-4-2 09:58:26 来自手机 | 显示全部楼层
dukelec 发表于 2022-4-2 00:39
共享內存
兩間程序可以訪問同一段內存數據,通過該共享內存傳遞數據

(引用自11楼)


谢谢您的回复,看到这部分了,有些函数不熟悉,一边看,一边查资料,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-16 19:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表