irpas技术客

S32K的flash组件使用(操作FLASH)_阿衰0110_flash组件

大大的周 7395

本文摘要:本文章介绍如何使用NXP官方软件S32KDS中的flash组件(操作FLASH)

开发平台:S32 Design Studio for ARM Version 2.2

SDK版本:S32_SDK_S32K1xx_RTM_3.0.0

使用芯片:S32K148

组件例程下载方式在文末!!!

1. 添加flash组件到工程

2. 打开flash配置页面

3. 配置flash参数(无特殊要求则采用默认配置)

一些参数的介绍:

P-Flash:存放程序代码的地方,即ROM

D-Flash:存放数据的地方,即RAM

FlexRAM:灵活配置的RAM,提供给用户以实现不同需求

S32K1XX系列的FTFC模块中断事件共有以下三个:

FTFC命令和CSEc命令完成中断事件;

FTFC读冲突错误中断事件;

FTFC ECC错误检测中断事件。

4.?配置好参数后点击如下图按钮或选项即可将配置数据更新至代码

5.?在代码中加入flash初始化的代码即可操作flash #include "main.h" //#define FLASH_test // flash操作的返回结果 static uint8_t flashResult = 0; // 系统参数 flash_ssd_config_t flashSSDConfig; // 使用EEPROM存储用户数据 #define EEPROM // EEPROM基地址 uint32_t EEPROM_BaseAddress = 0; // EEPROM当前存储大小 uint32_t EEPROM_Size = 0; void Flash_Init(void) { // /* Disable cache to ensure that all flash operations will take effect instantly, this is device dependent */ MSCM->OCMDR[0u] |= MSCM_OCMDR_OCM1(0x3u); MSCM->OCMDR[1u] |= MSCM_OCMDR_OCM1(0x3u); flashResult = FLASH_DRV_Init(&Flash1_InitConfig0, &flashSSDConfig); #ifdef LOG_printf SEGGER_RTT_printf(0,"["__FILE__":%d]flash init T(0)/F(!0) %d.\n", __LINE__, flashResult); #endif // 将flexRAM配置为EEPROM用于保存用户数据 #ifdef EEPROM if(flashSSDConfig.EEESize == 0u) { /* * Configure FlexRAM as EEPROM and FlexNVM as EEPROM backup region, * DEFlashPartition will be failed if the IFR region isn't blank. * Refer to the device document for valid EEPROM Data Size Code * and FlexNVM Partition Code. For example on S32K148: * - EEEDataSizeCode = 0x02u: EEPROM size = 4 Kbytes * - DEPartitionCode = 0x04u: EEPROM backup size = 64 Kbytes * */ flashResult = FLASH_DRV_DEFlashPartition(&flashSSDConfig, 0x02u, 0x04u, 0x0u, false, true); #ifdef LOG_printf SEGGER_RTT_printf(0,"["__FILE__":%d]DEFlashPartition T(0)/F(!0) %d.\n", __LINE__, flashResult); #endif /* Re-initialize the driver to update the new EEPROM configuration */ flashResult = FLASH_DRV_Init(&Flash1_InitConfig0, &flashSSDConfig); #ifdef LOG_printf SEGGER_RTT_printf(0,"["__FILE__":%d]flash init T(0)/F(!0) %d.\n", __LINE__, flashResult); #endif /* Make FlexRAM available for EEPROM */ flashResult = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL); #ifdef LOG_printf SEGGER_RTT_printf(0,"["__FILE__":%d]SetFlexRamFunction T(0)/F(!0) %d.\n", __LINE__, flashResult); #endif } else /* FLexRAM is already configured as EEPROM */ { /* Make FlexRAM available for EEPROM, make sure that FlexNVM and FlexRAM * are already partitioned successfully before */ flashResult = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL); #ifdef LOG_printf SEGGER_RTT_printf(0,"["__FILE__":%d]SetFlexRamFunction T(0)/F(!0) %d.\n", __LINE__, flashResult); #endif } EEPROM_BaseAddress = flashSSDConfig.EERAMBase; #endif #ifdef FLASH_test // 擦除flash INT_SYS_DisableIRQGlobal(); // S32K148的FLASH_DRV_EraseSector最小擦除扇区大小是 4KB flashResult = FLASH_DRV_EraseSector(&flashSSDConfig, 0x160000, 4096); #ifdef DEBUG_printf SEGGER_RTT_printf(0,"flash erase T(0)/F(!0) %d.\n",flashResult); #endif // 验证擦除 flashResult = FLASH_DRV_VerifySection(&flashSSDConfig, 0x160000, 4096 / 16, 1u); #ifdef DEBUG_printf SEGGER_RTT_printf(0,"flash verify T(0)/F(!0) %d.\n",flashResult); #endif uint8_t data[8] = {0x07,0x77,0,0,0,0,0,0}; // S32K148的FLASH_DRV_Program最小可写大小是8B flashResult = FLASH_DRV_Program(&flashSSDConfig, 0x160000, 8, data); // S32K148的FLASH_DRV_ProgramSection最小可写大小是1KB //flashResult = FLASH_DRV_ProgramSection(&flashSSDConfig, CANID_private_addr, 4096 / 16); #ifdef DEBUG_printf SEGGER_RTT_printf(0,"flash write T(0)/F(!0) %d.\n",flashResult); #endif uint32_t failAddr = 0; // 验证写数据 flashResult = FLASH_DRV_ProgramCheck(&flashSSDConfig, 0x160000, 8, data, &failAddr, 1u); #ifdef DEBUG_printf SEGGER_RTT_printf(0,"check write T(0)/F(!0) %d, fail address %x.\n", flashResult, failAddr); #endif INT_SYS_EnableIRQGlobal(); #endif } /** * @brief 向EEPROM写数据 * @param *data: 要写入的数据 * @param addrOffset: 要写入的地址偏移,基于EEPROM的基地址的偏移 * @param size: 要写入的数据的大小,以字节为单位 * @retval flashResult: 0为成功 非0为失败 * @note 写入数据大小最小1Byte */ uint8_t writeDataToEEPROM(uint8_t *data, uint32_t addrOffset, uint32_t size) { flashResult = FLASH_DRV_EEEWrite(&flashSSDConfig, EEPROM_BaseAddress + addrOffset, size, data); #ifdef DEBUG_printf uint8_t i = 0; for(i = 0; i < size; i++) { SEGGER_RTT_printf(0,"(flash)write EEPROM Byte %d : 0x%02x\n", i, data[i]); } SEGGER_RTT_printf(0,"(flash)write EEPROM T(0)/F(!0) %d\n", flashResult); #endif return flashResult; } /** * @brief 从EEPROM读数据 * @param *read: 数据存放地址 * @param addrOffset: 要读出的地址偏移,基于EEPROM的基地址的偏移 * @param size: 要读出的数据的大小,以字节为单位 * @retval None * @note 读出数据大小最小1Byte */ void readDataFromEEPROM(uint8_t *read, uint32_t addrOffset, uint32_t size) { uint8_t i = 0; for(i = 0; i < size; i++) { read[i] = *((uint32_t *)(EEPROM_BaseAddress + addrOffset + i)); #ifdef DEBUG_printf SEGGER_RTT_printf(0,"(flash)read EEPROM byte %d : 0x%02x\n", i, read[i]); #endif } } 6. 部分函数介绍

6.0 S32K1XXMCU字节对齐要求

6.1?FLASH_DRV_EraseSector()

该函数是扇区擦除flash,S32K14X系列最小擦除扇区大小是 4KB

uint32_t address = 0x1000; uint32_t size = 4096; // address 注意字节对齐,S32K148为16字节对齐,其他参见手册 // size 必须为4096的倍数,最小为4096 // 具体参数含义参见手册 FLASH_DRV_EraseSector(&flashSSDConfig, address, size);

6.2 FLASH_DRV_VerifySection()

该函数是校验扇区擦除,一般配合扇区擦除函数使用,用以校验擦除

uint32_t address = 0x1000; uint32_t size = 4096; // address 注意字节对齐,S32K148为16字节对齐,其他参见手册 // size 必须为4096的倍数,最小为4096 // 具体参数含义参见手册 FLASH_DRV_VerifySection(&flashSSDConfig, address, size / 16, 1u);

6.3 FLASH_DRV_Program()

该函数是写入flash,S32K148的最小可写大小是 8B

uint32_t address = 0x1000; uint32_t size = 8; uint8_t data[8] = {0}; // address 注意字节对齐,S32K148为16字节对齐,其他参见手册 // size 必须为8的倍数,最小为8 // data 要写的内容 // 具体参数含义参见手册 FLASH_DRV_Program(&flashSSDConfig, address, size, data);

6.4 FLASH_DRV_ProgramCheck()

该函数是校验写入flash,一般配合写入flash函数使用,用以校验写入

uint32_t address = 0x1000; uint32_t size = 8; uint8_t data[8] = {0}; Uint32_t failAddr = 0; // address 注意字节对齐,S32K148为16字节对齐,其他参见手册 // size 必须为8的倍数,最小为8 // data 校验的内容 // failAddr 出错的地址,为0则校验通过 // 具体参数含义参见手册 FLASH_DRV_ProgramCheck(&flashSSDConfig, address, size, data, &failAddr, 1u); 7. 特别注意事项

7.1 flash操作函数返回结果为0即为成功

7.2 flash地址必须按要求对齐(分区不同对齐要求不同)

7.3 flash操作前要关闭全局中断,操作后再开启

INT_SYS_DisableIRQGlobal(); FLASH_DRV_EraseSector(&flashSSDConfig, address, size); INT_SYS_EnableIRQGlobal();

7.4 flash操作时间较长,如果启动了看门狗,必须倍频看门狗频率延长复位时间,防止在操作flash时复位;或者FTFC的Callback回调函数,以便在Flash驱动API调用过程中重置看门狗,防止复位

// __attribute__((section (".code_ram")))”将此函数重映射到SRAM中运行,防止操作flash时意外修改此部分内容 void __attribute__((section (".code_ram"))) Flash_Command_Callback(void) { /* refresh the WDOG watchdog to avoid timeout reset */ WDOG->CNT = 0xB480A602U; }

7.5 flash操作时一般不操作当前程序所处地址范围,如果意外操作了当前程序地址,则可能会造成运行出错,程序跑飞

组件例程下载地址:

https://download.csdn.net/download/m0_50669075/85051862

END?


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #flash组件 #design #Studio #for #ARM #version