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

📄 flash.c

📁 嵌入式实时操作系统VxWorks下面的Flash驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************
 blueyna,2002-2003
 提供FLASH 28F320B3的写入和读出,暂时不支持锁定.
 
 说明:现有的配置模式是基于如下地址处理方式的:
        对单片flash,地址增加1,可以获取到16bit数据,而这个
        地址的提供必须是cpu地址+8,相当于cpu地址+8,用
        unsigned short型可以获取2byte数据。使用在flash.h中定义的
        FLASH2CPU_ADDR(flashAddr)宏来转换地址。
 **********************************************************************/
#include "vxworks.h"
#include "semLib.h"
#include "taskLib.h"
#include "logLib.h"
#include "stdio.h"
#include "string.h"

#include "flash.h"

void flashInit();
char flashIDCheck();
char flashDataSet(int dataNum,char *pBuff,int buffLen);
char flashDataGet(int dataNum,char *pBuff,int buffLen);
char flashDataErase(int dataNum, int eraseLen);
char flashUnLock(int dataNum, int unLockLen);
char flashShutDown();

char flashTest(int testBlockNum);

extern struct BoardIndex 	boardIndex;
extern struct BoardWorkEnv	boardWorkEnv;

SEM_ID semFlash;	/*flash保护信号灯,在对flash操作前获取,操作结束释放*/

/**********************************************************************
 void flashInit()
 函数描述:Flash初始化
 调用:		
 			char flashIDCheck()
 被调用:
 		usrFCIRoot.c
 			void usrFCIRoot();
 **********************************************************************/
void flashInit()
{
	if(!(boardWorkEnv.boardInit&BOARD_FLASH_INITED))	/*如果已经初始化了,不再重复进行*/
	{
		boardWorkEnv.boardInit = boardWorkEnv.boardInit & (~(BOARD_FLASH_INITED));

		/*创建信号灯*/
		semFlash = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
		if(semFlash == NULL)
		{
			printf("flashInit: unable to create semFlash\n");
			exit(-1);
		}

	 	/*检查芯片类型*/
	 	if(flashIDCheck()!=STATUS_NORMAL)
	 	{
	 		printf("flashInit: only 28F320C3 is acceptable\n");
	 		semDelete(semFlash);
			exit(-1);
	 	}
	 	
		/*设置为read array模式*/
		*FLASH2CPU_ADDR(0) = FLASH_CC_READ_ARRAY;

		/*释放flash控制权*/
		semGive(semFlash);
		
		boardWorkEnv.boardInit = boardWorkEnv.boardInit | BOARD_FLASH_INITED;
	}
}

/**********************************************************************
 char flashDataSet(int dataNum,char *pBuff,int buffLen);
 函数描述:将从pBuff开始的buffLen长度的数据写入Flash 中
				dataNum对应的地址。使用datatNum对应FLASH的块号。
				如果buffLen 不是4的整数倍,则将最后的数据填
				在高位上。
 调用:	
 被调用:
			char flashTest(int testBlockNum)
  		FCITask.c
 			STATUS t0x1600(char*pBuff);
 			STATUS t0x1601(char*pBuff);
 **********************************************************************/
char flashDataSet(int dataNum,char *pBuff,int buffLen)
{
	char stateReturn=STATUS_NORMAL;
	int iBuff,iBuffEnd;
	
	FLASH_VALUE *addr;
	FLASH_VALUE value;


	/*获取flash控制权*/
 	if(semTake(semFlash,100)==ERROR)
	{
		printf("flashDataSet: unable to get semFlash\n");
		return(STATUS_ERROR);
	}

	/*计算是否过界,如果过界取到最后一个字节*/
	iBuffEnd = (FLASH_DATA_BLOCK_NUM-dataNum)*FLASH_DATA_BLOCK_SIZE_W*2;
	if(buffLen> iBuffEnd)
	{
		printf("flashDataSet: no enough place for write\n");
		stateReturn = STATUS_WARNING;
	}
	else
		iBuffEnd = buffLen;
 	 
	if(stateReturn == STATUS_NORMAL)
 	{
 		iBuffEnd = ((unsigned int)(buffLen/2))*2;	/*填充长度取整*/

		printf("flashDataSet: addr 0x        ");

		/*首次的地址和数据*/
		addr = FLASH2CPU_ADDR(dataNum*FLASH_DATA_BLOCK_SIZE_W);
		value = pBuff[0]*0x0100+pBuff[1];
		iBuff=0;
		while(iBuff<buffLen)
		{
			/*设置为program格式*/
			*addr = FLASH_CC_PROGRAM_SETUP;
			*addr = value;
				
			/*计算下一次的地址和数据*/
			iBuff=iBuff+2;
			value = pBuff[iBuff]*0x0100+pBuff[iBuff+1];
			addr = addr+4;

			if(((UINT)addr&0xFFFF)==0)
				printf("\b\b\b\b\b\b\b\b%8x",(UINT)addr);
				
			/*检查状态*/
			*addr = FLASH_CC_READ_STATUS;
			while(!((*addr)&FLASH_CC_SET_CHECK1))
			{
				*addr = FLASH_CC_READ_STATUS;
			}
			if(((*addr)&FLASH_CC_SET_CHECK2)!=0x0000)
			{
				printf("\nflashDataSet: error in set set addr %x value %x in time\n",(int)addr,value);
				stateReturn = STATUS_ERROR;	/*出错,停止配置,跳出*/
				break;
			}
		}

		printf("\n");
		if(stateReturn==STATUS_NORMAL)
			printf("flashDataSet: finished\n");
	}
 	else
 	{
 		printf("\nflashDataSet: no enough place for file,quit\n");
 		stateReturn = STATUS_ERROR;
 	}

	/*配置为array read*/
	*FLASH2CPU_ADDR(0) = FLASH_CC_READ_ARRAY;
	
 	/*释放FLASH控制权*/
	semGive(semFlash);
	return(stateReturn);
}

/**********************************************************************
 char flashDataGet(int dataNum,char *pBuff,int buffLen)
 函数描述:从Flash中dataNum对应地址开始读取buffLen个
 				字节到pBuff。
 调用:	
 被调用:
			char flashTest(int testBlockNum)
 		bootConfig.c
 			LOCAL char autoboot (int timeout)
 **********************************************************************/
char flashDataGet(int dataNum,char *pBuff,int buffLen)
{
	char stateReturn=STATUS_NORMAL;
	int iBuff,iBuffEnd;
	FLASH_VALUE * addr;
	FLASH_VALUE value;

	/*获取flash控制权*/
 	if(semTake(semFlash,100)==ERROR)
	{
		printf("flashDataGet: unable to get semFlash\n");
		return(STATUS_ERROR);
	}

	/*计算是否过界,如果过界取到最后一个字节*/
	iBuffEnd = (FLASH_DATA_BLOCK_NUM-dataNum)*FLASH_DATA_BLOCK_SIZE_W*2;
	
	if(buffLen> iBuffEnd)
	{
		printf("flashDataGet: no enough place for read\n");
		stateReturn = STATUS_WARNING;
	}
	else
		iBuffEnd = buffLen;
	
	if(stateReturn!= STATUS_ERROR)
	{

		/*读数据*/
		for(iBuff=0;iBuff<iBuffEnd;iBuff=iBuff+2)
		{

			addr = FLASH2CPU_ADDR(dataNum*FLASH_DATA_BLOCK_SIZE_W+iBuff/2);

			/*设置为read array, 然后读数据*/
			*(addr) = FLASH_CC_READ_ARRAY;
			value = *addr;		/*因为是直接付值,读取时也直接读取,保证字序一致*/

			if(iBuffEnd-iBuff>=2)	/* 普通情况*/
			{
				pBuff[iBuff]	= (char)((value>>8) &0xFF);
				pBuff[iBuff+1]	= (char)(value&0xFF);
			}
			else	/*不是整块情况,取高位*/
			{
				pBuff[iBuff] 	= (char)((value>>8) &0xFF);
			}
		}
		/*设置为read array状态*/
		*FLASH2CPU_ADDR(0) = FLASH_CC_READ_ARRAY;
	}

	/*释放flash控制权*/
	semGive(semFlash);

	return (stateReturn);
}


/**********************************************************************
 char flashTest(int testBlockNum)
 函数描述:flash联接测试。写入再读出,用以检查。由于
				 调用的flashDataSet(),flashDataGet()中已经调用了semTake(),semGive(),
				 因此这里使用taskLock(),taskUnlock()保证不会被重复调用.
 调用:	
		char flashDataSet(int dataNum,char *pBuff,int buffLen);
		char flashDataGet(int dataNum,char *pBuff,int buffLen);
		char flashDataErase(int dataNum, int eraseLen);
 被调用:
  		FCITask.c
 			STATUS t0x1300(char*pBuff);
 **********************************************************************/
char flashTest(int testBlockNum)
{
	char buffIn[1003];
	char buffOut[1003];
	char buffSave[FLASH_DATA_BLOCK_SIZE_W*4];
	int i;
	char state;
	char stateReturn = STATUS_NORMAL;
	int width;

	if(testBlockNum == 0)
		testBlockNum = 31;
	width = 2;

	taskLock();	/*任务切换锁定*/

	/*取出待测区存放的数据*/
	state = flashDataGet(testBlockNum,buffSave,FLASH_DATA_BLOCK_SIZE_W*width);
	if(state == STATUS_NORMAL)	/*成功取出*/
	{
		for(i=0;i<1003;i++)
		{
			buffIn[i] = i;
			buffOut[i] = i+10;
		}

		/*擦除原有数据*/

⌨️ 快捷键说明

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