在线时间1351 小时
UID3338155
注册时间2017-7-26
NXP金币1313
TA的每日心情 | 奋斗 前天 09:55 |
---|
签到天数: 588 天 [LV.9]以坛为家II
金牌会员
- 积分
- 6976
- 最后登录
- 2024-4-18
|
本帖最后由 andeyqi 于 2023-4-12 11:28 编辑
LPC845 的片内flsah 的编程SDK内提供了IAP的一组接口完成对flash 的编程处理,说明可以参照论坛如下文章描述([分享] [痞子衡]为什么说内部Flash驱动是个既冷门又不冷门的话题),细节可以参考大佬的文章,我们先看下SDK 的IAP 接口文档的API 说明。
一.IAP 接口描述
1 .Basic operations
- The function IAP_ReadPartID() reads the part id of the board.
- The function IAP_ReadBootCodeVersion() reads the boot code Version.
- The function IAP_ReadUniqueID() reads the unique id of the boards.
- The function IAP_ReinvokeISP() reinvokes the ISP mode.
- The function IAP_ReadFactorySettings() reads the factory settings.
2 .Flash operations
- The function IAP_PrepareSectorForWrite() prepares a sector for write or erase operation. Then, the function IAP_CopyRamToFlash() programs the flflash memory.
- The function IAP_EraseSector() erases a flflash sector while the function IAP_ErasePage() erases a flflash page.
- The function IAP_BlankCheckSector() is used to blank check a sector or multiple sectors of on-chip flflash memory.
- The function IAP_Compare() is used to compare the memory contents at two locations. The user can compare several bytes (must be a multiple of 4) content in two different flflash locations.
- The function IAP_ReadFlashSignature() can get the 32-bits signature of the entire flflash and the function IAP_ExtendedFlashSignatureRead() can calculate the signature of one or more flflash pages.
对片内flash 的操作调用 Flash operations 这组接口即可完成对flash的编程操作,上述接口中对flash 的擦除是以section/page 为单位,写的单位为page,lpc845的片内flash的sector 和 page 配置信息如下表,lpc845 片内有64k flash 有64个sector 每个sector 为1k,每个sector 包含16个page 每个page 64Bkye.
API 接口说明:- status_t IAP_PrepareSectorForWrite ( uint32_t startSector, uint32_t endSector )
This function prepares sector(s) for write/erase operation. This function must be called before calling the IAP_CopyRamToFlash() or IAP_EraseSector() or IAP_ErasePage() function. The end sector number must be greater than or equal to the start sector number.
从接口描述可知在对falsh 进行write/erase 前需要先调用该接口。
- status_t IAP_BlankCheckSector(uint32_t startSector, uint32_t endSector)
/*!
* @brief Blank check sector(s)
*
* Blank check single or multiples sectors of flash memory. The end sector number must be greater than or equal to the
* start sector number. It can be used to verify the sector erasure after IAP_EraseSector call.
*
* @param startSector Start sector number.
* @param endSector End sector number.
* @retval kStatus_IAP_Success One or more sectors are in erased state.
* @retval kStatus_IAP_NoPower Flash memory block is powered down.
* @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
* @retval kStatus_IAP_SectorNotblank One or more sectors are not blank.
*/
status_t IAP_BlankCheckSector(uint32_t startSector, uint32_t endSector)
该接口在用于擦除flash 后校验擦除是否成功。
- status_t IAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock)
/*!
* @brief Erase sector.
*
* This function erases sector(s). The end sector number must be greater than or equal to the start sector number.
*
* @param startSector Start sector number.
* @param endSector End sector number.
* @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
* flash controller has a fixed reference clock, this parameter is bypassed.
*
* @retval kStatus_IAP_Success Api has been executed successfully.
* @retval kStatus_IAP_NoPower Flash memory block is powered down.
* @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
* @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number.
* @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
* @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
*/
status_t IAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock)
- status_t IAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock)
/*!
* @brief Copy RAM to flash.
*
* This function programs the flash memory. Corresponding sectors must be prepared via IAP_PrepareSectorForWrite before
* calling this function. The addresses should be a 256 byte boundary and the number of bytes should be 256 | 512 |
* 1024 | 4096.
*
* @param dstAddr Destination flash address where data bytes are to be written.
* @param srcAddr Source ram address from where data bytes are to be read.
* @param numOfBytes Number of bytes to be written.
* @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the
* flash controller has a fixed reference clock, this parameter is bypassed.
*
* @retval kStatus_IAP_Success Api has been executed successfully.
* @retval kStatus_IAP_NoPower Flash memory block is powered down.
* @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked.
* @retval kStatus_IAP_SrcAddrError Source address is not on word boundary.
* @retval kStatus_IAP_DstAddrError Destination address is not on a correct boundary.
* @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map.
* @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map.
* @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value.
* @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed.
* @retval kStatus_IAP_Busy Flash programming hardware interface is busy.
*/
status_t IAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock)
该接口用于对flash 的写入,接口描述是写入的最小长度是256 本地试验的一次写一个page 64Byte也是可以的。
二 .编写接口验证测试代码
本地的代码文件从编译的map 及 编译log 可知代码占用flash前32k,后32k 为空闲状态,我们对最后一个page 进行擦除写入验证。
Memory region Used Size Region Size %age Used
PROGRAM_FLASH: 27192 B 64 KB 41.49%
SRAM: 9768 B 16352 B 59.74%
IAP_SRAM: 0 GB 32 B 0.00%
Finished building target: lpc845breakout_hello_world.axf
unsigned int iap(char argc,char ** argv)
{
int cmd;
uint32_t partID = 0u;
uint32_t bootCodeVersion = 0u;
uint32_t * paddr;
status_t status;
static uint32_t s_PageBuf[FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES/4];
memset((void *)s_PageBuf,0x5a,FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES);
cmd = atoi(argv[1]);
switch(cmd)
{
case 1:
IAP_ReadPartID(&partID);
PRINTF("partID = %x.\r\n",partID);
break;
case 2:
IAP_ReadBootCodeVersion(&bootCodeVersion);
PRINTF("bootCodeVersion = %x.\r\n",bootCodeVersion);
break;
case 3:
PRINTF("dump page data.\r\n");
paddr = (uint32_t *)(1023*FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES);
trace_word_stream(paddr,16);
break;
case 4:
PRINTF("erase page data.\r\n");
/* Erase sector before writing */
IAP_PrepareSectorForWrite(63, 63);
IAP_EraseSector(63, 63, SystemCoreClock);
status = IAP_BlankCheckSector(63, 63);
if (status != kStatus_IAP_Success)
{
PRINTF("\r\nSector erase failed\r\n");
}
break;
case 5:
PRINTF("write page data.\r\n");
/* First write a page */
IAP_PrepareSectorForWrite(63, 63);
IAP_CopyRamToFlash(1023 * FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, &s_PageBuf[0],
FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, SystemCoreClock);
break;
}
}
LTSH_FUNCTION_EXPORT(iap,"test iap api");
此测试接口:
串口输入
iap 3 会dump出最后一个page 的数据,用于确认数据是否按照预期写入及擦除
iap 4 会擦除最后一个sector 的数据
iap 5 会对最后一个page 写入0x5a的测试数据。
三 .实际验证
step1.上电后输入iap 3 此时应该会dump 出当前flash 内容默认应该是全0xff数据,串口终端输出信息如下(跟预期一致的全0xff数据):
#iap 3
dump page data.
0 4 8 C
0:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
10:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
20:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
30:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
#
step2. 在step1的基础上输入iap 5对数据进行写入后dump flash数据,串口终端信息如下(跟预期一致的全0x5a数据):
#
#iap 3
dump page data.
0 4 8 C
0:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
10:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
20:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
30:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
#iap 5
write page data.
#iap 3
dump page data.
0 4 8 C
0:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
10:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
20:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
30:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
#
step3. 在step2的基础上输入iap 4对数据进行擦除后dump flash数据,串口终端输出信息如下(跟预期一致的全0xff数据):
#
#iap 3
dump page data.
0 4 8 C
0:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
10:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
20:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
30:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
#iap 5
write page data.
#iap 3
dump page data.
0 4 8 C
0:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
10:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
20:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
30:5A5A5A5A 5A5A5A5A 5A5A5A5A 5A5A5A5A ZZZZZZZZZZZZZZZZ
#
#iap 4
erase page data.
#iap 3
dump page data.
0 4 8 C
0:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
10:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
20:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
30:FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF ................
从上面的测试结果可知iap 接口已经成功的对片内flash 进行写入和擦除操作了。
IAP 接口里还有其他API,IAP_ReadPartID(&partID) 读取device id,该接口读取获取值和如小表格一致。
#iap 1
partID = 8452.
#iap 2
bootCodeVersion = d01.
#
=================代码如下=================
|
|