Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Bootloader
ota在线升级
bootloader下载APP后不能正常跳转
发布于 2020-10-13 14:01:58 浏览:3289
订阅该版
![image.png](/uploads/20201013/01364a934efed351e0043adec958248c.png) 三个没有什么用处的打印函数,任意屏蔽一个就会导致不能正常跳转,这是为啥啊
查看更多
2
个回答
默认排序
按发布时间排序
hichard
认证专家
2020-10-13
这家伙很懒,什么也没写!
下面的流程基本适用于所有的处理器,具体代码实现以Cortex-M为例。 在Cortex-M处理器上,Bootloader程序可以使用RTOS,也可以裸机实现,但是都要遵循以下流程。现在总结如下: 1.内核级,实现堆栈切换,跳转指令 2.NVIC级别,关闭所有的NVIC中断,清空所有pend的中断 3.具体芯片级,复位必要的外设,尤其是EXTI这类。SDRAM QSPI FLASH这类不需要复位,也不能复位。 下面着重讲解上面三级代码的具体实现,这3步是相互嵌套是关系。最终用户调用的都具体芯片级别的跳转函数。 1.内核级 实现函数__hal_app_jump,该函数的C语言声明为:extern void __hal_app_jump(rt_uint32_t u32AppAddr); 具体源码是汇编语言实现的,如下: ```asm __hal_app_jump CPSID I ; 关闭中断 LDR R1, =0xE000ED08 ; 切换向量表到应用程序的起始地址 STR R0, [R1] MOV R2, #0x00 ; 切换工作模式,工作到特权级的线程模式 使用MSP MSR CONTROL, R2 LDR R1, [R0] ; 设置堆栈指针 MOV SP, R1 CPSIE I ; 使能中断 LDR R0, [R0, #4] ; 设置当前PC的值,开始运行新的应用程序 BX R0 ``` 通过注释,可以很清晰的明白本函数的功能,该函数完整实现了bootloader的跳转流程,一些裸机场合,有些可能就不需要实现。 2.NVIC级别 先上代码,在根据代码来讲解。 ```c void hal_app_jump(rt_uint32_t u32AppAddr) { /** * Step1, 关闭中断 */ __asm(" CPSID I\n"); /** * Step2, 关闭NVIC中的所有中断 */ memset((void *)HAL_NVIC_DIS_BASE, 0, sizeof(rt_uint32_t) * 8); /** * Step3, 清空NVIC中已经Pending中的所有中断 */ memset((void *)HAL_NVIC_PEND_CLEAR_BASE, 0, sizeof(rt_uint32_t) * 8); /** * Step4, 清空Systick中断及已经挂起的中断 */ HWREG32(HAL_NVIC_ST_CTRL) = 0; HWREG32(HAL_NVIC_INT_CTRL) |= ((1UL << 25) | (1UL << 27)); /** * Step5, 执行跳转流程 */ __hal_app_jump(u32AppAddr); } ``` 可以看到NVIC级别,分5步,如果是非Cortex-M处理器,也是这5步,主要是对中断控制器清零,复位操作,避免在跳转的瞬间正好遇上了中断,造成乱跳转,跑飞。第五步 调用了步骤1的函数,执行真正的跳转。 3.具体芯片级别, 先上代码,再来谈具体实现。 ```c void rt_hw_app_jump(rt_uint32_t u32AppAddr) { /** * Step1, 关闭中断 */ rt_hw_interrupt_disable(); /** * Step2, 如果需要的话,复位除GPIO、SYSCFG、PWR和QSPI外的所有外设 */ //SystemPeripheralAllReset(); HWREG32(RCC_BASE + RCC_AHB3RSTR) = 0x7FFFBFFF; HWREG32(RCC_BASE + RCC_AHB1RSTR) = 0xFFFFFFFF; HWREG32(RCC_BASE + RCC_AHB2RSTR) = 0xFFFFFFFF; HWREG32(RCC_BASE + RCC_AHB4RSTR) = 0xFFFF0000; HWREG32(RCC_BASE + RCC_APB3RSTR) = 0xEFFFFFFF; HWREG32(RCC_BASE + RCC_APB1LRSTR) = 0xFFFFFFFF; HWREG32(RCC_BASE + RCC_APB1HRSTR) = 0xEFFFFFFF; HWREG32(RCC_BASE + RCC_APB2RSTR) = 0xFFFFFFFF; HWREG32(RCC_BASE + RCC_APB4RSTR) = 0xEFFFFFFD; HWREG32(RCC_BASE + RCC_AHB3RSTR) = 0; HWREG32(RCC_BASE + RCC_AHB1RSTR) = 0; HWREG32(RCC_BASE + RCC_AHB2RSTR) = 0; HWREG32(RCC_BASE + RCC_AHB4RSTR) = 0; HWREG32(RCC_BASE + RCC_APB3RSTR) = 0; HWREG32(RCC_BASE + RCC_APB1LRSTR) = 0; HWREG32(RCC_BASE + RCC_APB1HRSTR) = 0; HWREG32(RCC_BASE + RCC_APB2RSTR) = 0; HWREG32(RCC_BASE + RCC_APB4RSTR) = 0; /** * Step3, 执行跳转 */ rt_hw_cpu_icache_disable(); rt_hw_cpu_dcache_disable(); HWREG32(HAL_ACCESS_CACR) &= ~(((rt_uint32_t)1) << 2); // 禁止D-CACHE透写 hal_app_jump(u32AppAddr); } ``` 具体芯片级别分了3步,该函数是H7下的例子。该步骤主要就是清除具体是外设,让CPU恢复到最初上电时的状态。第三步执行了NVIC级别的跳转函数。应用层只要调用该函数即可实现跳转。 如,如果要跳转到0x08020000处执行代码,则可以运行代码:rt_hw_app_jump(0x08020000),,严谨一点,跳转代码写如下: ```c if((HWREG32(0x08020000) != 0xFFFFFFFF) && (HWREG32(0x08020000) >= 0x20000000) && (HWREG32(0x08020000) < STM32_HEAP_END) && (HWREG32(0x08020000 + 4) != 0xFFFFFFFF) && (HWREG32(0x08020000 + 4) >= 0x08020000)) { rt_hw_app_jump(HN_APP_ADDR); } ``` 4.其他问题 上面描述基本已经可以实现一个完整的BootLoader跳转了。细心的读者可能发现,复位外设,缺没有复位GPIO等外设,这里其实可能一些潜在隐患。如果BootLoader里面使用了GPIO中断, 在跳转的瞬间,由于静电干扰造成触发了中断信号,也可能造成跳转失败。这里比较妥当的做法当然的将EXIT的GPIO中断关闭,这通常是在按键驱动实现的。建议的是,如果在BootLoader中open了某个 外设,那么跳转前,请先close掉,在跳转。其它特殊的硬件,如有存在外部看门狗,不能关闭,在跳转前最好先喂狗一次,避免跳转的时候发生看门狗溢出,造成跳转不成功。 读完本文,读者是不是发现跳转没有那么简单。跳转异常基本都是跳转瞬间发生中断引起,只要控制好中断,就能控制好跳转流程。 hichard
xiaoyuan_svip
2020-10-21
哈哈哈
知道跳转的逻辑,但是就是跳转不成功,哈哈哈
撰写答案
登录
注册新账号
关注者
1
被浏览
3.3k
关于作者
xiaoyuan_svip
哈哈哈
提问
79
回答
12
被采纳
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项目助手v0.2.0 - 支持Env Windows
2
RttreadV5.10上,GD32F450Z RTC时间显示问题
3
rt-smart启动流程分析
4
EtherKit快速上手PROFINET
5
RTThread USB转串口无法接收数据
热门标签
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
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部