]> rtime.felk.cvut.cz Git - arc.git/commitdiff
more work an statemachine
authormahi <devnull@localhost>
Tue, 24 Jan 2012 07:29:14 +0000 (08:29 +0100)
committermahi <devnull@localhost>
Tue, 24 Jan 2012 07:29:14 +0000 (08:29 +0100)
memory/NvM/NvM.c

index aea7920db473ab3ce776c1381a92c0e6351429cf..d3449dfffeb39f088ff7cb141ba288da7e1f07f8 100644 (file)
  *\r
  *      So how much data should be read from MemIf if a CRC checksum is used. Assuming that we use a physical layout where the CRC is located\r
  *      after the NV Block it would be BALIGN(NvNvmBlockLength,4) + 4 bytes. The same applies to the RAM block (ROM block to not have CRC, NVM127)\r
+ *\r
+ * SPEED\r
+ *   To get some speed into this multiple thing must be done in the same MainFunction loop.\r
+ *\r
  */\r
 \r
 \r
 #define NVM_BLOCK_ALIGNMENT                    4\r
 #define NVM_CHECKSUM_LENGTH                    4\r
 \r
+#define NVM_BLOCK_OFFSET               0\r
+\r
+\r
 //#define NVM_SERVICE_ID               0x00            // TODO: What number shall this ID have?\r
 \r
 #if  ( NVM_DEV_ERROR_DETECT == STD_ON )\r
 \r
 // State variable\r
 typedef enum {\r
-  NVM_UNINITIALIZED = 0,   //!< NVM_UNINITIALIZED\r
-  NVM_IDLE,                //!< NVM_IDLE\r
-  NVM_READ_ALL_REQUESTED,  //!< NVM_READ_ALL_REQUESTED\r
-  NVM_READ_ALL_PROCESSING, //!< NVM_READ_ALL_PROCESSING\r
-  NVM_READ_ALL_PENDING,    //!< NVM_READ_ALL_PENDING\r
-  NVM_WRITE_ALL_REQUESTED, //!< NVM_WRITE_ALL_REQUESTED\r
-  NVM_WRITE_ALL_PROCESSING,//!< NVM_WRITE_ALL_PROCESSING\r
-  NVM_WRITE_ALL_PENDING,    //!< NVM_WRITE_ALL_PENDING\r
-\r
+  NVM_UNINITIALIZED = 0,\r
+  NVM_IDLE,\r
+  NVM_READ_ALL,\r
+  NVM_WRITE_ALL,\r
   NVM_READ_BLOCK,\r
+  NVM_WRITE_BLOCK,\r
 } NvmStateType;\r
 \r
 typedef enum {\r
        BLOCK_STATE_IDLE,\r
-       BLOCK_STATE_RECALC_CRC,\r
-       BLOCK_STATE_RECALC_CRC_DONE,\r
-       BLOCK_STATE_POSTCALC_CRC,\r
-       BLOCK_STATE_POSTCALC_CRC_DONE,\r
-\r
-       BLOCK_STATE_LOAD_FROM_NV,\r
-//     BLOCK_STATE_LOAD_FROM_NV_DONE,\r
-//     BLOCK_STATE_LOAD_FROM_NV_REDUNDANT,\r
-//     BLOCK_STATE_LOAD_FROM_ROM,\r
-\r
-       BLOCK_STATE_WRITE_TO_NV\r
-//     BLOCK_STATE_WRITE_TO_NV_DONE\r
+       BLOCK_STATE_START,\r
+       BLOCK_STATE_PROCESS,\r
+       BLOCK_STATE_CALC_CRC,\r
 } BlockStateType;\r
 \r
+\r
+\r
+\r
 typedef struct {\r
        NvM_RequestResultType   ErrorStatus;                    // Status from multi block requests i.e. Read/Write/CancelWrite-all\r
 } AdministrativeMultiBlockType;\r
@@ -210,7 +207,7 @@ static NvmStateType                                 nvmState = NVM_UNINITIALIZED;
 \r
 static int                                                     nvmSubState = 0;\r
 static int nvmSetNr;\r
-static AdministrativeBlockType                 AdminBlock[NVM_NUM_OF_NVRAM_BLOCKS];\r
+static AdministrativeBlockType                 AdminBlock[NVM_NUM_OF_NVRAM_BLOCKS+NVM_BLOCK_OFFSET];\r
 static AdministrativeMultiBlockType AdminMultiBlock;\r
 \r
 \r
@@ -250,7 +247,7 @@ static MemIfJobAdminType MemIfJobAdmin = {
 };\r
 \r
 typedef struct {\r
-       uint16                                  NextBlockIndex;         // Keeps track of next unfinished block\r
+       uint16                                  currBlockIndex;         // Keeps track of next unfinished block\r
        NvM_RequestResultType   PendingErrorStatus;     // Status from multi block requests i.e. Read/Write/CancelWrite-all\r
 } AdminMultiReqType;\r
 \r
@@ -353,11 +350,10 @@ static void ReadAllInit(void)
        AdministrativeBlockType *AdminBlockTable = AdminBlock;\r
        uint16 i;\r
 \r
-       nvmState = NVM_READ_ALL_PROCESSING;\r
        AdminMultiReq.PendingErrorStatus = NVM_REQ_OK;\r
-       AdminMultiReq.NextBlockIndex = 0;\r
+       AdminMultiReq.currBlockIndex = 0;\r
 \r
-       for (i = 0; i < NVM_NUM_OF_NVRAM_BLOCKS; i++) {\r
+       for (i = NVM_BLOCK_OFFSET; i < ( NVM_NUM_OF_NVRAM_BLOCKS + NVM_BLOCK_OFFSET); i++) {\r
                if ((BlockDescriptorList->SelectBlockForReadall)\r
 #if (NVM_SET_RAM_BLOCK_STATUS_API == STD_ON)                                           /** @req NVM345 */\r
                                && ((!AdminBlockTable->BlockValid)                      // TODO: Check if this is to be done like this\r
@@ -373,7 +369,7 @@ static void ReadAllInit(void)
                                AdminBlockTable->BlockState = BLOCK_STATE_LOAD_FROM_NV;\r
                        }\r
                } else {\r
-                       AdminBlockTable->ErrorStatus = NVM_REQ_BLOCK_SKIPPED;\r
+                       AdminBlockTable->ErrorStatus = NVM_REQ_BLOCK_SKIPPED;   /* @req 3.1.5/NVM287 */\r
                }\r
 \r
                AdminBlockTable++;\r
@@ -387,51 +383,99 @@ static void ReadAllInit(void)
  */\r
 static void ReadAllMain(void)\r
 {\r
-       const NvM_BlockDescriptorType   *BlockDescriptorList = NvM_Config.BlockDescriptor;\r
-       AdministrativeBlockType *AdminBlockTable = AdminBlock;\r
-       uint16 i;\r
+       const NvM_BlockDescriptorType   *bPtr = &NvM_Config.BlockDescriptor[AdminMultiReq.currBlockIndex];\r
+       AdministrativeBlockType *admPtr = &AdminBlock[AdminMultiReq.currBlockIndex];\r
+\r
+       /* Cases:\r
+        * 1. We process each block until it's finished\r
+        * 2. We start to process a lot of blocks. The blocks may use different devices\r
+        *    and should be able to read a lot of them. This includes CRC.\r
+        *\r
+        *    1) is much simpler and 2) probably much faster.\r
+        *    This implementation will use 1) since it's simpler and maximum time that is\r
+        *    spent in MainFunction() can be controlled much better.\r
+        */\r
+       bool blockDone = 0;\r
 \r
-       // Search forward to first unfinished block\r
-       while ((AdminMultiReq.NextBlockIndex < NVM_NUM_OF_NVRAM_BLOCKS) && (AdminBlockTable[AdminMultiReq.NextBlockIndex].ErrorStatus != NVM_REQ_PENDING)) {\r
-               AdminMultiReq.NextBlockIndex++;\r
-       }\r
+       /* This block pending? */\r
+       assert( admPtr->ErrorStatus == NVM_REQ_PENDING );\r
 \r
-       if (AdminMultiReq.NextBlockIndex == NVM_NUM_OF_NVRAM_BLOCKS) {\r
-               // All block processed\r
-               if (AdminMultiReq.PendingErrorStatus == NVM_REQ_OK) {\r
-                       AdminMultiBlock.ErrorStatus = NVM_REQ_OK;\r
-               } else {\r
-                       AdminMultiBlock.ErrorStatus = NVM_REQ_NOT_OK;\r
-               }\r
+       switch (admPtr->BlockState) {\r
+       case BLOCK_STATE_IDLE:\r
+               /* Read block from NV */\r
+               ReadBlock(&bPtr[i], &admPtr[i], 0, bPtr->RamBlockDataAddress);\r
+               admPtr->BlockState = BLOCK_STATE_PROCESS;\r
+               break;\r
 \r
-               nvmState = NVM_IDLE;\r
+       case BLOCK_STATE_PROCESS:\r
+               /* Check read */\r
+               MemIf_JobResultType jobResult = MemIf_GetJobResult();\r
 \r
-               if (NvM_Config.Common.MultiBlockCallback != NULL) {\r
-                       NvM_Config.Common.MultiBlockCallback(NVM_SERVICE_ID, AdminMultiBlock.ErrorStatus);\r
-               }\r
+               if( MEMIF_JOB_PENDING == jobResult ) {\r
+                       /* Keep on waiting */\r
+               } else if( MEMIF_JOB_PENDING == jobResult ) {\r
+                       /* We are done */\r
+                       if( bPtr->CalcRamBlockCrc ) {                           /* @req 3.1.5/NVM362 */\r
+                               admPtr->BlockState = BLOCK_STATE_CALC_CRC;\r
+                       } else {\r
+                               admPtr->BlockState = BLOCK_STATE_IDLE;\r
+                               blockDone = 1;\r
+                       }\r
+                       break;\r
+               } else {\r
+                       /* Something failed */\r
+                       AdminMultiReq.PendingErrorStatus = NVM_REQ_NOT_OK;\r
+                       blockDone = 1;\r
+                       admPtr->BlockState = BLOCK_STATE_IDLE;  /* TODO, this really true for all result below */\r
 \r
-       } else {\r
-               for (i = AdminMultiReq.NextBlockIndex; (i < NVM_NUM_OF_NVRAM_BLOCKS) && (nvmState == NVM_READ_ALL_PROCESSING); i++) {\r
-                       switch (AdminBlockTable[i].BlockState) {\r
-                       case BLOCK_STATE_POSTCALC_CRC_DONE:\r
-                               // TODO: Check CRC\r
-                               break;\r
+                       switch( jobResult ) {\r
+                       case MEMIF_BLOCK_INVALID:\r
+                               /* @req 3.1.5/NVM342 */\r
+                               admPtr->ErrorStatus = NVM_REQ_NV_INVALIDATED;\r
 \r
-                       case BLOCK_STATE_RECALC_CRC_DONE:\r
-                               // TODO: If CRC is ok do not reload from NVRAM\r
-                               // TODO: else reload\r
                                break;\r
-\r
-                       case BLOCK_STATE_LOAD_FROM_NV:\r
-                               nvmState = NVM_READ_ALL_PENDING;\r
-                               ReadBlock(&BlockDescriptorList[i], &AdminBlockTable[i], 0, BlockDescriptorList[i].RamBlockDataAddress);\r
+                       case MEMIF_BLOCK_INCONSISTENT:\r
+                               /* @req 3.1.5/NVM360 */\r
+                               admPtr->ErrorStatus = NVM_REQ_INTEGRITY_FAILED;\r
+                               DEM_REPORTERRORSTATUS(NVM_E_REQ_INTEGRITY_FAILED,DEM_EVENT_STATUS_FAILED);\r
+                               blockDone = 1;\r
                                break;\r
-\r
+                       case MEMIF_JOB_FAILED:\r
+                               /* @req 3.1.5/NVM361 */\r
+                               admPtr->ErrorStatus = NVM_REQ_NOT_OK;\r
+                               DEM_REPORTERRORSTATUS(NVM_E_REQ_FAILED,DEM_EVENT_STATUS_FAILED);\r
+                               blockDone = 1;\r
                        default:\r
+                               assert(0);\r
                                break;\r
-                       } // Switch\r
-               } // for\r
-       } // else\r
+                       }\r
+               }\r
+\r
+       case BLOCK_STATE_CALC_CRC:\r
+               /* TODO: */\r
+               break;\r
+       }\r
+\r
+       if( blockDone  ) {\r
+\r
+               /*  @req 3.1.5/NVM281 */\r
+               if( bPtr->SingleBlockCallback() != NULL ) {\r
+                       bPtr->SingleBlockCallback();\r
+               }\r
+\r
+               AdminMultiReq.currBlockIndex++;\r
+               if( AdminMultiReq.currBlockIndex >= NVM_NUM_OF_NVRAM_BLOCKS ) {\r
+                       AdminMultiReq.currBlockIndex = 0;\r
+\r
+                       /* @req 3.1.5/NVM301 */\r
+                       if( NVM_REQ_NOT_OK == AdminMultiReq.PendingErrorStatus ) {\r
+                               AdminMultiBlock.ErrorStatus = NVM_REQ_NOT_OK;\r
+                       } else {\r
+                               AdminMultiBlock.ErrorStatus = NVM_REQ_OK;\r
+                       }\r
+                       nvmState = NVM_IDLE;\r
+               }\r
+       }\r
 }\r
 \r
 \r
@@ -533,7 +577,7 @@ static void WriteAllInit(void)
 \r
        nvmState = NVM_WRITE_ALL_PROCESSING;\r
        AdminMultiReq.PendingErrorStatus = NVM_REQ_OK;\r
-       AdminMultiReq.NextBlockIndex = 0;\r
+       AdminMultiReq.currBlockIndex = 0;\r
 \r
        for (i = 0; i < NVM_NUM_OF_NVRAM_BLOCKS; i++) {\r
                if ((BlockDescriptorList->RamBlockDataAddress != NULL)\r
@@ -568,11 +612,11 @@ static void WriteAllMain(void)
        uint16 i;\r
 \r
        // Search forward to first unfinished block\r
-       while ((AdminMultiReq.NextBlockIndex < NVM_NUM_OF_NVRAM_BLOCKS) && (AdminBlockTable[AdminMultiReq.NextBlockIndex].ErrorStatus != NVM_REQ_PENDING)) {\r
-               AdminMultiReq.NextBlockIndex++;\r
+       while ((AdminMultiReq.currBlockIndex < NVM_NUM_OF_NVRAM_BLOCKS) && (AdminBlockTable[AdminMultiReq.currBlockIndex].ErrorStatus != NVM_REQ_PENDING)) {\r
+               AdminMultiReq.currBlockIndex++;\r
        }\r
 \r
-       if (AdminMultiReq.NextBlockIndex == NVM_NUM_OF_NVRAM_BLOCKS) {\r
+       if (AdminMultiReq.currBlockIndex == NVM_NUM_OF_NVRAM_BLOCKS) {\r
                // All block processed\r
                if (AdminMultiReq.PendingErrorStatus == NVM_REQ_OK) {\r
                        AdminMultiBlock.ErrorStatus = NVM_REQ_OK;\r
@@ -587,7 +631,7 @@ static void WriteAllMain(void)
                }\r
 \r
        } else {\r
-               for (i = AdminMultiReq.NextBlockIndex; (i < NVM_NUM_OF_NVRAM_BLOCKS) && (nvmState == NVM_WRITE_ALL_PROCESSING); i++) {\r
+               for (i = AdminMultiReq.currBlockIndex; (i < NVM_NUM_OF_NVRAM_BLOCKS) && (nvmState == NVM_WRITE_ALL_PROCESSING); i++) {\r
                        switch (AdminBlockTable[i].BlockState) {\r
                        case BLOCK_STATE_POSTCALC_CRC_DONE:\r
                                // TODO: Check CRC\r
@@ -696,7 +740,6 @@ void NvM_Init(void)
  */\r
 void NvM_ReadAll(void)\r
 {\r
-       AdministrativeBlockType *AdminBlockTable = AdminBlock;\r
        uint16 i;\r
 \r
        VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_READ_ALL_ID, NVM_E_NOT_INITIALIZED);\r
@@ -705,15 +748,19 @@ void NvM_ReadAll(void)
 \r
        // Check state\r
        if (nvmState == NVM_IDLE) {\r
-               nvmState = NVM_READ_ALL_REQUESTED;              /** @req NVM243 */\r
+\r
+               /** !req 3.1.5/NVM243 TODO: Must check that queue is empty */\r
+               nvmState = NVM_READ_ALL;\r
 \r
                // Set status to pending in the administration blocks\r
-               AdminMultiBlock.ErrorStatus = NVM_REQ_PENDING;\r
+               AdminMultiBlock.ErrorStatus = NVM_REQ_PENDING; /** @req 3.1.5/NVM304 */\r
 \r
-               for (i = 0; i < NVM_NUM_OF_NVRAM_BLOCKS; i++) {\r
-                       AdminBlockTable->ErrorStatus = NVM_REQ_PENDING;\r
-                       AdminBlockTable++;\r
+               /** @req 3.1.5/NVM244 */\r
+               for (i = NVM_BLOCK_OFFSET; i < (NVM_NUM_OF_NVRAM_BLOCKS+NVM_BLOCK_OFFSET); i++) {\r
+                       AdminBlock[i].ErrorStatus = NVM_REQ_PENDING;\r
                }\r
+\r
+               ReadAllInit();\r
        }\r
 }\r
 \r
@@ -768,8 +815,10 @@ void NvM_GetErrorStatus(NvM_BlockIdType blockId, uint8 *requestResultPtr)
        if (blockId == 0) {\r
                // Multiblock ID\r
                *requestResultPtr = AdminMultiBlock.ErrorStatus;\r
+       } else if (blockId == 1) {\r
+               /* TODO */\r
        } else {\r
-               *requestResultPtr = AdminBlock[blockId-1].ErrorStatus;\r
+               *requestResultPtr = AdminBlock[blockId-NVM_BLOCK_OFFSET].ErrorStatus;\r
        }\r
 \r
 }\r
@@ -1045,8 +1094,8 @@ void NvM_MainFunction(void)
                CalcCrc();\r
                break;\r
        }\r
-       case NVM_READ_ALL_REQUESTED:\r
-               ReadAllInit();\r
+       case NVM_READ_ALL:\r
+               ReadAllMain();\r
                break;\r
 \r
        case NVM_READ_ALL_PROCESSING:\r