问题描述:
vxWorks下TFFS文件系统创建好后,单任务写日志,一段时间后出现异常。具体见下。因为已经搞了一个多月了,仍旧没有解决问题,压力很大,特请求大家给予指导!我在这里先谢谢了!贴的内容比较多,是怕有疏漏的地方,请高手不辞辛苦,能够耐心指导。
开发环境:
vxWorks5.5+MPC852,flash芯片为JS28F128的norflash
空间安排:
flash大小16M(0x1000000),基地址0xfe000000,前0.5M(0x80000)做为boot,后面的做为flash文件系统
测试过程描述:
创建一个文本文件,通过一个任务不断的写日志信息,通常写了几百k(部分时候几M)后发现写日志任务出现exception,并且SUSPEND了,shell命令运行“ls”时也被阻塞SUSPEND的,错误信息包括但不全部为下:
1.
i0x1ecd030 (tApCtrlLogRecord): disk cache error: device 1ee2ed8 block 84 errno c0006, disk removed while writing data, possible data loss
0x1ecd030 (tApCtrlLogRecord): disk cache error: device 1ee2ed8 block 7281 errno c0006, disk removed while writing data, possible data loss
2.
0x1ea6288 (tApCtrlLogRecord): dosFsLib.c : Problem finding volume data, trying to use the next block as boot block.
0x1ea6288 (tApCtrlLogRecord): dosFsLib.c : Malformed boot sector. Offset 0, value 0.
通过反汇编后,发现错误地方在logical2physicl()附近,复位后有时会文件系统错误,表现为
1.
boot无法挂载文件系统,系统启动不了
2.
针对上次写入错误的那个文件日志,再次打开写入时,任务又异常,若打开写入前先删除此文件,再重新打开写入,则正常,但写入一段时间又出现如上问题。即错误的文件不能够再读写,否则又引起错误,删除后正常。
分析提问:
已经排除了应用层任务,写文件导致文件系统错误,看异常点是翻译层问题,但是翻译层为vxWorks提供的,不应该出现问题,那就是配置socket或MTD层时出现问题,查了很多网上资料,也测试了参数配置,问题依旧。因为该代码主要是公司以前人员留下的,我对这方面也是第一次搞,我已经搞了一个月也没结果,请大家帮助或给指明查找方向,谢谢!
主要配置部分代码:
#define FLASH_BASE_ADRS 0xFE000000 /* Flash memory base address */
#define FLASH_SIZE 0x01000000L /* Flash memory size */
(1)sysPhysMemDesc定义:
PHYS_MEM_DESC sysPhysMemDesc [] =
{
...
{
(void *) FLASH_BASE_ADRS,
(void *) FLASH_BASE_ADRS,
FLASH_SIZE, /* 16 m - I28F128 window */
VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE |
VM_STATE_MASK_GUARDED,
VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE_NOT |
VM_STATE_GUARDED
},
...
}
(2)格式化部分,能够正常格式化
STATUS sysTffsFormat (void)
{
STATUS status;
tffsDevFormatParams params =
{
#define HALF_FORMAT /* lower 0.5MB for bootimage, upper 1.5MB for TFFS */
#ifdef HALF_FORMAT
{0x80000l, 99, 1, 0x0, NULL, {0,0,0,0}, NULL, 2, 0, NULL},
#else
{0x000000l, 99, 1, 0x0, NULL, {0,0,0,0}, NULL, 2, 0, NULL},
#endif /* HALF_FORMAT */
/*FTL_FORMAT*/
FTL_FORMAT
};
/* we assume that the drive number 0 is SIMM */
status = tffsDevFormat (0, (int)¶ms);
return (status);
}
(3)文件系统mount也正常,可以通过FTP看到文件系统和创建的目录,tffsShow可以正常显示
0: socket=SIMM: type=0x8918, unitSize=0x20000, mediaSize=0x1000000
SOCKET层代码:
LOCAL void simmRegister (void)
{
FLSocket vol = flSocketOf (noOfDrives);
tffsSocket[noOfDrives] = "SIMM";
vol.window.baseAddress = FLASH_BASE_ADRS 12;
vol.cardDetected = simmCardDetected;
vol.VccOn = simmVccOn;
vol.VccOff = simmVccOff;
vol.initSocket = simmInitSocket;
vol.setWindow = simmSetWindow;
vol.setMappingContext = simmSetMappingContext;
vol.getAndClearCardChangeIndicator = simmGetAndClearCardChangeIndicator;
vol.writeProtected = simmWriteProtected;
noOfDrives++;
}
LOCAL void simmSetWindow
(
FLSocket vol /* pointer identifying drive */
)
{
/* Physical base as a 4K page */
vol.window.baseAddress = FLASH_BASE_ADRS 12;
flSetWindowSize (&vol, FLASH_SIZE 12);
}
MTD层代码:
FLStatus i28f016Identify(FLFlash vol)
{
FlashWPTR flashPtr;
flSetWindowBusWidth(vol.socket,16);/* use 16-bits */
flSetWindowSpeed(vol.socket,120); /* 120 nsec. */
flSetWindowSize(vol.socket,2); /* 8 KBytes */
flashPtr = (FlashWPTR) flMap(vol.socket,0);
vol.noOfChips = 0;
flashPtr[0] = READ_ID;
if (flashPtr[0] == 0x0089 && flashPtr[1] == 0x0018) {
/* Word mode */
vol.type = I28F016_FLASH;
vol.interleaving = 1;
flashPtr[0] = READ_ARRAY;
}
else {
/* Use standard identification routine to detect byte-mode */
flIntelIdentify(&vol, NULL,0);
if (vol.interleaving == 1)
vol.type = NOT_FLASH; /* We cannot handle byte-mode interleaving-1 */
}
if (vol.type == I28F016_FLASH) {
vol.chipSize = FLASH_SIZE;/*gxf_flash*/----这句改为FLASH_SIZE-0x80000(512K),仍旧错误
vol.erasableBlockSize = 0x20000L * vol.interleaving;
checkStatus(vol.interleaving == 1 ?
i28f016WordSize(&vol) :
flIntelSize(&vol, NULL,0));
/* Register our flash handlers */
vol.write = i28f016Write;
vol.erase = i28f016Erase;
return flOK;
}
else {
return flUnknownMedia; /* not ours */
}
写函数:
static FLStatus i28f016Write(FLFlash vol,
CardAddress address,
const void FAR1 *buffer,
int length,
FLBoolean overwrite)
{
/* Set timeout ot 5 seconds from now */
unsigned long writeTimeout = flMsecCounter + 5000;
FLStatus status;
int i;
FlashWPTR flashWPtr;
int wLength;
if (flWriteProtected(vol.socket))
return flWriteProtect;
if ((length & 1) || (address & 1)) /* Only write words on word-boundary */
return flBadParameter;
flashWPtr = (FlashWPTR) vol.map(&vol, address,length);
wLength = length1;
while (wLength = 1) {
*flashWPtr = SETUP_WRITE;
*flashWPtr = *(const unsigned short FAR1 *)buffer;
wLength--;
buffer = (const unsigned short FAR1 *) buffer + 1; /* bBuffer++; */
flashWPtr++;
while (!(flashWPtr[-1] & WSM_READY) && flMsecCounter
1楼
接上: while (!(flashWPtr[-1] & WSM_READY) && flMsecCounter
2楼
接上: while (!(flashWPtr[-1] & WSM_READY) && flMsecCounter
3楼
不好意思,不知问什么接不上了,再试试 while (!(flashWPtr[-1] & WSM_READY)&&flMsecCounter
4楼
while (!(flashWPtr[-1] & WSM_READY) && flMsecCounter小于 writeTimeout);} flashWPtr -= wLength; buffer -= length; /* bBuffer -= length */ status = flOK; for (i = 0; i
5楼
剩下了写入的部分代码和擦除的代码,不知何故带“
6楼
代码中带“小于”号,无法显示后面的内容,害我搞的提问更乱了 请看到的人谅解,等待大家给分析下.......
7楼
没看懂啊
8楼
内容太多啊