You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CH32V203 RISC-V MCU软件跳转Bootloader故障求助

解决CH32V203软件跳转内置Bootloader硬故障问题

你的问题出在仅直接跳转地址,没有完成Bootloader运行所需的前置硬件配置和上下文清理。CH32V203的内置Bootloader依赖特定的内存映射、栈指针和无干扰的硬件环境,单纯函数指针跳转无法满足这些要求,以下是正确的实现步骤和代码:

关键前置操作

  • 关闭所有中断与异常:当前程序的中断会干扰Bootloader运行,必须先禁用全局中断,关闭外设中断并清除挂起的中断标志。
  • 配置内存重映射:将存储Bootloader的Flash区域映射到0x00000000(和BOOT0引脚拉高时的映射一致),这需要修改SYSCFG的内存重映射寄存器。
  • 设置Bootloader的栈指针:RISC-V架构下,程序启动首先从复位向量表加载栈指针,跳转前必须先读取Bootloader复位向量表的栈指针值并写入CPU的SP寄存器。

正确的跳转代码实现

#include "ch32v20x.h"

typedef void (*BootloaderEntry)(void);

void JumpToBootloader(void)
{
    // 读取Bootloader复位向量表的栈指针和入口地址
    uint32_t bootloader_sp = *(volatile uint32_t *)0x1FFF8000;
    BootloaderEntry bootloader_entry = (BootloaderEntry)*(volatile uint32_t *)0x1FFF8004;

    // 1. 关闭全局中断
    __disable_irq();

    // 2. 关闭所有外设中断并清除挂起标志
    NVIC->ICER[0] = 0xFFFFFFFF;
    NVIC->ICER[1] = 0xFFFFFFFF;
    NVIC->ICPR[0] = 0xFFFFFFFF;
    NVIC->ICPR[1] = 0xFFFFFFFF;

    // 3. 配置内存重映射,将Bootloader Flash映射到0x00000000
    SYSCFG->MEMRMP = 0x01; // 对应BOOT0=1时的映射模式,具体值参考官方手册

    // 4. 设置Bootloader的栈指针(RISC-V架构必须手动配置)
    __asm__ volatile ("mv sp, %0" : : "r"(bootloader_sp));

    // 5. 跳转到Bootloader复位入口
    bootloader_entry();
}

int main(void)
{
    // 可添加跳转触发条件(如按键检测)
    JumpToBootloader();

    while(1);
}

原代码的问题分析

你之前的代码仅直接调用了Bootloader的入口地址,但存在三个核心问题:

  • 未配置内存重映射:Bootloader运行时会默认访问0x00000000地址,此时该地址仍映射为用户Flash而非Bootloader区域,直接触发地址访问错误。
  • 未设置Bootloader栈指针:Bootloader启动后使用当前程序的栈空间,栈可能已被破坏或不符合Bootloader的要求,导致硬故障。
  • 未关闭中断:跳转后残留的中断触发会干扰Bootloader的正常执行流程。

内容的提问来源于stack exchange,提问作者gv260ea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:42:40