CH32V系列MCU IAP升级跳转方法
来源:https://www.cnblogs.com/liaigu/p/17982248
目前CH32V系列MCU EVT提供的IAP升级方式都是在SW_Handler函数中进行APP地址的跳转,如下图1,该方式在程序中需要使能该软件中断,如下图2配置。
图1
图2
该方式无需配置工程在机器模式下,无需修改启动文件中mstatus寄存器的值。
但某些情况下,软件中断函数需用做他用,或用户不想通过中断进行跳转,可直接在IAP程序中需跳转位置直接进行跳转。当不通过中断直接进行跳转时,需要配置工程在机器模式下,需要修改mstatus寄存器的值。
mstatus寄存器为机器模式状态寄存器,通过该寄存器可配置MCU运行在机器模式或用户模式下。此外,对于支持浮点运算的MCU,通过该寄存器可开启或关闭浮点运算功能。关于该寄存器的具体介绍,可参考各MCU对应的青稞手册,具体可在沁恒官网搜索下载。
CH32V103机器模式下配置mstatus的值为:0x1888
CH32V307机器模式下配置mstatus的值为:0x7888
关于跳转方式:
当直接跳转到某一固定地址时,直接在程序中使用跳转指令进行跳转即可,如下图:
当需要写成函数形式通过传参形式进行跳转时,具有以下三种方式:
方式1:
跳转函数按照下方式编写,注意此处一定要使用a0,需要加__attribute__((noinline)),具体如下:
__attribute__((noinline)) void jump_APP(uint32_t addr) { __asm("jr a0"); while(1); }
使用时,直接在函数进行调用该函数即可,如下图:
方式2:
跳转函数按照下方式写,如下:
void jump_APP(uint32_t addr) { __asm volatile("jr %0": :"r"(addr)); while(1); }
使用方法与方式1一致,直接在程序调用即可。
方式3:
该方式相对比较简单,当需要跳转多个地址,且跳转地址确定时,可以使用下列方式:
void jump_APP(uint8_t value) { if(value==1) { __asm("li a6, 0x5000"); __asm("jr a6"); } else if (value==2) { __asm("li a6, 0x6000"); __asm("jr a6"); } else if (value==3) { __asm("li a6, 0x7000"); __asm("jr a6"); } else { __asm("li a6, 0x8000"); __asm("jr a6"); } while(1); }
程序中可以使用if_else语句或switch case,该方式相对比较简单,使用方式与上述两种方式一致。