小涛DZGZS 发表于 2020-6-5 09:00

HC32F003/005 Bootloader 跳转后有的app不能正常运行

请问 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不知道咋设置,哪位大佬指导下 谢谢

wangshujun 发表于 2020-6-8 21:19

调转过去了,但是跑几下就死了,最大可能是boot里面开的中断没有关闭,建议跳转前取消掉所有中断使能,不能是关总中断方式

小涛DZGZS 发表于 2020-6-8 21:27

wangshujun 发表于 2020-6-8 21:19
调转过去了,但是跑几下就死了,最大可能是boot里面开的中断没有关闭,建议跳转前取消掉所有中断使能,不能 ...

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

martinhu 发表于 2020-6-9 15:38

本帖最后由 martinhu 于 2020-6-9 15:58 编辑

在app工程的启动文件里面,可以设置中断向量的偏移,这个是KEIL的例子

另外app工程设置里面也需要设置对应的flash区域



wangshujun 发表于 2020-6-9 18:04

向量表都没设置,那么你的app单独运行都一定会死,和boot与否没关系,讨论boot的时候一般假设app单独运行是正确的

小涛DZGZS 发表于 2020-6-9 21:38

martinhu 发表于 2020-6-9 15:38
在app工程的启动文件里面,可以设置中断向量的偏移,这个是KEIL的例子

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

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

小涛DZGZS 发表于 2020-6-9 21:40

wangshujun 发表于 2020-6-9 18:04
向量表都没设置,那么你的app单独运行都一定会死,和boot与否没关系,讨论boot的时候一般假设app单独运行是 ...

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

wangshujun 发表于 2020-6-10 09:05

小涛DZGZS 发表于 2020-6-9 21:40
app独立是可以正常运行的,app独立都不能运行我就不在这问了,我先搞定app了变成 ...

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

小涛DZGZS 发表于 2020-6-10 20:31

wangshujun 发表于 2020-6-10 09:05
你的条件有问题呀,你独立正常运行的app应该和加入boot以后的app不在完全相同的空间,如果完全相同,app ...

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

wangshujun 发表于 2020-6-10 22:00

小涛DZGZS 发表于 2020-6-10 20:31
地址当然不一样啊偏移0X1000,前面的是boot空间后面的是app空间啊。app独立运行当然是在0地址啊。 ...

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

小涛DZGZS 发表于 2020-6-10 23:05

wangshujun 发表于 2020-6-10 22:00
app独立运行说的是app直接写在0x1000地址,仿真器,跳转到入口

还有这种操作?

wangshujun 发表于 2020-6-11 17:53

小涛DZGZS 发表于 2020-6-10 23:05
还有这种操作?

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

小涛DZGZS 发表于 2020-6-11 20:43

wangshujun 发表于 2020-6-11 17:53
仿真器的ini文件里面可以配置,也可以手动跳转

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

wangshujun 发表于 2020-6-11 22:45

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

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

小涛DZGZS 发表于 2020-6-12 18:14

wangshujun 发表于 2020-6-11 22:45
没记得c里面有设置向量表的地方,一般都要在汇编里面做设置
倒是51里面很多是做地址重映射的,在boot程序 ...

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

lesheng002 发表于 2020-7-3 22:21

本帖最后由 lesheng002 于 2020-7-3 22:22 编辑

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

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

lesheng002 发表于 2020-7-3 22:32

在文件core_cm0plus.h中有个内联函数定义
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
第一个参数不理解,要给哪个 IRQn呢,Reset_Handler是属于哪个IRQn呢

liuyanhb 发表于 2020-7-7 14:23

lesheng002 发表于 2020-7-3 22:32
在文件core_cm0plus.h中有个内联函数定义
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_ ...

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

liuyanhb 发表于 2020-7-7 14:30

本帖最后由 liuyanhb 于 2020-7-7 14:31 编辑

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

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

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

。。。。。。
}

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



liuyanhb 发表于 2020-7-7 14:37

本帖最后由 liuyanhb 于 2020-7-7 14:44 编辑

接上一层
; Reset Handler

Reset_Handler   PROC
                EXPORTReset_Handler            
                IMPORTSystemInit
                IMPORT__main

;                ;reset NVIC if in rom debug
;               LDR   R0, =0x20000000
;               LDR   R2, =0x0
;               MOVS    R1, #0               ; for warning,
;               ADD   R1, PC,#0            ; for A1609W,
;               CMP   R1, R0
;               BLS   RAMCODE

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

                LDR   R0, =SystemInit
                BLX   R0
                LDR   R0, =__main
                BX      R0
                ENDP


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