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

 

posted @ 2023-04-18 20:54  SweetTea_lllpc  阅读(458)  评论(0编辑  收藏  举报