Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Bootloader
MSC_MassStroage_U盘
ota在线升级
请问ST公司的STM32F407,在RT-Thread开发环境下,如何用U盘离线更新MCU程序
发布于 2023-10-09 10:42:55 浏览:739
订阅该版
请问: 我用的是ST公司的STM32F407芯片, 请问在RT-Thread开发环境下, 如何用U盘离线更新的MCU程序,谢谢!
查看更多
sync
2023-10-09
这家伙很懒,什么也没写!
1.先使用软件包qboot制作bootload程序,给flash做好分区工作 2.在app程序中启用usb的host U盘功能 3.在app程序中 获取U盘插入后,判断是否存在待更新的固件bin。如存在将bin拷贝至bootload程序需要的download分区,重启 4.bootload程序将判断download分区的bin完整性,如果校验通过,就会更新app分区,并跳转至app 楼主需要熟悉软件包qboot以及usb U盘功能的启用
9
个回答
默认排序
按发布时间排序
Hunt
2023-10-09
这家伙很懒,什么也没写!
这个就是直接自己实现bootloader,在bootloader里面添加USB读取U盘内的升级文件,读取刷写至片上flash即可。
嚜軒公告
2023-10-09
努力中
要搞bootload了,自己搞了得,加油吧。
Tonyk
2023-10-09
Find it
意思就是直接用U盘来更新STM32F4的MCU程序
xiaorui
认证专家
2023-10-09
小睿手办 https://item.taobao.com/item.htm?id=674889867009
这问题太大了呢😴 不如先说说你的需求,现在的情况,接下来的想法。
梦笑真美
2023-10-09
这家伙很懒,什么也没写!
固件bin文件放U盘里,启动bootload时,检测到有bin文件就更新固件
小狼
2023-10-10
这家伙很懒,什么也没写!
我们公司他们搞过用串口,使用bootload开机使用一个按键检测是不是烧写程序
StackYuan
认证专家
2023-10-11
这家伙很懒,什么也没写!
这个实现难度不大,app里能读U盘能把bin转移到升级固件区就行了。
ThinkCode
2024-04-02
这家伙很懒,什么也没写!
```C /* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-02-01 admin the first version */ #include
#include "rtconfig.h" #include
#include
#include
#include
#define DBG_TAG "FW" #define DBG_LVL DBG_LOG #include
#define DOWNLOAD_PART QBOOT_DOWNLOAD_PART_NAME #define FILE_BUFF_SIZE (4*1024) static char file_buf[FILE_BUFF_SIZE] = {0}; static const struct fal_partition * dl_part = RT_NULL; static rt_err_t check_mount(){ rt_device_t dev = rt_device_find("udisk0"); if(dev != RT_NULL){ return RT_EOK; } else{ return RT_ERROR; } } static size_t get_file_size(FILE *f){ fseek(f, 0, SEEK_END); size_t ret = ftell(f); rewind(f); return ret; } rt_err_t fw_load(const char* fw_path){ rt_err_t ret = RT_EOK; char* recv_partition = DOWNLOAD_PART; FILE *f = fopen(fw_path, "rd"); if(f == NULL){ LOG_E("Open file error!"); ret = RT_ERROR; goto _exit; } size_t fw_file_size = get_file_size(f); LOG_I("Firmware file size:%d byte", fw_file_size); if ((dl_part = fal_partition_find(recv_partition)) == RT_NULL) { LOG_E("Partition (%s) find error!\n", recv_partition); ret = RT_ERROR; goto _exit; } if(fw_file_size > dl_part->len){ LOG_E("Firmware is too large! File size (%d), '%s' partition size (%d)", fw_file_size, dl_part->name, dl_part->len);; ret = RT_ERROR; goto _exit; } if (fal_partition_erase(dl_part, 0, fw_file_size) < 0) { LOG_E("Firmware download failed! Partition (%s) erase error!", dl_part->name); ret = RT_ERROR; goto _exit; } int buff_block_len = fw_file_size / FILE_BUFF_SIZE; int buff_block_count = 0; size_t update_file_cur_size = 0; do{ int read_size = fw_file_size > FILE_BUFF_SIZE? FILE_BUFF_SIZE:fw_file_size; fread(file_buf, 1, read_size, f); if (fal_partition_write(dl_part, update_file_cur_size, (uint8_t*)file_buf, read_size) < 0) { LOG_E("Firmware download failed! Partition (%s) write data error!", dl_part->name); ret = RT_ERROR; goto _exit; } update_file_cur_size += read_size; fw_file_size -= read_size; rt_kprintf("\r[%d/%d] %s=>download, replicating firmware file...", buff_block_count, buff_block_len, fw_path); buff_block_count ++; }while(fw_file_size != 0); _exit: if(f != NULL) fclose(f); return ret; } rt_err_t src_load(const char* src_path){ rt_err_t ret = RT_EOK; DIR *dir = opendir(src_path); struct dirent *ent; if(dir == NULL){ LOG_E("Not found dir: %s", src_path); ret = RT_ERROR; goto _exit; } while((ent = readdir(dir)) != NULL){ if(strcmp(ent->d_name, "System Volume Information") == 0) continue; rt_kprintf("copy %s ", ent->d_name); FILE *f_in; { char path_buff[64] = {0}; strcat(path_buff,src_path); strcat(path_buff,"/"); strcat(path_buff,ent->d_name); f_in = fopen(path_buff, "rb"); } FILE *f_out; { char path_buff[32] = {0}; strcat(path_buff,"/"); strcat(path_buff,ent->d_name); f_out = fopen(path_buff, "wb"); } size_t file_size = get_file_size(f_in); rt_kprintf("size: %d byte\n", file_size); do{ int read_size = file_size > FILE_BUFF_SIZE? FILE_BUFF_SIZE:file_size; fread(file_buf, 1, read_size, f_in); fwrite(file_buf, 1, read_size, f_out); if(file_size > FILE_BUFF_SIZE) fseek(f_out, read_size, SEEK_CUR); file_size -= read_size; }while(fseek(f_in, FILE_BUFF_SIZE, SEEK_CUR) == 0 && file_size != 0); fclose(f_in); fclose(f_out); } _exit: if(dir != NULL) closedir(dir); return ret; } extern int access(const char *path, int amode); int fw_from_udisk(){ if(check_mount() != RT_EOK){ return 0; } const char* fw_path = UDISK_MOUNTPOINT"/new.fw"; const char* fw_path_old = UDISK_MOUNTPOINT"/old.fw"; const char* src_path = UDISK_MOUNTPOINT"/new_i18n"; const char* src_path_old = UDISK_MOUNTPOINT"/old_i18n"; LOG_I("Check the firmware in the Udisk"); if(access(fw_path, 4)!= 0){ LOG_E("not found %s", fw_path); } else{ if(fw_load(fw_path) == RT_EOK){ rename(fw_path, fw_path_old); remove(fw_path); LOG_I("success: %s -> %s", fw_path, fw_path_old); } else{ LOG_E("load fw failed!"); } } if(access(src_path, 4)!= 0){ LOG_E("not found %s", src_path); } else{ if(src_load(src_path) == RT_EOK){ rename(src_path, src_path_old); remove(src_path); LOG_I("success: %s -> %s", src_path, src_path_old); } else{ LOG_E("load src failed!"); } } return 0; } int fw_copy_init(){ qbt_hook_register(fw_from_udisk); return 0; } INIT_ENV_EXPORT(fw_copy_init); int copy_fw(int argc, char **argv){ if(strcmp(argv[1], "src") == 0){ src_load(argv[2]); } else if(strcmp(argv[1], "fw") == 0) { fw_load(argv[2]); } else{ rt_kprintf("src [dir_path]\n"); rt_kprintf("fw [fw_path]\n"); } return 0; } MSH_CMD_EXPORT(copy_fw, download firmware from disk); ``` 这是我写的固件复制的代码, 就是挂载U盘或是SD卡, 然后把固件拷贝到指定flash扇区, 之后就让qboot启动, qboot我做了一些改造, 加了一个函数能把复制固件的代码加到它的启动流程中 另外, 使用能挂载文件系统的程序会使固件增加150KB的体积.
撰写答案
登录
注册新账号
关注者
0
被浏览
739
关于作者
Tonyk
Find it
提问
7
回答
3
被采纳
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
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
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
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
a1012112796
13
个答案
1
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部