框图
参见《9.4 NVM User Row Mapping (UROW)》
0x00804000处512字节
前面32字节为配置信息,启动时自动加载到相应的寄存器。
后面480字节为用户可自由使用。
注意如果需要修改,则先将前面32字节读出来,然后修改需要修改的内容,再回写,保持前面32字节内容不被破坏。
比如我们要使能RAMECC则需要将bit39 RAM ECCDIS设置为0
可以仿真查看当前值如下
配置如下
自动生成的代码见
plib_nvmctrl.c
plib_nvmctrl.h
对应UROW操作的读写接口是
NVMCTRL_Read
NVMCTRL_USER_ROW_RowErase
NVMCTRL_USER_ROW_PageWrite
按照先读-修改-擦除-写的操作进行修改。
以修改使能RAM ECC为例
前面看到RAM ECCDIS对应bit39,我们先读出512字节内容再,修改bit39为0,使能RAM ECC
以上一篇的demo工程为基础
修改main.c
void print_buffer(uint8_t* data,uint32_t len)
{
printf("\r\n");
for(int i=0;i<len;i++)
{
printf("%02x ",data);
if(i%16==15)
{
printf("\r\n");
}
}
}
uint8_t buffer[NVMCTRL_USERROW_PAGESIZE] __attribute__ ((aligned (4)));
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
SYSTICK_TimerStart();
PORT_REGS->GROUP[1].PORT_PINCFG[24] = 0x1U;
PORT_REGS->GROUP[1].PORT_PINCFG[25] = 0x1U;
PORT_REGS->GROUP[1].PORT_PMUX[12] = 0x33U;
printf("Hello Burnon ATSAMD51 EVK");
NVMCTRL_Read((uint32_t*)buffer,NVMCTRL_USERROW_PAGESIZE,NVMCTRL_USERROW_START_ADDRESS);
print_buffer(buffer,NVMCTRL_USERROW_PAGESIZE);
buffer[4] &= 0x7F; //bit39=0 enable ramecc
//buffer[4] |= 0x80; //bit39=1 disable ramecc
NVMCTRL_USER_ROW_RowErase(NVMCTRL_USERROW_START_ADDRESS);
NVMCTRL_USER_ROW_PageWrite((uint32_t*)buffer,NVMCTRL_USERROW_START_ADDRESS);
NVMCTRL_Read((uint32_t*)buffer,NVMCTRL_USERROW_PAGESIZE,NVMCTRL_USERROW_START_ADDRESS);
print_buffer(buffer,NVMCTRL_USERROW_PAGESIZE);
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
打印可以看到byte[4],80变为了00,说明修改成功。
Byte[17] byte[18]之前改为了0,这里一并改为了默认值0x40,0x80.
修改之后发现程序运行异常了进入了hardfault
这是因为使能RAM ECC后RAM有效区域减半,需要i需改分散加载文件
0x40000改为0x20000
《25. NVMCTRL – Nonvolatile Memory Controller》
借助自动成成的库文件,能方便的进行UROW的修改,本篇也进行了使能RAM ECC的操作,为RAM ECC测试做准备。
本帖最后由 qinyunti 于 2022-12-1 10:07 编辑感谢楼主测试