1、回呼函式
關于回呼函式,在之前的文章《回呼函式》已經詳解講解過了,這個文章不再講解,不太懂的同學請看之前的文章《回呼函式》,在之前講解回呼函式中就使用串口作為示例,使用回呼函式可以方便封裝通訊庫,芯片/模塊廠家的SDK和部分開源庫經常這樣做,這樣可以實作模塊間的解耦,模塊化編程,
這篇文章主要講解回呼函式在命令決議中的應用,一般命令中都會有功能碼,用于區分這條命令到底執行的什么動作,命令字后面的資料的意義,在這種場景中,使用回呼函式是一個不錯的選擇,
2、經典寫法
在命令決議中,經典的寫法使用switch case陳述句,這種寫法很經典,也很基礎,即使是剛學C語言的小白也能看懂,
void poll_task(rt_uint8_t cmd, rt_uint8_t *msg, uint8_t len){ switch (cmd){ case cmd1: func1(); break; case cmd2: func2(); break; case cmd3: func3(); break; case cmd4: func4(); break; default: default_func(); break; } }
他的缺點是,如果在增加一個功能碼需要修改poll_task函式,增加case陳述句,如果要統計功能碼的個數,只能手動數,
使用回呼函式和功能碼系結的方式會更加方便一些,結構更加清晰,
3、回呼函式
功能碼和回呼函式系結方式
typedef struct { rt_uint8_t CMD; rt_uint8_t (*callback_func)(rt_uint8_t cmd, rt_uint8_t *msg, uint8_t len); } _FUNCCALLBACK; _FUNCCALLBACK callback_list[]= { { cmd1,func_callback1}, { cmd2,func_callback2}, { cmd3,func_callback3}, { cmd4,func_callback41}, ... }; void poll_task(rt_uint8_t cmd, rt_uint8_t *msg, uint8_t len){ int cmd_indexmax = sizeof(callback_list) / sizeof(_FUNCCALLBACK); int cmd_index = 0; for (cmd_index = 0; cmd_index < cmd_indexmax; cmd_index++) { if (callback_list[cmd_index].CMD == cmd) { if(callback_list[cmd_index]) { /* 處理邏輯 */ callback_list[cmd_index].callback_func(cmd,msg,len); } } } }
這種方式優點是:提供了一個“模板”,加入我們增加一個功能碼,我們只需要在結構體中新增命令和回呼函式即可,主運行邏輯不需要去修改,大大降低代碼的可維護性,
比起經典的方法,將功能碼和回呼函式系結的方式,代碼更模塊化,起到代碼結構將解耦的目的,由于增加一個功能碼主邏輯沒有修改,這樣就不會影響到其他功能碼執行函式,
更進一步,將命令決議放入一個佇列,再用這種方法決議命令,這樣就能封裝成一個通用的模塊,即使更換單片機型號,也能很快的移植過去,并且保證代碼穩定運行,
點擊查看本文所在的專輯:C語言進階專輯
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/470539.html
標籤:其他
上一篇:痞子衡嵌入式:淺談i.MXRT1xxx系列MCU時鐘相關功能引腳的作用
下一篇:我想把一個串列放在一個字串上
