* for more details.\r
* -------------------------------- Arctic Core ------------------------------*/\r
\r
+/** @reqSettings DEFAULT_SPECIFICATION_REVISION=3.1.5 */\r
\r
\r
+/*\r
+ * Author: pete\r
+ *\r
+ * Part of Release:\r
+ * 3.1.5\r
+ *\r
+ * Description:\r
+ * Implements the Fee module\r
+ *\r
+ * Support:\r
+ * General Have Support\r
+ * -------------------------------------------\r
+ * FEE_DEV_ERROR_DETECT Y\r
+ * FeeIndex N (always 0)\r
+ * FEE_NVM_JOB_END_NOTIFICATION Y (Under ArcCore FEE_USE_JOB_NOTIFICATIONS is used)\r
+ * FEE_NVM_JOB_ERROR_NOTIFICATION Y (Under ArcCore FEE_USE_JOB_NOTIFICATIONS is used)\r
+ * FEE_POLLING_MODE Y\r
+ * FEE_VERSION_INFO_API Y\r
+ * FEE_VIRTUAL_PAGE_SIZE Y\r
+ *\r
+ * Block Have Support\r
+ * -------------------------------------------\r
+ * FeeBlockNumber Y\r
+ * FeeBlockSize Y\r
+ * FeeImmediateData N\r
+ * FeeNumberOfWriteCycles N\r
+ * FeeDeviceIndex N\r
+ *\r
+ * Published Information Have Support\r
+ * -------------------------------------------\r
+ * FEE_BLOCK_OVERHEAD N\r
+ * FEE_MAXIMUM_BLOCKING_TIME N\r
+ * FEE_PAGE_OVERHEAD N\r
+ */\r
\r
\r
+//lint -emacro(904,DET_VALIDATE_RV,DET_VALIDATE_NO_RV) //904 PC-Lint exception to MISRA 14.7 (validate macros).\r
\r
-\r
-\r
+// Exception made as a result of that NVM_DATASET_SELECTION_BITS can be zero\r
+//lint -emacro(835, MIN_BLOCKNR) // 835 PC-lint: A zero has been given as right argument to operator '<<' or '>>'\r
+//lint -emacro(835, GET_BLOCK_INDEX_FROM_BLOCK_NUMBER) // 835 PC-lint: A zero has been given as right argument to operator '<<' or '>>'\r
+//lint -emacro(835, GET_DATASET_FROM_BLOCK_NUMBER) // 835 PC-lint: A zero has been given as right argument to operator '<<' or '>>'\r
+//lint -emacro(778, GET_DATASET_FROM_BLOCK_NUMBER) // 778 PC-lint: Constant expression evaluates to 0 in operation '-'\r
+//lint -emacro(845, GET_DATASET_FROM_BLOCK_NUMBER) // 845 PC-lint: The right argument to operator '&' is certain to be 0\r
+//lint -emacro(835, BLOCK_INDEX_AND_SET_TO_BLOCKNR) // 835 PC-lint: A zero has been given as right argument to operator '<<' or '>>'\r
\r
#include <string.h>\r
#include "Fee.h"\r
#include "Fee_Cbk.h"\r
+#include "Fee_Memory_Cfg.h"\r
#include "NvM.h"\r
#include "Fls.h"\r
#include "Rte.h" // ???\r
//#include "SchM_NvM.h"\r
#include "MemMap.h"\r
\r
+#include <stdio.h>\r
+//#define DEBUG_FEE 1\r
+#if defined(DEBUG_FEE)\r
+#define DEBUG_PRINTF(format,...) printf(format,## __VA_ARGS__ );\r
+#else\r
+#define DEBUG_PRINTF(format,...)\r
+#endif\r
+\r
+\r
+\r
/*\r
* Local definitions\r
*/\r
*/\r
#if ( FEE_DEV_ERROR_DETECT == STD_ON )\r
#include "Det.h"\r
-#define VALIDATE(_exp,_api,_err ) \\r
+#define DET_VALIDATE(_exp,_api,_err ) \\r
if( !(_exp) ) { \\r
Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
}\r
\r
-#define VALIDATE_RV(_exp,_api,_err,_rv ) \\r
+#define DET_VALIDATE_RV(_exp,_api,_err,_rv ) \\r
if( !(_exp) ) { \\r
Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
return _rv; \\r
}\r
\r
-#define VALIDATE_NO_RV(_exp,_api,_err ) \\r
+#define DET_VALIDATE_NO_RV(_exp,_api,_err ) \\r
if( !(_exp) ) { \\r
Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
return; \\r
\r
#define DET_REPORTERROR(_module,_instance,_api,_err) Det_ReportError(_module,_instance,_api,_err)\r
\r
+#define MIN_BLOCKNR ((uint16)((uint16)1 << NVM_DATASET_SELECTION_BITS))\r
+\r
#else\r
-#define VALIDATE(_exp,_api,_err )\r
-#define VALIDATE_RV(_exp,_api,_err,_rv )\r
-#define VALIDATE_NO_RV(_exp,_api,_err )\r
+#define DET_VALIDATE(_exp,_api,_err )\r
+#define DET_VALIDATE_RV(_exp,_api,_err,_rv )\r
+#define DET_VALIDATE_NO_RV(_exp,_api,_err )\r
#define DET_REPORTERROR(_module,_instance,_api,_err)\r
#endif\r
\r
\r
/*\r
- * Block numbering recalculation macros
+ * Block numbering recalculation macros\r
*/\r
-#define GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(_blocknr) (((_blocknr) >> NVM_DATASET_SELECTION_BITS) - 1)\r
-#define GET_DATASET_FROM_BLOCK_NUMBER(_blocknr) ((_blocknr) & ((1 << NVM_DATASET_SELECTION_BITS) - 1))\r
-#define BLOCK_INDEX_AND_SET_TO_BLOCKNR(_blocknr, _set) ((_blocknr + 1) << NVM_DATASET_SELECTION_BITS | set)\r
+#define GET_DATASET_FROM_BLOCK_NUMBER(_blocknr) ((_blocknr) & ((uint16)((uint16)1u << NVM_DATASET_SELECTION_BITS) - 1u))\r
\r
/*\r
- * Page alignment macros
+ * Page alignment macros\r
*/\r
-#define PAGE_ALIGN(_size) ((((_size) + FEE_VIRTUAL_PAGE_SIZE - 1) / FEE_VIRTUAL_PAGE_SIZE) * FEE_VIRTUAL_PAGE_SIZE)\r
+#define PAGE_ALIGN(_size) ((uint16)((((_size) + FEE_VIRTUAL_PAGE_SIZE - 1) / FEE_VIRTUAL_PAGE_SIZE) * FEE_VIRTUAL_PAGE_SIZE))\r
\r
/*\r
- * Bank properties list
+ * Bank properties list\r
*/\r
#define NUM_OF_BANKS 2\r
typedef struct {\r
} BankPropType;\r
\r
static const BankPropType BankProp[NUM_OF_BANKS] = {\r
- {\r
- .Start = FEE_BANK1_OFFSET,\r
- .End = FEE_BANK1_OFFSET + FEE_BANK1_LENGTH\r
- },\r
- {\r
- .Start = FEE_BANK2_OFFSET,\r
- .End = FEE_BANK2_OFFSET + FEE_BANK2_LENGTH\r
- },\r
+ {\r
+ .Start = FEE_BANK1_OFFSET,\r
+ .End = FEE_BANK1_OFFSET + FEE_BANK1_LENGTH\r
+ },\r
+ {\r
+ .Start = FEE_BANK2_OFFSET,\r
+ .End = FEE_BANK2_OFFSET + FEE_BANK2_LENGTH\r
+ },\r
};\r
\r
\r
\r
/*\r
- * Macros and variables for flash bank administration
+ * Macros and variables for flash bank administration\r
*/\r
-typedef enum {\r
- BANK_STATUS_OLD = 0x00,\r
- BANK_STATUS_NEW = 0xFF\r
-} FlsBankStatusEnumType;\r
+#define BANK_STATUS_OLD 0x00\r
+#define BANK_STATUS_NEW 0xFF\r
typedef uint8 FlsBankStatusType;\r
\r
#define BANK_CTRL_PAGE_SIZE PAGE_ALIGN(sizeof(FlsBankStatusType))\r
\r
\r
/*\r
- * Macros and variables for flash block administration in flash
+ * Macros and variables for flash block administration in flash\r
*/\r
-typedef enum {\r
- BLOCK_STATUS_INUSE = 0x00,\r
- BLOCK_STATUS_INVALIDATED = 0x02,\r
- BLOCK_STATUS_EMPTY = 0xFF\r
-} BlockStatusEnumType;\r
+#define BLOCK_STATUS_INUSE 0x00\r
+#define BLOCK_STATUS_INVALIDATED 0x02\r
+#define BLOCK_STATUS_EMPTY 0xFF\r
typedef uint8 BlockStatusType;\r
\r
typedef struct {\r
uint16 BlockNo;\r
Fls_AddressType BlockDataAddress;\r
uint16 BlockDataLength;\r
-} FlsBlockDataType;\r
+} FlsBlockCtrlDataType;\r
\r
-#define BLOCK_DATA_PAGE_SIZE PAGE_ALIGN(sizeof(FlsBlockDataType))\r
+#define BLOCK_CTRL_DATA_PAGE_SIZE PAGE_ALIGN(sizeof(FlsBlockCtrlDataType))\r
\r
typedef union {\r
- FlsBlockDataType Data;\r
- uint8 Byte[BLOCK_DATA_PAGE_SIZE];\r
-} FlsBlockDataPageType;\r
+ FlsBlockCtrlDataType Data;\r
+ uint8 Byte[BLOCK_CTRL_DATA_PAGE_SIZE];\r
+} FlsBlockCtrlDataPageType;\r
\r
\r
#define BLOCK_MAGIC_LEN 4\r
-static const uint8 MagicMaster[BLOCK_MAGIC_LEN] = { 0xeb, 0xba, 0xba, 0xbe };\r
-#define BLOCK_MAGIC_PAGE_SIZE PAGE_ALIGN(BLOCK_MAGIC_LEN)\r
+static const uint8 BlockMagicMaster[BLOCK_MAGIC_LEN] = { 0xeb, 0xba, 0xba, 0xbe };\r
+#define BLOCK_CTRL_MAGIC_PAGE_SIZE PAGE_ALIGN(BLOCK_MAGIC_LEN)\r
\r
\r
typedef union {\r
uint8 Magic[BLOCK_MAGIC_LEN];\r
- uint8 Byte[BLOCK_MAGIC_PAGE_SIZE];\r
-} FlsBlockMagicPageType;\r
+ uint8 Byte[BLOCK_CTRL_MAGIC_PAGE_SIZE];\r
+} FlsBlockCtrlMagicPageType;\r
\r
typedef struct {\r
- FlsBlockDataPageType DataPage;\r
- FlsBlockMagicPageType MagicPage;\r
+ FlsBlockCtrlDataPageType DataPage;\r
+ FlsBlockCtrlMagicPageType MagicPage;\r
} FlsBlockControlType;\r
\r
#define BLOCK_CTRL_PAGE_SIZE PAGE_ALIGN(sizeof(FlsBlockControlType))\r
\r
-#define BLOCK_CTRL_DATA_POS_OFFSET 0\r
-#define BLOCK_CTRL_MAGIC_POS_OFFSET BLOCK_DATA_PAGE_SIZE\r
+#define BLOCK_CTRL_DATA_POS_OFFSET (/*lint --e(835)*/0) // Inform PC-Lint that I want the constant to be zero\r
+#define BLOCK_CTRL_MAGIC_POS_OFFSET BLOCK_CTRL_DATA_PAGE_SIZE\r
\r
typedef union {\r
FlsBlockControlType BlockCtrl;\r
\r
typedef struct {\r
uint8 BankNumber;\r
+ uint8 ForceGarbageCollect;\r
+ uint8 NofFailedGarbageCollect;\r
Fls_AddressType NewBlockAdminAddress;\r
Fls_AddressType NewBlockDataAddress;\r
FlsBankStatusType BankStatus[NUM_OF_BANKS];\r
\r
\r
/*\r
- * Variables for quick reporting of status and job result
+ * Variables for quick reporting of status and job result\r
*/\r
static MemIf_StatusType ModuleStatus = MEMIF_UNINIT;\r
static MemIf_JobResultType JobResult = MEMIF_JOB_OK;\r
\r
/*\r
- * Variables for the current job
+ * Variables for the current job\r
*/\r
typedef enum {\r
FEE_UNINITIALIZED = 0,\r
FEE_READ_REQUESTED,\r
FEE_READ,\r
\r
- FEE_CANCEL_REQUESTED,\r
- FEE_CANCEL_PENDING,\r
-\r
FEE_INVALIDATE_REQUESTED,\r
FEE_INVALIDATE_MARK_BANK_OLD,\r
FEE_WRITE_INVALIDATE_HEADER_REQUESTED,\r
FEE_GARBAGE_COLLECT_MAGIC_WRITE_REQUESTED,\r
FEE_GARBAGE_COLLECT_MAGIC_WRITE,\r
FEE_GARBAGE_COLLECT_ERASE,\r
+\r
+ FEE_CORRUPTED\r
+\r
} CurrentJobStateType;\r
\r
typedef struct {\r
CurrentJobStateType State;\r
- uint16 InStateCounter;\r
uint16 BlockNumber;\r
uint16 Length;\r
const Fee_BlockConfigType *BlockConfigPtr;\r
AdminFlsBlockType *AdminFlsBlockPtr;\r
union {\r
struct {\r
- uint16 NrOfBanks;\r
- uint16 BankNumber;\r
+ uint8 NrOfBanks;\r
+ uint8 BankNumber;\r
Fls_AddressType BlockAdminAddress;\r
}Startup;\r
struct {\r
Fls_AddressType WriteDataAddress;\r
}Invalidate;\r
struct {\r
- uint16 NrOfBanks;\r
- uint16 BankNumber;\r
+ uint8 BankNumber;\r
Fls_AddressType WriteAdminAddress;\r
Fls_AddressType WriteDataAddress;\r
- sint16 BytesLeft;\r
+ uint16 BytesLeft;\r
uint16 DataOffset;\r
}GarbageCollect;\r
} Op;\r
\r
static CurrentJobType CurrentJob = {\r
.State = FEE_IDLE,\r
- .InStateCounter = 0\r
+ //lint -e{785} PC-Lint (785) - rest of structure members is initialized when used.\r
};\r
\r
/*\r
- * Misc definitions
+ * Misc definitions\r
*/\r
-#define STATE_COUNTER_MAX 0xffff\r
-#define GARBAGE_COLLECTION_DELAY 10\r
-\r
+#define MAX_NOF_FAILED_GC_ATTEMPTS 5\r
/***************************************\r
* Local functions *\r
***************************************/\r
+uint16 GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(uint16 blockNumber) {\r
+ const Fee_BlockConfigType *FeeBlockCon;\r
+ uint16 BlockIndex = FEE_NUM_OF_BLOCKS + 1; // An invalid block\r
+\r
+ FeeBlockCon = Fee_Config.BlockConfig;\r
+ for (uint16 i = 0; i < FEE_NUM_OF_BLOCKS; i++)\r
+ {\r
+ if (FeeBlockCon[i].BlockNumber == blockNumber)\r
+ {\r
+ BlockIndex = i;\r
+ break;\r
+ }\r
+ }\r
\r
-#if (FEE_POLLING_MODE == STD_ON)\r
-static void SetFlsJobBusy()\r
-{\r
- /* Nothing needed here */\r
+ return BlockIndex;\r
}\r
\r
+\r
+#if (FEE_POLLING_MODE == STD_ON)\r
+#define SetFlsJobBusy() /* Nothing needs to be done here */\r
+\r
static boolean CheckFlsJobFinnished(void)\r
{\r
MemIf_JobResultType flsJobResult;\r
CurrentJob.State = FEE_IDLE;\r
ModuleStatus = MEMIF_IDLE;\r
JobResult = MEMIF_JOB_OK;\r
-\r
- if (Fee_Config.General.NvmJobEndCallbackNotificationCallback != NULL) {\r
- Fee_Config.General.NvmJobEndCallbackNotificationCallback();\r
+ if(!AdminFls.ForceGarbageCollect){\r
+ if (Fee_Config.General.NvmJobEndCallbackNotificationCallback != NULL) {\r
+ Fee_Config.General.NvmJobEndCallbackNotificationCallback();\r
+ }\r
}\r
}\r
\r
\r
static void AbortJob(MemIf_JobResultType result)\r
{\r
- CurrentJob.State = FEE_IDLE;\r
+ if(AdminFls.NofFailedGarbageCollect >= MAX_NOF_FAILED_GC_ATTEMPTS){\r
+ DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_GLOBAL_ID, FEE_FLASH_CORRUPT);\r
+ AdminFls.ForceGarbageCollect = 0;\r
+ CurrentJob.State = FEE_CORRUPTED;\r
+ } else {\r
+ CurrentJob.State = FEE_IDLE;\r
+ }\r
ModuleStatus = MEMIF_IDLE;\r
JobResult = result;\r
\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
CurrentJob.State = FEE_STARTUP_READ_BANK1_STATUS;\r
/* Read bank status of bank 1 */\r
- if (Fls_Read(BankProp[0].End - BANK_CTRL_PAGE_SIZE, (uint8*)&AdminFls.BankStatus[0], sizeof(FlsBankStatusType)) == E_OK) {\r
+ // PC-Lint exception (MISRA 11.4) - Pointer to pointer conversion ok by AUTOSAR\r
+ if (Fls_Read(BankProp[0].End - BANK_CTRL_PAGE_SIZE, /*lint -e(926)*/(uint8*)&AdminFls.BankStatus[0], sizeof(FlsBankStatusType)) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
AbortStartup(Fls_GetJobResult());\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
/* Read bank status of bank 2 */\r
CurrentJob.State = FEE_STARTUP_READ_BANK2_STATUS;\r
- if (Fls_Read(BankProp[1].End - BANK_CTRL_PAGE_SIZE, (uint8*)&AdminFls.BankStatus[1], sizeof(FlsBankStatusType)) == E_OK) {\r
+ // PC-Lint exception (MISRA 11.4) - Pointer to pointer conversion ok by AUTOSAR\r
+ if (Fls_Read(BankProp[1].End - BANK_CTRL_PAGE_SIZE, /*lint -e(926)*/(uint8*)&AdminFls.BankStatus[1], sizeof(FlsBankStatusType)) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
AbortStartup(Fls_GetJobResult());\r
\r
\r
/*\r
- * Check job result of bank status 2 read - request for block status reading
+ * Check job result of bank status 2 read - request for block status reading\r
*/\r
static void StartupReadBank2Status(void)\r
{\r
if (jobResult != MEMIF_JOB_OK) {\r
AbortStartup(jobResult);\r
} else {\r
- CurrentJob.Op.Startup.BlockAdminAddress = BankProp[CurrentJob.Op.Startup.BankNumber].End - BLOCK_CTRL_PAGE_SIZE - BANK_CTRL_PAGE_SIZE;\r
+ CurrentJob.Op.Startup.BlockAdminAddress = BankProp[CurrentJob.Op.Startup.BankNumber].End - (BLOCK_CTRL_PAGE_SIZE + BANK_CTRL_PAGE_SIZE);\r
CurrentJob.State = FEE_STARTUP_READ_BLOCK_ADMIN_REQUESTED;\r
}\r
}\r
}\r
\r
/*\r
- * Start of block admin read
+ * Start of block admin read\r
*/\r
static void StartupReadBlockAdminRequested(void)\r
{\r
\r
/*\r
* Check job result of block admin read, if all block processed finish\r
- * otherwise request for a new block admin read
+ * otherwise request for a new block admin read\r
*/\r
static void StartupReadBlockAdmin(void)\r
{\r
if (CheckFlsJobFinnished()) {\r
if (Fls_GetJobResult() == MEMIF_JOB_OK) {\r
if (RWBuffer.BlockCtrl.DataPage.Data.Status == BLOCK_STATUS_EMPTY) {\r
- VALIDATE(CurrentJob.Op.Startup.NrOfBanks != 0, FEE_STARTUP_ID, FEE_FLASH_CORRUPT);\r
+ DET_VALIDATE(CurrentJob.Op.Startup.NrOfBanks != 0, FEE_STARTUP_ID, FEE_FLASH_CORRUPT);\r
CurrentJob.Op.Startup.NrOfBanks--;\r
CurrentJob.Op.Startup.BankNumber = (CurrentJob.Op.Startup.BankNumber + 1) % 2;\r
- CurrentJob.Op.Startup.BlockAdminAddress = BankProp[CurrentJob.Op.Startup.BankNumber].End - BLOCK_CTRL_PAGE_SIZE - BANK_CTRL_PAGE_SIZE;\r
+ CurrentJob.Op.Startup.BlockAdminAddress = BankProp[CurrentJob.Op.Startup.BankNumber].End - (BLOCK_CTRL_PAGE_SIZE + BANK_CTRL_PAGE_SIZE);\r
} else { /* Block not empty */\r
- if ((memcmp(RWBuffer.BlockCtrl.MagicPage.Byte, MagicMaster, BLOCK_MAGIC_LEN) == 0) &&\r
+ if ((memcmp(RWBuffer.BlockCtrl.MagicPage.Magic, BlockMagicMaster, BLOCK_MAGIC_LEN) == 0) &&\r
((RWBuffer.BlockCtrl.DataPage.Data.Status == BLOCK_STATUS_INUSE) || (RWBuffer.BlockCtrl.DataPage.Data.Status == BLOCK_STATUS_INVALIDATED))) {\r
/* This is a valid admin block */\r
uint16 blockIndex;\r
}\r
}\r
}\r
+ // TODO Check wrap around here\r
CurrentJob.Op.Startup.BlockAdminAddress -= BLOCK_CTRL_PAGE_SIZE;\r
AdminFls.NewBlockAdminAddress = CurrentJob.Op.Startup.BlockAdminAddress;\r
}\r
/* If current bank is marked as old we need to switch to a new bank */\r
if (AdminFls.BankStatus[AdminFls.BankNumber] == BANK_STATUS_OLD) {\r
AdminFls.BankNumber = (AdminFls.BankNumber + 1) % 2;\r
- AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - BLOCK_CTRL_PAGE_SIZE - BANK_CTRL_PAGE_SIZE;\r
+ AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - (BLOCK_CTRL_PAGE_SIZE + BANK_CTRL_PAGE_SIZE);\r
AdminFls.NewBlockDataAddress = BankProp[AdminFls.BankNumber].Start;\r
}\r
/* We are done! */\r
}\r
\r
/*\r
- * Check job result of block data read
+ * Check job result of block data read\r
*/\r
static void Reading(void)\r
{\r
*/\r
static void BankHeaderOldWrite(uint8 bank)\r
{\r
+ /* Need to collect garbage */\r
+ AdminFls.ForceGarbageCollect = 1;\r
/* Mark the bank as old */\r
- memset(RWBuffer.BankCtrl.Data, 0xff, BLOCK_DATA_PAGE_SIZE);\r
+ memset(RWBuffer.BankCtrl.Data, 0xff, BANK_CTRL_PAGE_SIZE);\r
RWBuffer.BankCtrl.BankStatus = BANK_STATUS_OLD;\r
if (Fls_Write(BankProp[bank].End - BANK_CTRL_PAGE_SIZE, RWBuffer.BankCtrl.Data, BANK_CTRL_PAGE_SIZE) == E_OK) {\r
SetFlsJobBusy();\r
static void BlockHeaderDataWrite(void)\r
{\r
/* Write the header excluding the magic */\r
- memset(RWBuffer.BlockCtrl.DataPage.Byte, 0xff, BLOCK_DATA_PAGE_SIZE);\r
+ memset(RWBuffer.BlockCtrl.DataPage.Byte, 0xff, BLOCK_CTRL_DATA_PAGE_SIZE);\r
RWBuffer.BlockCtrl.DataPage.Data.Status = BLOCK_STATUS_INUSE;\r
RWBuffer.BlockCtrl.DataPage.Data.BlockNo = CurrentJob.BlockNumber;\r
RWBuffer.BlockCtrl.DataPage.Data.BlockDataAddress = AdminFls.NewBlockDataAddress;\r
RWBuffer.BlockCtrl.DataPage.Data.BlockDataLength = CurrentJob.Length;\r
- if (Fls_Write(CurrentJob.Op.Write.WriteAdminAddress + BLOCK_CTRL_DATA_POS_OFFSET, RWBuffer.Byte, BLOCK_DATA_PAGE_SIZE) == E_OK) {\r
+ if (Fls_Write(CurrentJob.Op.Write.WriteAdminAddress + BLOCK_CTRL_DATA_POS_OFFSET, RWBuffer.Byte, BLOCK_CTRL_DATA_PAGE_SIZE) == E_OK) {\r
SetFlsJobBusy();\r
AdminFls.NewBlockDataAddress += CurrentJob.Length;\r
AdminFls.NewBlockAdminAddress -= BLOCK_CTRL_PAGE_SIZE;\r
AdminFls.BankStatus[AdminFls.BankNumber] = BANK_STATUS_OLD;\r
\r
/* Change of bank */\r
- AdminFls.BankNumber ^= 0x1;\r
+ AdminFls.BankNumber ^= 0x1u;\r
AdminFls.NewBlockDataAddress = BankProp[AdminFls.BankNumber].Start;\r
- AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - BLOCK_CTRL_PAGE_SIZE - BANK_CTRL_PAGE_SIZE;\r
+ AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - (BLOCK_CTRL_PAGE_SIZE + BANK_CTRL_PAGE_SIZE);\r
\r
CurrentJob.Op.Write.WriteDataAddress = AdminFls.NewBlockDataAddress;\r
CurrentJob.Op.Write.WriteAdminAddress = AdminFls.NewBlockAdminAddress;\r
\r
\r
/*\r
- * Start of header write
+ * Start of header write\r
*/\r
static void WriteHeaderRequested()\r
{\r
\r
\r
/*\r
- * Start block data write
+ * Start block data write\r
*/\r
static void WriteDataRequested(void)\r
{\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
CurrentJob.State = FEE_WRITE_DATA;\r
/* Write the actual data */\r
+ DEBUG_PRINTF("WriteDataRequested: 0x%x 0x%x %d ",CurrentJob.Op.Write.WriteDataAddress, CurrentJob.Op.Write.RamPtr, CurrentJob.Length );\r
+\r
if (Fls_Write(CurrentJob.Op.Write.WriteDataAddress, CurrentJob.Op.Write.RamPtr, CurrentJob.Length) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
\r
\r
/*\r
- * Start magic write
+ * Start magic write\r
*/\r
static void WriteMagicRequested(void)\r
{\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
CurrentJob.State = FEE_WRITE_MAGIC;\r
- memset(RWBuffer.BlockCtrl.MagicPage.Byte, 0xff, BLOCK_MAGIC_PAGE_SIZE);\r
- memcpy(RWBuffer.BlockCtrl.MagicPage.Byte, MagicMaster, BLOCK_MAGIC_LEN);\r
- if (Fls_Write(CurrentJob.Op.Write.WriteAdminAddress + BLOCK_CTRL_MAGIC_POS_OFFSET, RWBuffer.BlockCtrl.MagicPage.Byte, BLOCK_MAGIC_PAGE_SIZE) == E_OK) {\r
+ memset(RWBuffer.BlockCtrl.MagicPage.Byte, 0xff, BLOCK_CTRL_MAGIC_PAGE_SIZE);\r
+ memcpy(RWBuffer.BlockCtrl.MagicPage.Magic, BlockMagicMaster, BLOCK_MAGIC_LEN);\r
+ if (Fls_Write(CurrentJob.Op.Write.WriteAdminAddress + BLOCK_CTRL_MAGIC_POS_OFFSET, RWBuffer.BlockCtrl.MagicPage.Byte, BLOCK_CTRL_MAGIC_PAGE_SIZE) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
AbortJob(Fls_GetJobResult());\r
*/\r
static void GarbageCollectStartJob(void)\r
{\r
- uint16 blockIndex,set;\r
+ uint16 blockIndex;\r
+ uint16 set;\r
boolean found = FALSE;\r
- uint8 sourceBank, destBank;\r
+ uint8 sourceBank;\r
\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
- if (AdminFls.BankStatus[0] == BANK_STATUS_OLD) {\r
- sourceBank = 0;\r
- destBank = 1;\r
- } else if (AdminFls.BankStatus[1] == BANK_STATUS_OLD) {\r
- sourceBank = 1;\r
- destBank = 0;\r
- } else {\r
- CurrentJob.State = FEE_IDLE;\r
- return;\r
- }\r
+ if ((AdminFls.BankStatus[0] == BANK_STATUS_OLD) || (AdminFls.BankStatus[1] == BANK_STATUS_OLD)) {\r
+ if (AdminFls.BankStatus[0] == BANK_STATUS_OLD) {\r
+ sourceBank = 0;\r
+ } else {\r
+ sourceBank = 1;\r
+ }\r
\r
- for (blockIndex = 0; (blockIndex < FEE_NUM_OF_BLOCKS) && !found; blockIndex++) {\r
- for (set = 0; (set < FEE_MAX_NUM_SETS) && !found; set++) {\r
- if (AdminFls.BlockDescrTbl[blockIndex][set].Status != BLOCK_STATUS_EMPTY) {\r
- if ((AdminFls.BlockDescrTbl[blockIndex][set].BlockAdminAddress >= BankProp[sourceBank].Start) && (AdminFls.BlockDescrTbl[blockIndex][set].BlockAdminAddress < (BankProp[sourceBank].End))) {\r
- CurrentJob.AdminFlsBlockPtr = &AdminFls.BlockDescrTbl[blockIndex][set];\r
- CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
- CurrentJob.BlockNumber = BLOCK_INDEX_AND_SET_TO_BLOCKNR(blockIndex, set);\r
- if (AdminFls.BlockDescrTbl[blockIndex][set].Status == BLOCK_STATUS_INVALIDATED) {\r
- CurrentJob.Length = 0;\r
- } else {\r
- CurrentJob.Length = PAGE_ALIGN(CurrentJob.BlockConfigPtr->BlockSize);\r
+ for (blockIndex = 0; (blockIndex < FEE_NUM_OF_BLOCKS) && (!found); blockIndex++) {\r
+ for (set = 0; (set < FEE_MAX_NUM_SETS) && (!found); set++) {\r
+ if (AdminFls.BlockDescrTbl[blockIndex][set].Status != BLOCK_STATUS_EMPTY) {\r
+ if ((AdminFls.BlockDescrTbl[blockIndex][set].BlockAdminAddress >= BankProp[sourceBank].Start) && (AdminFls.BlockDescrTbl[blockIndex][set].BlockAdminAddress < (BankProp[sourceBank].End))) {\r
+ CurrentJob.AdminFlsBlockPtr = &AdminFls.BlockDescrTbl[blockIndex][set];\r
+ CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
+ CurrentJob.BlockNumber = Fee_Config.BlockConfig[blockIndex].BlockNumber;\r
+ if (AdminFls.BlockDescrTbl[blockIndex][set].Status == BLOCK_STATUS_INVALIDATED) {\r
+ CurrentJob.Length = 0;\r
+ } else {\r
+ CurrentJob.Length = PAGE_ALIGN(CurrentJob.BlockConfigPtr->BlockSize);\r
+ }\r
+\r
+ found = TRUE;\r
}\r
-\r
- found = TRUE;\r
}\r
}\r
}\r
- }\r
\r
- if (found) {\r
- CurrentJob.Op.GarbageCollect.WriteDataAddress = AdminFls.NewBlockDataAddress;\r
- CurrentJob.Op.GarbageCollect.WriteAdminAddress = AdminFls.NewBlockAdminAddress;\r
+ if (found) {\r
+ CurrentJob.Op.GarbageCollect.WriteDataAddress = AdminFls.NewBlockDataAddress;\r
+ CurrentJob.Op.GarbageCollect.WriteAdminAddress = AdminFls.NewBlockAdminAddress;\r
\r
- CurrentJob.State = FEE_GARBAGE_COLLECT_HEADER_WRITE;\r
- BlockHeaderDataWrite();\r
- } else {\r
- if (Fls_Erase(BankProp[sourceBank].Start, BankProp[sourceBank].End - BankProp[sourceBank].Start) == E_OK) {\r
- SetFlsJobBusy();\r
+ CurrentJob.State = FEE_GARBAGE_COLLECT_HEADER_WRITE;\r
+ BlockHeaderDataWrite();\r
} else {\r
- AbortJob(Fls_GetJobResult());\r
+ if (Fls_Erase(BankProp[sourceBank].Start, BankProp[sourceBank].End - BankProp[sourceBank].Start) == E_OK) {\r
+ SetFlsJobBusy();\r
+ CurrentJob.Op.GarbageCollect.BankNumber = sourceBank;\r
+ CurrentJob.State = FEE_GARBAGE_COLLECT_ERASE;\r
+ } else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
+ AbortJob(Fls_GetJobResult());\r
+ }\r
}\r
- CurrentJob.Op.GarbageCollect.BankNumber = sourceBank;\r
- CurrentJob.State = FEE_GARBAGE_COLLECT_ERASE;\r
+ } else {\r
+ CurrentJob.State = FEE_IDLE;\r
}\r
}\r
}\r
CurrentJob.State = FEE_GARBAGE_COLLECT_DATA_READ_REQUESTED;\r
} else {\r
/* Yes, we are finished */\r
- VALIDATE_NO_RV(CurrentJob.AdminFlsBlockPtr->Status == BLOCK_STATUS_EMPTY, FEE_GARBAGE_WRITE_HEADER_ID, FEE_UNEXPECTED_STATUS);\r
+ DET_VALIDATE_NO_RV(CurrentJob.AdminFlsBlockPtr->Status == BLOCK_STATUS_INVALIDATED, FEE_GARBAGE_WRITE_HEADER_ID, FEE_UNEXPECTED_STATUS);\r
CurrentJob.State = FEE_GARBAGE_COLLECT_MAGIC_WRITE_REQUESTED;\r
}\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
if (Fls_Read(CurrentJob.AdminFlsBlockPtr->BlockDataAddress + CurrentJob.Op.GarbageCollect.DataOffset, RWBuffer.Byte, CurrentJob.Length) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
if (Fls_GetJobResult() == MEMIF_JOB_OK) {\r
CurrentJob.State = FEE_GARBAGE_COLLECT_DATA_WRITE_REQUESTED;\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
if (Fls_Write(CurrentJob.Op.GarbageCollect.WriteDataAddress + CurrentJob.Op.GarbageCollect.DataOffset, RWBuffer.Byte, CurrentJob.Length) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
{\r
if (CheckFlsJobFinnished()) {\r
if (Fls_GetJobResult() == MEMIF_JOB_OK) {\r
- CurrentJob.Op.GarbageCollect.DataOffset += RWBUFFER_SIZE;\r
- CurrentJob.Op.GarbageCollect.BytesLeft -= RWBUFFER_SIZE;\r
- if (CurrentJob.Op.GarbageCollect.BytesLeft <= 0) {\r
+ if (CurrentJob.Op.GarbageCollect.BytesLeft <= RWBUFFER_SIZE) {\r
/* Yes, we are finished */\r
CurrentJob.State = FEE_GARBAGE_COLLECT_MAGIC_WRITE_REQUESTED;\r
} else {\r
/* More data to move */\r
+ CurrentJob.Op.GarbageCollect.DataOffset += RWBUFFER_SIZE;\r
+ CurrentJob.Op.GarbageCollect.BytesLeft -= RWBUFFER_SIZE;\r
CurrentJob.State = FEE_GARBAGE_COLLECT_DATA_READ_REQUESTED;\r
}\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
{\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
CurrentJob.State = FEE_GARBAGE_COLLECT_MAGIC_WRITE;\r
- memset(RWBuffer.BlockCtrl.MagicPage.Byte, 0xff, BLOCK_MAGIC_PAGE_SIZE);\r
- memcpy(RWBuffer.BlockCtrl.MagicPage.Byte, MagicMaster, BLOCK_MAGIC_LEN);\r
- if (Fls_Write(CurrentJob.Op.GarbageCollect.WriteAdminAddress + BLOCK_CTRL_MAGIC_POS_OFFSET, RWBuffer.BlockCtrl.MagicPage.Byte, BLOCK_MAGIC_PAGE_SIZE) == E_OK) {\r
+ memset(RWBuffer.BlockCtrl.MagicPage.Byte, 0xff, BLOCK_CTRL_MAGIC_PAGE_SIZE);\r
+ memcpy(RWBuffer.BlockCtrl.MagicPage.Magic, BlockMagicMaster, BLOCK_MAGIC_LEN);\r
+ if (Fls_Write(CurrentJob.Op.GarbageCollect.WriteAdminAddress + BLOCK_CTRL_MAGIC_POS_OFFSET, RWBuffer.BlockCtrl.MagicPage.Byte, BLOCK_CTRL_MAGIC_PAGE_SIZE) == E_OK) {\r
SetFlsJobBusy();\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
if (Fls_GetJobResult() == MEMIF_JOB_OK) {\r
CurrentJob.AdminFlsBlockPtr->BlockAdminAddress = CurrentJob.Op.GarbageCollect.WriteAdminAddress;\r
CurrentJob.AdminFlsBlockPtr->BlockDataAddress = CurrentJob.Op.GarbageCollect.WriteDataAddress;\r
- FinnishJob();\r
+ CurrentJob.State = FEE_GARBAGE_COLLECT_REQUESTED;\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
if (CheckFlsJobFinnished()) {\r
if (Fls_GetJobResult() == MEMIF_JOB_OK) {\r
AdminFls.BankStatus[CurrentJob.Op.GarbageCollect.BankNumber] = BANK_STATUS_NEW;\r
+ AdminFls.ForceGarbageCollect = 0;\r
+ AdminFls.NofFailedGarbageCollect = 0;\r
FinnishJob();\r
} else {\r
+ AdminFls.NofFailedGarbageCollect++;\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
memset(RWBuffer.Byte, 0xff, BLOCK_CTRL_PAGE_SIZE);\r
RWBuffer.BlockCtrl.DataPage.Data.Status = BLOCK_STATUS_INVALIDATED;\r
RWBuffer.BlockCtrl.DataPage.Data.BlockNo = CurrentJob.BlockNumber;\r
- RWBuffer.BlockCtrl.DataPage.Data.BlockDataAddress = 0;\r
+ RWBuffer.BlockCtrl.DataPage.Data.BlockDataAddress = AdminFls.NewBlockDataAddress;\r
RWBuffer.BlockCtrl.DataPage.Data.BlockDataLength = 0;\r
- memcpy(RWBuffer.BlockCtrl.MagicPage.Byte, MagicMaster, BLOCK_MAGIC_LEN);\r
+ memset(RWBuffer.BlockCtrl.MagicPage.Byte, 0xff, BLOCK_CTRL_MAGIC_PAGE_SIZE);\r
+ memcpy(RWBuffer.BlockCtrl.MagicPage.Magic, BlockMagicMaster, BLOCK_MAGIC_LEN);\r
\r
- if (Fls_Write(CurrentJob.Op.Invalidate.WriteAdminAddress + BLOCK_CTRL_DATA_POS_OFFSET, RWBuffer.Byte, BLOCK_DATA_PAGE_SIZE) == E_OK) {\r
+ if (Fls_Write(CurrentJob.Op.Invalidate.WriteAdminAddress + BLOCK_CTRL_DATA_POS_OFFSET, RWBuffer.Byte, BLOCK_CTRL_PAGE_SIZE) == E_OK) {\r
SetFlsJobBusy();\r
AdminFls.NewBlockDataAddress += CurrentJob.Length;\r
AdminFls.NewBlockAdminAddress -= BLOCK_CTRL_PAGE_SIZE;\r
AdminFls.BankStatus[AdminFls.BankNumber] = BANK_STATUS_OLD;\r
\r
// Change of bank\r
- AdminFls.BankNumber ^= 0x1;\r
+ AdminFls.BankNumber ^= 0x1u;\r
AdminFls.NewBlockDataAddress = BankProp[AdminFls.BankNumber].Start;\r
- AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - BLOCK_CTRL_PAGE_SIZE - BANK_CTRL_PAGE_SIZE;\r
+ AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - (BLOCK_CTRL_PAGE_SIZE + BANK_CTRL_PAGE_SIZE);\r
\r
CurrentJob.Op.Invalidate.WriteDataAddress = AdminFls.NewBlockDataAddress;\r
CurrentJob.Op.Invalidate.WriteAdminAddress = AdminFls.NewBlockAdminAddress;\r
\r
CurrentJob.State = FEE_WRITE_INVALIDATE_HEADER_REQUESTED;\r
- BlockHeaderInvalidWrite();\r
} else {\r
AbortJob(Fls_GetJobResult());\r
}\r
}\r
\r
/*\r
- * Start the writing of the "Invalid" header.
+ * Start the writing of the "Invalid" header.\r
*/\r
static void InvalidateWriteInvalidateHeaderRequested(void)\r
{\r
if (Fls_GetStatus() == MEMIF_IDLE) {\r
CurrentJob.State = FEE_WRITE_INVALIDATE_HEADER;\r
BlockHeaderInvalidWrite();\r
- } else {\r
- AbortJob(Fls_GetJobResult());\r
}\r
}\r
\r
if (CheckFlsJobFinnished()) {\r
if (Fls_GetJobResult() == MEMIF_JOB_OK) {\r
// Update the block admin table\r
- CurrentJob.AdminFlsBlockPtr->Status = BLOCK_STATUS_INUSE;\r
+ CurrentJob.AdminFlsBlockPtr->Status = BLOCK_STATUS_INVALIDATED;\r
CurrentJob.AdminFlsBlockPtr->BlockAdminAddress = CurrentJob.Op.Invalidate.WriteAdminAddress;\r
CurrentJob.AdminFlsBlockPtr->BlockDataAddress = CurrentJob.Op.Invalidate.WriteDataAddress;\r
\r
void Fee_Init(void)\r
{\r
uint16 i,j;\r
-#if 0\r
- uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;\r
- t1 = sizeof(FlsBankStatusType);\r
- t2 = BANK_CTRL_PAGE_SIZE;\r
- t3 = sizeof(FlsBankCtrlPageType);\r
-\r
- t4 = sizeof(BlockStatusType);\r
- t5 = sizeof(FlsBlockDataType);\r
- t6 = BLOCK_DATA_PAGE_SIZE;\r
- t7 = sizeof(FlsBlockDataPageType);\r
-\r
-\r
- t8 = sizeof(FlsBlockMagicPageType);\r
- t9 = BLOCK_MAGIC_PAGE_SIZE;\r
- t10 = sizeof(FlsBlockControlType);\r
- t11 = BLOCK_CTRL_PAGE_SIZE;\r
-#endif\r
-\r
-\r
\r
/* Reporting information */\r
ModuleStatus = MEMIF_BUSY_INTERNAL;\r
\r
/* State of device */\r
CurrentJob.State = FEE_STARTUP_REQUESTED;\r
- CurrentJob.InStateCounter = 0;\r
#if (FEE_POLLING_MODE == STD_OFF)\r
FlsJobReady = TRUE;\r
#endif\r
\r
AdminFls.BankNumber = 0;\r
+ AdminFls.ForceGarbageCollect = 0;\r
+ AdminFls.NofFailedGarbageCollect = 0;\r
AdminFls.NewBlockDataAddress = BankProp[AdminFls.BankNumber].Start;\r
- AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - BLOCK_CTRL_PAGE_SIZE - BANK_CTRL_PAGE_SIZE;\r
+ AdminFls.NewBlockAdminAddress = BankProp[AdminFls.BankNumber].End - (BLOCK_CTRL_PAGE_SIZE + BANK_CTRL_PAGE_SIZE);\r
\r
for (i = 0; i < NUM_OF_BANKS; i++) {\r
AdminFls.BankStatus[i] = BANK_STATUS_NEW;\r
#if ( FLS_SET_MODE_API == STD_ON )\r
Fls_SetMode(mode);\r
#else\r
+ //lint --e{715} PC-Lint (715) - variable "mode" not used in this case\r
DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_SET_MODE_ID, FEE_E_NOT_SUPPORTED);\r
#endif\r
}\r
uint16 blockIndex;\r
uint16 dataset;\r
\r
- VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_READ_ID, FEE_E_UNINIT, E_NOT_OK);\r
- VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_READ_ID, FEE_E_BUSY, E_NOT_OK);\r
+ DET_VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_READ_ID, FEE_E_UNINIT, E_NOT_OK);\r
+ if(AdminFls.ForceGarbageCollect || (FEE_CORRUPTED == CurrentJob.State)){\r
+ return E_NOT_OK;\r
+ }\r
+ if( !(ModuleStatus == MEMIF_IDLE) ) {\r
+ DET_REPORTERROR(MODULE_ID_FEE, FEE_READ_ID, FEE_E_BUSY, E_NOT_OK);\r
+ return E_NOT_OK;\r
+ }\r
\r
- VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
- VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
- VALIDATE_RV(dataBufferPtr != NULL, FEE_READ_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
- VALIDATE_RV(blockOffset < Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_OFS, E_NOT_OK);\r
- VALIDATE_RV(blockOffset + length <= Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_LEN, E_NOT_OK);\r
+ DET_VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
+ DET_VALIDATE_RV(dataBufferPtr != NULL, FEE_READ_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
+ DET_VALIDATE_RV(blockOffset < Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_OFS, E_NOT_OK);\r
+ DET_VALIDATE_RV(blockOffset + length <= Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_LEN, E_NOT_OK);\r
\r
dataset = GET_DATASET_FROM_BLOCK_NUMBER(blockNumber);\r
- VALIDATE_RV(dataset < FEE_MAX_NUM_SETS, FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
+ DET_VALIDATE_RV(dataset < FEE_MAX_NUM_SETS, FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
\r
\r
/** @req FEE022 */\r
uint16 blockIndex;\r
uint16 dataset;\r
\r
- VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_WRITE_ID, FEE_E_UNINIT, E_NOT_OK);\r
- VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_WRITE_ID, FEE_E_BUSY, E_NOT_OK);\r
+ DET_VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_WRITE_ID, FEE_E_UNINIT, E_NOT_OK);\r
+ if(AdminFls.ForceGarbageCollect || (FEE_CORRUPTED == CurrentJob.State)){\r
+ return E_NOT_OK;\r
+ }\r
+ if( !(ModuleStatus == MEMIF_IDLE) ) {\r
+ DET_REPORTERROR(MODULE_ID_FEE, FEE_READ_ID, FEE_E_BUSY, E_NOT_OK);\r
+ return E_NOT_OK;\r
+ }\r
\r
- VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
- VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
- VALIDATE_RV(dataBufferPtr != NULL, FEE_WRITE_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
+ DET_VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
+ DET_VALIDATE_RV(dataBufferPtr != NULL, FEE_WRITE_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
\r
dataset = GET_DATASET_FROM_BLOCK_NUMBER(blockNumber);\r
- VALIDATE_RV(dataset < FEE_MAX_NUM_SETS, FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
+ DET_VALIDATE_RV(dataset < FEE_MAX_NUM_SETS, FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
\r
\r
/** @req FEE025 */\r
*/\r
MemIf_StatusType Fee_GetStatus(void)\r
{\r
- return ModuleStatus;\r
+ if(AdminFls.ForceGarbageCollect && (FEE_IDLE == CurrentJob.State)){\r
+ return MEMIF_BUSY_INTERNAL;\r
+ } else {\r
+ return ModuleStatus;\r
+ }\r
}\r
\r
\r
uint16 blockIndex;\r
uint16 dataset;\r
\r
- VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_INVALIDATE_BLOCK_ID, FEE_E_UNINIT, E_NOT_OK);\r
- VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_INVALIDATE_BLOCK_ID, FEE_E_BUSY, E_NOT_OK);\r
+ DET_VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_INVALIDATE_BLOCK_ID, FEE_E_UNINIT, E_NOT_OK);\r
+ if(AdminFls.ForceGarbageCollect || (FEE_CORRUPTED == CurrentJob.State)){\r
+ return E_NOT_OK;\r
+ }\r
+ if( !(ModuleStatus == MEMIF_IDLE) ) {\r
+ DET_REPORTERROR(MODULE_ID_FEE, FEE_READ_ID, FEE_E_BUSY, E_NOT_OK);\r
+ return E_NOT_OK;\r
+ }\r
\r
- VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
- VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
+ DET_VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
\r
dataset = GET_DATASET_FROM_BLOCK_NUMBER(blockNumber);\r
- VALIDATE_RV(dataset < FEE_MAX_NUM_SETS, FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
+ DET_VALIDATE_RV(dataset < FEE_MAX_NUM_SETS, FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
\r
\r
ModuleStatus = MEMIF_BUSY;\r
*/\r
Std_ReturnType Fee_EraseImmediateBlock(uint16 blockNumber)\r
{\r
+ //lint --e{715} PC-Lint (715) - function is not implemented and thus variable "blockNumber" is not used yet\r
+\r
DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_ERASE_IMMEDIATE_ID, FEE_E_NOT_IMPLEMENTED_YET);\r
\r
+\r
return E_NOT_OK;\r
}\r
\r
*/\r
void Fee_MainFunction(void)\r
{\r
- static CurrentJobStateType LastState = FEE_UNINITIALIZED;\r
-\r
- if (CurrentJob.State == LastState) {\r
- if (CurrentJob.InStateCounter < STATE_COUNTER_MAX) {\r
- CurrentJob.InStateCounter++;\r
- }\r
- } else {\r
- LastState = CurrentJob.State;\r
- CurrentJob.InStateCounter = 0;\r
- }\r
\r
switch (CurrentJob.State) {\r
case FEE_UNINITIALIZED:\r
break;\r
\r
case FEE_IDLE:\r
- if (CurrentJob.InStateCounter > GARBAGE_COLLECTION_DELAY) {\r
+ if (AdminFls.ForceGarbageCollect) {\r
CheckIfGarbageCollectionNeeded();\r
}\r
break;\r
break;\r
\r
/*\r
- * Write states
+ * Write states\r
*/\r
case FEE_WRITE_REQUESTED:\r
WriteStartJob();\r
break;\r
\r
/*\r
- * Garbage collection states
+ * Garbage collection states\r
*/\r
case FEE_GARBAGE_COLLECT_REQUESTED:\r
GarbageCollectStartJob();\r
break;\r
\r
/*\r
- * Invalidate states
+ * Invalidate states\r
*/\r
case FEE_INVALIDATE_REQUESTED:\r
InvalidateStartJob();\r
InvalidateWriteInvalidateHeader();\r
break;\r
\r
+ /*\r
+ * Corrupted state\r
+ */\r
+ case FEE_CORRUPTED:\r
+ break;\r
\r
/*\r
- * Other
+ * Other\r
*/\r
default:\r
break;\r