加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

嵌入式Linux 對(duì)接星閃,用C++設(shè)計(jì)一個(gè)通用的AT指令解析器

10/21 10:30
2521
閱讀需 6 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

我是老溫,一名熱愛(ài)學(xué)習(xí)的嵌入式工程師關(guān)注我,一起變得更加優(yōu)秀!

為了可以讓嵌入式Linux產(chǎn)品方便地對(duì)接AT指令通信模組,我們?cè)谠O(shè)計(jì)嵌入式應(yīng)用程序的時(shí)候,可以用 C/C++ 設(shè)計(jì)一個(gè)通用的AT指令解析器,這個(gè)AT指令解析器具有以下特性:

1、使用UART串口進(jìn)行硬件連接通信。

2、AT指令容易擴(kuò)展,提供處理函數(shù)的注冊(cè)接口。

3、通過(guò)隊(duì)列進(jìn)行指令管理,發(fā)送、接收、處理、多線(xiàn)程同步互斥。

4、具有超時(shí)重發(fā)機(jī)制,可設(shè)置超時(shí)時(shí)間與重發(fā)次數(shù)。

5、面向?qū)ο笤O(shè)計(jì),高內(nèi)聚,容易移植使用。

前段時(shí)間,小熊派官方發(fā)布了星閃核心板 H2821-Pico 的AT指令固件,并且支持 1 對(duì) 8 組網(wǎng)通信,有了豐富的AT指令集單片機(jī)或者其他MPU芯片就可以很容易地通過(guò)星閃網(wǎng)絡(luò)進(jìn)行互聯(lián)通信。

關(guān)于星閃 AT 固件的詳情,可以查看之前的文章進(jìn)行回顧:開(kāi)啟星閃互聯(lián),組建一對(duì)多小型網(wǎng)絡(luò)!

這個(gè)通用的 AT 指令解析器主要由以下兩部分組成:串口通信模塊 serial_port,AT指令解析器模塊 at_cmd_paeser,以下是解析器的具體設(shè)計(jì)過(guò)程。

1、頭文件 serial_port.h 主要提供底層串口硬件的操作接口,包括配置串口,打開(kāi)或關(guān)閉串口,數(shù)據(jù)發(fā)送和接口,以及判斷串口是否已經(jīng)打開(kāi),具體代碼如下圖所示。

2、源文件 serial_port.cpp 主要是實(shí)現(xiàn)底層串口硬件的操作邏輯,相關(guān)的操作都通過(guò) termios 提供的接口進(jìn)行實(shí)現(xiàn),串口硬件在配置或者數(shù)據(jù)收發(fā)時(shí),要先判斷 is_port_opened 是否置位,串口成功打開(kāi)后才能進(jìn)行相關(guān)的操作。

3、頭文件 at_cmd_parser.h 主要是把AT 指令解析器抽象成一個(gè)類(lèi) class at_cmd_parser,這個(gè)類(lèi)提供了AT指令和處理函數(shù)的注冊(cè)接口,解析器的啟停,AT指令發(fā)送,三個(gè)線(xiàn)程,數(shù)據(jù)收發(fā)隊(duì)列,互斥鎖與條件變量,等等。

4、源文件 at_cmd_parser.cpp 主要是對(duì)解析器類(lèi)的接口實(shí)現(xiàn),構(gòu)造函數(shù)主要是打開(kāi)和配置串口,start() 和 stop() 函數(shù)主要是啟動(dòng)和停止三大線(xiàn)程,代碼實(shí)現(xiàn)如下圖所示。

5、函數(shù) add_command_handler() 主要是把AT指令和處理函數(shù)進(jìn)行注冊(cè)綁定,把處理函數(shù)用一個(gè)哈希表 command_handler 進(jìn)行管理,AT指令的字符串是鍵key,具體的處理函數(shù)是健對(duì)應(yīng)的值value。

6、調(diào)用 send_at_cmd() 函數(shù)發(fā)送 AT 指令,在這個(gè)函數(shù)里面,主要是把待發(fā)送的AT指令放入隊(duì)列 send_queue,入隊(duì)列采用互斥鎖保護(hù),然后調(diào)用 send_cv 事件喚醒發(fā)送線(xiàn)程 send_thread() 進(jìn)行指令發(fā)送。

7、在發(fā)送線(xiàn)程 send_thread() 里面,先獲取 send_mtx 互斥鎖,然后等待send_cv信號(hào)的到達(dá),使用for循環(huán)不斷從send_queue里面取出 struct at_command 類(lèi)型的數(shù)據(jù),然后調(diào)用 serial.send_data() 進(jìn)行發(fā)送。

在發(fā)送AT指令之前,先記錄發(fā)送前的時(shí)間點(diǎn),超過(guò)一定時(shí)間之后還沒(méi)有收到當(dāng)前AT指令的正確回復(fù),則會(huì)繼續(xù)重新發(fā)送并記錄重發(fā)次數(shù),達(dá)到最大重發(fā)次數(shù)后,丟棄該條AT指令。

8、在數(shù)據(jù)接收線(xiàn)程 receiving_thread() 里面,每隔100ms輪詢(xún)讀取串口緩沖區(qū),如果讀取到數(shù)據(jù),先嘗試獲取互斥鎖,并把數(shù)據(jù)存入 recv_queue 接收隊(duì)列,然后發(fā)送 recv_cv 事件喚醒數(shù)據(jù)處理線(xiàn)程 processing_thread()

9、在數(shù)據(jù)處理線(xiàn)程 proessing_thread() 里面,獲取數(shù)據(jù)接收互斥鎖,然后等待收到 recv_cv 事件后,從數(shù)據(jù)接收隊(duì)列 revv_queue 里面取出數(shù)據(jù),不斷從 command_handler 哈希表里進(jìn)行鍵值匹配,執(zhí)行對(duì)應(yīng)的注冊(cè)函數(shù),執(zhí)行成功后,把該條AT指令從發(fā)送隊(duì)列里面刪除。

10、把星閃核心板 Bearpi-Pico H2821 通過(guò)USB接口連接到Linux開(kāi)發(fā)板上面,開(kāi)發(fā)板的內(nèi)核需要支持CH34x驅(qū)動(dòng),會(huì)在/dev 目錄下生成 ttyUSB0 節(jié)點(diǎn),我們可以做一個(gè)簡(jiǎn)單的界面來(lái)進(jìn)行指令發(fā)送,點(diǎn)擊【指令:AT】按鈕,可以看到調(diào)試終端輸出打印信息,AT指令解析器可以在開(kāi)發(fā)板上面順利運(yùn)行。

下一步,我們將會(huì)基于這個(gè)通用的 AT 指令解析器,把星閃核心板BearPi-Pico H2821的 AT 指令都集成到一個(gè)模塊組件里面,通過(guò)這個(gè)組件,就可以讓嵌入式 Linux 開(kāi)發(fā)板輕松獲得星閃通信功能。

 

相關(guān)推薦

電子產(chǎn)業(yè)圖譜