久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

博客專欄

EEPW首頁 > 博客 > 聯合體原來是這么用的!

聯合體原來是這么用的!

發布人:魚鷹談單片機 時間:2022-06-22 來源:工程師 發布文章

不管是線程間、還是設備間通信,都需制定一個通信協議,規定數據的格式、內容等。

線程間通信因為在芯片內部傳輸,基本可以排除數據干擾導致的異常,所以通常會設計的比較簡單,但是設備間的通信(不管是無線還是有線)就會復雜一些,一般都包含幀頭、校驗位之類的,因此魚鷹在一篇文章中介紹了一個基本的串口協議框架《如何寫一個健壯且高效的串口接收程序?》。

因為當時剛畢業沒多久,所以雖然從大的方向介紹了基本協議內容,但在細節處理上還不夠好,比如可維護性、可讀性等方面。

后來,魚鷹在學習開源的飛控源碼時,發現里面使用了聯合體+結構體的方式,大大提高了程序的可維護性和可讀性。

比如,我們的協議中有這樣三條命令,心跳包、獲取固件版本號、獲取序列號。

初級版本:

直接使用基本的類型聲明所需要的數據結構。

uint8_t heartbeat;char version[6]; 
// "2.0.4"
char sn[7]; // "654321"

一般這樣寫的,大概率是工作一兩年,當然也不排除工作好多年的也可能這樣寫。看似簡單,但可維護性、可讀性都非常差。

中級版本:

使用結構體的形式聲明各種消息內容。

typedef struct {  uint8_t heart_nbr;}msg_heartbeat_def;
typedef struct {  char version[sizeof("2.0.4") + 1];}msg_version_def;
typedef struct {  char sn[sizeof("123456") + 1]; }msg_serial_number_def;

這種方式,一般是工作兩三年以上的,開始使用結構體容納數據內容,可擴展性比較強,可維護性、可讀性也不錯。比如假設后面版本號這個消息里面希望同時獲取編譯時間,那直接在里面增加即可。

typedef struct {  char version[sizeof("2.0.4") + 1];   
char compile_time[sizeof("2022-12-12, 12:00:00") + 1]; 
}msg_version_def;

如果其它代碼寫的比較好,甚至不需要多大改動,即可完成一次擴展。

高級版本:

在中級版本的基礎上,使用聯合體容納前面的所有消息類型。

typedef union {  msg_heartbeat_def      heartbeat;     // 心跳包  msg_version_def        version_nbr;   // 版本號  msg_serial_number_def  serial_number; // 產品序列號}msg_data_def;

當你需要發送消息的時候,可以這樣發送:


typedef enum {  MSG_ID_HEARTBEAT,  MSG_ID_VERSION,  MSG_ID_SN,}msg_id_def;
void msg_uart_send(msg_id_def id, msg_data_def *msg_data, uint32_t size){// 這里加入幀頭、消息ID、校驗之類的再發送出去#define FRAME_FIX_SIZE_MIN  10  // 組成一幀數據的最小空間,包含幀頭之類的  uint8_t send_buff[sizeof(msg_data_def) + FRAME_FIX_SIZE_MIN]; }void msg_send_vesion(void){   msg_data_def data;    strcpy(data.version_nbr, "1.0.1");         msg_uart_send(MSG_ID_VERSION, &data, sizeof(data.version_nbr));}

因為現在大部分 IDE 都有代碼提示功能,所以當你需要發送數據的時候,可以根據提示選擇你需要的消息進行發送,相當方便快捷,也不容易出錯。


接收消息時,可以使用 switch(id) 之類的解析對應數據。


在這個例子中,我們利用聯合體的特性,將所有消息類型集成在一起,這樣當你需要發送一條消息時,很容易就能找到想要的數據類型。并且在空間占用上也是非常合理的。當需要開辟緩存容納數據幀格式,利用了聯合體空間占用特性(找最大),這樣你開辟的空間一定是剛剛好,不多也不少,節省了空間使用。


所以,當我們需要傳輸一類消息,但這些消息不會同時存在時,不如使用聯合體吧。


*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



關鍵詞: 單片機

相關推薦

技術專區

關閉