fdi_fmt.c

来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 603 行 · 第 1/2 页

C
603
字号
###
### 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;
   /* E.5.5.937 Begin */
#if (BUFFER_SIZE > 0)
   WORD i;
#endif
   /* E.5.5.937 End */

#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

/* E.1.5.800 BEGIN */
#if (DIRECT_ACCESS_VOLUME == TRUE)
   /* E5.1.797 START */
   if (DAV_InitializationComplete == TRUE)
   /* E5.1.797 END */
   {
      DAV_Terminate();
   }
#endif
/* E.1.5.800 END */


   if (FDI_InitComplete == TRUE)
   {
      /* Call the ReadData function to read the data. */
      if ((ReadModify((BYTE_PTR) & spare_erase_count, (DWORD_PTR)&current_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.5.5.987 Begin */
#if( (SEM_CREATE_DESTROY == TRUE) || defined(CUSTOM_SEM_MTX) ) 
/* E.5.5.5.987 End */

/* E5.3.919 START */
#ifdef CUSTOM_SEM_MTX
   /* Initialize the mutex space before creating new semaphores */
   if( Sem_Mtx_Init() != ERR_NONE )
   {
      return ERR_INIT;
   }
#endif
/* E5.3.919 END */

/* E.5.0.596 START */
   if ((SEM_FlashWrite == SEM_NULL)         &&     /* check for existance    */
       ((SEM_FlashWrite = SEM_MTX_CREATE()) == SEM_NULL))
   {
      return ERR_INIT;
   }

/* E5.3.875 START */
/*#if (DIRECT_ACCESS_VOLUME == TRUE)*/
   if ((SEM_FlashErase == SEM_NULL)         &&     /* check for existance    */
      ((SEM_FlashErase = SEM_MTX_CREATE()) == SEM_NULL))
   {
      SEM_MTX_DESTROY(SEM_FlashWrite);
      return ERR_INIT;
   }
/*#endif / DIRECT_ACCESS_VOLUME */
/* E5.3.875 START */
/* E.5.0.596 END */

/* E.5.5.5.987 Begin */
#endif /* SEM_CREATE_DESTROY and CUSTOM_SEM_MTX */
/* E.5.5.5.987 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;
      /* E.5.5.937 Begin */
#if (BUFFER_SIZE > 0)
      for( i = 0; i < sizeof(block_information.pad1); i++)
      {
         block_information.pad1[i] = BYTEMAX;
      }
#endif
      /* E.5.5.937 End */

      /* 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. */

/* E5.1.806 START */
   /* initialize  logical block table, data lookup table, etc */
   status = FDI_Init();
   if (status != ERR_NONE)
   {
      return ERR_INIT;
   }
/* E5.1.806 END */

#if(DIRECT_ACCESS_VOLUME == TRUE)

/* E.5.5.5.987 Begin */
#if( (SEM_CREATE_DESTROY == TRUE) || defined(CUSTOM_SEM_MTX) ) 
/* E.5.5.5.987 End */

/* E.5.5.5.987 Begin */
#if(SEM_CREATE_DESTROY == TRUE)
/* E.5.5.5.987 End */
/* 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))
#else
   if ((SEM_DAVReclLock == SEM_NULL)      &&
     ((SEM_DAVReclLock = SEM_MTX_CREATE()) == SEM_NULL))
/* E.5.5.5.987 Begin */
#endif
/* E.5.5.5.987 End */
   {
      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 */
   
/* E.5.5.5.987 Begin */
#endif /* SEM_CREATE_DESTROY and CUSTOM_SEM_MTX */
/* E.5.5.5.987 End */
   
   if (DAV_Format(&fdi_flash_info) != ERR_NONE)
   {
      return ERR_FORMAT;
   }
#endif /* DIRECT_ACCESS_VOLUME */

/* E5.1.806 START */
   /*
    * Because Code Manager uses semaphores created during Data Manager
    * initialization, Data Manager initialization is moved so that Data 
    * Manager initialization occurs before the formatting of the CM volume
    */
/* E5.1.806 END */


   /* 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 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?