Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Bootloader
ota在线升级
bootloader下载APP后不能正常跳转
发布于 2020-10-13 14:01:58 浏览:2692
订阅该版
 三个没有什么用处的打印函数,任意屏蔽一个就会导致不能正常跳转,这是为啥啊
查看更多
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
被浏览
2.7k
关于作者
xiaoyuan_svip
哈哈哈
提问
77
回答
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
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
五分钟玩转RT-Thread新社区
5
国产MCU移植系列教程汇总,欢迎查看!
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
github高阶加速,速度可达带宽峰值,测试到146Mbit/s
2
英飞凌携手RT-Thread举办嵌入式网络应用开发沙龙,带你从0到1搭建智能数据网关
3
BL808 RT-Thread Wi-Fi 驱动适配
4
rt-thread 系统运行期改变网卡配置
5
简单的步进电机驱动调试
热门标签
RT-Thread Studio
串口
LWIP
Env
AT
SPI
Bootloader
FinSH
ART-Pi
CAN总线
Hardfault
USB
文件系统
RT-Thread
DMA
SCons
线程
MQTT
RT-Thread Nano
STM32
RTC
ESP8266
rt-smart
flash
ota在线升级
WIZnet_W5500
FAL
I2C
packages_软件包
UART
cubemx
freemodbus
潘多拉开发板_Pandora
定时器
BSP
PWM
ADC
socket
中断
rt_mq_消息队列_msg_queue
keil_MDK
SDIO
Debug
AB32VG1
MicroPython
C++_cpp
编译报错
msh
QEMU
ulog
本月问答贡献
出出啊
1500
个答案
338
次被采纳
小小李sunny
1389
个答案
276
次被采纳
张世争
714
个答案
157
次被采纳
crystal266
522
个答案
153
次被采纳
whj467467222
1216
个答案
146
次被采纳
本月文章贡献
出出啊
1
篇文章
12
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
2
篇文章
1
次点赞
crystal266
2
篇文章
5
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部