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

📄 ramdisk.c

📁 HFAT32是我依据FAT标准,按照自己的理解写出来的一个FAT文件系统 特性: 1.HFAT32 是一个小型的嵌入式FAT文件系统,可以方便地在nand flash,RAM和SD Card
💻 C
字号:
//---------------------------------------------------------------------------------
// Copyright jinhailiao 2008-2010
// E-mail:   jinhailiao@163.com
// Project:			HFAT16/32
// File:			ramdisk.c
// Description:		
//-------------------------------------------------------------
// Reversion Histroy:
//-------------------------------------------------------------
// Version		date		operations				by who
// 1.0.0		2008-06-01  create                  Kingsea
//---------------------------------------------------------------------------------
#include "hfstype.h"
#include "ftdevice.h"
#include "haiclib.h"


#ifdef ADD_RAM_DISK_DRIVER

#ifdef RAMDISK_SIMULATOR
#include <stdio.h>
#endif

//macro define
//
#define RAMDISK_SECTOR_BYTES			512
#define RAMDISK_SECTOR_MAX				0x20000/*64MB*/
#define RAMDISK_SECT_PER_CLST			8
#define RAMDISK_BUFFER_CLST_MAX			6

#define RAMDISK_BUFFER_NEEDFLUSH		0x01000000


//function prototype
//
static int RamDiskReadCluster(S_DWORD cluster, S_BYTE *OutBuf);
static int RamDiskWriteCluster(S_DWORD cluster, S_BYTE *InBuf);
static void IncreaseUseCount(int BufNo);
static int FindLeastUseCluster(void);

int RamDiskDevInit(void);
int RamDiskDevStatus(void);
int RamDiskDevRead(S_DWORD sector, S_BYTE *OutBuf);
int RamDiskDevWrite(S_DWORD sector, S_BYTE *InBuf);
int RamDiskDevCmd(S_DWORD cmd, S_DWORD arg, S_DWORD *OutVal);
int RamDiskDevFlush(S_DWORD sector, S_BOOL FreeBuffer);

//assert driver struct
//
const S_FATDEVDRV RamDiskDrv =
{
	"ramdisk16",
	RamDiskDevInit,
	RamDiskDevStatus,
	RamDiskDevRead,
	RamDiskDevWrite,
	RamDiskDevCmd,
	RamDiskDevFlush,
};

//RamDisk Driver Buffer
//
static S_BYTE *RamDiskStartAddr;
static S_BYTE RamDiskBuf[RAMDISK_BUFFER_CLST_MAX][RAMDISK_SECTOR_BYTES*RAMDISK_SECT_PER_CLST];
static S_DWORD RamDiskFlag[RAMDISK_BUFFER_CLST_MAX];
static S_DWORD RamDiskClst[RAMDISK_BUFFER_CLST_MAX];

int RamDiskDevInit(void)
{
	int i;
#ifdef RAMDISK_SIMULATOR
	FILE *fp = fopen(".\\ramdisk16.dat", "rb+");
	if (fp == S_NULL)
		return -1;
	RamDiskStartAddr = (S_BYTE*)fp;
#else
	RamDiskStartAddr = 0x????????;//note: This addr must align 4-bytes;
#endif
	for (i = 0; i < RAMDISK_BUFFER_CLST_MAX; i++)
		RamDiskFlag[i] = 0;
	for (i = 0; i < RAMDISK_BUFFER_CLST_MAX; i++)
		RamDiskClst[i] = 0xFFFFFFFF;
	return 0;	
}

int RamDiskDevStatus(void)
{
	return 0;
}

int RamDiskDevRead(S_DWORD sector, S_BYTE *OutBuf)
{
	int i, m = RAMDISK_BUFFER_CLST_MAX-1;
	S_DWORD cluster = sector/RAMDISK_SECT_PER_CLST;
	S_DWORD current = sector%RAMDISK_SECT_PER_CLST;
	
	//find if in driver buffer
	for (i = 0; i < RAMDISK_BUFFER_CLST_MAX; i++)
	{
		if (RamDiskClst[i] == 0xFFFFFFFF)
			m = i;
		else if (RamDiskClst[i] == cluster)
			break;
	}
	
	if (i == RAMDISK_BUFFER_CLST_MAX)// not found out
	{
		if (RamDiskClst[m] != 0xFFFFFFFF) // have not idle cluster, make one idle cluster
		{
			m = FindLeastUseCluster();
			if ((RamDiskFlag[m]&RAMDISK_BUFFER_NEEDFLUSH) == RAMDISK_BUFFER_NEEDFLUSH)
				if (RamDiskWriteCluster(RamDiskClst[m], RamDiskBuf[m]))
				{
					return -1;
				}
		}
		RamDiskFlag[m] = 0;
		RamDiskClst[m] = cluster;
		if (RamDiskReadCluster(RamDiskClst[m], RamDiskBuf[m]))//ok, have one idle cluster
		{
			RamDiskClst[m] = 0xFFFFFFFF;//Oh, shit! fail on read disk
			return -1;
		}
		i = m;//make it as found successful....
	}

	if (RamDiskClst[i] == cluster)//OK, found out
	{
		S_BYTE *pDat = &RamDiskBuf[i][current*RAMDISK_SECTOR_BYTES];
#if 0		
		for (m = 0; m < RAMDISK_SECTOR_BYTES; m++)
			OutBuf[m]  = pDat[m];
#else
		hai_memcpy(OutBuf, pDat, RAMDISK_SECTOR_BYTES);
#endif
		IncreaseUseCount(i);
	}
	
	return 0;	
}

int RamDiskDevWrite(S_DWORD sector, S_BYTE *InBuf)
{
	int i, m = RAMDISK_BUFFER_CLST_MAX-1;
	S_DWORD cluster = sector/RAMDISK_SECT_PER_CLST;
	S_DWORD current = sector%RAMDISK_SECT_PER_CLST;
	
	//find if in driver buffer
	for (i = 0; i < RAMDISK_BUFFER_CLST_MAX; i++)
	{
		if (RamDiskClst[i] == 0xFFFFFFFF)
			m = i;
		else if (RamDiskClst[i] == cluster)
			break;
	}
	
	if (i == RAMDISK_BUFFER_CLST_MAX)// not found out
	{
		if (RamDiskClst[m] != 0xFFFFFFFF) // have not idle cluster, make one idle cluster
		{
			m = FindLeastUseCluster();
			if ((RamDiskFlag[m]&RAMDISK_BUFFER_NEEDFLUSH) == RAMDISK_BUFFER_NEEDFLUSH)
				if (RamDiskWriteCluster(RamDiskClst[m], RamDiskBuf[m]))
				{
					return -1;
				}
		}
		RamDiskFlag[m] = 0;
		RamDiskClst[m] = cluster;
		if (RamDiskReadCluster(RamDiskClst[m], RamDiskBuf[m]))//ok, have one idle cluster
		{
			RamDiskClst[m] = 0xFFFFFFFF;//Oh, shit! fail on read disk
			return -1;
		}
		i = m;//make it as found successful....
	}

	if (RamDiskClst[i] == cluster)//OK, found out
	{
		S_BYTE *pDat = &RamDiskBuf[i][current*RAMDISK_SECTOR_BYTES];
#if 0		
		for (i = 0; i < RAMDISK_SECTOR_BYTES; i++)
			pDat[i] = InBuf[i];
#else
		hai_memcpy(pDat, InBuf, RAMDISK_SECTOR_BYTES);
#endif
		RamDiskFlag[i] |= RAMDISK_BUFFER_NEEDFLUSH;
		IncreaseUseCount(i);
	}
		
	return 0;
}

int RamDiskDevCmd(S_DWORD cmd, S_DWORD arg, S_DWORD *OutVal)
{
	int err = 0;
	switch (cmd)
	{
	case DEVCMD_WRITE_PROTECT:
		//*OutVal = DEVINFO_FLAG_WRITE_DETECT; //if have write protect 
		*OutVal = 0;
		break;
	case DEVCMD_SECTOR_SIZE:
		*OutVal = RAMDISK_SECTOR_BYTES;//this is a recommand val, otherwise:1024, 2048, 4096.
		break;
	case DEVCMD_TOTAL_SECTOR:
		*OutVal = RAMDISK_SECTOR_MAX;
		break;
	case DEVCMD_SEC_PER_CLUS:
		*OutVal = RAMDISK_SECT_PER_CLST; //or 1, 2, 4, 8, 16, 32, 64, 128;
		break;
	default:
		*OutVal = 0;
		break;
	}
	return err;
}

int RamDiskDevFlush(S_DWORD sector, S_BOOL FreeBuffer)
{
	int i, start, end;
	
	if (sector == 0xFFFFFFFF)
	{
		start = 0; end = RAMDISK_BUFFER_CLST_MAX;
	}
	else
	{
		S_DWORD cluster = sector/RAMDISK_SECT_PER_CLST;
		for (i = 0; i < RAMDISK_BUFFER_CLST_MAX; i++)
			if (RamDiskClst[i] == cluster)
				break;
		if (i == RAMDISK_BUFFER_CLST_MAX)
		{
			start = 0; end = 0;
		}
		else
		{
			start = i; end = i+1;
		}
	}
	
	for (i = start; i < end; i++)
	{
		if ((RamDiskFlag[i]&RAMDISK_BUFFER_NEEDFLUSH) == RAMDISK_BUFFER_NEEDFLUSH)
		{
			if (RamDiskWriteCluster(RamDiskClst[i], RamDiskBuf[i]))
			{
				return -1;
			}
			RamDiskFlag[i] &= ~RAMDISK_BUFFER_NEEDFLUSH;
		}
		if (FreeBuffer)
		{
			RamDiskFlag[i] = 0x00;
			RamDiskClst[i] = 0xFFFFFFFF;
		}
	}
	return 0;
}



static void IncreaseUseCount(int BufNo)
{
	S_DWORD UseCnt = RamDiskFlag[BufNo]&0x0000FFFF;
	
	UseCnt = (UseCnt<0xFFFF)? (UseCnt+1):(UseCnt);//increase use count
	RamDiskFlag[BufNo] = (RamDiskFlag[BufNo]&0xFFFF0000)|(UseCnt&0x0000FFFF);
}

static int RamDiskReadCluster(S_DWORD cluster, S_BYTE *OutBuf)
{
	S_DWORD offset = cluster * RAMDISK_SECTOR_BYTES * RAMDISK_SECT_PER_CLST;
	
#ifdef RAMDISK_SIMULATOR
	if (!fseek((FILE*)RamDiskStartAddr, offset, SEEK_SET))
	{
		if (fread(OutBuf, RAMDISK_SECTOR_BYTES, RAMDISK_SECT_PER_CLST, (FILE*)RamDiskStartAddr) != RAMDISK_SECT_PER_CLST)
			return -1;
		return 0;
	}
	return -1;
#else
	int i;
	S_BYTE *pDat = RamDiskStartAddr + offset;
	for (i = 0; i < RAMDISK_SECTOR_BYTES * RAMDISK_SECT_PER_CLST; i++)
		OutBuf[i] = pDat[i];
	return 0;
#endif
}

static int RamDiskWriteCluster(S_DWORD cluster, S_BYTE *InBuf)
{
	S_DWORD offset = cluster * RAMDISK_SECTOR_BYTES * RAMDISK_SECT_PER_CLST;
	
#ifdef RAMDISK_SIMULATOR
	if (!fseek((FILE*)RamDiskStartAddr, offset, SEEK_SET))
	{
		if (fwrite(InBuf, RAMDISK_SECTOR_BYTES, RAMDISK_SECT_PER_CLST, (FILE*)RamDiskStartAddr) != RAMDISK_SECT_PER_CLST)
			return -1;
		fflush((FILE*)RamDiskStartAddr);
		return 0;
	}
	return -1;
#else
	int i;
	S_BYTE *pDat = RamDiskStartAddr + offset;
	for (i = 0; i < RAMDISK_SECTOR_BYTES * RAMDISK_SECT_PER_CLST; i++)
		pDat[i] = InBuf[i];
	return 0;
#endif
}

static int FindLeastUseCluster(void)
{
	int i = 0, m = 0;
	S_DWORD UseCnt = RamDiskFlag[i]&0x0000FFFF;
	
	for (i = 1; i < RAMDISK_BUFFER_CLST_MAX; i++)
	{
		if (UseCnt > (RamDiskFlag[i]&0x0000FFFF))
		{
			UseCnt = RamDiskFlag[i]&0x0000FFFF;
			m = i;
		}
	}
	return m;
}

#endif //#ifdef ADD_RAM_DISK_DRIVER

⌨️ 快捷键说明

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