GSM模塊_GPRS傳輸長數據包時的經驗總結

前言

    本文接着之前的項目繼續往下做,現在需要增加一個程序在線升級的功能,代碼通過GPRS傳輸給ARM,然後更新到Flash,完成程序升級。
    爲了縮短程序升級的時間,也爲了和之前的軟件一致,我們設置每次數據傳輸的最大長度爲2K,即2048字節,加上數據格式幀頭和AT命令幀頭,實際接收的數據長度爲2075字節。 
 

遇到的新問題

1、當GPRS傳輸數據超過一定長度的時候,GSM模塊有可能會把數據分段傳輸到MCU,比如上面提到的2075字節,有時會一次性發回來,有時會分成1400字節和675字節傳給MCU,而在服務器端,數據都是一起傳輸回來的,那麼分段的時候就需要對數據進行拼接處理。
    可以將數據長度作爲是否需要進行拼接的依據,我們在設計數據幀的時候,在幀頭放入了數據的長度信息。當每次接收到服務器發回來的數據幀的時候,取出AT命令裏的長度信息AT_Length和數據幀裏的數據長度信息DATA_Length。
將兩者進行比較
if( DATA_Length > AT_Length)    
//說明數據出現了分段的情況,將接收狀態置爲 RECEIVE_ING,當接收到下一幀數據的時候,將AT_Length1 + AT_Length2組成新的AT_Length。與之前的DATA_Length進行比較。如果還是出現DATA_Length比較大的情況,那麼以此類推,繼續接收下一幀數據,直到AT_Length >= DATA_Length,此時將接收狀態置爲RECEIVE_READY,在應用程序裏面將接收到的數據取出處理。

2、前期開發的時候由於測試數據長度都比較短,所以我直接在串口中斷裏面對數據進行處理,包括將有效數據拷貝到指定的RAM裏面。而當數據長度加長,特別是有問題1出現時,很容易導致中斷處理時間過長,後續數據接收不到的情況。這個問題在軟件設計之初就應該是不被允許的,或者說這樣的操作本身就是錯誤的,是需要儘量避免的,希望大家在設計的時候注意。中斷裏面應該儘量減少操作,儘快跳出中斷,以處理後續的中斷事件。
    由於GPRS數據格式的特殊性,我在數據處理的時候,分配了兩塊存儲空間UART_Buf和GPRS_Buf,UART_Buf用於接收串口中斷數據,GPRS_Buf用於存儲預處理後的數據,即存儲服務器發回來的有效數據。我在開頭提到的數據格式特殊性,就是指串口接收到的原始數據會包含AT命令的幀頭,結束符,操作的應答等等不需要過多關注的內容,但是又爲了中斷操作的及時性,我會先把這些數據一並存在UART_Buf裏面,簡化串口中斷處理。
    UART_Buf直接在中斷裏面進行處理,每次進中斷,只需要將數據填到這個Buf的尾部,如果接收到AT命令的結束符,這個時候對數據進行一次判斷,判斷是否是服務器發回來的數據,如果是,記錄數據存儲的位置Addr,並對該位置的狀態進行設置,設置成RECEIVE_READY,然後跳出中斷,其他操作在主循環裏面進行。
    GPRS_Buf預處理的操作首先判斷位置的狀態,當檢測到有狀態置爲RECEIVE_READY的時候,取出Addr信息,將Addr開始地址的數據依次取出,判斷AT數據幀頭,AT_Length和DATA_Length ,這個時候有可能會需要進行分段拼接的處理,在問題1裏面已經講到了。當取出該位置的有效數據後,將有效數據存儲到GPRS_Buf裏面,並將該位置的狀態設置成RECEIVE_EMPTY,這樣該位置就可以用於下一次數據的接收處理。

總結

本文簡單介紹了GSM模塊串口中斷的設計,數據存儲方式的設計,以及數據長度較大時應該注意的地方,供大家設計的時候參考。
發佈了54 篇原創文章 · 獲贊 83 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章