📄 flash_misc.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 + -