单片机实战-flash存储架构模型

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、flash存储应用层模型
    • 1.1 应用层模型理论建立
    • 1.2 应用层模型代码建立
  • 二、flash存储传输层模型
    • 2.1 传输层模型理论建立
    • 2.2 传输层模型代码建立
  • 三、flash存储链层模型
    • 3.1 链路层模型理论建立
    • 3.2 链路层模型代码建立
  • 四 总结

前言

在单片机项目的编程中,存储模块是很常见的,所以有必要对存储模块进行架构分析并完成代码封装
此次文章以flash存储模块举例,主要讨论存储地址的划分、存储空间的划分、存储内容的格式、以及
代码如何分层的问题。

一、flash存储应用层模型

1.1 应用层模型理论建立

在存储模块中,我们可以将内存分为很多个块、每一个块存储不同的数据、而且存储的数据可能不止一个。这个时候应用层可以将内存抽象化为块设备,属性有如下:数据的长度、实际存储数据的长度、接受写入数据的缓存区、接受读出数据的缓存区、写入数据的条数(将来映射为地址)、读出数据的起始条数、读出数据的结束条数。块设置的状态可分为:空闲状态、du写请求、写挂起、写成功、写失败,读状态和写状态一样。当用户需要写入数据的时候我们,用户需要将数据的内容、哪个块、地址(条数)传入。有如下操作将写入的数据拷贝到定义好的缓存中、地址复制靠缓存中。将快设备的状态置为写请求。将块设置的状态置为写状态。当应用层的数据给传输层的时候,我们需要知道传出层的状态如下:
typedef void (*pDflashIf_InitType)(void);
typedef void (*pDflashIf_MainType)(void);
typedef void (*pDflashIf_ReadAllType)(void);
typedef uint8_t (*pDflashIf_WriteBankType)(uint16_t BankID, const uint8_t *BankData);
typedef uint8_t (*pDflashIf_GetIdleStatusType)(void);

typedef struct
{
pDflashIf_InitType MidInitMemory;
pDflashIf_MainType MidMainFunction;
pDflashIf_ReadAllType MidReadAll;
pDflashIf_WriteBankType MidWriteBank;
pDflashIf_GetIdleStatusType MidGetIdleStatus;
pDflashIf_InitType DrvInit;
pDflashIf_InitType DrvInitMemory;
pDflashIf_MainType DrvMainFunction;
}DflashIf_ApiType_Struct;
然后在主任务里面查询设备的状态来去给传输层传递数据。当设备是写状态的时候,我们将设备开始准备写。在准备写的操作中,需要知道传输层的状态是空闲,然后去查询设备有没有请求写,如果有就将数据和状态给传输层。

1.2 应用层模型代码建立

static void Dflash_PrepareWrite( void )
{
uint16 TempBankId;

if((uint8)TRUE == gv_stDflashIf_ApiFun[0u].MidGetIdleStatus())
{
	if(DFLASH_WRITE_PENDING == lv_stDflashM.lv_arrDflashWriteBankFlag[lv_stDflashM.usCurrWriteBankId])
	{
		DflashM_SetBankWriteFlag(lv_stDflashM.usCurrWriteBankId, DFLASH_WRITE_OK);
	}
	else
	{}
		for(TempBankId = 0u; TempBankId < (uint16)DFLASHM_BANK_MAX_NUM; TempBankId++ )
		{
			if(DFLASH_WRITE_REQ == lv_stDflashM.lv_arrDflashWriteBankFlag[TempBankId])
			{
				//д״ֵ̬Ϊ��
				DflashM_SetWriteBankStatus(TempBankId,FALSE);
		        LIB_Copy(gv_stDflashBankCfg[TempBankId].ucRamAdd,gv_stDflashBankCfg[TempBankId].ucKam1Add, gv_stDflashBankCfg[TempBankId].usLength);
				if((uint8)E_OK == gv_stDflashIf_ApiFun[0u].MidWriteBank(TempBankId,gv_stDflashBankCfg[TempBankId].ucRamAdd))  //DVM_WriteBank
				{
					DflashM_SetBankWriteFlag(TempBankId, DFLASH_WRITE_PENDING);
					lv_stDflashM.usWriteTimeOutCnt = DFLASH_WRITE_TIMEOUT_MAX_TIMER;
					lv_stDflashM.bSlDflashReqStatus = FALSE;
				}
				else
				{

				}
				lv_stDflashM.usCurrWriteBankId = TempBankId;
				break;
			}
			else
			{}
		}
}

}

二、flash存储传输层模型

2.1 传输层模型理论建立

在传输层我们要定义好块的起始地址和结束地址、块的数据长度、读写的起始地址和长度。
typedef struct
{
uint8 ucMode;
uint8 ucCtrStatus;
uint8 ucApiFlag;
uint8 ucBuff[1024];
uint8 ucReReadCnt;
uint8 ucReadBankStep;
uint8 ucReWriteCnt;
uint8 ucWriteBankStep;
uint16 usWriteBankId;
uint16 usReadBankId;
uint16 usCurWriteAmount;
uint16 usStartReadAmount;
uint16 usStopReadAmount;
} Dvm_Struct;

2.2 传输层模型代码建立

void DVM_MainFunction( void )
{
switch(gv_stDvM.ucMode)
{
case DVM_MODE_IDLE:
DVM_ModeIdleHandle();
break;
case DVM_MODE_READALL:
DVM_ModeReadAllHandle();
break;

case DVM_MODE_WRITE_BANK:
    DVM_ModeWriteBankHandle();
    break;

default:
    gv_stDvM.ucMode = DVM_MODE_IDLE;
    break;
}
switch(gv_stDvM.ucCtrStatus)
{
case DVM_CTR_READ_BANK:
    DVM_InternalReadBank();
    break;

case DVM_CTR_WRITE_BANK:
    DVM_InternalWriteBank();
    break;
default:
    gv_stDvM.ucCtrStatus = DVM_CTR_IDLE;
    break;
}

}

三、flash存储链层模型

3.1 链路层模型理论建立

typedef struct
{
DFJobResult_Enum ucJobResult;
DFJobType_Enum ucJob;
uint8 *ucDataPtr;
uint32 ulStartAddress;
uint32 ulLenIndex;
uint32 ulLength;
}DF_Struct;

3.2 链路层模型代码建立

void DF_MainFunction( void )
{

DFJobResult_Enum workResult = DF_JOB_OK;
if( DF_JOB_PENDING == lv_stDF.ucJobResult )
{
	switch( lv_stDF.ucJob )
	{
		case DF_JOB_READ:
			workResult = DF_DoJobRead();
			break;
		case DF_JOB_WRITE:
			workResult = DF_DoJobWrite();
			break;
		default:lv_stDF.ucJob = DF_JOB_IDLE;
			break;
	}
	
	lv_stDF.ucJobResult = workResult;


	if( DF_JOB_OK == lv_stDF.ucJobResult )
	{
		//DF_WriteDisable();
	}
	else if( DF_JOB_FAILED == lv_stDF.ucJobResult )
	{
		//DF_WriteDisable();

		LOG_DEBUG(LOG_MODULE_FLH,"SPI����\r\n");
	}
	else
	{
	       ;
	}
}

}

四 总结

对于存储设备完全可以按照上面的思路来编写驱动模型,具体代码实现,可以私信我。我

你可能感兴趣的:(单片机,架构,嵌入式硬件)