1,概念
本系统包含一块
64K
字节(
Byte
)容量的
FLASH
存储器,共划分为
128
个页(
Sector
),每个页(
Sector
)
的容量为
512
字节(
Byte
)。
FLASH
控制器支持对
FLASH
存储器的擦除、编程以及读操作。本控制器
还支持对
FLASH
存储器擦写保护,以及控制寄存器的写保护。
2,功能描述
本控制器支持对
FLASH
的字节(
8
位)、半字(
16
位)和字(
32
位)三种位宽的数据读写操作。注意,
字节操作的目标地址必须按字节对齐,半字操作的目标地址必须按半字对齐(地址最低位为
1’b0
),字
操作的地址必须按字对齐(地址最低两位为
2’b00
)。如果目标地址没有按照位宽对齐,则该操作无效,
并且
CPU
会进入
Hard Fault
出错中断。
本控制器采用高安全性的硬件设计,具有
FLASH
操作源防御功能:仅当
FLASH
操作函数的地址位于
0~32K
,才能正确执行
FLASH
擦写操作。
FLASH
地址的
0~32K
具有更高的安全性,重要函数须放置此区域内;例如重要程序入口、中断入口函
数、高安全算法模块、
UID
、
AES
、真随机数、
RTC
的算法配合,组成高安全认证系统
擦除方式:1 页擦除 2 全片擦除
3,实例
en_result_t WriteConfigToFlash(SubDeviceNode_t* sSubNode)
{
uint32_t point = 0;
uint16_t crc16 = 0 ;
char i = 0;
en_result_t ret = Ok;
FlashEraseSector();
point += 2;
point += 2;
for(i = 0; i < MAX_SUB_NODE; i++)
{
ret = Flash_WriteWord((uint32_t)(CONFIG_ADDRESS+point), sSubNodeDev[i].subNodeId);
point += 4;
}
for(i = 0; i < sizeof(gMqttIP); i++)
{
Flash_WriteByte((uint32_t)(CONFIG_ADDRESS+point),gMqttIP[i]);
point++;
}
for(i = 0; i < sizeof(gMqttTopic); i++)
{
Flash_WriteByte((uint32_t)(CONFIG_ADDRESS+point), gMqttTopic[i]);
point++;
}
for(i = 0; i < sizeof(gMqttUser); i++)
{
Flash_WriteByte((uint32_t)(CONFIG_ADDRESS+point), gMqttUser[i]);
point++;
}
for(i = 0; i < sizeof(gMqttPassword); i++)
{
Flash_WriteByte((uint32_t)(CONFIG_ADDRESS+point), gMqttPassword[i]);
point++;
}
Flash_WriteHalfWord((uint32_t)(CONFIG_ADDRESS+point), gMqttPort);
point += 2;
for(i = 0; i < sizeof(gMqttClientId); i++)
{
Flash_WriteByte((uint32_t)(CONFIG_ADDRESS+point), gMqttClientId[i]);
point++;
}
//Printf("gImei=%s\n",gImei);
for(i = 0; i < sizeof(gICCID); i++)
{
Flash_WriteByte((uint32_t)(CONFIG_ADDRESS+point), gICCID[i]);
point++;
}
ret = Flash_WriteHalfWord((uint32_t)(CONFIG_ADDRESS), point);
crc16 = CRC16_Modbus(0xFFFF, (unsigned char*)CONFIG_ADDRESS, point);
ret = Flash_WriteHalfWord((uint32_t)(CONFIG_ADDRESS+point), crc16);
Printf("Write Flash point=%d crc16=0x%04x ret=%d\n",point, crc16, ret);
return ret;
}
/**
*****************************************************************************
** \brief FLASH 字写
**
** 用于向FLASH写入1个字的数据.
**
** \param [in] u32Addr Flash地址
** \param [in] u32Data 1个字数据
**
** \retval Ok 写入成功.
** \retval ErrorInvalidParameter FLASH地址无效
** \retval ErrorTimeout 操作超时
*****************************************************************************/
en_result_t Flash_WriteWord(uint32_t u32Addr, uint32_t u32Data)
{
en_result_t enResult = Ok;
volatile uint32_t u32TimeOut = FLASH_TIMEOUT_PGM;
if (FLASH_END_ADDR < u32Addr)
{
enResult = ErrorInvalidParameter;
return (enResult);
}
//busy?
u32TimeOut = FLASH_TIMEOUT_PGM;
while (TRUE == M0P_FLASH->CR_f.BUSY)
{
if(0 == u32TimeOut--)
{
return ErrorTimeout;
}
}
//Flash 解锁
Flash_UnlockAll();
//set OP
u32TimeOut = FLASH_TIMEOUT_PGM;
while(Program != M0P_FLASH->CR_f.OP)
{
if(u32TimeOut--)
{
FLASH_BYPASS();
M0P_FLASH->CR_f.OP = Program;
}
else
{
return ErrorTimeout;
}
}
//write data
*((volatile uint32_t*)u32Addr) = u32Data;
//busy?
u32TimeOut = FLASH_TIMEOUT_PGM;
while (TRUE == M0P_FLASH->CR_f.BUSY)
{
if(0 == u32TimeOut--)
{
return ErrorTimeout;
}
}
//Flash 加锁
Flash_LockAll();
return (enResult);
}
当出现无法把数据 写入内存时可从这几个方面查