Flash - aman396271/Flagchip_Study GitHub Wiki
FlashDriver
Sync=>Async=>interrupt=>Cache=>ECC=>FEE
Flash API(Chapter 58)
In the FC4150F2M, FLASH is divided into program flash (2MB) and data flash (256KB). Program flash is composed of a block, and a block is divided into 256 sectors, that is, the size of a sector is 8KB. Data flash is composed of a block, and a block is divided into 32 sectors, that is, the size of a sector is 8KB. Sector is the smallest unit of FLASH erase
写入前必须擦除;读写的最小单位是sector(对于FC4150F2M,sector大小为8KB);最小的写入单位是8byte(写入前需擦除至少1sector);支持最高30MHz的读取频率
Memory Map
The FC4150F2M has 2 MB PFlash, 256 KB data flash (DFlash), and 256 KB SRAM
FC4150F2M,其PFlash地址范围为0x00000000-0x00200000,其NVR的地址范围为0x01000000-0x01002000,其DFlash地址范围为0x01100000-0x01118000
Synchronous 同步读写
读写地址及Sector、最小写入大小配置
#define USER_STORAGE_START_ADDRESS 0x00180000U //0x00200000-0x00180000=512Kb
#define FLASH_SECTOR_SIZE 0x2000U //8Kb
#define FLASH_WRITE_MIN_SIZE 0x08 //8byte
FLASHDRIVER_Init();初始化,开启ROM Clock Gating,为使用Flash要开启ROM的时钟门限,因为RM中Flash API contains several parts, which are all implemented on ROM. The first part contains all API function entry addresses.The second part contains flash parameters,Flash操作API,部署在ROM中
void FLASHDRIVER_Init(void)
{
#if SMISC_ROM_CLOCK_GATING_SUPPORT
SMISC->SYSCGC |= SMISC_SYSCGC_CGCROM(1);
#endif
}
设置读写地址和长度,先进行擦除
tFlashParam.u32Address = USER_STORAGE_START_ADDRESS;
tFlashParam.u32Length = FLASH_SECTOR_SIZE;
async_status = FLASHDRIVER_SyncErase(&g_tFlashHandle, &tFlashParam);
在代码 FLASH_DRIVER_ParamType tFlashParam = {.pData = fls_test_buff_w} 其中由于显式初始化的原因,除pData外的结构体成员会被初始化为0,避免野指针出现,若单个赋值,如果有变量忘记赋值,容易出现野指针进入HardFault
配置写入地址和长度,进行写入
tFlashParam.u32Address = USER_STORAGE_START_ADDRESS;
tFlashParam.u32Length = FLASH_WRITE_MIN_SIZE*10;
async_status = FLASHDRIVER_SyncWrite(&g_tFlashHandle, &tFlashParam);
Asynchronous 异步读写
同步与异步擦除对比
同步擦除和异步擦除都是调用APIFLASH_DRV_EraseSector实现擦除功能,不同的是,同步擦除是一次性以阻塞的方式擦除n个Sector,而异步擦除一次只擦除一个扇区,若擦除n个扇区则需要多次调用,如使用状态机,好处是不需要等待,节省资源
Interrupt 中断读写
注意:在Flash中断部分,函数入口为FC_IRQHandler,此处的FC并不是FlagChip,而是Flash Controller的意思
其中断逻辑和其他外设的逻辑一致,不过在SDK中并没有Callback
打开中断,在中断入口中进行中断处理
void Interrupt_Init(void)
{
__NVIC_EnableIRQ(Flash_IRQn);
}
void FC_IRQHandler(void)
{
Fls_CommonProcessInterrupt(&g_tFlashHandle);
}
关于SDK中的中断处理函数Fls_CommonProcessInterrupt,其内容如下:
Fls_ReturnType Fls_CommonProcessInterrupt(FLASH_HandleType *pFlashHandle)
{
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
//从ROM中获取API,方便后续处理,FLASH_API_ENTRY(0x0187000)
Fls_ReturnType interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
//根据目前所处状态是FLS_WRITING/FLS_ERASING进行操作
if (pFlashHandle->tStatus.eFlsStatus == FLS_WRITING)
{
/* check if finished */
if (STATUS_SUCCESS == (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear())//调用API查询是否写完
{
/*做成功标记,并进行中断写处理*/
interrupt_ret = FLASH_INTERRUPT_ERR_OK;
if (pFlashHandle->tStatus.u32CurrentAddress < (pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length))
{
pFlashHandle->tStatus.pData += pFlashHandle->tStatus.u32ProgramSize;
FLASHDRIVER_INTSingleProgram(pFlashHandle);
}
else
{
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
}
}
else
{
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
}
}
else if (pFlashHandle->tStatus.eFlsStatus == FLS_ERASING)
{
if (STATUS_SUCCESS == (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear())
{
interrupt_ret = FLASH_INTERRUPT_ERR_OK;
if (pFlashHandle->tStatus.u32CurrentAddress < (pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length))
{
FLASHDRIVER_INTSingleErase(pFlashHandle);
}
else
{
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
}
}
else
{
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
}
}
else
{
}
return interrupt_ret;
}
记得使能中断!!!
ECC
Flash ECC (Error Correction Code,错误纠正码)
Flash Controller with ECC protection. The ECC implements a 64 + 8 structure which is able to support single-bit correction and double-bit detection. An ECC error will trigger a bus fault to the system.
Hamming Code 汉明码
Flash Controller with ECC protection. The ECC implements a 64 + 8 structure which is able to support single-bit correction and double-bit detection. An ECC error will trigger a bus fault to the system.
Double-bit ECC error detection on PFLASH and DFLASH read access if FEEC[DDBEE]=0.
ECC events of single-bit error and double-bit error on every read data will be reported to ERM.
关于ERM(Error Register Module)
The Error Reporting Module (ERM) provides information and optional interrupt notification on memory error events associated with ECC. The ERM collects ECC events on memory accesses for memory arrays, such asflash memory, system RAM, or DMA_CFG RAMs.
Support 5 channels for reporting corresponding memory error event source
Support reporting the address information on single-bit correction and non-correctable Error Correction Code (ECC)
events
Selectable interrupt request assertion on captured ECC events
Support for ECC event capturing for memory sources, with individual reporting fields and interrupt configuration per memory channel
#1