基于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
MKD-S7826
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