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

📄 flash_misc.c

📁 ucos平台下的文件系统的源代码
💻 C
字号:
/*
 * COPYRIGHT (c) Notifier 1993-2004, All Rights Reserved
 *
 * 描述:        uC/FS的Flash磁盘的驱动
 *
 * 版本历史:
 *
 * 版本     作者        日期        修改内容
 * 1.0      王璀        2005-11-05  创建
 * 1.1      王璀        2006-01-17  标准化
 *                                  添加了Cache功能
 * 1.11     王璀        2006-06-27  小修改
*/

//==============================================================================
// 包含的头文件
//==============================================================================
#include "flash_misc_cfg.h"

#include "sys_cfg.h"
#include "bsp_cfg.h"

#include <stdio.h>
#include <assert.h>

#include <fs_shell_cmd.h>
#include "library\lib_shell.h"
#include "library\lib_log.h"

#include "driver\drv_sst39vf160.h"

#include "fs_port.h"
#include "fs_dev.h" 
#include "fs_lbl.h" 
#include "fs_conf.h"

#include "includes.h"
#include "fs_api.h"
#include "fs_clib.h"

//==============================================================================
// 本地宏及类型定义
//==============================================================================
#define MODULE "flash_misc"
LogDesc g_logDescFlashMisc = 
    {
        MODULE,
        LOG_LEVEL_ALL_OFF,
        NULL,
    };
static LogDesc *sg_pLogDesc = &g_logDescFlashMisc;

#define FAT_SEC_PER_TRACK   (FS_FLASH_SECTOR_SIZE/FS_FAT_SEC_SIZE)        
#define NUM_OF_FAT_SEC      (FS_FLASH_SECTOR_NUM * FAT_SEC_PER_TRACK)

#define FS_FLASH_MAXUNIT    1

typedef struct {
  FS_u32 m_track;
  FS_u8  m_cache[FAT_SEC_PER_TRACK][FS_FAT_SEC_SIZE];
} _FS_FlashCache;

//==============================================================================
// 内部函数声明
//==============================================================================
//------------------------------------------------------------------------------
// 函数描述:FS driver function. Get status of the FLASH disk.
static int//==1 (FS_LBL_MEDIACHANGED) - The media of the device has changed.
          //==0                       - Device okay and ready for operation.
          //<0                        - An error has occured.
_FS_FLASH_DevStatus
    (
    FS_u32 Unit//Unit number.
    );
//------------------------------------------------------------------------------
// 函数描述:FS driver function. Read a sector from the FLASH disk.
static int//==0         - Sector has been read and copied to pBuffer.
          //<0          - An error has occured.
_FS_FLASH_DevRead
    (
    FS_u32 Unit,//Unit number.
    FS_u32 Sector,//Sector to be read from the device.
    void *pBuffer//Pointer to buffer for storing the data.
    );
//------------------------------------------------------------------------------
// 函数描述:FS driver function. Write sector to the FLASH disk.
static int//==0         - Sector has been written to the device.
          //<0          - An error has occured.
_FS_FLASH_DevWrite
    (
    FS_u32 Unit,//Unit number.
    FS_u32 Sector,//Sector to be written to the device.
    void *pBuffer//Pointer to data to be stored.
    );
//------------------------------------------------------------------------------
// 函数描述:FS driver function. Execute device command.
static int//Command specific. In general a negative value means an error.
_FS_FLASH_DevIoCtl
    (
    FS_u32 Unit,//Unit number.
    FS_i32 Cmd,//Command to be executed.
    FS_i32 Aux,//Parameter depending on command.
    void *pBuffer//Pointer to a buffer used for the command.
    );
    
//==============================================================================
// 全局变量定义
//==============================================================================
const FS__device_type FS__flashdevice_driver = {
  "FLASH DISK device",
  _FS_FLASH_DevStatus,
  _FS_FLASH_DevRead,
  _FS_FLASH_DevWrite,
  _FS_FLASH_DevIoCtl
};

//==============================================================================
// 内部变量定义
//==============================================================================
static int sg_devStatusChecked[FS_FLASH_MAXUNIT] = {0};

static _FS_FlashCache sg_cache[FS_FLASH_MAXUNIT][FS_FLASH_CACHE_NUM];

//==============================================================================
// 函数定义
//==============================================================================
//------------------------------------------------------------------------------
// 函数描述:FS driver function. Get status of the FLASH disk.
static int//==1 (FS_LBL_MEDIACHANGED) - The media of the device has changed.
          //==0                       - Device okay and ready for operation.
          //<0                        - An error has occured.
_FS_FLASH_DevStatus
    (
    FS_u32 Unit//Unit number.
    )
{
  FS_u32 i;
  
  
  #if FS_FLASH_DBG_EN
  PDBG("_FS_FLASH_DevStatus, Unit: %lu", Unit);
  #endif

  if (Unit >= FS_FLASH_MAXUNIT)
  {
    return -1;  // Invalid unit number
  }
  
  if (sg_devStatusChecked[Unit] == 0)
  {
    sg_devStatusChecked[Unit] = 1;
    
    for (i = 0; i < FS_FLASH_CACHE_NUM; i++) {
      sg_cache[Unit][i].m_track = -1;
    }

    //Make sure, the function returns FS_LBL_MEDIACHANGED when it is
    //called the first time
    return FS_LBL_MEDIACHANGED;
  }
  
  return 0;
}

//------------------------------------------------------------------------------
// 函数描述:FS driver function. Read a sector from the FLASH disk.
static int//==0         - Sector has been read and copied to pBuffer.
          //<0          - An error has occured.
_FS_FLASH_DevRead
    (
    FS_u32 Unit,//Unit number.
    FS_u32 Sector,//Sector to be read from the device.
    void *pBuffer//Pointer to buffer for storing the data.
    )
{
  FS_u32 trackOffset = Sector/FAT_SEC_PER_TRACK;
  FS_u32 fatSectorOffset = Sector%FAT_SEC_PER_TRACK;
  FS_u32 i;
  

  #if FS_FLASH_DBG_EN
  PDBG("_FS_FLASH_DevRead, Unit: %lu, Sector: %lu, pBuffer: 0x%lx", Unit, Sector, (INT32U)pBuffer);
  #endif

  if (Unit >= FS_FLASH_MAXUNIT)
  {
    return -1;  //Invalid unit number
  }

  if (Sector >= NUM_OF_FAT_SEC)
  {
    return -1;  //Out of physical range
  }
  
  //检查是否在Cache中
  for (i = 0; i < FS_FLASH_CACHE_NUM; i++) {
    if (sg_cache[Unit][i].m_track == trackOffset) {
      FS__CLIB_memcpy(pBuffer, sg_cache[Unit][i].m_cache[fatSectorOffset], FS_FAT_SEC_SIZE);
      return 0;
    }
  }
  //不在Cache中

  //读取一个FAT Sector
  FS__CLIB_memcpy(pBuffer, (INT8U *)(FS_FLASH_USER_START + (Sector * FS_FAT_SEC_SIZE)), FS_FAT_SEC_SIZE); 

  return 0;
}

//------------------------------------------------------------------------------
// 函数描述:FS driver function. Write sector to the FLASH disk.
static int//==0         - Sector has been written to the device.
          //<0          - An error has occured.
_FS_FLASH_DevWrite
    (
    FS_u32 Unit,//Unit number.
    FS_u32 Sector,//Sector to be written to the device.
    void *pBuffer//Pointer to data to be stored.
    )
{
  FS_u32 trackOffset = Sector/FAT_SEC_PER_TRACK;
  FS_u32 fatSectorOffset = Sector%FAT_SEC_PER_TRACK;
  FS_u32 i;
  FS_u32 j;
  
  
  #if FS_FLASH_DBG_EN
  PDBG("_FS_FLASH_DevWrite, Unit: %lu, Sector: %lu, pBuffer: 0x%lx", Unit, Sector, (INT32U)pBuffer);
  #endif

  if (Unit >= FS_FLASH_MAXUNIT)
  {
    return -1;  //Invalid unit number
  }
  
  if (Sector >= NUM_OF_FAT_SEC)
  {
    return -1;  //Out of physical range
  }

  //检查是否在Cache中
  for (i = 0; i < FS_FLASH_CACHE_NUM; i++) {
    if (sg_cache[Unit][i].m_track == trackOffset) {
      FS__CLIB_memcpy(sg_cache[Unit][i].m_cache[fatSectorOffset], pBuffer, FS_FAT_SEC_SIZE);
      return 0;
    }
  }
  //不在Cache中

  //检查是否有可用的Cache
  for (i = 0; i < FS_FLASH_CACHE_NUM; i++) {
    if (sg_cache[Unit][i].m_track == -1) {
      //设置该Cache的Track号码
      sg_cache[Unit][i].m_track = trackOffset;
      //从Flash中载入一个Track到该Cache
      FS__CLIB_memcpy(
        sg_cache[Unit][i].m_cache,
        (INT8U *)(FS_FLASH_USER_START + (sg_cache[Unit][i].m_track*FS_FLASH_SECTOR_SIZE)),
        FS_FLASH_SECTOR_SIZE );
      //将数据写入Cache
      FS__CLIB_memcpy(sg_cache[Unit][i].m_cache[fatSectorOffset], pBuffer, FS_FAT_SEC_SIZE);
      return 0;
    }
  }
  //无可用的Cache
  
  //将整个Cache写入Flash
  for (;;)
  {
    //寻找第一个有内容的Cache
    for (i = 0; i < FS_FLASH_CACHE_NUM; i++) {
      if (sg_cache[Unit][i].m_track != -1) {//找到第一个有内容的Cache
        break;  // Valid cache entry found
      }
    }
    
    //检查是否找到有内容的Cache
    if (i >= FS_FLASH_CACHE_NUM) {//未找到有内容的Cache,跳出for (;;)循环
      break;
    }
    
    //遍历整个Cache,找到Track最小的那个Cache
    for (j = 0; j < FS_FLASH_CACHE_NUM; j++) {
      if (sg_cache[Unit][j].m_track != -1) {//找到一个有内容的Cache
        if (sg_cache[Unit][j].m_track < sg_cache[Unit][i].m_track) {//这个Track比前面的都小
          i = j;//记住这个Track
        }
      }
    }
    //找到了block value最小的那个Cache
    if (sg_cache[Unit][i].m_track != -1) {
      //将该Cache写入Flash
      #if FS_FLASH_DBG_EN
      PDBG("call FlashProgramOneSector, src: 0x%08lX, dest: 0x%08lX",
           (unsigned long)sg_cache[Unit][i].m_cache,
           (unsigned long)(FS_FLASH_USER_START + (sg_cache[Unit][i].m_track*FS_FLASH_SECTOR_SIZE)) );
      #endif

      OS_ENTER_CRITICAL();
      FlashProgramOneSector 
        (
        (INT16U *)sg_cache[Unit][i].m_cache,    
        (INT16U *)(FS_FLASH_USER_START + (sg_cache[Unit][i].m_track*FS_FLASH_SECTOR_SIZE))
        );
      OS_EXIT_CRITICAL();
      //指示该Cache未使用
      sg_cache[Unit][i].m_track = -1;
    }
  }

  //设置第0个Cache的Track号码
  sg_cache[Unit][0].m_track = trackOffset;
  //从Flash中载入一个Track到该Cache
  FS__CLIB_memcpy(
    sg_cache[Unit][0].m_cache,
    (INT8U *)(FS_FLASH_USER_START + (sg_cache[Unit][0].m_track*FS_FLASH_SECTOR_SIZE)),
    FS_FLASH_SECTOR_SIZE );
  //将数据写入Cache
  FS__CLIB_memcpy(sg_cache[Unit][0].m_cache[fatSectorOffset], pBuffer, FS_FAT_SEC_SIZE);

  return 0;
}

//------------------------------------------------------------------------------
// 函数描述:FS driver function. Execute device command.
static int//Command specific. In general a negative value means an error.
_FS_FLASH_DevIoCtl
    (
    FS_u32 Unit,//Unit number.
    FS_i32 Cmd,//Command to be executed.
    FS_i32 Aux,//Parameter depending on command.
    void *pBuffer//Pointer to a buffer used for the command.
    )
{
  /*struct {
    FS_u32 hiddennum;
    FS_u32 headnum;
    FS_u32 secnum;
    FS_u32 partsize;
  } devinfo;*/
  FS_u32 *info;
  int idx;
  #if FS_FLASH_DBG_EN
  char *pStrIoCmd;
  STATUS result;
  #endif
  int i;


  #if FS_FLASH_DBG_EN
  result = EnumToStr(g_fsIoCmdStrTbl, Cmd, &pStrIoCmd);
  assert(result == OK);

  PDBG("_FS_FLASH_DevIoCtl, Unit: %lu, Cmd: %s, Aux: %lu, pBuffer: 0x%lx",
    Unit,
    pStrIoCmd,
    Aux,
    (INT32U)pBuffer);
  #endif

  Aux = Aux;  //Get rid of compiler warning

  if (Unit >= FS_FLASH_MAXUNIT)
  {
    return -1;  //Invalid unit number
  }

  switch (Cmd)
  {
  case FS_CMD_FLUSH_CACHE:
    if (sg_devStatusChecked[Unit]) {
      for (i = 0; i < FS_FLASH_CACHE_NUM; i++) {
        if (sg_cache[Unit][i].m_track != -1) {
          #if FS_FLASH_DBG_EN
          PDBG("call FlashProgramOneSector, src: 0x%08lX, dest: 0x%08lX",
               (unsigned long)sg_cache[Unit][i].m_cache,
               (unsigned long)(FS_FLASH_USER_START + (sg_cache[Unit][i].m_track*FS_FLASH_SECTOR_SIZE)) );
          #endif

          //将该Cache写入Flash
          OS_ENTER_CRITICAL();
          FlashProgramOneSector 
            (
            (INT16U *)sg_cache[Unit][i].m_cache,    
            (INT16U *)(FS_FLASH_USER_START + (sg_cache[Unit][i].m_track*FS_FLASH_SECTOR_SIZE))
            );
          OS_EXIT_CRITICAL();
          //指示该Cache未使用
          sg_cache[Unit][i].m_track = -1;
        }
      }
      //sg_devStatusChecked[Unit] = 0;
    }
    break;
      
  //case FS_CMD_CHK_DSKCHANGE:
    //什么也不用做
  //    break;
      
  //case FS_CMD_READ_SECTOR:
    //上层会处理
  //    break;
      
  //case FS_CMD_WRITE_SECTOR:
    //上层会处理
  //    break;
      
  //case FS_CMD_FORMAT_MEDIA:
    //上层会处理
  //    break;
      
  //case FS_CMD_FORMAT_AUTO:
    //上层会处理
  //    break;
      
  //case FS_CMD_INC_BUSYCNT:
    //什么也不用做
  //    break;
      
  //case FS_CMD_DEC_BUSYCNT:
    //什么也不用做
      //break;
      
  //case FS_CMD_GET_DISKFREE:
    //上层会处理
  //    break;
      
  case FS_CMD_GET_DEVINFO:
    if (!pBuffer)
    {
      return -1;
    }
    info = pBuffer;

    *info = 0;                //hidden

    info++;
    *info = 0;                //head

    info++;
    *info = FAT_SEC_PER_TRACK;//sec per track

    info++;
    *info = NUM_OF_FAT_SEC;   //num of sectors
    break;
    
  case FS_CMD_FLASH_ERASE_CHIP:
    OS_ENTER_CRITICAL();
    for (idx = 0; idx < FS_FLASH_SECTOR_NUM; ++idx)
    {
      #if FS_FLASH_DBG_EN
      PDBG("call FlashEraseOneSector, dest: 0x%08lX",
           (unsigned long)(FS_FLASH_USER_START + (idx*FS_FLASH_SECTOR_SIZE)) );
      #endif

      FlashEraseOneSector((INT16U *)(FS_FLASH_USER_START + (idx*FS_FLASH_SECTOR_SIZE)));
    }
    OS_EXIT_CRITICAL();
    break;
      
  default:
    break;
  }

  return 0;
}

//------------------------------------------------------------------------------
// 函数描述:Initialize Flashdisk
int//==0 means init successfully
   //!=0 means init failure
FlashDiskInit(void)
{
    FS_DISKFREE_T disk_data;
    int x;


    x = FS_IoCtl("flash:", FS_CMD_GET_DISKFREE, 0, (void*)(&disk_data));
    if (x != 0)
    {//表示该磁盘未格式化或已损坏
        printf("\r\n""磁盘" "flash:" "未格式化或已损坏!");
        printf("\r\n""自动格式化...");
        
        x = FS_IoCtl("flash:",FS_CMD_FORMAT_AUTO,0,0);	//read error format it
        if (x != 0) 
        {
            printf("失败");
            return -1;
        }
        else
        {
            printf("成功");
            return 0;
        }
    }

    return 0;
}

⌨️ 快捷键说明

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