⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcl_gdi_eeprom.c

📁 用一个Flash的两个扇区虚拟一个Eeprom
💻 C
📖 第 1 页 / 共 3 页
字号:
/**********************************************************************************

File Name   : TCL_GDI_Eeprom.c

Description : virtual eeprom manage, i use one sector of flash simulate eeprom

COPYRIGHT (C) 

Date               Modification                                             Name
----------------------------------------------------------------------------------
20070712        Created                                                 JokQu
<$ModMark> (do not move/delete)
***********************************************************************************/
#include <stdio.h>
#include "stddefs.h"      

#define  USE_VIRTUAL_EEPROM 	/* 使用虚拟eeprom(用一个flash 扇区虚拟eeprom)*/

#ifdef USE_VIRTUAL_EEPROM
#include "TCL_GDI_Flash.h"
#else
#include "ste2p.h"
#endif

#include "TCL_Define.h"
#include "TCL_Error.h"
#include "TCL_Osp.h"
#include "TCL_Log.h"
#include "TCL_GDI_Eeprom.h"

#define TCL_GDI_EEPROM_DEBUG /* Eeprom 调试开关*/

/* 打印宏*/
#ifdef TCL_GDI_EEPROM_DEBUG
#define EEPROM_DEBUG(x) TCL_Log_Debug x
#else
#define EEPROM_DEBUG(x) 
#endif
#define EEPROM_ERROR(x)	 TCL_Log_Error x

static const TCL_CHAR	*TCL_Eeprom_Version 	= "tcl_eeprom-1.0.0";	/*eeprom 版本号 */
static TCL_BOOL 		gbEepromDriverInit		= TCL_FALSE;			/* eeprom 子系统是否初始化*/

#ifdef USE_VIRTUAL_EEPROM
#define TCL_GDI_TOTAL_EEPROM_SIZE 				(64 * 1024)	/* eeprom 总大小(一个扇区)*/
#define TCL_GDI_EEPROM_AREA_SIZE					(8 * 1024)	/* eeprom 大小*/
#define TCL_GDI_EEPGOM_AREA_AMOUNT				(TCL_GDI_TOTAL_EEPROM_SIZE /TCL_GDI_EEPROM_AREA_SIZE) /* eeprom 个数*/ 
#define TCL_GDI_WRITE_FLAG_BUFFER_LENGTH		(0x10)		/* 写标志字节数*/			
#define TCL_GDI_WRITE_FLAG 						(0x88)		/* 写标志 */	

#ifndef TCL_GDI_EEPROM_ONE_SECOND
#define TCL_GDI_EEPROM_ONE_SECOND	(ST_GetClocksPerSecond())		/* 一秒钟*/
#endif

/* 读/ 写buffer */
typedef struct _EEPROM_WRITE_BUFFER_	
{
	TCL_UINT16		uBufferLength;		/* buffer 字节数*/	
	TCL_BOOL		uNeedWriteToFlash;	/* 写Flash 标志TCL_TRUE: 需要把buffer 中的数据
										写入flash */
	TCL_UINT8		*pBuff;				/* buffer*/
	TCL_UINT8		*pWriteBuffer;		/* 此buffer 中的数据写入flash*/
} EEPROM_WRITE_BUFFER;

static TCL_UINT32 				gbCurAreaIndex 			= 0;					/* 当前操作的区域index */
static TCL_UINT32				gbFlashSectorNo			= 133;				/* 用来虚拟eeprom 的扇区号 */
static TCL_UINT32				gbFlashSectorNo2		= 134;				/* 用来虚拟eeprom 的扇区号 */
static TCL_UINT32 				giCurFlashSectorNo		= 133;				/* 当前在使用的扇区号*/
static EEPROM_WRITE_BUFFER 	EepromBuffer; 								/* write/read buffer */
static TCL_UINT32 				uLastWriteFlashTime 	= 0;					/* 上次写flash 的时间*/
static TCL_BOOL 				bFirstWriteFlash 		= TCL_TRUE;			/* 是否是第一次写flash */	
static TCL_UINT32				guWriteCount			= 0;

static TCL_HANDLE				gEepromTaskId			= NULL;				/* 任务句柄*/
static TCL_CHAR 				gcEepromTaskName[]	= "TaskEep";			/* 任务名称*/
static TCL_CHAR 				gcEepromSemName[]	= "SemEep";			/* 信号量名称*/
#else
STE2P_Handle_t				E2PHndl;
ST_DeviceName_t				E2PDeviceName	= "EEPROM";
extern ST_Partition_t        		 *SystemPartition;
#endif

static TCL_HANDLE				ghEepromMutex		= NULL;				/* 信号量句柄*/
static TCL_VOID Eeprom_Lock( TCL_VOID );
static TCL_VOID Eeprom_UnLock( TCL_VOID );


#ifdef USE_VIRTUAL_EEPROM
static TCL_VOID Eeprom_Task_Entry(TCL_VOID *pArg);
static TCL_UINT32 Eeprom_FlashWrite(TCL_UINT32 uFlashSectorNo,TCL_UINT32 uOffset, TCL_UINT32 uSize, TCL_UINT8 *uBuff,TCL_UINT32 *pAlreadyWriteLen );
static TCL_UINT32 Eeprom_FlashRead(TCL_UINT32 uFlashSectorNo, TCL_UINT32 uOffset, TCL_UINT32 uSize, TCL_UINT8 *uBuff ,TCL_UINT32 *pAlreadyReadLen);
static TCL_UINT32 Eeprom_InitBuffer(TCL_VOID);

extern ST_Partition_t          *SystemPartition;
#endif


/******************************************************************************
* Function:            TCL_GDI_Eeprom_Init
* Description:        eeprom 驱动初始化
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		void
* Output:              	none
* Return:        	TCL_NO_ERROR 	- 成功
				其它- 请参考TCL_GDI_EEPROM_RETURN_VALUE 定义
* Others: 		
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20070712						create
******************************************************************************/
TCL_UINT32 TCL_GDI_Eeprom_Init(TCL_VOID)
{	
	TCL_UINT32	uReturnValue = 0;
	#ifndef USE_VIRTUAL_EEPROM
	ST_ErrorCode_t		eErrCode;			/* STAPI 返回值*/
	STE2P_InitParams_t	InitParams;			/* E2P初始化参数*/
	STE2P_OpenParams_t	stE2POpenParams;	/* E2P open 参数*/	
	#endif
	
	/* 创建信号量*/
	ghEepromMutex = TCL_OSP_Mutex_Create("Eeprom");		
	if ( NULL == ghEepromMutex)
	{
		/* 创建信号量失败*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init - create ghEepromMutex failure( iReturnValue = %s)\n",
			TCL_GetErrorText(uReturnValue)));		
	
		return TCL_GDI_EEPROM_OSP_ERROR;
	}
		
	#ifdef USE_VIRTUAL_EEPROM
	/* 是否初始化?*/
	if ( TCL_TRUE == gbEepromDriverInit )
	{
		/* 已初始化*/
		/* 返回*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init - eeprom driver already initalized \n"));
		return TCL_GDI_EEPROM_ALREADY_INITIALIZED;	
	}
	else
	{	
		/* 没有初始化*/
		/* 初始化Buffer*/
		if ( TCL_NO_ERROR!= Eeprom_InitBuffer() )
		{
			/* 初始化Buffer 失败*/
			EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init --init buffer failure \n"));
			return TCL_GDI_EEPROM_INIT_BUFFER_FAILURE;
		}

		/* 创建信号量*/
		ghEepromMutex = TCL_OSP_Mutex_Create("Eeprom");		
		if ( NULL == ghEepromMutex)
		{
			/* 创建信号量失败*/
			EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init - create ghEepromMutex failure( iReturnValue = %s)\n",
				TCL_GetErrorText(uReturnValue)));		
		
			return TCL_GDI_EEPROM_OSP_ERROR;
		}


		/* 创建一任务用来定时写flash */
		gEepromTaskId = TCL_OSP_TaskCreate(gcEepromTaskName,
										TCL_GDI_EEPROM_TASK_STACK_SIZE,
										Eeprom_Task_Entry,
										TCL_GDI_EEPROM_TASK_PRIORITY,
										NULL);
		if ( NULL == gEepromTaskId )
		{
			/* 创建任务失败*/
			EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init -- create gEepromTaskId failure(eErrCode = %s)\n",
				TCL_GetErrorText( uReturnValue )));		
			
			return TCL_GDI_EEPROM_OSP_ERROR;		
		}

		/* 初始化虚拟eeprom 驱动成功*/
		gbEepromDriverInit = TCL_TRUE;
		return TCL_NO_ERROR;
	}
	#else


	/* 是否初始化?*/
	if ( TCL_TRUE == gbEepromDriverInit )
	{
		/* 已初始化*/
		/* 返回*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init - eeprom driver already initalized \n"));
		return TCL_GDI_EEPROM_ALREADY_INITIALIZED;	
	}
	else
	{		
		/* 没有初始化*/		
		strcpy( InitParams.I2CDeviceName, "I2CBACK" );			/* must match I2C Name	*/
		InitParams.BaseAddress	= NULL;						/* not memory-mapped	*/
		InitParams.MemoryWidth	= 1;							/* this is not used by driver	*/
		InitParams.SizeInBytes		= (8*1024 - 4);				/* M24C64	in use , Top 4 bytes for MFG id	*/
		InitParams.PagingBytes		= STE2P_SIZEOF_PAGE;		/*32*/	      /* max. number of	writes in page	*/
		InitParams.DeviceCode		= STE2P_SUPPORTED_DEVICE;	/*0xA0*/  /* Manufacturer's code            */
		InitParams.MaxSimOpen	= 2;							/* up to 2 simultaneous opens	*/
		InitParams.DriverPartition	= SystemPartition;

		/* 初始化eeprom 驱动*/
		eErrCode = STE2P_Init( E2PDeviceName, &InitParams );		
		if ( eErrCode != ST_NO_ERROR	)			
		{
			EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init - STE2P_Init failure(error = %s)",GetErrorText(eErrCode)));
			return TCL_GDI_EEPROM_INIT_FAILURE;
		}
		
		/* 初始化eeprom 成功*/
		EEPROM_DEBUG(("info: TCL_GDI_Eeprom_Init - STE2P_Init success\n"));
		
		stE2POpenParams.Offset = 0x0000;
    		stE2POpenParams.Length = 8*1024-4;    

		/* 打开eeprom 驱动*/
		eErrCode = STE2P_Open( E2PDeviceName,&stE2POpenParams,&E2PHndl );
		if ( ST_NO_ERROR != eErrCode )
		{		
			/* 打开eeprom 驱动失败*/
			EEPROM_ERROR(("error: TCL_GDI_Eeprom_Init - STE2P_Open failure(error = %s)",GetErrorText(eErrCode)));
			return TCL_GDI_EEPROM_OEPN_FAILURE;
		}

		/* 初始化eeprom 成功*/
		gbEepromDriverInit = TCL_TRUE;
		return TCL_NO_ERROR;
	}	
	#endif	
}


/******************************************************************************
* Function:		TCL_GDI_Eeprom_IsInit
* Description:		Eeprom 模块是否已初始化
* Calls:			omit
* Called By:		omit
* Table Accessed:	none
* Table Updated:	none
* Input:			none
* Output:			none
* Return:			TCL_TRUE - 已初始化
				TCL_FALSE - 未初始化
* Others:								
* Note:
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20070716						create
*******************************************************************************/
TCL_BOOL TCL_GDI_Eeprom_IsInit(TCL_VOID)
{
	return gbEepromDriverInit;
}


/******************************************************************************
* Function:            TCL_GDI_Eeprom_Write
* Description:        写eeprom
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		TCL_UINT32 auAddr	- 写地址			
				TCL_UINT32 auLength	- 写字节数(不能<= 0)	
				TCL_UINT8 *pBuff		- 写buffer(不能为NULL)
* Output:              	TCL_UINT32 *auAlreadyWriteLen - 实际写成功的字节数
* Return:        	TCL_NO_ERROR - 操作成功
				其它- 参考TCL_GDI_EEPROM_RETURN_VALUE 定义
* Others: 			
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20070712						create
******************************************************************************/
TCL_UINT32 TCL_GDI_Eeprom_Write(TCL_UINT32 auAddr,TCL_UINT32 auWriteLen,TCL_UINT8 *pBuff,TCL_UINT32 *auAlreadyWriteLen)
{
	#ifndef USE_VIRTUAL_EEPROM
	ST_ErrorCode_t 	eErrCode 			= ST_NO_ERROR;	/* STAPI 返回值*/
	#endif

	*auAlreadyWriteLen = 0;

	/* eeprom 子系统是否初始化?*/
	if ( TCL_FALSE == gbEepromDriverInit)
	{
		/* 没有*/
		/* 返回*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Write -- eeprom driver have not init\n"));
		return TCL_GDI_EEPROM_NOT_INITIALIZED;
	}	

	/* pBuff 是否为NULL*/	
	if ( NULL == pBuff )
	{	
		/* 为NULL */
		/* 返回*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Write --pbuff is NULL \n"));
		return TCL_GDI_EEPROM_PARAMTER_INVALID;
	}

	/* auAlreadyWriteLen 是否为NULL */
	if ( NULL == auAlreadyWriteLen )
	{
		/* 为NULL */
		/* 返回*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Write --auAlreadyWriteLen is NULL \n"));
		return TCL_GDI_EEPROM_PARAMTER_INVALID;
	}	

	/* auLength > 0?*/
	if ( auWriteLen <= 0 )
	{
		/* auLength <= 0*/
		/* 返回*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Write --aulength is 0 \n"));
		return TCL_GDI_EEPROM_PARAMTER_INVALID;
	}

	#ifdef USE_VIRTUAL_EEPROM
	/* 判断写地址和写字节数是否越界*/
	if ( ( auAddr + auWriteLen ) > ( TCL_GDI_EEPROM_AREA_SIZE - TCL_GDI_WRITE_FLAG_BUFFER_LENGTH ) )
	{
		/* 越界*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Write --address and write size is invalid ( auAddr + auWriteLen = %d, total size = %d)\n",
			auAddr + auWriteLen,TCL_GDI_EEPROM_AREA_SIZE - TCL_GDI_WRITE_FLAG_BUFFER_LENGTH));
		return TCL_GDI_EEPROM_PARAMTER_INVALID;
	}

	/* 等待信号量*/
	Eeprom_Lock();

	/* 将数据写入buffer 中*/
	memcpy(EepromBuffer.pBuff + auAddr,pBuff,auWriteLen);

	/* 置'需要写flash 标志' 为TCL_TRUE */
	EepromBuffer.uNeedWriteToFlash = TCL_TRUE;

	/* 释放信号量*/
	Eeprom_UnLock();

	*auAlreadyWriteLen = auWriteLen;
	#else

	/* 等待信号量*/
	Eeprom_Lock();
	
	/* 通过ST 的eeprom 驱动写eeprom */
	eErrCode = STE2P_Write(E2PHndl,
							auAddr,
							pBuff,
							auWriteLen,
							auAlreadyWriteLen);
	/* 写eeprom 成功*/
	if( ST_NO_ERROR == eErrCode )
	{		
		/* 成功*/
		/* 释放信号量*/
		Eeprom_UnLock();		
		
		EEPROM_DEBUG(("info: TCL_GDI_Eeprom_Write --STE2P_Write eeprom success\n"));
	}
	else
	{
		/* 失败*/
		EEPROM_ERROR(("error: TCL_GDI_Eeprom_Write --STE2P_Write eeprom failure(eErrCode =%d, error = %s) \n",
			eErrCode,GetErrorText(eErrCode)));

		/* 释放信号量*/
		Eeprom_UnLock();		
		
		return TCL_GDI_EEPROM_WRITE_FAILURE;
	}
	
	#endif
	
	/* 操作成功*/
	return TCL_NO_ERROR;
}


/******************************************************************************
* Function:            TCL_GDI_Eeprom_Read
* Description:        读eeprom
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		TCL_UINT32 auAddr 	- 读地址
				TCL_UINT32 auLength 	- 读字节数(不能<= 0)	
				TCL_UINT8 *pBuff 		- 读buffer(不能为NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -