代码在非零等待区运行,一写flash就死机请问怎么解决?

我的芯片是ch32v208,根据我的需求,对设备进行了分区,分别是164K,156K,156K,后分别是bootloader,app1与app2。

bootloader能正常通过蓝牙对app1与app2进行更新,但是我的业务还有可能app1与app2相互更新(app1通过网线对app2进行更新,app2通过网线对app1进行更新)。根据分区情况来看,整个app1与app2都在非零等待区中。

现在现象是无论app1还是app2,只要对对方分区进行更新就会死机。但是如果把相同的代码编译到零等待区就能正常工作。

目前我做了如下实验:

1.把相同的代码编译到零等待区就能正常工作。(修改Link.ld文件)

2.操作flash前手动主动开启hsi,无效果,开启代码如下:

RCC_HSICmd(ENABLE);
temp = 0;
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET && temp < 250)
{
    temp++;
    Delay_Ms(20);
}
if (temp >= 250)
{
    return -2;
}

3.操作flash前手动将hclk改为1/4分频,默认是1/2分频,主动关闭增强读模式以及将FLASH时钟分频,无效果,修改代码如下:

FLASH_Enhance_Mode(DISABLE);
RCC_HCLKConfig(RCC_SYSCLK_Div4);
FLASH_Access_Clock_Cfg(FLASH_Access_SYSTEM_HALF);
FLASH_Unlock();
FLASH_Unlock_Fast();

请问在非零等待区进行flash的操作到底要注意哪些细节?方不方便告知一下?这也太让人绝望了。



icon_rar.gifFLASH_TEST.zip

附件是我基于官方FLASH_TEST修改的代码,改动非常小,很容易读懂。与我反馈的问题有相同的现象,请协助看如何解决。

改动内容:

  1. 主频从96MHz改为了120MHz。

  2. 修改了测试的flash地址,改为了如果在29000,就擦写50000。如果在50000,就擦除29000,通过77000的内容进行判断。默认在50000,擦除29000。

  3. 将启动代码改为了D8W,因为我用的是ch23V208。

现象是如果程序本身在0地址,能正常擦写FLASH,但是如果程序在29000或是50000,那么打印到FLASH Test是最后一条log,应该是死在了FLASH_ErasePage这个函数中。


你好,目前复现了该问题,问题原因待查,你可先将这几个快速编程函数放到零等待区域,经测试是可以的。将函数放零等待方法见链接:https://www.cnblogs.com/liaigu/p/17330342.html 


目前我自己已经将问题解决,解决方法如下:

  1. 由于bootloader能正常工作,可以肯定bootloader关于flash的函数是在0等待区,其他部分的程序如果能成功调用到bootloader中的函数,则改问题解决,因此将bootloader中相关函数的地址在bootloader中读取出来,然后保存到flash的特定扇区中。

    截图_选择区域_20231112013002.png

  2. 在app中改写flash.c文件,读取特定扇区的内容,然后跳转到bootloader中的0等待区函数中去。

    截图_选择区域_20231112012750.png

再额外加上关闭中断等的操作,目前来看是可以正常对芯片进行ota的。

其核心思路是,虽然app整个都在非0等待区,但是bootloader的相关函数在0等待区,因此想办法让app调用bootloader中的函数去做想做的事情即可。


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