NXP S32K314读写PFLASH
S32K314读写PFLASH方法
准备工作
- 开发、调试工具:S32DS 3.5,S32K3xx系列RTD(符合AUTOSAR标准的SDK)安装包;
- VECTOR AUTOSAR APP源码,或其他厂商提供的AUTOSAR APP源码;
RTD安装后的目录
RTD安装后的目录功能列表,RTD操作FLASH相关接口在Fls_Ts目录中达芬奇工具配置后的AUTOSAR APP代码目录
操作方法
1.新建C文件,需要包含操作FLASH的头文件C40_Ip.h
2.C40_Ip.h文件依赖“C40_Ip_Cfg.h”,这个文件由AUTOSAR配置工具生成,S32DS新建的工程没有这个文件
3.按照以下流程操作PFLASH:清除PFLASH需要读写的片区保护状态-》擦PFLASH需要读写的片区(单片区8kb)-》向PFLASH地址中写入数据
参考代码如下:
具体实现
清除扇区保护、擦扇区,填入对应扇区枚举,枚举列表在“C40_Ip_Cfg.h”文件中定义
读写PFLASH填对应地址,跨扇区操作需要分开读写2个扇区
.c读写接口封装
#include "pFlsCtrl.h"
#include "C40_Ip.h"
#define DO_START do {
#define DO_ASSERT(ex) if(ex) {break;}
#define DO_ASSERT_ASSIGNMENT(ex, exp) if(ex) {exp; break;}
#define DO_ASSERT_COUT_LOG(ex, log) if (ex) { LOG_DEBUG(log); break;}
#define DO_END } while(0);
#define MCU_APP_A C40_CODE_ARRAY_0_BLOCK_1_S128
#define MCU_APP_A_ADDR 0x00500000U
#define MCU_APP_B C40_CODE_ARRAY_0_BLOCK_2_S256
#define MCU_APP_B_ADDR 0x00600000U
C40_ConfigType C40ConfigSetVs0InitCfg =
{
NULL_PTR, /* FlsStartFlashAccessNotif */
NULL_PTR, /* FlsFinishedFlashAccessNotif */
};
LS_PFLASH_STATE LsPflashEraseState = LS_PFLASH_MAX;
LS_PFLASH_STATE LsPflashWriteState = LS_PFLASH_MAX;
static inline unsigned char clearFlashLock(unsigned char AorB)
{
unsigned char Ret = LS_PFLASH_FAIL; //error
C40_Ip_StatusType C40Status = STATUS_C40_IP_ERROR;
if (UPTADE_A == AorB) {
C40Status = C40_Ip_GetLock(MCU_APP_A);
if (STATUS_C40_IP_SECTOR_PROTECTED == C40Status) {
if (STATUS_C40_IP_SUCCESS == C40_Ip_ClearLock(MCU_APP_A, FLS_MASTER_ID)) {
Ret = LS_PFLASH_SUCCESS;
}
} else if (STATUS_C40_IP_SECTOR_UNPROTECTED == C40Status) {
Ret = LS_PFLASH_SUCCESS;
} else {
//empty
}
} else {
C40Status = C40_Ip_GetLock(MCU_APP_B);
if (STATUS_C40_IP_SECTOR_PROTECTED == C40Status) {
if (STATUS_C40_IP_SUCCESS == C40_Ip_ClearLock(MCU_APP_B, FLS_MASTER_ID)) {
Ret = LS_PFLASH_SUCCESS;
}
} else if (STATUS_C40_IP_SECTOR_UNPROTECTED == C40Status) {
Ret = LS_PFLASH_SUCCESS;
} else {
//empty
}
}
return Ret;
}
LS_PFLASH_STATE checkPflashEraseState(void)
{
C40_Ip_StatusType InitStatus = C40_Ip_MainInterfaceSectorEraseStatus();
if (STATUS_C40_IP_BUSY == InitStatus) {
LsPflashEraseState = LS_PFLASH_BUSY;
} else if (STATUS_C40_IP_SUCCESS == InitStatus) {
LsPflashEraseState = LS_PFLASH_IDLE;
} else {
LsPflashEraseState = LS_PFLASH_ERROR;
}
return LsPflashEraseState;
}
LS_PFLASH_STATE checkPflashWriteState(void)
{
C40_Ip_StatusType InitStatus = C40_Ip_MainInterfaceWriteStatus();
if (STATUS_C40_IP_BUSY == InitStatus) {
LsPflashWriteState = LS_PFLASH_BUSY;
} else if (STATUS_C40_IP_SUCCESS == InitStatus) {
LsPflashWriteState = LS_PFLASH_IDLE;
} else {
LsPflashWriteState = LS_PFLASH_ERROR;
}
return LsPflashWriteState;
}
unsigned char lsPflsIint(void)
{
unsigned char Ret = LS_PFLASH_FAIL;
if (STATUS_C40_IP_SUCCESS == C40_Ip_Init(&C40ConfigSetVs0InitCfg)) {
Ret = LS_PFLASH_SUCCESS;
}
return Ret;
}
void lsPflsErase(unsigned char AorB)
{
if (LS_PFLASH_SUCCESS == clearFlashLock(AorB)) {
if (UPTADE_A == AorB) {
C40_Ip_MainInterfaceSectorErase(MCU_APP_A , FLS_MASTER_ID);
} else {
C40_Ip_MainInterfaceSectorErase(MCU_APP_B, FLS_MASTER_ID);
}
}
}
void lsPflsWrite(unsigned char AorB, unsigned char * WriteData, unsigned short DataLen)
{
if (UPTADE_A == AorB) {
C40_Ip_MainInterfaceWrite(MCU_APP_A_ADDR, DataLen, WriteData, FLS_MASTER_ID);
} else {
C40_Ip_MainInterfaceWrite(MCU_APP_B_ADDR, DataLen, WriteData, FLS_MASTER_ID);
}
}
unsigned char lsPflsRead(unsigned char AorB, unsigned char* ReadData, unsigned short ReadLen)
{
unsigned char Ret = LS_PFLASH_SUCCESS;
DO_START;
if (UPTADE_A == AorB) {
DO_ASSERT_ASSIGNMENT(STATUS_C40_IP_ERROR == C40_Ip_Read(MCU_APP_A_ADDR, ReadLen, ReadData), Ret = LS_PFLASH_FAIL);
DO_ASSERT_ASSIGNMENT(STATUS_C40_IP_ERROR == C40_Ip_Compare(MCU_APP_A_ADDR, ReadLen, ReadData), Ret = LS_PFLASH_FAIL);
} else {
DO_ASSERT_ASSIGNMENT(STATUS_C40_IP_ERROR == C40_Ip_Read(MCU_APP_B_ADDR, ReadLen, ReadData), Ret = LS_PFLASH_FAIL);
DO_ASSERT_ASSIGNMENT(STATUS_C40_IP_ERROR == C40_Ip_Compare(MCU_APP_B_ADDR, ReadLen, ReadData), Ret = LS_PFLASH_FAIL);
}
DO_END;
return Ret;
}
头文件.h
#ifndef __PFLSCTRL_H__
#define __PFLSCTRL_H__
///接口使用说明
///先擦后写,擦之前需要检查扇区是否写保护
#ifndef LS_PFLASH_SUCCESS
#define LS_PFLASH_SUCCESS (1U)
#endif
#ifndef LS_PFLASH_FAIL
#define LS_PFLASH_FAIL (0U)
#endif
#ifndef FLS_MASTER_ID
#define FLS_MASTER_ID (0U)
#endif
#ifndef UPTADE_A
#define UPTADE_A (0U)
#endif
#ifndef UPTADE_B
#define UPTADE_B (1U)
#endif
#pragma pack(1)
typedef struct _FLASG_PARAMS
{
unsigned int WriteCounter;
unsigned int ChargingCycles;
unsigned int Counter;
unsigned int Soh;
}FLASG_PARAMS;
typedef enum
{
LS_PFLASH_BUSY = 0U,
LS_PFLASH_ERROR,
LS_PFLASH_IDLE,
LS_PFLASH_MAX
}LS_PFLASH_STATE;
#pragma pack ()
///清除扇区读写保护
extern LS_PFLASH_STATE checkPflashEraseState(void);
///检查写操作状态
extern LS_PFLASH_STATE checkPflashWriteState(void);
///pflash操作初始化
extern unsigned char lsPflsIint(void);
///pflash擦
extern void lsPflsErase(unsigned char AorB);
///pflash写
extern void lsPflsWrite(unsigned char AorB, unsigned char* WriteData, unsigned short DataLen);
///pflash读
extern unsigned char lsPflsRead(unsigned char AorB, unsigned char* ReadData, unsigned short ReadLen);
#endif /* __PFLSCTRL_H__ */
接口使用示例
#include "pFlsCtrl.h"
unsigned int PflsInit = 0;
uint8 DataT[16] = {0};
uint8 DataR[16] = { 0 };
uint8 Erae = 0;
uint8 Write = 0;
uint8 Read = 0;
int main(){
if (LS_PFLASH_SUCCESS == lsPflsIint()) {
PflsInit = 1;
}
(void)memset(DataT, 0x31, 16);
DataT[0] = 0x32;
DataT[1] = 0x33;
if (PflsInit == 1) {
if (LS_PFLASH_BUSY != checkPflashEraseState() && Erae == 0) {
lsPflsErase(UPTADE_A); Erae++;
}
if (LS_PFLASH_BUSY != checkPflashEraseState() && LS_PFLASH_BUSY != checkPflashWriteState() && Write == 0) {
lsPflsWrite(UPTADE_A, DataT, 16); Write++;
}
if (LS_PFLASH_BUSY != checkPflashWriteState() && Read == 0) {
Read++;
if (LS_PFLASH_SUCCESS == lsPflsRead(UPTADE_A, DataR, 16)) {
Read++;
}
}
}
return 0;
}
参考链接
https://blog.csdn.net/balance_c/article/details/124818176