AT組件是RT-Thread繼SAL之後的又一重磅發布,解決了不同網絡模塊AT命令之間的差異導致的重複開發的問題,大幅度簡化了MCU+無線模塊方案開發。
1 本文的目的和結構
1.1 本文的目的和背景
隨著 AT 命令的逐漸普及,越來越多的嵌入式產品上使用了 AT 命令,一般AT 命令作為主晶片和通訊模塊的協議接口,硬體接口一般為串口,這樣主控設備可以通過簡單的命令和硬體設計完成多種操作。
但是不同廠家的不同 AT 命令之間還是沒有完全的標準化,這直接提高了用戶使用的複雜性。對於 AT 命令的發送和接收以及數據的解析沒有統一的處理方式,並且在使用 AT 設備連接網絡時,只能通過命令完成簡單的設備連接和數據收發功能,很難做到對上層網絡應用接口的適配,不利於產品設備的開發。
為了方便用戶使用 AT 命令,並且適配不同廠家的不同設備, RT-Thread 提供了 AT 組件用於 AT 設備的連接和數據通訊。AT 組件的使用包括客戶端的和伺服器,對於嵌入式設備而言,更多的情況下設備使用 AT 組件作為客戶端連接伺服器設備,所以本文將為大家介紹 AT 組件中客戶端的原理、移植方式和主要功能使用,並介紹在客戶端的基礎上實現標準 BSD Socket API,使用 AT 命令進行網絡通訊。
1.2 本文的結構
本應用筆記將從以下幾個方面來介紹 RT-Thread AT 組件:
AT 組件介紹AT Client 配置與使用AT Socket 配置與使用
2 問題闡述
本應用筆記將圍繞下面幾個問題來介紹 RT-Thread AT 組件。
什麼是 AT 命令? AT 組件的主要功能是什麼?什麼是 AT Client,它與 AT Server 之間如何進行數據交互?如何使用 AT 命令實現標準 BSD Socket API,支持多種網絡軟體包和功能?想要解決這些問題,就要了解 RT-Thread AT 組件基本原理和功能使用方式。下面就從 RT-Thread AT 組件 AT Client 原理開始逐步介紹 配置方式、移植以及功能使用,使用戶快速上手 AT 組件的 AT Client 功能。
3 問題的解決
3.1 AT 命令簡介
AT 命令是一種應用於 AT 客戶端(AT Client)與 AT 伺服器(AT Server)間的設備連接與數據通信的方式。 其基本結構如下圖所示:
3.1.1AT 命令基本概念
一般 AT 命令由三個部分組成,分別是:前綴、主體和結束符。其中前綴由字符 AT 構成;主體由命令、參數和可能用到的數據組成;結束符一般為<CR><LF>("\r\n")。AT 功能的實現需要 AT Server 和 AT Client 兩個部分共同完成;AT Server 主要用於接收 AT Client 發送的命令,判斷接收的命令及參數格式,並下發對應的響應數據,或者主動下發數據;AT Client 主要用於發送命令、等待 AT Server 響應,並對 AT Server 響應數據或主動發送的數據進行解析處理,獲取相關信息。AT Client 和 AT Server 之間支持多種數據通訊的方式(UART、SPI等),目前最常用的是串口 UART 通訊方式。AT Client 接收到的數據類型分成兩種:響應數據和 URC 數據。響應數據: AT Client 發送命令之後收到的 AT Server 響應狀態和信息;URC 數據: AT Server 主動發送給 AT Client 的數據,一般出現在一些特殊的情況,比如 WIFI 連接斷開、TCP 接收數據等,這些情況往往需要用戶做出相應操作。3.1.2AT 組件介紹
AT 組件是基於 RT-Thread 系統的AT Server和AT Client的實現,組件完成 AT 命令的發送、命令格式及參數判斷、命令的響應、響應數據的接收、響應數據的解析、URC 數據處理等整個 AT 命令數據交互流程。
通過 AT 組件,設備可以作為 AT Client 使用串口連接其他設備完成數據的發送、接收與解析,可以作為 AT Server 讓其他設備甚至 PC 設備連接完成數據的響應,也可以在本地 shell 啟動 CLI 模式使設備同時支持 AT Server 和 AT Clinet 功能,該模式多用於設備開發調試。
3.2 AT Client 功能
本文將基於正點原子 STM32F4 探索者開發板和樂鑫 ESP8266 開發板,給出了 AT 組件中 AT Client 功能的配置、移植和使用方式。
下圖為本文使用的兩個開發板的底板圖,開發者可以使用 ESP8266 開發板或模組,若缺少正點原子 STM32F4 探索者開發板可使用其他帶額外串口的開發板代替,需確保開發板正常運行 RT-Thread 系統且串口使用正常即可:
AT 組件中 AT Client 主要完成 AT 命令的發送和響應數據的接收與解析。這裡我們使用正點原子 STM32F4 探索者開發板串口 2 作為 AT Client 連接 ESP8266 開發板的串口 2,ESP8266 開發板的串口 2 作為 AT Server,完成 AT Client 數據收發和解析的功能,下面就具體給出配置、移植和使用方式的介紹。
3.2.1AT Client 配置
1.下載RT-Thread 源碼
2.下載env 工具
3.開啟 env 工具,進入 rt-thread\bsp\stm32f4xx-HAL 目錄,在 env 命令行輸入 menuconfig 進入配置界面配置工程。
配置串口支持:勾選 Using UART1、Using UART2 選項,選擇晶片型號為 STM32F407ZG ,外部時鐘源為 8MHz。
配置 shell 設備:RT-Thread Kernel ---> Kernel Device Object ---> 修改 the device name for console 為uart1,配置 shell 默認設備為串口 1。
開啟 AT Client 功能:RT-Thread Components ---> Network ---> AT commands --> 開啟 AT DEBUG,開啟 AT Client 支持,設置 AT Client 使用設備為串口 2。
AT Client 配置選項介紹如下:
Enable debug log output:開啟調試日誌;Enable AT commands client:開啟 AT 客戶端;Client device name:配置 AT 客戶端設備的名稱;The maximum length of client data accepted:配置 AT 客戶端單次接收數據最大長度;Enable print RAW format AT command communication data: 配置開啟收發數據實時列印功能。4.配置完成,保存並退出配置選項,輸入命令 scons --target=mdk5 生成 keil 工程;
3.2.2AT Client 移植
AT Client 的移植主要是對 URC 數據的處理,實現獲取不同的 URC 數據時執行相應的操作函數的功能。如下函數為 AT Client 移植初始化函數,AT 組件源碼src/at_client.c文件中給出了移植初始化函數的弱函數定義,用戶可在項目中新建移植文件實現如下函數完成移植接口,也可以直接在源碼文件中修改弱函數完成移植接口。
int at_client_port_init(void);對於 URC 數據,AT 組件中已經提供完善的 URC 數據判斷和處理方式,下面給出 AT Client 移植具體示例,該示例主要展示at_client_port_init()移植函數中 URC 數據的具體處理方式,用戶可直接複製應用到自己的移植文件中,或者進行自定義修改實現功能,最終完成 AT Client 的移植。
/* URC 數據相關結構體定義 */struct at_urc{ const char *cmd_prefix; //URC 數據前綴 const char *cmd_suffix; //URC 數據後綴 void (*func)(const char *data, rt_size_t size); //URC 數據執行函數}; static void urc_func(const char *data, rt_size_t size){ /* 自定義 URC 數據處理方式 */ LOG_D("URC data : %.*s", size, data);}static struct at_urc urc_table[] = { {"ready", "\r\n", urc_func}, {"WIFI CONNECTED", "\r\n", urc_func}, {"WIFI DISCONNECT", "\r\n", urc_func},};int at_client_port_init(void){ /* 添加多個 URC 結構體至 URC 列表中,當接收到同時匹配 URC 前綴和後綴的數據,執行 URC 函數 */ at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0])); return RT_EOK;}3.2.3 AT Client 示例添加
下載AT Client 示例代碼,添加到打開的 keil 工程中,如下圖所示:
示例添加完成,就可以編譯、下載程序到開發板,之後打開 PC 上串口工具,這裡使用 xshell 工具,選擇正確的串口(配置串口參數為 115200-8-1-N、無流控),然後按下復位後就可以在串口 1 連接的終端上看到 RT-Thread 系統啟動日誌,並可以看到 AT Client 的啟動日誌,說明 AT Client 功能配置啟動成功,如下圖所示:
3.2.4AT Client 使用
1.AT Client 模式
該模式下正點原子 STM32F4 探索者開發板串口 2 作為 AT Client, ESP8266 開發板作為 AT Server,進行數據交互模式,在本地 shell 中輸入at_client_test命令,該 shell 命令用於發送 AT 命令到伺服器,並且接收和解析伺服器響應數據,如下圖所示過程:
2.AT Client CLI 模式
AT Client CLI 功能可以轉發本地 shell 輸入的數據到設備連接的 AT Server 串口設備上,並在本地 shell 上實時顯示 AT Client 串口接收到的數據。在本地 shell 中執行at client命令進入 AT Client CLI 模式即可進行數據的收發。通過 AT Client CLI 模式,用戶可以很方便的完成與 AT Server 的連接與調試,極大的提高開發效率。
下圖演示了 AT Client CLI 功能的使用和退出:
3.2.5AT Client 使用流程
本文使用的 AT Client 示例代碼演示了 AT Client 的整個使用流程,示例代碼完成 STM32F4 設備 AT 命令的發送並接收和解析 ESP8266 設備的響應數據。代碼的使用和平臺有關,開發者可以根據自己使用的平臺修改示例代碼並運行,主要修改命令的名稱和解析的方式。下面通過示例代碼介紹一下 AT Client 的具體使用流程:
#include <stdlib.h>#include <string.h>#include <rtthread.h>#include <at.h>/* AT+CIFSR Query local IP address and MAC */int at_client_test(int argc, char **argv){ at_response_t resp = RT_NULL; int result = 0; if (argc != 1) { LOG_E("at_client_test - AT client send commands to AT server."); return -1; } /* 創建響應結構體,設置最大支持響應數據長度為 256 字節 (最大響應長度用戶根據實際需求自定義),響應數據行數無限制,超時時間為 5 秒 */ resp = at_create_resp(256, 0, rt_tick_from_millisecond(5000)); if (resp == RT_NULL) { LOG_E("No memory for response structure!"); return -2; } /* 關閉回顯功能 */ at_exec_cmd(resp, "ATE0"); /* AT Client 發送查詢 IP 地址命令並接收 AT Server 響應,響應數據及信息存放在 resp 結構體中 */ result = at_exec_cmd(resp, "AT+CIFSR"); if (result != RT_EOK) { LOG_E("AT client send commands failed or return response error!"); goto __exit; } /* 按行數循環列印接收到的響應數據 */ { const char *line_buffer = RT_NULL; LOG_D("Response buffer"); for(rt_size_t line_num = 1; line_num <= resp->line_counts; line_num++) { if((line_buffer = at_resp_get_line(resp, line_num)) != RT_NULL) { LOG_D("line %d buffer : %s", line_num, line_buffer); } else { LOG_E("Parse line buffer error!"); } } } /* 按自定義表達式(sscanf 解析方式)解析數據,得到對應數據 */ { char resp_arg[AT_CMD_MAX_LEN] = { 0 }; /* 自定義數據解析表達式 ,用於解析兩雙引號之間字符串信息 */ const char * resp_expr = "%*[^\"]\"%[^\"]\""; LOG_D(" Parse arguments"); /* 解析響應數據中第一行數據,得到對應 IP 地址 */ if (at_resp_parse_line_args(resp, 1, resp_expr, resp_arg) == 1) { LOG_D("Station IP : %s", resp_arg); memset(resp_arg, 0x00, AT_CMD_MAX_LEN); } else { LOG_E("Parse error, current line buff : %s", at_resp_get_line(resp, 4)); } /* 解析響應數據中第二行數據,得到對應 MAC 地址 */ if (at_resp_parse_line_args(resp, 2, resp_expr, resp_arg) == 1) { LOG_D("Station MAC : %s", resp_arg); } else { LOG_E("Parse error, current line buff : %s", at_resp_get_line(resp, 5)); goto __exit; } }__exit: if(resp) { /* 刪除 resp 結構體 */ at_delete_resp(resp); } return result;}#ifdef FINSH_USING_MSH#include <finsh.h>/* 添加 AT Client 測試命令到 shell */MSH_CMD_EXPORT(at_client_test, AT client send cmd and get response);#endifAT Client 使用流程大致如下:at_create_resp() 創建響應結構體 ---> at_exec_cmd() 發送命令並接收響應 ---> at_resp_get_line()/at_resp_parse_line_args() 列印或解析響應數據 ---> at_delete_resp() 刪除響應結構體。at_exec_cmd() 函數完成對傳入 AT 命令的發送和響應數據的接收,響應數據以按行的形式存放與結構體中,便於數據按行列印或及解析。列印或解析數據時對於不同的命令的響應數據有不同的數據解析方式,需要自定義數據解析的表達式,這要求開發者提前知道發送命令的具體響應結構,可以通過查看設備 AT 命令手冊了解。
3.3 AT Socket 功能(進階)
為了方便開發者使用 AT 組件進行網絡相關操作,降低 RT-Thread 系統對單獨協議棧網絡連接的依賴,RT-Thread 系統在 AT 組件和 SAL 組件的基礎上推出了 AT Socket 功能。
AT Socket 功能是建立在 AT Client 功能基礎上,主要作用是使用 AT 命令完成設備連接網絡並進行數據通訊,AT Socket 功能提供的網絡接口支持標準的 BSD Socket API,並通過 SAL 組件的接口抽象,實現接口統一化。
AT Socket 功能使設備無需進行網絡連接使用串口連接 AT 伺服器的方式完成設備聯網,簡化了設備開發的軟硬體設計,方便開發者開發。此外,不同於傳統的軟體網絡協議棧,AT Socket 網絡功能的運行與實現主要是在串口連接的 AT Server 設備上完成,根據不同的 AT Server 設備,可同時支持 5-6 個 socket,這樣極大了降低了 AT Client 設備上 MCU 資源佔用,提高 MCU 工作效率,確保數據通訊的質量和硬體的資源的合理分配。AT Socket 功能佔用最少資源體積約為 20K ROM 、 3K RAM(支持 5 個 Socket)。
AT Socket 功能對於不同的 AT 設備需要完成移植適配過程,AT Socket 的移植通過at_device 軟體包的形式給出,目前支持設備有:ESP32、ESP8266、 M26 等。下面主要通過 ESP8266 設備,對 AT Socket 功能的配置和使用進行介紹。
3.3.1AT Socket 配置
AT Socket 功能的使用依賴於如下幾個組件:
AT 組件,AT Socket 功能基於 AT Client 功能的實現;SAL 組件,SAL 組件主要是 AT Socket 接口的抽象,實現標準 BSD Socket API;at_device 軟體包,針對不同設備的 AT Socket 移植和示例文件,以軟體包的形式給出;下面主要介紹 env 中配置 AT Socket 功能的整個流程:
1.開啟 env 工具,進入 rt-thread\bsp\stm32f4xx-HAL 目錄,在 env 命令行輸入 menuconfig 進入配置界面配置工程。
2.開啟 AT Socket: RT-Thread Components ---> Network ---> AT commands ---> Provide similar BSD Socket API by AT 開啟 AT Socket 支持。
3.AT Socket 功能配置成功後,需要開啟 at_device 軟體包,at_device 軟體包中作為 AT Socket 功能的移植需要配置使用的 AT Client 設備型號,確保正確運行:RT-Thread online packages ---> IoT - internet of things ---> 開啟AT DEVICE 軟體包支持,配置 AT Socket device modules 為 ESP8266 設備,配置 wifi ssid 和 wifi password 用於設備聯網。
4.之後需要開啟 SAL 組件支持,在 SAL 組件中需要配置 AT Socket 功能支持:RT-Thread Components ---> Network ---> Socket abstraction laye ---> 開啟 SAL 組件功能支持,開啟SAL_USING_POSIX支持,支持使用 read/write、poll/select 等文件系統接口函數。
5.配置完成,保存並退出配置選項,輸入命令 scons --target=mdk5 生成 keil 工程。
6.打開 keil 工程,編譯、下載代碼到開發板中。
7.打開 PC 上串口工具 xshell,配置打開串口(配置串口參數為 115200-8-1-N、無流控),然後按下復位後就可以在串口 1 連接的終端上看到 RT-Thread 系統啟動日誌,並可以看到 AT Client 的啟動日誌、SAL 的啟動日誌且設備自動連接網絡成功,說明 AT Socket 功能初始化成功,如下圖所示。
3.3.2AT Socket 使用
1.網絡連接測試
AT Socket 功能提供at_ping命令用於測試設備網絡連接環境,並且測試 AT Socket 功能啟動是否正常,at_ping 命令原理是通過 AT 命令發送請求到伺服器,伺服器響應數據,客戶端解析 ping 數據並顯示。如下圖所示,命令設備網絡連接成功,AT Socket 組件運行成功:
2.MQTT 組件示例測試
AT Socket 功能完成設備通過串口 AT 命令進行網絡數據通訊,設備可以通過 AT Socket 功能啟動 MQTT 協議並運行 MQTT 示例代碼,具體配置步驟和示例使用方式如下:
AT Socket 功能開啟的基礎上,配置下載 MQTT 組件包及示例代碼,具體配置方式:RT-Thread online packages ---> IOT - internet of things ---> 開啟 paho MQTT 組件包,配置開啟 MQTT 示例代碼。
配置完成,保存並退出配置選項,scons 重新生成工程,編譯下載代碼到開發板中。打開串口工具,系統啟動成功,輸入mq_start命令啟動 MQTT 協議,啟動完成之後輸入mq_pub mqtt_test_data命令,用於向固定的 MQTT Topic 發送數據,同時 MQTT 伺服器會立刻向該 Topic 發送同樣數據,MQTT 示例測試完成,如下圖所示:
上述展示了正點原子 STM32F4 設備在未連接網絡的情況下使用 AT Socket 功能運行 MQTT 網絡示例,實現了 AT Socket 網絡數據收發的功能,目前 AT Socket 功能只支持設備作為網絡客戶端連接伺服器,這也符合嵌入式設備多用於客戶端設備的特性。AT Socket 目前已經支持多種網絡相關組軟體包和功能,如下所示:
MQTT 軟體包webclient 軟體包mbedtls 軟體包onenet 軟體包NTP 時間查詢功能iperf 網絡測試功能at_ping 網絡測試功能更多 AT 組件以及 AT Socket 功能的使用請參考《RT-Thread編程手冊》中AT 組件介紹章節。
4 常見問題
1.設備啟動時,出現"xxxx is not implement."錯誤怎麼辦?
該錯誤提示由於設備 AT Client 功能開啟後未完成移植功能,可以查看上述 AT Client 功能的移植方式完成設備移植。2.開啟 AT 命令收發數據實時列印功能,shell 上日誌顯示錯誤怎麼辦?
提高 shell 對應串口設備波特率為 921600,提高串口列印速度,防止數據量過大時列印顯示錯誤。3.AT Socket 功能啟動時,編譯提示The AT socket device is not selected, please select it through the env menuconfig怎麼辦?