Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Bootloader
STM32F103VE+Air720H+AT_Client升级过程分享
发布于 2020-04-14 19:54:52 浏览:1667
订阅该版
* 本帖最后由 yc985055 于 2020-4-14 19:58 编辑 * 这些天一直在测试STM32F103VE通过Air720H的HTTP功能升级固件。 其中参考了官方文档 [https://www.rt-thread.org/docume ... -rtboot/#bootloader](https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/#bootloader) 和以下链接 [https://www.rt-thread.org/qa/for ... ypeid%26typeid%3D64](https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=423550&extra=page%3D1%26filter%3Dtypeid%26typeid%3D64) 1.下面是擦除download分区和写数据函数。 /*************************************************************************************************** * @fn hw_upgrade_start(void) * * @brief erase flash * * @param * * @return none ****************************************************************************************************/; static void hw_upgrade_start(void) { http_size_bytes = 0; http_size_conts = 0; http_size_conts_max = 0; u16UdpCrc = 0; rt_kprintf("hw_upgrade_start() !!!
"); if ((dl_part = fal_partition_find(recv_partition)) == RT_NULL) { rt_kprintf("Firmware download failed! Partition (%s) find error!", recv_partition); return; } /* erase DL section */ if (fal_partition_erase(dl_part, 0, 196 * 1024) < 0) { rt_kprintf("Firmware download failed! Partition (%s) erase error!", dl_part->name); return ; } //stm32_flash_erase ((rt_uint32_t)INT_FLASH_DOWNLOAD_ADDR, 196 * 1024); } /*************************************************************************************************** * @fn void hw_upgrade_data_save(rt_uint8_t *pDataBuf, rt_uint16_t dataLen) * * @brief save upgrade data to flash * * @param * * @return none ****************************************************************************************************/ static void hw_upgrade_data_save(rt_uint8_t *pDataBuf, rt_uint16_t dataLen) { rt_uint16_t tempU16 = 0; tempU16 = dataLen; //if (tempU16 == stm32_flash_write((rt_uint32_t)INT_FLASH_DOWNLOAD_ADDR + (rt_uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), pDataBuf, dataLen)) if (fal_partition_write(dl_part, (rt_uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), pDataBuf, dataLen) > 0) { http_size_conts++; //计算校验,最后两字节是校验值,不参与运算 rt_kprintf("http_size_conts is-%d!!! UdpCrc is 0x%04x !!!0x%02x 0x%02x
", http_size_conts, u16UdpCrc, pDataBuf[tempU16 - 2], pDataBuf[tempU16 - 1]); if (tempU16 < HTTP_SIZE_PER_PKT) { tempU16 -= 2; } for (rt_uint16_t i = 0; i < tempU16; i++) { u16UdpCrc = hw_udp_pkt_run_poly(u16UdpCrc, pDataBuf*); } } else { rt_kprintf("fal_partition_write() error
"); } } 注:其实用stm32_flash_erase(...) stm32_flash_write(...)来执行是一样的,我开始升级不成功,以为是它们的原因。所以调用了ymodem_ota中的两个函数。 2.http读取数据函数。 http线程函数 { case HTTP_READ_DATA: { if ((http_size_bytes - http_size_conts * HTTP_SIZE_PER_PKT) >= HTTP_SIZE_PER_PKT) { u16Temp = HTTP_SIZE_PER_PKT; } else { u16Temp = http_size_bytes - http_size_conts * HTTP_SIZE_PER_PKT; } rt_kprintf("http_size_bytes %d http_size_conts:%d http_size_conts_max:%d
", http_size_bytes, http_size_conts, http_size_conts_max); at_delete_resp(resp); resp = at_create_resp(HTTP_SIZE_PER_PKT + 56, 0, rt_tick_from_millisecond(500)); if(resp == NULL) { rt_kprintf(" create HTTP resp no memory"); } sprintf((char *)HTTP_CMD_READ,(char const *)"%s%d%s%d",(char const *)"AT+HTTPREAD=", (rt_uint32_t)(http_size_conts * HTTP_SIZE_PER_PKT), ",", u16Temp); if (at_exec_cmd(resp, HTTP_CMD_READ) == RT_EOK) { http_read_func(resp); } else { rt_kprintf("at_exec_cmd return error
"); } } } /*************************************************************************************************** * @fn void http_read_func(at_response_t httpReadResp) * * @brief 读取http下载的数据 * * @param none * * @return none ****************************************************************************************************/ static void http_read_func(at_response_t httpReadResp) { rt_bool_t bIsHaveData = RT_FALSE; rt_uint16_t u16Temp ,i; const char *line_buffer = RT_NULL; char *httpReadBuf = RT_NULL; if (httpReadResp == RT_NULL || httpReadResp->line_counts < 4) { return; } httpReadBuf = rt_malloc(HTTP_SIZE_PER_PKT); if (httpReadBuf == RT_NULL) { rt_kprintf("http_read_func out of memory!!
"); } if ((http_size_bytes - http_size_conts * HTTP_SIZE_PER_PKT) >= HTTP_SIZE_PER_PKT) { u16Temp = HTTP_SIZE_PER_PKT; } else { u16Temp = http_size_bytes - http_size_conts * HTTP_SIZE_PER_PKT; } rt_kprintf("The max lines is %d size is %d
", httpReadResp->line_counts, httpReadResp->buf_len); for (rt_size_t line_num = 1; line_num <= httpReadResp->line_counts; line_num++) { if((line_buffer = at_resp_get_line(httpReadResp, line_num)) != RT_NULL) { //找到数据区的前一行 if(strstr(line_buffer, "+HTTPREAD:")) { //找到数据区的首行 if((line_buffer = at_resp_get_line(httpReadResp, line_num + 1)) != RT_NULL) { bIsHaveData = RT_TRUE; break; } } //rt_kprintf("line %d %02x %02x %02x %02x
", line_num, line_buffer[0],line_buffer[1],line_buffer[2],line_buffer[3]); } } if (httpReadResp->line_counts > 4) { for (i = 0; i < u16Temp; i++) { if (line_buffer* == 0x0D && line_buffer[i + 1] == 0x00) { httpReadBuf[i++] = 0x0D; httpReadBuf* = 0x0A; } else { httpReadBuf* = line_buffer*; } } } if (bIsHaveData) { if (httpReadResp->line_counts > 4 ) { hw_upgrade_data_save((rt_uint8_t *)httpReadBuf, u16Temp); } else { hw_upgrade_data_save((rt_uint8_t *)line_buffer, u16Temp); } } //判断是否下载完成 if (http_size_conts >= http_size_conts_max) { //系统重启 air_cur_status = HTTP_TERM; rt_kprintf("System now will restart...u16UdpCrc value is 0x%04x
", u16UdpCrc); hw_upgrade_crc_check(); /* wait some time */ rt_thread_delay(500); rt_hw_cpu_reset(); rt_thread_delay(500); } else { air_cur_status = HTTP_READ_DATA; } rt_free(httpReadBuf); } 注:这里遇到不少问题。 A. 不能用urc函数获取{"+HTTPREAD", "
", urc_http_read_func}. 因为没有结束符。 B. 想用at_client_recv代替at_exec_cmd和at_create_resp函数来读数据。老返回失败 C. 后面在AT_Client中找了,没有合适函数还是用at_exec_cmd和at_create_resp. 这里我通过每条数据包校验打印才发现。at_create_resp以行为单位读取数据,会把文件中的0x0D 0x0A转换成0x0D 0x00。 现在我是做了判断,把数据反转回来。暂时可以这样做,升级没有问题。 **********D.没用采用ota_http升级中的函数,或许会更容易,我是为了减少源码大小。***** *****E期间,我还自己写了C#代码来计算校验值,看是哪个包出错啦。 ***** ***** 在此要感谢以下两位的帮助:面码1314 发表于 2020-4-12 18:07 小小李sunny 发表于 2020-4-12 22:07 *****
查看更多
1
个回答
默认排序
按发布时间排序
jerry4cool
2020-06-19
这家伙很懒,什么也没写!
感谢分享。。。。
whj467467222
认证专家
2020-06-19
开源,分享,交流,共同进步
谢谢分享哦
crystal266
2022-01-14
嵌入式
谢谢分享
撰写答案
登录
注册新账号
关注者
0
被浏览
1.7k
关于作者
yc985055
这家伙很懒,什么也没写!
提问
6
回答
38
被采纳
0
关注TA
发私信
相关问题
1
Linux下通过USBTinyISP为Arduino开发板烧?写Bootloader
2
请教修改NVIC后RTT调度函数失效的问题[已解决 bootloader中打开了不必要的中断]
3
进入bootloader的方式探讨
4
求助:IAP里的APP使用的RTT,跳转后出错。[已解决]
5
有没有人在STM32F103上用UART IAP跑过RT-Thread?
6
想做网口的IAP远程升级,不知可不可行
7
IAP问题
8
[已解决]请教基于RTT的IAP程序切换到应用程序不成功的问题(基于STM32F4)?
9
stm32f4xx-----IAP移植APP程序需要注意的地方
10
在调试IAP网络升级遇到跳转之后bootloader程序网络不通
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用
2
Rt-thread中OTA下载后,bootloader不搬程序
3
ulog 日志 LOG_HEX 输出时间改为本地日期时间
4
在RT-Thread Studio中构建前执行python命令
5
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
5
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部