搜索

[技术问答] HC32F003/005 Bootloader 跳转后有的app不能正常运行

[复制链接]
816|29
 楼主 | 2020-6-5 09:00 | 显示全部楼层 |阅读模式
请问 HC32F003/005 Bootloader 跳转后有的app不能正常运行 一般是哪里出了问题
参照官方L110的bootloader例程改的
bootloader里就用了串口0 跳转前寄存器复位
void MCU_Config(void)
{
        M0P_GPIO->P35_SEL_f.SEL = 0;
        M0P_GPIO->P3DIR_f.P35 = 1;   

        M0P_GPIO->P36_SEL_f.SEL = 0;
        M0P_GPIO->P3DIR_f.P36 = 1;

        M0P_BT1->CR = 0x00;

        EnableNvic(TIM1_IRQn,0,FALSE);

        M0P_BT0->CR = 0x00;

        M0P_UART0->SCON = 0x00;         

        EnableNvic(UART0_IRQn,0,FALSE);

//        M0P_CLOCK->PERI_CLKEN = 0xC0800000;         
      
        DI();//禁止中断      
}


跳转的程序也是官方的
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(uint32_t appxaddr)
{
        if(((*(__IO uint32_t*)appxaddr)&0x2FFE0000)==0x20000000)        //检查栈顶地址是否合法.
        {
                jump2app=(iapfun)*(__IO uint32_t*)(appxaddr+4);                //用户代码区第二个字为程序开始地址(复位地址)               
                MSR_MSP(*(__IO uint32_t*)appxaddr);                                        //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
                jump2app();                                                                        //跳转到APP.
        }
}


Flash的读写也是官方的,就串口通信部分是自己写的。
串口接收固件包和写入固件都是正确的,仿真看过flash里的数据了,也试过烧入bootloader和app 有一个5K左右的app可以运行 另一个13K左右的app运行了几条程序到delay1ms函数里的while里卡死了,奇怪的是5k的那个app里也有用到delay1ms
不过5K的没用到定时器13K的那个用了定时器1,但是bootloader里只有串口用了定时器0,也没用的到定时器1跳转前也恢复默认了


前几天一位大佬提醒我可能是没设置中断向量偏移,我没用过bootloader不知道咋设置,哪位大佬指导下 谢谢

使用特权

评论回复

评论

某大少 2020-7-2 16:29 回复TA
大佬,为什么我下的官方驱动库里面没有 L110 bootload的驱动历程呀,跪求分享 
| 2020-6-8 21:19 | 显示全部楼层
调转过去了,但是跑几下就死了,最大可能是boot里面开的中断没有关闭,建议跳转前取消掉所有中断使能,不能是关总中断方式

使用特权

评论回复
 楼主 | 2020-6-8 21:27 | 显示全部楼层
wangshujun 发表于 2020-6-8 21:19
调转过去了,但是跑几下就死了,最大可能是boot里面开的中断没有关闭,建议跳转前取消掉所有中断使能,不能 ...

不是中断没关 是中断向量没设置  M0怎么设置中断向量偏移呢

使用特权

评论回复
| 2020-6-9 15:38 | 显示全部楼层
本帖最后由 martinhu 于 2020-6-9 15:58 编辑

在app工程的启动文件里面,可以设置中断向量的偏移,这个是KEIL的例子
892385edf3c021a949.png 438315edf3c3550332.png
另外app工程设置里面也需要设置对应的flash区域
321675edf3c6ecd7ed.png


使用特权

评论回复
| 2020-6-9 18:04 | 显示全部楼层
向量表都没设置,那么你的app单独运行都一定会死,和boot与否没关系,讨论boot的时候一般假设app单独运行是正确的

使用特权

评论回复
 楼主 | 2020-6-9 21:38 | 显示全部楼层
martinhu 发表于 2020-6-9 15:38
在app工程的启动文件里面,可以设置中断向量的偏移,这个是KEIL的例子

另外app工程设置里面也需要设置对应 ...

代理的FAE告诉我 .s文件里151行那个 LDR    R2,=0x1000  我试了确实可以运行 不知道这样是不是也可以改中断向量表偏移  你那那么多汇编代码 我看不懂   代理商的FAE说的那个能运行,但是不知道有没有什么问题

使用特权

评论回复
 楼主 | 2020-6-9 21:40 | 显示全部楼层
wangshujun 发表于 2020-6-9 18:04
向量表都没设置,那么你的app单独运行都一定会死,和boot与否没关系,讨论boot的时候一般假设app单独运行是 ...

app独立是可以正常运行的,app独立都不能运行我就不在这问了,我先搞定app了变成

使用特权

评论回复
| 2020-6-10 09:05 | 显示全部楼层
小涛DZGZS 发表于 2020-6-9 21:40
app独立是可以正常运行的,app独立都不能运行我就不在这问了,我先搞定app了变成 ...

你的条件有问题呀,你独立正常运行的app应该和加入boot以后的app不在完全相同的空间,如果完全相同,app独立运行不加映射时也应该出问题

使用特权

评论回复
 楼主 | 2020-6-10 20:31 | 显示全部楼层
wangshujun 发表于 2020-6-10 09:05
你的条件有问题呀,你独立正常运行的app应该和加入boot以后的app不在完全相同的空间,如果完全相同,app ...

地址当然不一样啊偏移0X1000,前面的是boot空间后面的是app空间啊。app独立运行当然是在0地址啊。

使用特权

评论回复
| 2020-6-10 22:00 | 显示全部楼层
小涛DZGZS 发表于 2020-6-10 20:31
地址当然不一样啊偏移0X1000,前面的是boot空间后面的是app空间啊。app独立运行当然是在0地址啊。 ...

app独立运行说的是app直接写在0x1000地址,仿真器,跳转到入口

使用特权

评论回复
 楼主 | 2020-6-10 23:05 | 显示全部楼层
wangshujun 发表于 2020-6-10 22:00
app独立运行说的是app直接写在0x1000地址,仿真器,跳转到入口

还有这种操作?

使用特权

评论回复
| 2020-6-11 17:53 | 显示全部楼层

仿真器的ini文件里面可以配置,也可以手动跳转

使用特权

评论回复
 楼主 | 2020-6-11 20:43 | 显示全部楼层
wangshujun 发表于 2020-6-11 17:53
仿真器的ini文件里面可以配置,也可以手动跳转

问题是M0怎么设置中断向量表偏移呢,上面那个大佬的有点复杂 有简单的吗?比如C代码里实现

使用特权

评论回复
| 2020-6-11 22:45 | 显示全部楼层
小涛DZGZS 发表于 2020-6-11 20:43
问题是M0怎么设置中断向量表偏移呢,上面那个大佬的有点复杂 有简单的吗?比如C代码里实现 ...

没记得c里面有设置向量表的地方,一般都要在汇编里面做设置
倒是51里面很多是做地址重映射的,在boot程序和app里面程序看到的地址都是从0开始的
早期lpc的arm7有一个想想重映射寄存器,可以把一小片ram配置到向量区,然后那个区域可以自由改写

使用特权

评论回复
 楼主 | 2020-6-12 18:14 | 显示全部楼层
wangshujun 发表于 2020-6-11 22:45
没记得c里面有设置向量表的地方,一般都要在汇编里面做设置
倒是51里面很多是做地址重映射的,在boot程序 ...

STM32F0的好像就是RAM里怎么怎么弄的 还没仔细研究,回头我看看STM32F0的怎么弄。谢谢你们两位哥们了

使用特权

评论回复
| 2020-7-3 22:21 | 显示全部楼层
本帖最后由 lesheng002 于 2020-7-3 22:22 编辑

STM32FXX是这么设置向量偏移的
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x6000);

目前对华大芯片不是很熟悉,请华大技术给指点一下,怎么来设置向量偏移,类似ST这样的简单语句就搞定的

使用特权

评论回复
| 2020-7-3 22:32 | 显示全部楼层
在文件core_cm0plus.h中有个内联函数定义
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
第一个参数不理解,要给哪个 IRQn呢,Reset_Handler是属于哪个IRQn呢

使用特权

评论回复
| 2020-7-7 14:23 | 显示全部楼层
lesheng002 发表于 2020-7-3 22:32
在文件core_cm0plus.h中有个内联函数定义
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_ ...

这个不是设置向量表地址的

使用特权

评论回复
| 2020-7-7 14:30 | 显示全部楼层
本帖最后由 liuyanhb 于 2020-7-7 14:31 编辑

C语言设置中断向量表的地址很简单,直接修改VTOR寄存器就可以了,注意M0内核没有这个寄存器,不过华大的是M0+有这个寄存器。以下是我重写了SystemInit函数,里面第一件事就是设置中断向量表的位置。STM32的库都是这么做的。
  1. #ifndef __VTOR_PRESENT
  2. #define SCB_VTOR (*(vu32 *)(0xE000ED08)) // 从厂家提供的汇编启动文件可知 VTOR 是存在的。
  3. #else
  4. #define SCB_VTOR SCB->VTOR
  5. #endif

  6. void SystemInit(void) // 汇编启动代码会先调用这个,在调用main之前
  7. {
  8. // 设置本软件中断向量表地址
  9. #ifdef VECT_TAB_SRAM
  10.   SCB_VTOR = SRAM_BASE; /* Vector Table Relocation in Internal SRAM. */
  11. #else
  12.   #if (FLASH_BASE != 0)
  13.   SCB_VTOR = FLASH_BASE; /* Vector Table Relocation in Internal FLASH. */
  14.   #endif
  15. #endif

  16. // 确保接下来的所有指令都使用新配置
  17.   __DSB();
  18.   __ISB();

  19. 。。。。。。
  20. }
复制代码


厂家的汇编启动代码也做了这个寄存器的设置,不过被我屏蔽了,我还是喜欢在C语言里面设置。我修改之后的启动代码如下:



复制代码

使用特权

评论回复
| 2020-7-7 14:37 | 显示全部楼层
本帖最后由 liuyanhb 于 2020-7-7 14:44 编辑

接上一层
  1. ; Reset Handler

  2. Reset_Handler   PROC
  3.                 EXPORT  Reset_Handler             [WEAK]
  4.                 IMPORT  SystemInit
  5.                 IMPORT  __main

  6. ;                ;reset NVIC if in rom debug
  7. ;                 LDR     R0, =0x20000000
  8. ;                 LDR     R2, =0x0
  9. ;                 MOVS    R1, #0                 ; for warning,
  10. ;                 ADD     R1, PC,#0              ; for A1609W,
  11. ;                 CMP     R1, R0
  12. ;                 BLS     RAMCODE

  13. ;               ; ram code base address.
  14. ;                 ADD     R2, R0,R2           ; R2 = R0 + R2 = 0x20000000 (RAM_BASE)
  15. ; RAMCODE
  16. ;               ; reset Vector table address.
  17. ;                 LDR     R0, =0xE000ED08     ; SCB_VTOR的地址
  18. ;                 STR     R2, [R0]            ; SCB_VTOR = R2 (如果 PC 在 FALSH, R2 = 0, 否则 R2 = 0x20000000)
  19.                 ; 以上为MCU厂家增加的代码,其目的是:当发现PC指向RAM,设置 SCB_VTOR 为0x20000000,否则设置为0.
  20.                 ; SCB_VTOR默认为0,我不会让代码在RAM中运行,如果需要在C代码中修改SCB_VTOR寄存器更合理,所以注释掉以上代码。
  21.                 ; 且STM32的做法是:如果代码在RAM中运行,定义一个宏 VECT_TAB_SRAM ,在 SystemInit 函数中给 SCB_VTOR 赋值为RAM_BASE。

  22.                 LDR     R0, =SystemInit
  23.                 BLX     R0
  24.                 LDR     R0, =__main
  25.                 BX      R0
  26.                 ENDP
复制代码


以上复位中断函数实际上只有4句话,其它MCU厂家的启动文件都是这样的,华大增加了一些代码被我注释掉了。
APP启动做的第一件事情就是设置向量表的地址到APP的存放开始地址。楼主的问题原因就在于,厂家的启动汇编代码里面统一设置成了0X00000000为向量表的地址,所以APP烧录到0X0地址是可以运行的,但是烧录到其它地址就不能运行了。
中断发生后CPU会去中断向量表寻找中断函数入口,如果向量表设置的还是0X0,那在APP中发生中断却执行了BOOTLOADER的中断处理函数!自然会有问题。

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表