]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Fee, Garbage collection forced directly after a job which required a bank switch...
authorhebe <devnull@localhost>
Fri, 7 Sep 2012 07:22:37 +0000 (09:22 +0200)
committerhebe <devnull@localhost>
Fri, 7 Sep 2012 07:22:37 +0000 (09:22 +0200)
memory/Fee/Fee.c

index 327a3eff70e49b9c0ad835b95f0e439f86790083..dd78574e0ee7e766f6eb9ee18131c6f1a824f46a 100644 (file)
 \r
 \r
 /*\r
- * Block numbering recalculation macros
+ * Block numbering recalculation macros\r
  */\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)      ((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
@@ -156,7 +156,7 @@ static const BankPropType BankProp[NUM_OF_BANKS] = {
 \r
 \r
 /*\r
- * Macros and variables for flash bank administration
+ * Macros and variables for flash bank administration\r
  */\r
 #define BANK_STATUS_OLD                0x00\r
 #define BANK_STATUS_NEW                0xFF\r
@@ -171,7 +171,7 @@ typedef union {
 \r
 \r
 /*\r
- * Macros and variables for flash block administration in flash
+ * Macros and variables for flash block administration in flash\r
  */\r
 #define BLOCK_STATUS_INUSE                     0x00\r
 #define BLOCK_STATUS_INVALIDATED       0x02\r
@@ -235,6 +235,8 @@ typedef struct {
 \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
@@ -245,13 +247,13 @@ static AdminFlsType AdminFls;
 \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
@@ -289,7 +291,10 @@ typedef enum {
   FEE_GARBAGE_COLLECT_DATA_WRITE,\r
   FEE_GARBAGE_COLLECT_MAGIC_WRITE_REQUESTED,\r
   FEE_GARBAGE_COLLECT_MAGIC_WRITE,\r
-  FEE_GARBAGE_COLLECT_ERASE\r
+  FEE_GARBAGE_COLLECT_ERASE,\r
+\r
+  FEE_CORRUPTED\r
+\r
 } CurrentJobStateType;\r
 \r
 typedef struct {\r
@@ -335,11 +340,11 @@ static CurrentJobType CurrentJob = {
 };\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
@@ -408,16 +413,23 @@ static void FinnishJob(void)
        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
@@ -479,7 +491,7 @@ static void StartupReadBank2StatusRequested(void)
 \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
@@ -516,7 +528,7 @@ static void StartupReadBank2Status(void)
 }\r
 \r
 /*\r
- * Start of block admin read
+ * Start of block admin read\r
  */\r
 static void StartupReadBlockAdminRequested(void)\r
 {\r
@@ -534,7 +546,7 @@ static void StartupReadBlockAdminRequested(void)
 \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
@@ -621,7 +633,7 @@ static void ReadStartJob(void)
 }\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
@@ -640,6 +652,8 @@ static void Reading(void)
  */\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, BANK_CTRL_PAGE_SIZE);\r
        RWBuffer.BankCtrl.BankStatus = BANK_STATUS_OLD;\r
@@ -722,7 +736,7 @@ static void WriteMarkBankOldState(void)
 \r
 \r
 /*\r
- * Start of header write
+ * Start of header write\r
  */\r
 static void WriteHeaderRequested()\r
 {\r
@@ -749,7 +763,7 @@ static void WriteHeaderState(void)
 \r
 \r
 /*\r
- * Start block data write
+ * Start block data write\r
  */\r
 static void WriteDataRequested(void)\r
 {\r
@@ -783,7 +797,7 @@ static void WriteDataState(void)
 \r
 \r
 /*\r
- * Start magic write
+ * Start magic write\r
  */\r
 static void WriteMagicRequested(void)\r
 {\r
@@ -881,11 +895,12 @@ static void GarbageCollectStartJob(void)
                        } else {\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
-                               CurrentJob.Op.GarbageCollect.BankNumber = sourceBank;\r
-                               CurrentJob.State = FEE_GARBAGE_COLLECT_ERASE;\r
                        }\r
                } else {\r
                        CurrentJob.State = FEE_IDLE;\r
@@ -911,6 +926,7 @@ static void GarbageCollectWriteHeader(void)
                                CurrentJob.State = FEE_GARBAGE_COLLECT_MAGIC_WRITE_REQUESTED;\r
                        }\r
                } else {\r
+                       AdminFls.NofFailedGarbageCollect++;\r
                        AbortJob(Fls_GetJobResult());\r
                }\r
        }\r
@@ -933,6 +949,7 @@ static void GarbageCollectReadDataRequested(void)
                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
@@ -948,6 +965,7 @@ static void GarbageCollectReadData(void)
                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
@@ -965,9 +983,11 @@ static void GarbageCollectWriteDataRequested(void)
                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
@@ -991,6 +1011,7 @@ static void GarbageCollectWriteData(void)
                                CurrentJob.State = FEE_GARBAGE_COLLECT_DATA_READ_REQUESTED;\r
                        }\r
                } else {\r
+                       AdminFls.NofFailedGarbageCollect++;\r
                        AbortJob(Fls_GetJobResult());\r
                }\r
        }\r
@@ -1009,6 +1030,7 @@ static void GarbageCollectWriteMagicRequested(void)
                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
@@ -1024,8 +1046,9 @@ static void GarbageCollectWriteMagic(void)
                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
@@ -1040,8 +1063,11 @@ static void GarbageCollectErase(void)
        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
@@ -1121,7 +1147,7 @@ static void InvalidateMarkBankOld(void)
 }\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
@@ -1175,6 +1201,8 @@ void Fee_Init(void)
 #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
 \r
@@ -1216,7 +1244,9 @@ Std_ReturnType Fee_Read(uint16 blockNumber, uint16 blockOffset, uint8* dataBuffe
        uint16 dataset;\r
 \r
        DET_VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_READ_ID, FEE_E_UNINIT, E_NOT_OK);\r
-\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
@@ -1258,7 +1288,9 @@ Std_ReturnType Fee_Write(uint16 blockNumber, uint8* dataBufferPtr)
        uint16 dataset;\r
 \r
        DET_VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_WRITE_ID, FEE_E_UNINIT, E_NOT_OK);\r
-\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
@@ -1303,7 +1335,11 @@ void Fee_Cancel(void)
  */\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
@@ -1327,6 +1363,9 @@ Std_ReturnType Fee_InvalidateBlock(uint16 blockNumber)
        uint16 dataset;\r
 \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
@@ -1391,7 +1430,7 @@ void Fee_MainFunction(void)
                break;\r
 \r
        case FEE_IDLE:\r
-               if (CurrentJob.InStateCounter > GARBAGE_COLLECTION_DELAY) {\r
+               if (AdminFls.ForceGarbageCollect) {\r
                        CheckIfGarbageCollectionNeeded();\r
                }\r
                break;\r
@@ -1435,7 +1474,7 @@ void Fee_MainFunction(void)
                break;\r
 \r
        /*\r
-        * Write states
+        * Write states\r
         */\r
        case FEE_WRITE_REQUESTED:\r
                WriteStartJob();\r
@@ -1470,7 +1509,7 @@ void Fee_MainFunction(void)
                break;\r
 \r
        /*\r
-        * Garbage collection states
+        * Garbage collection states\r
         */\r
        case FEE_GARBAGE_COLLECT_REQUESTED:\r
                GarbageCollectStartJob();\r
@@ -1509,7 +1548,7 @@ void Fee_MainFunction(void)
                break;\r
 \r
        /*\r
-        * Invalidate states
+        * Invalidate states\r
         */\r
        case FEE_INVALIDATE_REQUESTED:\r
                InvalidateStartJob();\r
@@ -1527,9 +1566,14 @@ void Fee_MainFunction(void)
                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