📄 dms.c
字号:
/**
* Dms.c
*
* DESCRIPTION
* DMS api.
*
*/
#include "Dms.h"
#include "Cell.h"
#include "CellInfo.h"
#include "Sector.h"
#include "Device.h"
static BYTE lbDmsInitialized = 0;
/**
* dms_Format
*
* This function prepares the device for use by the DMS.
* Here all cells and their sizes are defined and written
* into the flash.
* This function requires the a global variable of name
* and type as folllows:
* SECTOR_DESCRIPTIOR gpDeviceArchitecture[];
* This is an array of structures that contain the flash
* structure information. See Ffs.h for more information.
* The global variable gpDeviceArchitecture must have the same
* value when dms_Format() and dms_Intialize() are called.
* After these two functions are complete this variable
* is no longer used.
* Each cell size within the array, must be evenly
* divisible by DATABLOCK_SIZE, insuring even DataBlock
* boundaries.
*
* The total number of blocks in the DMS cannot exceed 2^16
*
* Arguments
* aCellSize Array of DWORDS that contains the
* size, in bytes, of each cell.
* The array index is the Cell number
* and the value in the index is the
* size of the cell.
* awCellCount The number of elements in the array.
*/
DMS_STATUS dms_Format (DWORD *aCellSize, WORD awCellCount)
{
DMS_STATUS eStatus;
dms_Shutdown();
eStatus = dms_CellFormat(aCellSize, awCellCount);
if (eStatus != No_Error){
return eStatus;
}
return No_Error;
}
/**
* dms_Initialize()
*
* This function initializes the device. It must
* be called prior to accessing the DMS. In order
* for this function to execute the device must first
* be formatted.
* This function requires the a global variable of name
* and type as folllows:
* SECTOR_DESCRIPTIOR gpDeviceArchitecture[];
* This is an array of structures that contain the flash
* structure information. See Dms.h for more information.
* The global variable gpDeviceArchitecture must have the same
* value when dms_Format() and dms_Intialize() are called.
* After these two functions are complete this variable
* is no longer used.
* This function may return Not_Enough_Free_Blocks or
* No_Garbage_Blocks in which case the DMS is too full and
* it must be reformated with fewer blocks.
* dms_Read(), dms_Write(), and dms_Cleanup() cannot be used
* until dms_Initialize() completes returning No_Error.
*/
DMS_STATUS dms_Initialize (void)
{
DMS_STATUS eStatus;
eStatus = dms_CellInitialize();
if (eStatus != No_Error) {
lbDmsInitialized = 0;
return eStatus;
}
lbDmsInitialized = 1;
return No_Error;
}
/**
* dms_Cleanup()
* Finds the best sector to erase. If there are no garbage blocks then
* dms_SectorCleanup returns No_Garbage_Blocks. Otherwise it
* cleans one sector and returns No_Error if it was successful.
* If dms_Cleanup() returns anyting other than No_Garbage_Blocks
* or No_Error then the DMS software must be shutdown and
* reinitialized before attempting to read or write again. Failure
* to do so may cause lose of all data.
* Will return Dms_Not_Initialized if dms_Initialize() has not
* successfully completed.
*/
DMS_STATUS dms_Cleanup (void)
{
DMS_STATUS eStatus;
/*
* Check that DMS has been successfully initialized.
*/
if (!lbDmsInitialized) {
return Dms_Not_Initialized;
}
eStatus = dms_SectorCleanup();
if (eStatus != No_Error){
return eStatus;
}
return No_Error;
}
/**
* dms_Read()
*
* This function reads the contents of the cell
* specified by aiCellNumber. It stores the data
* in the user buffer, apBuffer.
* If dms_Read() returns anyting other than Invalid_Arguments_Error
* or No_Error then the DMS software must be shutdown and
* reinitialized before attempting to read or write again. Failure
* to do so may cause lose of all data.
* Will return Dms_Not_Initialized if dms_Initialize() has not
* successfully completed.
*/
DMS_STATUS dms_Read (WORD awCellIndex, void *apBuffer)
{
DMS_STATUS eStatus;
/*
* Check that DMS has been successfully initialized.
*/
if (!lbDmsInitialized) {
return Dms_Not_Initialized;
}
/*
* Verify the arguments passed to the function
* are valid before proceding.
*/
if (awCellIndex < 0 || awCellIndex >= dms_CellInfoGetCount() || apBuffer == NULL){
return Invalid_Arguments_Error;
}
eStatus = dms_CellRead((WORD) awCellIndex, (BYTE *)apBuffer);
if (eStatus != No_Error){
return eStatus;
}
return No_Error;
}
/**
* dms_Write()
*
* This function writes the contents of the user buffer
* (apBuffer) to the cell specified by aiCellNumber.
* Will not return until the write completes.
* The old cell data is destroyed when writing of the new
* cell has completed.
* If dms_Write() returns anyting other than Invalid_Arguments_Error
* or No_Error then the DMS software must be shutdown and
* reinitialized before attempting to read or write again. Failure
* to do so may cause lose of all data.
* Will return Dms_Not_Initialized if dms_Initialize() has not
* successfully completed.
*/
DMS_STATUS dms_Write (WORD awCellIndex, void *apBuffer)
{
DMS_STATUS eStatus;
/*
* Check that DMS has been successfully initialized.
*/
if (!lbDmsInitialized) {
return Dms_Not_Initialized;
}
/*
* Verify the arguments passed to the function
* are valid before proceding.
*/
if (awCellIndex < 0 || awCellIndex >= dms_CellInfoGetCount() || apBuffer == NULL){
return Invalid_Arguments_Error;
}
eStatus = dms_CellWrite((WORD) awCellIndex, apBuffer);
if (eStatus != No_Error){
return eStatus;
}
return No_Error;
}
/**
* dms_Shutdown
*
* This function shuts down the DMS and deallocates
* all memory.
* After this function is called then dms_Initialize()
* must be called before dms_Write(), dms_Read(), or
* dms_Cleanup() can be used.
*/
void dms_Shutdown(void)
{
/* Tell the Cell Layer to Shutdown */
dms_CellFinalize();
lbDmsInitialized = 0;
}
#ifdef DMS_DEBUG
/**
* dmsdbg_ErrorToString()
* Returns a pointer to a string that represents the error code.
*/
char* dmsdbg_ErrorToString(DMS_STATUS e) {
char *string;
switch (e) {
case No_Error: string = "No_Error"; break;
case Dms_Not_Initialized: string = "Dms_Not_Initialized"; break;
case No_Available_Blocks: string = "No_Available_Blocks"; break;
case Invalid_Sector_Count: string = "Invalid_Sector_Count"; break;
case Invalid_Sector_Size: string = "Invalid_Sector_Size"; break;
case Sector_Address_Overlap: string = "Sector_Address_Overlap"; break;
case Sector_Invalid_Address: string = "Sector_Invalid_Address"; break;
case Cannot_Obtain_Cell_Count: string = "Cannot_Obtain_Cell_Count"; break;
case No_Garbage_Blocks: string = "No_Garbage_Blocks"; break;
case Invalid_Arguments_Error: string = "Invalid_Arguments_Error"; break;
case Invalid_Cell_Status: string = "Invalid_Cell_Status"; break;
case Sector_Initialization_Failed: string = "Sector_Initialization_Failed"; break;
case Duplicate_Block: string = "Duplicate_Block"; break;
case Exact_Duplicate_Block: string = "Exact_Duplicate_Block"; break;
case More_Than_Two_Dirty_Cells: string = "More_Than_Two_Dirty_Cells"; break;
case Not_Enough_Free_Blocks: string = "Not_Enough_Free_Blocks"; break;
case Cell_Already_In_Process: string = "Cell_Already_In_Process"; break;
case Block_Already_In_Process: string = "Block_Already_In_Process"; break;
case Block_Not_Found: string = "Block_Not_Found"; break;
case Missing_Block_In_Cell: string = "Missing_Block_In_Cell"; break;
case Out_Of_Memory_Error: string = "Out_Of_Memory_Error"; break;
case Uneven_Cell_Size: string = "Uneven_Cell_Size"; break;
case Cell_Size_Too_Small: string = "Cell_Size_Too_Small"; break;
case Read_Sector_Header_Error: string = "Read_Sector_Header_Error"; break;
case Total_Cell_Size_Too_Large: string = "Total_Cell_Size_Too_Large"; break;
case Device_Not_Busy: string = "Device_Not_Busy"; break;
case Device_Confused: string = "Device_Confused"; break;
case Device_Invalid_Data: string = "Device_Invalid_Data"; break;
case Device_Erase_In_Progress: string = "Device_Erase_In_Progress"; break;
case Device_Write_Failed: string = "Device_Write_Failed"; break;
case Write_Count_Zero: string = "Write_Count_Zero"; break;
case Device_Memory_Map_Error: string = "Device_Memory_Map_Error"; break;
default: string = "Unknown" ; break;
}
return string;
}
#endif /* DMS_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -