CH573寫入Flash時(shí)導(dǎo)致設(shè)備重啟

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

{

? ? //#error "請(qǐng)自行完成MCU固件升級(jí)代碼,完成后請(qǐng)刪除該行"

? ? if(length == 0) {

? ? ? ? //固件數(shù)據(jù)發(fā)送完成

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

? ? ? ? /* 關(guān)閉當(dāng)前所有使用中斷,或者方便一點(diǎn)直接全部關(guān)閉 */

? ? ? ? DisableAllIRQ();


? ? ? ? /* 修改DataFlash,切換至ImageIAP */

? ? ? ? SwitchImageFlag(IMAGE_IAP_FLAG);


? ? ? ? /* 等待打印完成 ,復(fù)位*/

? ? ? ? mDelaymS(10);

? ? ? ? SYS_ResetExecute();

? ? ??

? ? }else {

? ? ? ? //固件數(shù)據(jù)處理,當(dāng)要寫入的數(shù)據(jù)超過(guò)已擦除的區(qū)域,則擦除下一塊區(qū)域

? ? ? ? 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);

? ? ? ? }



? ? ? ? //拷貝固件包數(shù)據(jù)至緩沖區(qū)中

//? ? ? ? memcpy(binBuffer,value,length);

//? ? ? ? binBufferLen = length;

//? ? ? ? tmos_set_event(halTaskID,HAL_FLASH_WRITE_EVENT);


? ? ? ? //寫入數(shù)據(jù)到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;

}


這個(gè)是一段通過(guò)wifi模組接收固件包并寫入flash的代碼,執(zhí)行到FLASH_ROM_WRITE()設(shè)備就會(huì)重啟,有沒(méi)有辦法定位問(wèn)題呢?FlashWriteAddr的起始地址為0x37000,我采用分區(qū)升級(jí)(4K,216K,216K,12K)的方式,使用藍(lán)牙完全沒(méi)有問(wèn)題

您好,可以參考博客,在硬件錯(cuò)誤中斷中添加打?。?a >CH57x/CH58x/CH32V wch risc-v 芯片hardfault問(wèn)題追蹤&程序卡死追蹤 - iot-fan - 博客園 (cnblogs.com)

操作flash復(fù)位的常見(jiàn)原因是,ram中的數(shù)組參數(shù),沒(méi)有4字節(jié)對(duì)齊,可以把數(shù)組地址打印出來(lái)看看能否被4整除。


數(shù)組地址是4字節(jié)對(duì)齊的,我在硬件錯(cuò)誤中斷中加了打印函數(shù),但是打印不出來(lái)

__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);

}


在上一條信息打印到一半的時(shí)候,串口就沒(méi)有任何顯示了


image.png把打印提前到復(fù)位前面,再加個(gè)10ms的延時(shí)讓打印結(jié)束再?gòu)?fù)位。


1720170102736.png

我單步打印出來(lái)的



錯(cuò)誤原因4,是沒(méi)有4字節(jié)對(duì)齊??梢钥匆幌虏僮鱢lash的緩存數(shù)組,是不是在0x2000531a這個(gè)地址。


不好意思,打印看了下,確實(shí)沒(méi)有4字節(jié)對(duì)齊,我以為4字節(jié)對(duì)齊指的是寫入地址,沒(méi)想到存放數(shù)據(jù)的數(shù)組也需要4字節(jié)對(duì)齊。我現(xiàn)在需要聲明一個(gè)四字節(jié)對(duì)齊的數(shù)組,拷貝數(shù)據(jù)后再用這個(gè)新的數(shù)組傳值寫入flash嗎?


“4字節(jié)對(duì)齊”的要求,一直是針對(duì)緩存數(shù)組,是針對(duì)ram的要求。更底層的原因是匯編代碼調(diào)用的指令,是4字節(jié)操作的指令。
聲明一個(gè)四字節(jié)對(duì)齊的數(shù)組,拷貝數(shù)據(jù)后再用這個(gè)新的數(shù)組傳值寫入flash”是的??梢杂谩癬_attribute__((aligned(4)))?”修飾一下。


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频