移遠BC26模組和阿里雲通訊使用openCpu除錯記錄
技術標籤:物聯網
1 從購買渠道獲取開發韌體BC26_OpenCPU_NB1_SDK_V1.5NF,可能有韌體版本和型號的區別。
2 我們主要使用的是mqtt和阿里雲連線,主要修改example目錄下的example_mqtt.c檔案
3 開啟除錯資訊,預設的除錯資訊是是從串列埠0輸出,為了和資料傳送串列埠區分開,可以改到串列埠2去,這個就方便系統除錯了,通過使能DEBUG_ENABLE開關,就可從串列埠2輸出系統除錯資訊
3.1 巨集定義除錯口輸出資訊
#define DEBUG_ENABLE 0 #if DEBUG_ENABLE > 0 #define DEBUG_PORT UART_PORT2 #define DBG_BUF_LEN 1024 static char DBG_BUFFER[DBG_BUF_LEN]; #define APP_DEBUG(FORMAT,...) {\ Ql_memset(DBG_BUFFER, 0, DBG_BUF_LEN);\ Ql_sprintf(DBG_BUFFER,FORMAT,##__VA_ARGS__); \ if (UART_PORT2 == (DEBUG_PORT)) \ {\ Ql_Debug_Trace(DBG_BUFFER);\ } else {\ Ql_UART_Write((Enum_SerialPort)(DEBUG_PORT), (u8*)(DBG_BUFFER), Ql_strlen((const char *)(DBG_BUFFER)));\ }\ } #else #define APP_DEBUG(FORMAT,...) #endif static Enum_SerialPort m_myUartPort = UART_PORT0; static Enum_SerialPort m_DebugUartPort = UART_PORT2;
3.2 在proc_main_task函式裡初始化除錯串列埠
void proc_main_task(s32 taskId) { s32 i; ST_MSG msg; Ql_SleepDisable(); ret = Ql_RIL_SendATCmd("AT+CPSMS=0\r\n\0",Ql_strlen("AT+CPSMS=0\r\n\0"),ATResponse_Handler,NULL,0); // Register & open UART port Ql_UART_Register(m_myUartPort, CallBack_UART_Hdlr, NULL); Ql_UART_Register(m_DebugUartPort, CallBack_UART_Hdlr, NULL); #if DEBUG_ENABLE > 0 Ql_UART_Open(m_myUartPort, 9600, FC_NONE); Ql_UART_Open(m_DebugUartPort, 115200, FC_NONE); #else Ql_UART_Open(m_myUartPort, 9600, FC_NONE); #endif if(read_coe()==0) { Ql_sprintf(coe.PK,product_key); Ql_sprintf(coe.DN,device_name); Ql_sprintf(coe.DS,device_secret); coe.addr[0] = 0x01; coe.addr[1] = 0x5c; }
4 BC26還提供了引數儲存和讀取介面函式,Ql_SecureData_Read讀取函式介面,Ql_SecureData_Store儲存函式介面,這樣就可以把一些配置引數儲存在BC26模組裡面,開機時讀回來。
5 系統主要跑2個執行緒,一個是接收阿里雲的訊息,一個是往阿里雲上報資料的執行緒,特別注意上報和下發的資料長度要求有限制,要求控制在256位元組以內,不然好像有問題。如果上報的資料量大,儘量分包處理。如果是通過串列埠和儀表連線的話,注意單次進入執行緒的讀寫串列埠次數,合理分配單次進入執行緒的時間,不要讓系統一直在此執行緒執行。
/***************************************************************** * MQTT timer param ******************************************************************/ #define MQTT_TIMER_ID TIMER_ID_USER_START #define MQTT_TIMER_PERIOD 500 #define MQTT_TIMER_POST_ID (TIMER_ID_USER_START + 1) #define MQTT_TIMER_POST_PERIOD 2500 static void Callback_PostTimer(u32 timerId, void* param) { } static void callback_mqtt_recv(u8* buffer,u32 length) { }
6 除錯問題歸納
6.1 模組宕機
除錯時還是遇到很多問題,最開始是長時間執行幾天就莫名宕機了,後面改了重新分配了進入執行緒的時間,把傳送資料的大小限制住了,就沒有出現宕機了現象了,當時和原廠的技術也溝通了好久,一直沒有找到問題,也不確定是不是這個問題。這個模組還有比較坑的地方就是沒有軟體看門狗,宕機後不能自動復位。後面我們用微控制器的通訊來判斷多久沒有收到報文後,就控制IO口對模組強制復位。
6.2 模組有時候掉線一段時間
這個不知道是運營商的問題,還是阿里雲的問題,我們用的公共例項,沒有買私有云。掉線有長有斷,有的幾十秒,有的幾分鐘。這個和原廠的溝通了下也沒有找到具體問題。
6.3 阿里雲的設定資料,發到儀表會觸發多次重發
開始接收到阿里雲的設定資料後,就直接在接收執行緒裡面對儀表設定資料了,這樣就會出現2條執行緒同時操作RS485匯流排的概率,導致接收到的資料出錯,從而觸發資料重發。後面優化改成設定資料在接收執行緒裡面先快取,然後統一在另外一個執行緒裡面處理串列埠資料,這樣就不會出現這種情況。
6.4 阿里雲設定的資料,模組過了很久才收到
這個不是每次都這樣,有的時候1,2秒就收到了,有的時候會1分鐘才收到,原來我們設定主動上報的時間是5分鐘一次,就會出現這個情況,後面把資料改到10秒上報一次,就沒有出現這種情況了。
6.5 報文ID號的問題
上報報文有編號記錄,這個值最大限定了65535的,如果超過了需要設定為1。
6.6 自動獲取阿里雲三要素
可以在開機的時候,讀取三要素,如果沒有沒有儲存就單獨開啟一條執行緒,連線公司伺服器或者阿里雲的伺服器,從伺服器上獲取雲配置資訊,也可以自動獲取三要素完成設備註冊和啟用。