CH32V系列MCU IAP升级跳转方法

目前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,该方式相对比较简单,使用方式与上述两种方式一致。

 

 

 

posted @ 2024-01-23 13:21  ZaiLi  阅读(185)  评论(0编辑  收藏  举报