基于RT-Thread 实现4GSTM32OTA 升级 基于RT-Thread 实现4G STM32 OTA 升级滤菌器
硬件:
STM32F429BIT6开发板
EC200S开发板
USB-TTL调试器
因为不想写AT架构,想快速实现⼀个验证的版本,就⽤RT-Thread来写。第⼀次⽤RT-Thread,肝了⼀天,基本可以使⽤了,还差把数据写⼊到Flash就⾏了,下⾯给出代码。 代码还有很多改进的地⽅,可能还有bug,没有具体测试。 齿轮齿条转向器这⾥采⽤的HTTP从服务器获取BIN⽂件,再保存在4G模块内部FLASH的⽅法,后⾯会做程序切⽚发送的。
平台使⽤⾃⼰搭建的,⽬前⽤的NodeRED来测试,后⾯弄成前后端分离的。
下⾯代码使⽤的msh来调试测试的,⼯程代码中需要增加AT_Client组件,同时给⼀个⼤的缓存。/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2022-01-08 zhengshijian the first version */#ifndef APPLICATIONS_EC200S_C_#define APPLICATIONS_EC200S_C_#include "ec200s.h"#include <stdlib.h>#include <string.h>#include <rtthread.h>#include <at_device.h>#include <netdev.h>#define DBG_TAG "ec200s"#define DBG_LVL DBG_LOG #include <rtdbg.h>#define FLASH_SECTOR_SIZE 4096#define FLASH_SECTOR_COUNT ((7 * 128 * 1024) / (4 * 1024)); //允许烧录多少个扇区 ⼤⼩为7*128k static int ec200s_check_ready (void ){ at_response_t resp = RT_NULL ; int result = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); if (resp == RT_NULL ) { LOG_E ("No memory for response structure!"); return -2; } result = at_exec_cmd (resp , "AT"); if (result != RT_EOK ) { LOG_E ("Failed Check Ready"); } 1
2
3
4
5
6
7
8
9
10
11
12
非法请求13
14
15
16
17
18
自动充电电动车19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
自行车防盗架
36
37
38
39
40
41偏振分束器
42
} if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_echo_close (void ){ at_response_t resp = RT_NULL ; int result = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); if (resp == RT_NULL ) { LOG_E ("No memory for response structure!"); return -2; } result = at_exec_cmd (resp , "ATE0"); if (result != RT_EOK ) { LOG_E ("Failed Close Echo"); } if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_sim_card_check (void ){ at_response_t resp = RT_NULL ; int result = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); result = at_exec_cmd (resp , "AT+CPIN?"); if (result != RT_EOK )
{ LOG_E ("Failed Check CPIN"); goto __exit ; }else { if (strstr (at_resp_get_line (resp , 2), "READY")){ LOG_I ("CPIN READY"); }else { LOG_E ("CSQ Parse error"); result = -1; } }__exit : if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_signal_quality_check (void ){ at_response_t resp = RT_NULL ; int rssi , ber ;42434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
int rssi , ber ; int result = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); result = at_exec_cmd (resp , "AT+CSQ"); if (result != RT_EOK ){ LOG_E ("Failed Check CSQ"); goto __exit ; } { /* ⾃定义数据解析表达式 ,⽤于解析两双引号之间字符串信息 */ const char * resp_expr = "+CSQ: %d,%d"; if (at_resp_parse_line_args (resp , 2, resp_expr , &rssi , &ber )) { LOG_I ("CSQ : %d %d", rssi , ber ); if (rssi == 99) { result = -1; } } else { LOG_E ("CSQ Parse error"); result = -1; goto __exit ; } }__exit : if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_gsm_network_check (void ){ at_response_t resp = RT_NULL ; int result = 0; int try = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); if (resp == RT_NULL ) { LOG_E ("No memory for response structure!"); return - 1; } while (try ++ < 10) { /* 查询信号强度 */ result = at_exec_cmd (resp , "AT+CREG?"); if (result != RT_EOK ){ LOG_E ("Failed Check GSM Network"); goto __exit ; } { int n , stat ; /* ⾃定义数据解析表达式 ,⽤于解析两双引号之间字符串信息 */ const char * resp_expr = "+CREG: %d,%d"; LOG_D (" Parse arguments"); /* 解析响应数据中第⼀⾏数据 */ if (at_resp_parse_line_args (resp , 2, resp_expr , &n , &stat ))
107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
if (at_resp_parse_line_args (resp , 2, resp_expr , &n , &stat )) { LOG_I ("CREG : %d %d", n , stat ); if (stat != 1){ LOG_E ("CREG stat error"); }else goto __exit ; } else { LOG_E ("CREG Parse error"); result = -1; goto __exit ; } } rt_thread_delay (2000); }__exit : if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_gprs_network_check (void ){ at_response_t resp = RT_NULL ; int result = 0; int try = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); if (resp == RT_NULL ) { LOG_E ("No memory for response structure!"); return -1; } while (try ++ < 10) { /* 查询信号强度 */ result = at_exec_cmd (resp , "AT+CGREG?"); if (result != RT_EOK ){ LOG_E ("Failed Check CGREG Network"); goto __exit ; } { int n , stat ;
/* ⾃定义数据解析表达式 ,⽤于解析两双引号之间字符串信息 */ const char * resp_expr = "+CGREG: %d,%d"; LOG_D (" Parse arguments"); /* 解析响应数据中第⼀⾏数据 */ if (at_resp_parse_line_args (resp , 2, resp_expr , &n , &stat )) { LOG_I ("CGREG : %d %d", n , stat ); if (stat != 1){ LOG_E ("CGREG stat error"); }else goto __exit ; } else { LOG_E ("CGREG Parse error"); result = -1; goto __exit ; } }172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
} rt_thread_delay (2000); }__exit : if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_close_apn (void ){ at_response_t resp = RT_NULL ; int result = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); if (resp == RT_NULL ) { LOG_E ("No memory for response structure!"); return -1; } result = at_exec_cmd (resp , "AT+QIDEACT=1"); if (result != RT_EOK ){ LOG_E ("Failed Close APN"); } if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}static int ec200s_set_apn (void ){ at_response_t resp = RT_NULL ; int result = 0; resp = at_create_resp (32, 0, rt_tick_from_millisecond (300)); if (resp == RT_NULL ) { LOG_E ("No memory for response structure!"); return -1; } result = at_exec_cmd (resp , "AT+QICSGP=1,
1,\"CMNET\"\r\n"); if (result != RT_EOK ){ LOG_E ("Failed Set PDP"); goto __exit ; } result = at_exec_cmd (resp , "AT+QIACT=1\r\n"); if (result != RT_EOK ){ LOG_E ("Failed Set APN"); }__exit : if (resp ) { /* 删除 resp 结构体 */ at_delete_resp (resp ); } return result ;}237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302