⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsinit.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            return -1;
          }
          break;
        }

        /*-------------------------------------------------------------*/
        /* Check header sector (last one) contains only signature.     */
        /*-------------------------------------------------------------*/
        if (Flash->read_sector(Flash->tmp_sect, sect + i))
        {
          set_errno(EIO);
          return -1;
        }

        /*-------------------------------------------------------------*/
        /* Check that non-sinature bytes are all 0xFF.                 */
        /*-------------------------------------------------------------*/
        for (j = 0; j < Flash->sect_sz - RES_BYTES; ++j)
          if (Flash->tmp_sect[j] != 0xFF)
          {
            if (Flash->erase_block_wrapper(addr))
            {
              set_errno(EIO);
              return -1;
            }
            break;
          }
        if (j < Flash->sect_sz - RES_BYTES)
          break;

        /*-------------------------------------------------------------*/
        /* Check the signature bytes.                                  */
        /*-------------------------------------------------------------*/
        if (Flash->tmp_sect[j] != NOR_BYTE1 ||
            Flash->tmp_sect[j + 1] != NOR_BYTE2 ||
            Flash->tmp_sect[j + 2] != NOR_BYTE3 ||
            Flash->tmp_sect[j + 3] != NOR_BYTE4)
        {
          if (Flash->erase_block_wrapper(addr))
          {
            set_errno(EIO);
            return -1;
          }
          break;
        }
      }
    }
  }
  return 0;
}

/***********************************************************************/
/*   FfsModule: Flash file system interface to software object manager */
/*                                                                     */
/*       Input: req = module request code                              */
/*              ... = additional parameters specific to request        */
/*                                                                     */
/***********************************************************************/
void *FfsModule(int req, ...)
{
  void *r_value = NULL;
  va_list ap;
  char *path;
  ui32 i, j;
  FlashGlob *vol;

  switch (req)
  {
    case kInitMod:
    {
      char sem_name[9];

      /*---------------------------------------------------------------*/
      /* Initialize the FAT semaphores.                                */
      /*---------------------------------------------------------------*/
      FlashSem = semCreate("FLASH_SEM", 1, OS_FIFO);
      if (FlashSem == NULL)
        return (void *)-1;
      for (i = 0; i < NUM_FFS_VOLS; ++i)
      {
        sprintf(sem_name, "FFS_%04d", i);
        FlashGlobals[i].sem = semCreate(sem_name, 1, OS_FIFO);
        if (FlashGlobals[i].sem == NULL)
        {
          while (i--)
            semDelete(&FlashGlobals[i].sem);
          semDelete(&FlashSem);
          return (void *)-1;
        }
      }
      return r_value;
    }

    /*-----------------------------------------------------------------*/
    /* Handle the unformat function call.                              */
    /*-----------------------------------------------------------------*/
    case kUnformat:
    {
      int do_unmount = FALSE;
      ui32 block, addr;

      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to fetch the path for unformat.      */
      /*---------------------------------------------------------------*/
      va_start(ap, req);
      path = va_arg(ap, char *);
      va_end(ap);

      /*---------------------------------------------------------------*/
      /* Go through all the existing unmounted volumes and if any has  */
      /* the given name, unformat it.                                  */
      /*---------------------------------------------------------------*/
      for (i = 0; i < NUM_FFS_VOLS; ++i)
      {
        /*-------------------------------------------------------------*/
        /* Set pointer to the current entry in the array.              */
        /*-------------------------------------------------------------*/
        vol = &FlashGlobals[i];

        /*-------------------------------------------------------------*/
        /* If this entry contains a valid volume and names match, then */
        /* unformat the volume.                                        */
        /*-------------------------------------------------------------*/
        if (vol->num_sects && !strcmp(path, vol->sys.name))
        {
          /*-----------------------------------------------------------*/
          /* Acquire exclusive access to volume and flash file system. */
          /*-----------------------------------------------------------*/
          semPend(vol->sem, WAIT_FOREVER);
          semPend(FlashSem, WAIT_FOREVER);
          Flash = vol;

          /*-----------------------------------------------------------*/
          /* If volume is mounted, remember to unmount, else do a semi */
          /* mount (i.e. read control up to bad block information.     */
          /*-----------------------------------------------------------*/
          if (Flash->sys.next || Flash->sys.prev ||
              &Flash->sys == MountedList.head)
            do_unmount = TRUE;
          else
          {
            /*---------------------------------------------------------*/
            /* Assign memory to hold bad block info.                   */
            /*---------------------------------------------------------*/
            Flash->blocks = malloc(Flash->num_blocks * sizeof(FFSBlock));
            if (Flash->blocks == NULL)
            {
              semPost(FlashSem);
              semPost(vol->sem);
              return (void *)-1;
            }

            /*---------------------------------------------------------*/
            /* Attempt to do a semi mount based on control from flash. */
            /*---------------------------------------------------------*/
            if (FlashSemiMount())
            {
              free(Flash->blocks);
              Flash->blocks = NULL;
              semPost(FlashSem);
              semPost(vol->sem);
              return (void *)1;
            }
          }

          /*-----------------------------------------------------------*/
          /* Release exclusive access to the flash file system.        */
          /*-----------------------------------------------------------*/
          semPost(FlashSem);

          /*-----------------------------------------------------------*/
          /* Walk the blocks list erasing all non-bad ones.            */
          /*-----------------------------------------------------------*/
          for (block = 0; block < vol->num_blocks; ++block)
            if (!vol->blocks[block].bad_block)
            {
              addr = vol->mem_base + block * vol->block_size;
              if (vol->type == FFS_NAND)
                (void)vol->driver.nand.erase_block(addr, vol->vol);
              else
                (void)vol->driver.nor.erase_block(addr, vol->vol);
            }

          /*-----------------------------------------------------------*/
          /* Release exclusive access to volume.                       */
          /*-----------------------------------------------------------*/
          semPost(vol->sem);

          /*-----------------------------------------------------------*/
          /* Do an unmount if necessary.                               */
          /*-----------------------------------------------------------*/
          if (do_unmount)
            FlashIoctl(NULL, UNMOUNT, vol->sys.volume, FALSE);
          else
          {
            free(vol->blocks);
            vol->blocks = NULL;
          }
          return (void *)1;
        }
      }
      break;
    }

    /*-----------------------------------------------------------------*/
    /* Handle the format function call.                                */
    /*-----------------------------------------------------------------*/
    case kFormat:
    {
      char *name;
      FileSys *fsys;
      int unmount_volume = FALSE;
      int fresh_format = FALSE;

      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to fetch the path for format.        */
      /*---------------------------------------------------------------*/
      va_start(ap, req);
      path = va_arg(ap, char *);
      va_end(ap);

      /*---------------------------------------------------------------*/
      /* Go through all the existing volumes (mounted and not mounted) */
      /* and if any has the given name, format it.                     */
      /*---------------------------------------------------------------*/
      for (i = 0; i < NUM_FFS_VOLS; ++i)
      {
        /*-------------------------------------------------------------*/
        /* Set pointer to the current entry in the array.              */
        /*-------------------------------------------------------------*/
        vol = &FlashGlobals[i];

        /*-------------------------------------------------------------*/
        /* If this entry contains a valid volume and the names match,  */
        /* format the volume.                                          */
        /*-------------------------------------------------------------*/
        if (vol->num_sects && !strcmp(path, vol->sys.name))
        {
          /*-----------------------------------------------------------*/
          /* If the volume is mounted, prepare it for erase operation. */
          /*-----------------------------------------------------------*/
          if (vol->sys.next || vol->sys.prev ||
              (&vol->sys == MountedList.head))
          {
            /*---------------------------------------------------------*/
            /* If sector freeing fails, return error.                  */
            /*---------------------------------------------------------*/
            if (prepare_mounted_for_format(vol))
              return (void *)-1;
          }

          /*-----------------------------------------------------------*/
          /* Else (volume not mounted) we have to mount the volume.    */
          /*-----------------------------------------------------------*/
          else
          {
            /*---------------------------------------------------------*/
            /* Try mounting the volume if possible.                    */
            /*---------------------------------------------------------*/
            fsys = FfsModule(kMount, path,  /*lint !e416 !e415 */
                             &name, TRUE);
            if (fsys != (FileSys *)-1)
            {
              /*-------------------------------------------------------*/
              /* If sector freeing fails, unmount with error.          */
              /*-------------------------------------------------------*/
              if (prepare_mounted_for_format(vol))
              {
                FlashIoctl(NULL, UNMOUNT, fsys->volume, FALSE);
                return (void *)-1;
              }
              unmount_volume = TRUE;
            }

            /*---------------------------------------------------------*/
            /* Else set up unformatted volume for mounting.            */
            /*---------------------------------------------------------*/
            else
            {
              /*-------------------------------------------------------*/
              /* Acquire access to volume and flash file system.       */
              /*-------------------------------------------------------*/
              semPend(vol->sem, WAIT_FOREVER);
              semPend(FlashSem, WAIT_FOREVER);
              Flash = vol;

              /*-------------------------------------------------------*/
              /* Set up volume as if empty.                            */
              /*-------------------------------------------------------*/
              if (init_volume())
              {
                semPost(FlashSem);
                semPost(vol->sem);
                return (void *)-1;
              }

              /*-------------------------------------------------------*/
              /* Call volume specific code.                            */
        

⌨️ 快捷键说明

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