AT指令的一種解析想法
最近一直在忙著做NBlot模組,話說部落格也好久沒有更新了,最近整理下思路,
做下總結,權當是一片部落格吧。
AT指令大家很熟悉了,這裡不再做介紹(不熟悉的,請參考《GSM Rec.07.07標準AT命令》)。
一個命令型別最多分為四類:
1、設定型別,CMD=設定引數,回覆OK或者ERROR; 可用通用模式解析
2、讀取型別,CMD?讀取引數當前值,回覆+CMD:引數列表;解析返回字串,可能做命令轉變
3、測試型別,CMD=?讀取預設引數值和可設定範圍; 解析返回字串,可能做命令轉變,也有可能返回OK
4、執行型別,CMD 讀取不可設定引數值; 解析返回字串,可能做命令轉變
這裡解析主要運用到訊息地圖的方法,同時為了減小地圖的大小,每個命令位元組不具體細分是那個
命令類別,交給具體的命令解析函式去處理。如下:
//! 訊息地圖 const static msg_t c_tMSGMap[] = { {"AT", JZQ_AT_CMD_AT}, {"ATE0", JZQ_AT_CMD_ATE0}, {"AT$MYGMR", JZQ_AT_CMD_MYGMR}, {"AT$MYTYPE", JZQ_AT_CMD_MYTYPE}, {"ATI", JZQ_AT_CMD_ATI}, {"AT$MYCCID", JZQ_AT_CMD_MYCCID}, {"AT+CSQ", JZQ_AT_CMD_CSQ}, {"AT+CREG", JZQ_AT_CMD_CREG}, {"AT+CIMI", JZQ_AT_CMD_CIMI}, };
在具體的命令解析函式裡面,都次都可以指定NBlot模組的資料返回解析函式,做到每個命令和命令
的回覆處理函式一 一對應。如下:
傳送給NBlot模組命令:
user_nblot_send(get_byte_pipe_buffer(&tBytePipe),get_byte_pipe_num(&tBytePipe));
s_tNblotAppBuffer.pRxCallBack = JZQ_AT_CMD_MYNETWRITE_ACK;
NBlot模組的命令接收解析:
switch(s_tState){ case FSM_NBLOT_PROTOCOL_START: s_tState = FSM_NBLOT_PROTOCOL_WAIT_DATA; s_tNBlotAppBuffer.hwBufferSize = 0; //break; case FSM_NBLOT_PROTOCOL_WAIT_DATA: if(nblot_rx_buffer_is_empty()){ break; } s_tState = FSM_NBLOT_PROTOCOL_REV_FRAME; //break; case FSM_NBLOT_PROTOCOL_REV_FRAME: tFsmRt = nblot_protocol_revice_frame(); if(fsm_rt_cpl == tFsmRt|| fsm_rt_buffer_full == tFsmRt){ s_tState = FSM_NBLOT_PROTOCOL_HANDLE; }else if(fsm_rt_err == tFsmRt){ RESET_FSM_NBLOT_PROTOCOL(); return fsm_rt_err; } break; case FSM_NBLOT_PROTOCOL_HANDLE: if(NULL != s_ptRxCallBack){ s_ptRxCallBack(s_tNBlotAppBuffer.chBuffer,s_tNBlotAppBuffer.hwBufferSize); } RESET_FSM_NBLOT_PROTOCOL(); return fsm_rt_cpl; default: FSM_DEFAULT_ACTION(); }
至此一個大體的AT命令解析架構介紹完畢了,但是這個架構會有一個問題,
就是如果僅僅考慮問答式命令形式,這個架構再加一個超時無效處理的維護
執行緒就可以(維護執行緒就幹一件事情,傳送命令後,啟動維護執行緒,設定超
時命令,如果在設定的超時時間內回覆,則通過傳送命令時候指定的處理函
數解析,如果超時了,就把指標清NULL,同時傳送超時訊息)。如果還要考
慮主動上報,那麼上面的架構就需要在(每個)處理函式裡面加入主動上報
的處理邏輯,否則邏輯上就不對。這樣就會產生很多“髒程式碼”,處理方法是利
用行為繼承,在FSM_NBLOT_PROTOCOL_HANDLE前面增加一個DEFULT_HANDLE
處理,把一些通用或者主動上報的(每個命令幀都需要考慮的情況)打包成一個處理函式。
到目前為止,AT指令解析,基本講完了,說些題外話:
1、下行資料可能要考慮拼包問題,因為在測試過程中發現主站下發一個APDU,在模組
端會被分為兩個socket包,並且時間間隔還很長(目前監控到最長30S);這裡有一
個問題,如果考慮拼包,那麼就和協議關聯了。
2、socket會自己斷開,一定要有重建機制;
2018.10.23
前幾天和一位老工程師交流這個AT指令解析方法,有一些心得,記錄下,也算是一種
思想上的提高。
這個解析方法有個確實,就是當指令閱讀,訊息地圖越大,檢索時間越長。如果系統
要求這個檢索時間和地圖大小無關,時間是“確定”的,怎麼解決?
首先我們就想到是什麼?什麼情況下檢索時間和資料表大小無關?我們是不是想到了
陣列下標,查表的方法。沒錯,查表的時間確定,並且和表的大小無關。那麼我們怎麼進行
查表呢?首先我們需要有一個格式化演算法,把AT指令流格式化為陣列下標,然後用陣列下標
直接查表來得到解析函式。
這個格式化的演算法怎麼設計,我目前還沒有很好的思路,如果你有什麼好的想法,請留言
給我。