CH573写入Flash时导致设备重启

unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)

{

    //#error "请自行完成MCU固件升级代码,完成后请删除该行"

    if(length == 0) {

        //固件数据发送完成

        PRINT("bin received completed.restart\r\n");

        /* 关闭当前所有使用中断,或者方便一点直接全部关闭 */

        DisableAllIRQ();


        /* 修改DataFlash,切换至ImageIAP */

        SwitchImageFlag(IMAGE_IAP_FLAG);


        /* 等待打印完成 ,复位*/

        mDelaymS(10);

        SYS_ResetExecute();

      

    }else {

        //固件数据处理,当要写入的数据超过已擦除的区域,则擦除下一块区域

        if(FlashWriteAddr + length >FlashEraseAddr){

            //擦除flash

            FLASH_ROM_ERASE(FlashEraseAddr, FLASH_BLOCK_SIZE);

            FlashEraseAddr += FLASH_BLOCK_SIZE;

            PRINT("Falsh erase. available addr: %08x\r\n",FlashEraseAddr);

        }



        //拷贝固件包数据至缓冲区中

//        memcpy(binBuffer,value,length);

//        binBufferLen = length;

//        tmos_set_event(halTaskID,HAL_FLASH_WRITE_EVENT);


        //写入数据到flash

        uint8_t status = FLASH_ROM_WRITE(FlashWriteAddr,value,length);

        if(status){

            PRINT("Flash Write error\r\n");

        }

        PRINT("flash write: %08x,length: %d\r\n",FlashWriteAddr,length);

        FlashWriteAddr += length;


    }

    return SUCCESS;

}


这个是一段通过wifi模组接收固件包并写入flash的代码,执行到FLASH_ROM_WRITE()设备就会重启,有没有办法定位问题呢?FlashWriteAddr的起始地址为0x37000,我采用分区升级(4K,216K,216K,12K)的方式,使用蓝牙完全没有问题

您好,可以参考博客,在硬件错误中断中添加打印:CH57x/CH58x/CH32V wch risc-v 芯片hardfault问题追踪&程序卡死追踪 - iot-fan - 博客园 (cnblogs.com)

操作flash复位的常见原因是,ram中的数组参数,没有4字节对齐,可以把数组地址打印出来看看能否被4整除。


数组地址是4字节对齐的,我在硬件错误中断中加了打印函数,但是打印不出来

__attribute__((interrupt("WCH-Interrupt-fast")))

__attribute__((section(".highcode")))

__attribute__((weak))

void HardFault_Handler(void)

{

    FLASH_ROM_SW_RESET();

    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;

    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;

    R16_INT32K_TUNE = 0xFFFF;

    R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;

    R8_SAFE_ACCESS_SIG = 0;



    uint32_t v_mepc,v_mcause,v_mtval;

    printf("hardfault\n");


    v_mepc=__get_MEPC();

    v_mcause=__get_MCAUSE();

    v_mtval=__get_MTVAL();


    printf("mepc:%08x\n",v_mepc);

    printf("mcause:%08x\n",v_mcause);

    printf("mtval:%08x\n",v_mtval);

    while(1);



    while(1);

}


在上一条信息打印到一半的时候,串口就没有任何显示了


image.png把打印提前到复位前面,再加个10ms的延时让打印结束再复位。


1720170102736.png

我单步打印出来的



错误原因4,是没有4字节对齐。可以看一下操作flash的缓存数组,是不是在0x2000531a这个地址。


不好意思,打印看了下,确实没有4字节对齐,我以为4字节对齐指的是写入地址,没想到存放数据的数组也需要4字节对齐。我现在需要声明一个四字节对齐的数组,拷贝数据后再用这个新的数组传值写入flash吗?


“4字节对齐”的要求,一直是针对缓存数组,是针对ram的要求。更底层的原因是汇编代码调用的指令,是4字节操作的指令。
声明一个四字节对齐的数组,拷贝数据后再用这个新的数组传值写入flash”是的。可以用“__attribute__((aligned(4))) ”修饰一下。


只有登录才能回复,可以选择微信账号登录