S32K的flash组件使用(操作FLASH)

本文摘要:本文章介绍如何使用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

S32K148更多例程和源码以及最新内容下载地址:

nxp_s32k148_template: 使用NXP的S32KDS软件基于S32_SDK_S32K1xx_RTM_3.0.0编写的的S32K148各组件测试例程,亲测可用,带有注释,适用于S32K14X系列的芯片。 (gitee.com)

END 

  • 8
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
s32k sdk是一款基于NXP S32K系列芯片的软件开发工具包。其中的flash驱动组件是该sdk中的重要组成部分,用于实现对芯片内嵌flash的读写操作。以下是flash驱动组件使用详解。 首先,在使用flash驱动组件之前,需要在主函数中进行初始化操作。初始化主要包括设置flash的访问权限和操作类型等内容。初始化代码如下: flash_config_t flashConfig; FLASH_GetDefaultConfig(&flashConfig); FLASH_Init(&flashConfig); 初始化完成后,即可开始进行flash的读写操作flash的写操作需要先对flash进行擦除,然后再进行写操作。擦除操作分为扇区擦除和整片擦除两种方式。扇区擦除的代码如下: status_t FLASH_Erase(uint32_t start, uint32_t length, uint32_t type); 其中,start为擦除起始地址,length为擦除长度,type为擦除类型(可选择扇区擦除或整片擦除)。例如,扇区擦除可以使用以下代码: FLASH_Erase(0x00080000, FLASH_SECTOR_SIZE, kFLASH_ApiEraseKey); 擦除完成后,可以进行写操作。写操作分为单字节写和批量写两种方式。单字节写的代码如下: status_t FLASH_Program(uint32_t start, uint32_t* src, uint32_t length); 其中,start为写入起始地址,src为写入数据的指针,length为写入数据的长度。例如,单字节写可以使用以下代码: uint32_t data = 0x12345678; FLASH_Program(0x00080000, &data, sizeof(data)); 批量写的代码如下: status_t FLASH_ProgramOnce(uint32_t start, uint32_t* src, uint32_t length); 与单字节写相比,批量写会将多个数据连续地写入flash中。例如,批量写可以使用以下代码: uint32_t data[4] = {0x12345678, 0x9ABCDEF0, 0x11223344, 0x55667788}; FLASH_Program(0x00080000, data, sizeof(data)); 综上所述,s32k sdk中的flash驱动组件是一个非常重要的组件,可实现对芯片内嵌flash的读写操作。通过对flash驱动组件的详细了解和实践,可以更好地掌握芯片的使用方法和技巧,提高开发效率和质量。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿衰0110

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值