CH58xFLASH操作
一、描述
- 读:从FLASH将数据赋值给buff;
- 写:从buff将数据赋值给FLASH;
CH573(RISC-V)
- PAGE:页--256B
- BLOCK:块--4KB
DataFlash特点:
擦/ERASE | 写/WRITE | 读/READ |
0.25KB(的倍数)/4KB(的倍数) | 1Byte/多个Byte/256Byte(的倍数,best) | 1Byte/多Byte |
CodeFlash特点:
擦/ERASE | 写/WRITE | 读/READ |
4KB(的倍数) | 4Byte/256Byte(的倍数,best) | 4Byte |
CH579(ARM)
CodeFlash特点:
擦/ERASE | 写/WRITE | 读/READ |
512B | 4Byte(是4字节对齐) | 通过指针处理的,1次读出来4B(4字节对齐的原因) |
FLASH加扰:
CodeFlash读、写经过内核,会进行加解密(写会加密,读会解密)。擦不会进行加密。因此先擦再读会只解密不加密,这样读出来的数据a9 bd f9 f3,实际上是擦除成功的。
BLE工程DataFlash占用:
Dataflash 偏移地址 |
占用长度 (截止地址) |
相关宏定义 | 用途 |
0 |
12K字节(0x2FFF) |
CONFIG_MESH_NVS_ADDR_DEF等 |
Mesh网络信息 |
0x7000 |
4字节(0x7003) |
OTA_DATAFLASH_ADD |
OTA升级的标志 |
0x7E00 |
512字节(0x7FFF) |
BLE_SNV_ADDR等 |
BLE配对绑定信息 |
二、实例
实现功能:按下RESET后MAC地址自加1。
实现方式:①先将FLASH的内容赋值给buf;②然后让buf[0]的内容自加;③擦除FLASH的内容;④将buf[0]的内容写给FLASH。
void FLASH_Init(){
uint8 status = R8_RESET_STATUS;
if(((status & 0x07) == 0x01 ))
{
MACBuf[0] = 6; MACBuf[1] = 3; MACBuf[2] = 4; MACBuf[3] = 5;
PRINT("Inter...\r\n");
EEPROM_ERASE(0, EEPROM_PAGE_SIZE);
EEPROM_WRITE(0, MACBuf, 4);
}
uint8 ret = EEPROM_READ(0, MACBuf, 4);
PRINT("MACBuf[0] = %02x \r\n", MACBuf[0]);
MACBuf[0]++;
EEPROM_ERASE(0, EEPROM_PAGE_SIZE);
EEPROM_WRITE(0, MACBuf, 4);
for(uint8 i = 0; i < 4; i++)
{
PRINT("%02x ", MACBuf[i]);
}PRINT("\n");
}
cfg.MacAddr[i] = MACBuf[0];
三、CH579读写FLASH并校验
检查FLASH
查看代码
#include "CH57x_common.h"
#define TEST_CODESIZE 128//100
//#define TEST_CODEADDR_ORIGINAL 0x00019000 //100K
#define TEST_CODEADDR_ORIGINAL 0x00003000 //12K
#define R16_CFG_PWR_PML2 (*((PUINT16V)0x40001048)) // RWA, Flash ROM configure register
UINT32 TestBuf[ TEST_CODESIZE ];
void DebugInit(void)
{
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
UART1_BaudRateCfg( 1000000 );
}
int main()
{
UINT32 i;
PUINT32 p32;
UINT32 x = 0;
UINT32 TEST_CODEADDR = TEST_CODEADDR_ORIGINAL;
DebugInit();
mDelaymS(3000);
PRINT( "ID3=%04X\n", R16_CFG_PWR_PML2);
PRINT( "ID4=%02X\n", R8_CFG_FLASH);
/* 配置串口调试 */
PRINT( ".....................................Start @ChipID...................................=%02X\n", R8_CHIP_ID );
for(x = 0; x <= 476; x++)
{
PRINT("第 %ld 次循环\r\n", x);
p32 = (PUINT32)TEST_CODEADDR; //擦操作
PRINT( "Earse addr=0x%08lx : ", (UINT32)p32 );
i = FlashBlockErase( (UINT32)p32 );
if( i == SUCCESS )
{
PRINT("success..\n");
}
else
{
PRINT("failed.and.break~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.\n");
break;
}
p32 = (PUINT32)TEST_CODEADDR; //读出来
PRINT( "Read addr=0x%08lx :\n", (UINT32)p32 );
for(i=0; i<TEST_CODESIZE; i++)
{
if(*p32 != 0xffffffff)
{
PRINT("%08lx ",*p32);
}
p32++;
}PRINT("\n");
for(i=0; i<TEST_CODESIZE; i++) //写操作
{
TestBuf[i] = i;
TestBuf[i] = (TestBuf[i]<<8) | i;
TestBuf[i] = (TestBuf[i]<<8) | i;
TestBuf[i] = (TestBuf[i]<<8) | i;
}
p32 = (PUINT32)TEST_CODEADDR;
PRINT( "Write addr=0x%08lx : ", (UINT32)p32 );
i = FlashWriteBuf( (UINT32)p32, TestBuf, TEST_CODESIZE*4 );
if( i == SUCCESS ) PRINT("success..\n");
else PRINT("failed...............................................................\n");
p32 = (PUINT32)TEST_CODEADDR; //读出来
PRINT( "Read addr=0x%08lx :\n", (UINT32)p32 );
for(i=0; i<TEST_CODESIZE; i++)
{
if(*p32 == 0xffffffff)
{
PRINT("%08lx ",*p32);
}
p32++;
}PRINT("\n");
TEST_CODEADDR += 0x200; //操作接下来的512字节,如此往复
}
while(1);
}