如何解决Flash被保护后的程序下载问题
-
在YTM32Bx系列MCU中,可通过EFM模块ADDR_PROT寄存器对内部Flash进行写保护,ADDR_PROT寄存器中的每个bit被设置为0时,其对应的Flash区域即被写保护。MCU上电后ADDR_PROT寄存器值仅允许从1变为0,而不允许从0变为1,即MCU允许过程中Flash一旦被写保护,则本次运行期间不能被取消写保护。
EFM模块中ADDR_PROT寄存器的初始值来自于MCU内部CUS_NVR Flash中指定位置(详见MCU参考手册),用户可根据自身需求通过写CUS_NVR Flash设置该寄存器的默认值,需注意,若该寄存器默认值被设置为0,则MCU上电后对齐的Flash即被写保护,后续将无法通过JTAG或软件内部的Flash driver对被写保护的Flash进行擦除或编程操作。
此时如果需要解锁被写保护的Flash,则只能通过重置ADDR_PROT寄存器初始值,即擦除重写CUS_NVR Flash中对应位置的值。若MCU内部所有Flash均被写保护,则该MCU无法在向Flash中下载任何程序,此时若需修改ADDR_PROT寄存器初始值,则需新建一个工程用于擦除CUS_NVR Flash,并将该工程所有代码放在RAM中运行.
下面以YTM32B1MD14为例介绍实现过程:
1.在YCT工具中新建工程,并配置YT-LINK模块,删除该模块中Flash中配置的所有sector信息,并在RAM中创建.text段以及.rodata段,用于存储代码及const类型数据。

2.在main.c中通过如下代码实现CUS_NVR擦除。
uint32_t TestCnt=5; void Test_CusterNvrErase(void) { EFM->CUS_KEY = 0x4dff32; EFM->CMD = 0U; EFM->STS = EFM_STS_FAIL_MASK | EFM_STS_ACCERR_MASK | EFM_STS_UNRECOVERR_MASK | EFM_STS_RECOVERR_MASK | EFM_STS_DONE_MASK; EFM->NVR_ADDR = 0x10000400U; EFM->CMD_UNLOCK = 0xfd9573f5; EFM->CMD = 0x41U; while ((EFM->STS & EFM_STS_DONE_MASK) == 0U) { } if(((EFM->STS&EFM_STS_ACCERR_MASK) != 0)||((EFM->STS&EFM_STS_FAIL_MASK) != 0)) { while(1) {} } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ Board_Init(); /* USER CODE BEGIN 2 */ Test_CusterNvrErase(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { TestCnt++; if(TestCnt>1000) { TestCnt = 0; } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } static void Board_Init(void) { }- 通过调试工具将代码下载至MCU运行,然后reset MCU即可完成Flash写保护解锁。
4.注意示例代码中写入的CUS_KEY为MCU默认值,若MCU CUS_KEY被修改,则需根据实际情况写入KEY值。
Erase_CUSNVR.zip -
目前没有专门针对每款芯片做示例,操作的方式是原理都是一样的,可以直接参考这个示例做。
-
houjun_xiao 请问,打开这个工程报如下错误怎么解决

-
Erase_CUSNVR.zip你试一试,这个是基于SDK 1.4.0的
-
houjun_xiao 好的,可以打开了,但HA01的 EFM_Type 没有 NVR_ADDR ,
代码里的 EFM->NVR_ADDR = 0x10000400U; 要怎么替换

-
直接对目的地址赋值即可,例如*((uint32_t *))0x10000400)=0;
需要注意HA0的FLASH存在WE控制位,在赋值前先将CTRL寄存器中的WE位置1

-
按照示例在RAM中调用接口对CUS_NVR擦除成功后,还是没办法对芯片擦写,JLink提示擦除失败。


有什么其他需要注意的地方吗? -
擦除NVR中的protect配置数据后,需要Reset MCU才能生效。
-
houjun_xiao 有个问题就是,软件上电之后会执行写保护的动作,就算之后在RAM中擦除了NVR,复位之后是不是也会被重新写保护?
-
擦除NVR后,Protect的配置数据就被清除了,所以Reset之后不会再有写保护,升级完程序后,如果想恢复写保护,就需要重写NVR。
-
houjun_xiao Project是指CUS_NVR的配置,还是用户代码的配置?
-
EFM写保护功能可以通过两种方式配置:1.通过CUS_NVR中合法的值在MCU初始化阶段即完成写保护写保护寄存器设置,2.若CUS_NVR中无合法的值,则可通过代码设置EFM写保护寄存器,从而配置写保护功能。需要注意,这个寄存器在代码中只能由1改写为0,不能由0改写为1, 该寄存器中某位的值为0时,该为位对应的区域被写保护。

-
houjun_xiao 对使用的方法没有疑问,有疑问的点是如何解除写保护,比如我在初始化时候 EFM->ADDR_PROT[0] = 0;
EFM->ADDR_PROT[1] = 0; EFM->ADDR_PROT[2] = 0;即写保护了全部Flash地址,这个时候没办法重新用JLink烧写软件了,使用示例的代码生成的Hex用JLink下载到RAM,然后在RAM去擦除CUS_NVR,这个时候擦除的只是NVR的数据吧,那么复位之后,初始化的时候是不是还是会重新写保护? -
如果你时代码设置的写保护,擦除CUS_NVR是没有用的。这种情况你如果想通过JLink下载程序,只能Attach到MCU,然后Reset,然后在执行EFM->ADDR_PROT[0] = 0;
EFM->ADDR_PROT[1] = 0; EFM->ADDR_PROT[2] = 0前打断点,此时可以下载。 -
houjun_xiao 好的,了解了多谢
快速上手云途开发生态
发帖前请查看
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...