📄 fdi_fmt.c
字号:
if (SEM_APIMutexSemaphore != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_APIMutexSemaphore);
}
if (SEM_OpenStream != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_OpenStream);
}
if (SEM_FDIErrorMutex != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_FDIErrorMutex);
}
if (SEM_FDIErrorIndicator != SEM_NULL)
{
SEM_DESTROY(SEM_FDIErrorIndicator);
}
if (SEM_FlashWrite != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_FlashWrite);
}
#if 1 /* added by jjs */
if (SEM_FlashErase != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_FlashErase);
}
#endif /* added by jjs */
#if(DIRECT_ACCESS_VOLUME == TRUE)
#if 0 /* added by jjs */
if (SEM_FlashErase != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_FlashErase);
}
#endif /* added by jjs */
if (SEM_DAVReclRequest != SEM_NULL)
{
SEM_DESTROY(SEM_DAVReclRequest);
}
if (SEM_DAVReclLock != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_DAVReclLock);
}
if (SEM_DAVAPILock != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_DAVAPILock);
}
#endif /* DIRECT_ACCESS_VOLUME */
#ifdef CUSTOM_SEM_MTX
if(SEM_Mutex_Space != SEM_NULL)
{
SEM_DESTROY(SEM_Mutex_Space);
}
#endif
if (SEM_TotalSize != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_TotalSize);
}
#endif /* SEM_CREATE_DESTROY */
#if(DIRECT_ACCESS_VOLUME == TRUE)
#ifdef TESTING
/* E.5.0.600 START */
/* free RAM if previously allocated during object modification. */
if(Buff_ptr != NULL)
{
free(Buff_ptr);
Buff_ptr = NULL;
}
/* E.5.0.600 END */
#endif
#endif
}
#ifdef TESTING
taskUnsafe();
#endif
return status;
} /* END FDI_Terminate */
#if (INCLUDE_FORMAT == TRUE)
/*
#############################################################################
### FDI_Format
###
### DESCRIPTION:
### FDI_Format function is used during development to format the flash,
### for manufacturing, and in the field for crucial errors. The format
### will erase all data blocks and set up the block information. It will
### also preserve a wear leveling count if the option is enabled.
###
### PARAMETERS:
### IN:
###
###
### OUT:
### error : a descriptive error code
###
### RETURNS:
### ERR_NONE ERR_WRITE ERR_ERASE ERR_NOTEXISTS ERR_PARAM
###
*/
ERR_CODE
FDI_Format(void)
{
BLOCK_INFO block_information;
DWORD spare_erase_count = 0;
#if (DIRECT_ACCESS_VOLUME == TRUE)
FLASH_Info fdi_flash_info;
#endif /* DIRECT_ACCESS_VOLUME */
DWORD block_info_address;
HW_ERROR hw_status;
ERR_CODE status;
DWORD current_block;
BYTE wear_level_data_exists = FALSE;
#ifdef TIMING
/* Get timestamp for start of update */
COMM_getTimestamp(&FDI_APIfmt);
#endif
if (FDI_InitComplete == TRUE)
{
/* Call the ReadData function to read the data. */
if ((ReadModify((BYTE_PTR) & spare_erase_count, (DWORD_PTR)¤t_block,
0, sizeof(DWORD), ERASE_COUNT_ID, ERASE_COUNT_TYPE, 1, READ_DATA)) ==
HW_ERR_NONE)
{
wear_level_data_exists = TRUE;
}
/* DESTROY ALL TASKS AND SEMAPHORES and indicate */
/* THAT INIT HAS NOT OCCURRED */
FDI_InitComplete = FALSE;
FDI_Terminate();
}
/* E.5.0.596 START */
if ((SEM_FlashWrite == SEM_NULL) && /* check for existance */
((SEM_FlashWrite = SEM_MTX_CREATE()) == SEM_NULL))
{
return ERR_INIT;
}
if ((SEM_FlashErase == SEM_NULL) && /* check for existance */
((SEM_FlashErase = SEM_MTX_CREATE()) == SEM_NULL))
{
SEM_MTX_DESTROY(SEM_FlashWrite);
return ERR_INIT;
} /* This IF statement was added by jjs */
#if (DIRECT_ACCESS_VOLUME == TRUE)
#if 0 /* added by jjs */
if ((SEM_FlashErase == SEM_NULL) && /* check for existance */
((SEM_FlashErase = SEM_MTX_CREATE()) == SEM_NULL))
{
SEM_MTX_DESTROY(SEM_FlashWrite);
return ERR_INIT;
}
#endif /* added by jjs */
#endif /* DIRECT_ACCESS_VOLUME */
/* E.5.0.596 END */
for (current_block = 0;
current_block < FDV_BLOCKCOUNT;
current_block++)
{
block_info_address = BLOCK_ADDRESS(current_block + 1) -
sizeof(BLOCK_INFO);
/* if wear leveling data exists, preserve it */
if (wear_level_data_exists == TRUE)
{
hw_status = FlashDevRead((BYTE_PTR) &block_information,
block_info_address,
sizeof(BLOCK_INFO));
if (hw_status != HW_ERR_NONE)
{
return ERR_READ;
}
}
else
{
block_information.current_state = 0;
}
#ifdef TIMING
/* Get timestamp for start of update */
COMM_getTimestamp(&FDI_APIers);
#endif
/* erase block */
hw_status = FlashDevEraseBlock(BLOCK_ADDRESS(current_block));
if (hw_status != HW_ERR_NONE)
{
return ERR_ERASE;
}
#ifdef TIMING
/* Get timestamp for start of update */
COMM_getTimestamp(&FDI_APIersend);
#ifdef writeToFile
fprintf(rw,"time to erase one block is %1.0f usecs \n",
((float)(FDI_APIersend.low - FDI_APIers.low)) * 163.84);
#endif
logMsg("time to erase one block is %d ticks\n",
(int) (FDI_APIersend.low - FDI_APIers.low), 0, 0, 0, 0, 0);
#endif
if (block_information.current_state != BLOCK_INTEGRITY)
{
/* if wear leveling data exists, restore it */
if (wear_level_data_exists == TRUE)
{
/* this could be the spare block, use spare erase count */
block_information.erase_count = spare_erase_count + 1;
}
else
{
block_information.erase_count = 1;
}
}
else
{
block_information.erase_count += 1;
}
/*
* if last block, break out. This is used as the spare block on a fresh
* formatted media. There is no block information written on the spare
* block.
*/
if (current_block >= MAX_DATA_BLOCKS)
{
break;
}
/* set up block info header for block */
block_information.status = BLK_WRITE;
block_information.logical_block_number = current_block;
block_information.physical_copy = WORDMAX;
block_information.current_state = BLOCK_INTEGRITY;
block_information.reserved_byte = BYTEMAX;
block_information.physical_erase_count = DWORDMAX;
/* write block information to block */
hw_status = FlashDevWrite((BYTE_PTR) &block_information,
block_info_address,
sizeof(BLOCK_INFO));
if (hw_status != HW_ERR_NONE)
{
return ERR_WRITE;
}
} /* End of for. */
/* Note:The last block is a clean erased block to be used as spare block. */
#if(DIRECT_ACCESS_VOLUME == TRUE)
/* E.5.0.596 START */
/* create a binary semaphore for the FDI_Error functions. */
if ((SEM_DAVReclRequest == SEM_NULL) &&
((SEM_DAVReclRequest = SEM_BIN_CREATE()) == SEM_NULL))
{
return ERR_INIT;
} else if ((SEM_DAVReclLock == SEM_NULL) &&
((SEM_DAVReclLock = SEM_MTX_CREATE()) == SEM_NULL))
{
SEM_DESTROY (SEM_DAVReclRequest);
return ERR_INIT;
} else if ((SEM_DAVAPILock == SEM_NULL) &&
((SEM_DAVAPILock = SEM_MTX_CREATE()) == SEM_NULL))
{
SEM_DESTROY (SEM_DAVReclRequest);
SEM_MTX_DESTROY(SEM_DAVReclLock);
return ERR_INIT;
}
/* E.5.0.596 END */
if (DAV_Format(&fdi_flash_info) != ERR_NONE)
{
return ERR_FORMAT;
}
#endif /* DIRECT_ACCESS_VOLUME */
/* initialize logical block table, data lookup table, etc */
status = FDI_Init();
if (status != ERR_NONE)
{
return ERR_INIT;
}
/* place erase count for spare block into param */
#if (CONSISTENT_ACCESS_TIME == TRUE)
SET_LOOKUP_TABLE(ERASE_COUNT_TYPE, ERASE_COUNT_ID, WORDMAX, DWORDMAX,\
LOOKUP_TABLE_OSFIELD(ERASE_COUNT_TYPE, ERASE_COUNT_ID));
#else
SET_LOOKUP_TABLE(ERASE_COUNT_ID, WORDMAX, \
LOOKUP_TABLE_OSFIELD(ERASE_COUNT_TYPE, ERASE_COUNT_ID),\
ERASE_COUNT_TYPE);
#endif
hw_status = WriteData((BYTE_PTR) & block_information.erase_count, 0,
ERASE_COUNT_ID, sizeof(DWORD), ERASE_COUNT_TYPE,
WRITE_APPEND);
if (hw_status != HW_ERR_NONE)
{
return ERR_WRITE;
}
#ifdef TIMING
/* Get timestamp for start of update */
COMM_getTimestamp(&FDI_APIend);
#ifdef writeToFile
fprintf(rw,"time to format is %1.0f usecs \n",
((float)(FDI_APIend.low - FDI_APIfmt.low)) * 163.84);
#endif
logMsg("time to format is %d ticks\n", (int) (FDI_APIend.low -
FDI_APIfmt.low), 0, 0, 0, 0, 0);
#endif /* TIMING */
return ERR_NONE;
}
#endif /* INCLUDE_FORMAT */
/*****************************************************************************
* $Log: fdi_fmt.c $
* Revision 1.5 2003/01/16 06:36:14 wavis
* Remove call to FDI_Init at the start of FDI_Format, since this will fail for the case where FDI_Init has already failed once.
* Revision 1.4 2003/01/15 13:47:24 gzhu
* check in for jjs
* Revision 1.5 2003/01/07 17:04:05 jjs
* Revision 1.4 2003/01/07 11:41:20 jjs
* Revision 1.3 2003/01/03 15:58:12 jjs
* destroy SEM_FlashErase & SEM_FlashWrite semaphore when
* FDI_Terminate.
* Revision 1.2 2002/12/17 15:01:45 jjs
* Add FDI_Init if it hasn't been called before.
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -