📄 flash.c
字号:
/**********************************************************************
chengjy@felab, copyright 2002-2004
flash.c
flash操作部分。提供FLASH的写入和读出,暂时不支持锁定.
函数:
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);
void flashShutDown();
调用: 无
被调用:
netTask.c
STATUS t0x1600(char*pBuff);
BSP bootConfig.c
LOCAL char autoboot (int timeout);
说明: 现有的配置模式是基于如下地址处理方式的:
对单片flash,地址增加1,可以获取到16bit数据,而这个
地址的提供必须是cpu地址+8,相当于cpu地址+8,用
unsigned short型可以获取2byte数据。使用在board.h中定义的
FLASH2CPU_ADDR(flashAddr)宏来转换地址。
**********************************************************************/
#include "vxworks.h"
#include "semLib.h"
#include "taskLib.h"
#include "logLib.h"
#include "stdio.h"
#include "string.h"
#include "board.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);
void flashShutDown();
extern struct BoardWorkEnv boardWorkEnv;
SEM_ID semFlash; /*flash保护信号灯,在对flash操作前获取,操作结束释放*/
/**********************************************************************
void flashInit()
函数描述: Flash初始化。使用boardWorkEnv.boardInit和BOARD_FLASH_INITED
控制重新初始化。首先检查flash的ID,然后创建信号灯。
参数: 无
返回: 无
调用:
char flashIDCheck()
被调用:
netTask.c
STATUS t0x1600(char*pBuff);
**********************************************************************/
void flashInit()
{
if(!(boardWorkEnv.boardInit&BOARD_FLASH_INITED)) /*如果已经初始化了,不再重复进行*/
{
/*创建信号灯*/
semFlash = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
if(semFlash == NULL)
{
logMsg("flashInit: unable to create semFlash\n",0,0,0,0,0,0);
return;
}
/*检查芯片类型*/
if(flashIDCheck()!=STATUS_NORMAL)
{
logMsg("flashInit: only 28F320C3 is acceptable\n",0,0,0,0,0,0);
semDelete(semFlash);
return;
}
/*设置为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的整数倍, 则将最后的数据填在高位上。
在写之前必须保证对应的块已经经过了解锁和擦除。
参数: dataNum, flash的块序号,取值范围从1~63
pBuff, 需要写到flash的数据的内存首地址
buffLen, 需要写到flash的数据的长度,单位byte
返回: 如果成功写入返回STATUS_NORMAL,否则返回对应的出错标志。
调用: 无
被调用:
netTask.c
STATUS t0x1600(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。
参数: dataNum, flash的块序号,取值范围从1~63
pBuff, 从flash 读取到的数据存储的内存首地址
buffLen, 从flash 读取的数据的长度,单位byte
返回: 如果成功读取返回STATUS_NORMAL,否则返回对应的出错标志。
调用: 无
被调用:
BSP 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 flashDataErase(int dataNum,int eraseLen)
函数描述: 将从dataNum开始的地址擦除,如果eraseLen不是
块长度的整数倍,仍然将最后一块整体擦除。
参数: dataNum, flash的块序号,取值范围从1~63
eraseLen, 需要擦除的总长度,和将要写flash的长度对应相等
返回: 如果成功擦除返回STATUS_NORMAL,否则返回对应的出错标志。
调用:
char flashUnLock(int dataNum, int unLockLen)
被调用:
netTask.c
STATUS t0x1600(char*pBuff);
**********************************************************************/
char flashDataErase(int dataNum, int eraseLen)
{
FLASH_VALUE *addr;
FLASH_VALUE value;
int iBlock,lenBlock,endBlock;
int eraseTime = 0;
char stateReturn = STATUS_NORMAL;
int eraseDelay;
/*因为解锁函数内部调用了semTake和semGive,
因此必须放在flashDataErase函数调用semTake前*/
if(flashUnLock(dataNum,eraseLen)!=STATUS_NORMAL)
{
printf("unable to unlock block from %d for %d bytes\n",dataNum,eraseLen);
return(STATUS_ERROR);
}
/*获取flash控制权*/
if(semTake(semFlash,100)==ERROR)
{
printf("flashDataErase: unable to get semFlash\n");
return(STATUS_ERROR);
}
/*计算需要擦除的块数量*/
lenBlock = (eraseLen-1)/(FLASH_DATA_BLOCK_SIZE_W*2)+1;
endBlock = dataNum+lenBlock;
if(endBlock>FLASH_DATA_BLOCK_NUM) /*超过范围,擦除到最后一块为止*/
{
printf("flashDataErase: no more place for erase %d blocks\n",lenBlock);
endBlock = FLASH_DATA_BLOCK_NUM;
stateReturn = STATUS_WARNING;
}
printf("flashDataErase: block number 0x ");
/*逐块擦除*/
for(iBlock=dataNum;iBlock<endBlock;iBlock++)
{
printf("\b\b%2x",iBlock);
addr = FLASH2CPU_ADDR((FLASH_VALUE*)((UINT)iBlock*FLASH_DATA_BLOCK_SIZE_W));
/*开始擦除*/
*addr = FLASH_CC_ERASE_SETUP;
*addr = FLASH_CC_ERASE_CONFIRM;
eraseTime = 0;
/*读取状态*/
while(1)
{
/*不断检查是否擦除完毕*/
*addr = FLASH_CC_READ_STATUS;
value = *addr;
if((value & FLASH_CC_ERASE_CHECK1) == FLASH_CC_ERASE_CHECK1) /*擦除完毕*/
break;
else
{
eraseTime++;
for(eraseDelay=0;eraseDelay<10000;eraseDelay++);
if(eraseTime ==FLASH_ERASE_BLOCK_TIME) /*操作超时*/
{
printf("\nflashDataErase: can't erase block %d in time\n",iBlock);
stateReturn = STATUS_ERROR;
break;
}
}
}
if(stateReturn==STATUS_NORMAL)
{
/*检查是否正确擦除*/
if((value & FLASH_CC_ERASE_CHECK2) != 0x0000) /*擦除出错*/
{
printf("\nflashDataErase: error in erase block %d, value =%x\n",iBlock,value);
stateReturn = STATUS_ERROR;
}
/*正确擦除,回到read array状态*/
*FLASH2CPU_ADDR(0) = FLASH_CC_READ_ARRAY;
}
else
{
break;
}
}
printf("\n");
printf("flashDataErase: erase finished\n");
/*无论是否正确擦除,都回到read array状态*/
*FLASH2CPU_ADDR(0) = FLASH_CC_READ_ARRAY;
/*释放flash控制权*/
semGive(semFlash);
/*全部擦除完毕*/
return(stateReturn);
}
/**********************************************************************
char flashUnLock(int dataNum, int unLockLen)
函数描述: 将从dataNum开始的地址解锁,如果eraseLen不是
块长度的整数倍,仍然将最后一块解锁。
参数: dataNum, flash的块序号,取值范围从1~63
unLockLen, 需要解锁的总长度,和将要写flash的长度对应相等
返回: 如果成功解锁返回STATUS_NORMAL,否则返回对应的出错标志。
调用: 无
被调用:
char flashDataErase(int dataNum, int eraseLen)
**********************************************************************/
char flashUnLock(int dataNum, int unLockLen)
{
FLASH_VALUE *addr;
int iBlock,lenBlock,endBlock;
char stateReturn = STATUS_NORMAL;
/*获取flash控制权*/
if(semTake(semFlash,100)==ERROR)
{
printf("flashUnLock: unable to get semFlash\n");
return(STATUS_ERROR);
}
/*计算需要解锁的块数量*/
lenBlock = (unLockLen-1)/(FLASH_DATA_BLOCK_SIZE_W*2)+1;
endBlock = dataNum+lenBlock;
if(endBlock>FLASH_DATA_BLOCK_NUM) /*超过范围,解锁到最后一块为止*/
{
printf("flashUnLock: no more place for unlock %d blocks\n",lenBlock);
endBlock = FLASH_DATA_BLOCK_NUM;
stateReturn = STATUS_WARNING;
}
/*逐块解锁*/
for(iBlock=dataNum;iBlock<endBlock;iBlock++)
{
addr = FLASH2CPU_ADDR((FLASH_VALUE*)((UINT)iBlock*FLASH_DATA_BLOCK_SIZE_W));
/*开始解锁*/
*addr = FLASH_CC_CONFIG_SETUP;
*addr = FLASH_CC_CONFIG_CONFIRM;
/*恢复到read array状态*/
*addr = FLASH_CC_READ_ARRAY;
}
/*释放信号灯*/
semGive(semFlash);
return(stateReturn);
}
/**********************************************************************
char flashIDCheck()
函数描述: 检查flash 芯片类型
参数: 无
返回: 如果是软件要求的flash,返回STATUS_NORMAL,否则返回STATUS_ERROR
调用: 无
被调用:
void flashInit()
**********************************************************************/
char flashIDCheck()
{
FLASH_VALUE id1,id2;
/*设置为read identify 模式*/
*FLASH2CPU_ADDR(0) = FLASH_CC_READ_IDENTIFY;
/*读芯片代号*/
id1 = *FLASH2CPU_ADDR(0);
id2 = *FLASH2CPU_ADDR(1);
/*根据芯片是否是28F320B3做出返回值*/
if( (id1==FLASH_28F320C3_ID) && ((id2==FLASH_28F320C3_IDENT_T)||(id2==FLASH_28F320C3_IDENT_B)) )
return(STATUS_NORMAL);
else
return(STATUS_ERROR);
}
/**********************************************************************
void flashShutDown()
函数描述: 关闭FLASH的操作,主要是解决一些在SHELL 下重复
使用flashInit()的信号灯没有删除的问题,在这里
删除信号灯,并将flash重新置到read array状态。
参数: 无
返回: 无
调用: 无
被调用:
netTask.c
STATUS t0x1600(char*pBuff);
**********************************************************************/
void flashShutDown()
{
if(boardWorkEnv.boardInit&BOARD_FLASH_INITED)
{
/*恢复成read array 状态*/
*FLASH2CPU_ADDR(0) = FLASH_CC_READ_ARRAY;
/*删除flash信号灯*/
semDelete(semFlash);
boardWorkEnv.boardInit = boardWorkEnv.boardInit & (~(BOARD_FLASH_INITED));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -