#学习日记之文件系统2

文件系统

从硬盘这一类的硬件操作,比如读地址,写地址,这种简单的硬件读写,到上层文件系统,串口对文件的读写操作,是个什么流程?

先看个底层SD卡的驱动程序

//SD¿¨CSD¼Ä´æÆ÷Êý¾Ý		  
typedef struct
{
	u8  CSDStruct;            /*!< CSD structure */
	u8  SysSpecVersion;       /*!< System specification version */
	u8  Reserved1;            /*!< Reserved */
	u8  TAAC;                 /*!< Data read access-time 1 */
	u8  NSAC;                 /*!< Data read access-time 2 in CLK cycles */
	u8  MaxBusClkFrec;        /*!< Max. bus clock frequency */
	u16 CardComdClasses;      /*!< Card command classes */
	u8  RdBlockLen;           /*!< Max. read data block length */
	u8  PartBlockRead;        /*!< Partial blocks for read allowed */
	u8  WrBlockMisalign;      /*!< Write block misalignment */
	u8  RdBlockMisalign;      /*!< Read block misalignment */
	u8  DSRImpl;              /*!< DSR implemented */
	u8  Reserved2;            /*!< Reserved */
	u32 DeviceSize;           /*!< Device Size */
	u8  MaxRdCurrentVDDMin;   /*!< Max. read current @ VDD min */
	u8  MaxRdCurrentVDDMax;   /*!< Max. read current @ VDD max */
	u8  MaxWrCurrentVDDMin;   /*!< Max. write current @ VDD min */
	u8  MaxWrCurrentVDDMax;   /*!< Max. write current @ VDD max */
	u8  DeviceSizeMul;        /*!< Device size multiplier */
	u8  EraseGrSize;          /*!< Erase group size */
	u8  EraseGrMul;           /*!< Erase group size multiplier */
	u8  WrProtectGrSize;      /*!< Write protect group size */
	u8  WrProtectGrEnable;    /*!< Write protect group enable */
	u8  ManDeflECC;           /*!< Manufacturer default ECC */
	u8  WrSpeedFact;          /*!< Write speed factor */
	u8  MaxWrBlockLen;        /*!< Max. write data block length */
	u8  WriteBlockPaPartial;  /*!< Partial blocks for write allowed */
	u8  Reserved3;            /*!< Reserded */
	u8  ContentProtectAppli;  /*!< Content protection application */
	u8  FileFormatGrouop;     /*!< File format group */
	u8  CopyFlag;             /*!< Copy flag (OTP) */
	u8  PermWrProtect;        /*!< Permanent write protection */
	u8  TempWrProtect;        /*!< Temporary write protection */
	u8  FileFormat;           /*!< File Format */
	u8  ECC;                  /*!< ECC code */
	u8  CSD_CRC;              /*!< CSD CRC */
	u8  Reserved4;            /*!< always 1*/
} SD_CSD;   

一堆寄存器,按顺序排列开。

//SD卡信息,包括CSD,CID等数据
typedef struct
{
  SD_CSD SD_csd;
  SD_CID SD_cid;
  long long CardCapacity;  	//SD卡容量,单位;字节,最大支持2^64字节大小的卡
  u32 CardBlockSize; 		//SD卡块大小
  u16 RCA;					//卡相对地址
  u8 CardType;				//卡类型
} SD_CardInfo;
extern SD_CardInfo SDCardInfo;//SD卡信息
又构成了一个SD卡信息的结构体,里面包括所有SD卡的信息,
//得到卡信息
//cardinfo:卡信息存储区
//返回值:错误状态
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
{
SD_Error errorstatus=SD_OK;
	u8 tmp=0;	 
	cardinfo->CardType=(u8)CardType; 				//¿¨ÀàÐÍ
	cardinfo->RCA=(u16)RCA;							//¿¨RCAÖµ
	tmp=(u8)((CSD_Tab[0]&0xFF000000)>>24);
	cardinfo->SD_csd.CSDStruct=(tmp&0xC0)>>6;		//CSD½á¹¹
	cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2;	//2.0ЭÒ黹û¶¨ÒåÕⲿ·Ö(Ϊ±£Áô),Ó¦¸ÃÊǺóÐøЭÒ鶨ÒåµÄ
	cardinfo->SD_csd.Reserved1=tmp&0x03;			//2¸ö±£Áôλ  
	tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16);			//µÚ1¸ö×Ö½Ú
	cardinfo->SD_csd.TAAC=tmp;				   		//Êý¾Ý¶Áʱ¼ä1
	tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8);	  		//µÚ2¸ö×Ö½Ú
	cardinfo->SD_csd.NSAC=tmp;		  				//Êý¾Ý¶Áʱ¼ä2
	tmp=(u8)(CSD_Tab[0]&0x000000FF);				//µÚ3¸ö×Ö½Ú
一系列的初始化硬件操作
return errorstatus;//返回错误状态
}
接下来的初始化磁盘,读写磁盘
//初始化磁盘
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber (0..) */
)
{
	u8 res=0;	    
	switch(pdrv)
	{
		case SD_CARD://SD¿¨
			res=SD_Init();//SD卡初始化
  			break;
		case EX_FLASH://外部FLASH
			W25QXX_Init();
			FLASH_SECTOR_COUNT=2048*12;//W25Q1218,前12M字节给FATFS占用 
 			break;
		default:
			res=1; 
	}		 
	if(res)return  STA_NOINIT;
	else return 0; //初始化成功
}  

注意看FLASH_SECTOR_COUNT=2048*12;//W25Q1218,前12M字节给FATFS占用这句话,这里面前12M字节就是给文件系统准备的,里面肯定包含了后面文件的所有信息,比如有多少文件,文件大小,文件类型等等等等。

到这里也复习了前面的内容,接下来讲我今天想通的一个事情,不是很复杂,Linux中使用secureCRT登录到ARM9开发板上,怎么就可以串口可以操作了呢?

其实这个很简单,就是把串口读上来的字符串作一个解析,要不然C语言里学字符串是干嘛的,还有去BAT大厂都要求操作字符串这种的,很重要,比如我从键盘输入一串“1:/system”,那我这里需要他打开盘符为1,目录为system的文件夹,我只需要把串口的数据后面加个\0,把这个作为目录进行操作,就像这样

while(1)
	{
		if(read_write_flag == 1)//дÎļþ
		{
			printf("The string is %s !\r\n",&USART_RX_BUF[1]);
			//len = f_open( fp, "1:/text", FA_READ | FA_WRITE|FA_CREATE_ALWAYS);
			len = f_mkdir(&USART_RX_BUF[1]);//1:/text
		USART_SendData(USART1, (len+0x30));         //向串口1发送数据,创建目录后返回值,发送到串口上
		if (len == 0 )
		{
			LED1 = !LED1;
			delay_ms(1000);
			LED1 = !LED1;
		}
		//f_unlink("1:/text");
		read_write_flag = 0;
		}
		if(read_write_flag == 2)//输出目录下所有文件
		{
			printf("%d\r\n",readdir_list(&USART_RX_BUF[1]));
			LED1 = !LED1;
			delay_ms(1000);
			LED1 = !LED1;
			read_write_flag = 0;
		}
char readdir_list( const u8 *path )
{
	DIR dp;
	FILINFO fno;
	printf("%p\r\n",&dp);
	if (f_opendir (&dp, path) == FR_OK)
	{	
	while ( f_readdir ( &dp , &fno ) == FR_OK) 
	{
		if ( !fno.fname[0] ) break;
		printf("%s\r\n",fno.fname);
	}
	f_closedir ( &dp );
	return 1;
	}
	return 2;
}

void usmart_scan(void)
{
	u8 sta,len;  
	if(USART_RX_STA&0x8000)//串口接收完成?
	{		
		if(USART_RX_BUF[0] == 0x31) read_write_flag = 1;
		if(USART_RX_BUF[0] == 0x32) read_write_flag = 2;
		len=USART_RX_STA&0x3fff;	//得到此次接收到的数据长度
		USART_RX_BUF[len]='\0';	//在末尾加入结束符
······
	}
}

串口数据放在USART_RX_BUF里面,在usmart_scan里面,我判断第一个字符是什么,如果是1,则while(1)里执行创建目录,如果是2,则执行输出目录下所有文件,然后我接着数字后面就是目录1:/system,把这个目录接在
printf("%d\r\n",readdir_list(&USART_RX_BUF[1]));
里面,这样我就可以从串口发送21:/system就可以打开system目录里面的内容。

到这里,我就可以通过串口发送上来的数据对硬盘进行操作了,接下来就是做功能了,可以做Linux里面的ls命令,读上来之后,写个功能就可以,类似上面我写的那样。

需要做的就是把硬盘底层驱动做好,型号不同读写方式也不同,SD卡和内存芯片读写方式都不一样,把硬件连接到文件系统上

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber (0..) */
)
{
	u8 res=0;	    
	switch(pdrv)
	{
		case SD_CARD://SD¿¨
			res=SD_Init();//SD¿¨³õʼ»¯ 
  			break;
		case EX_FLASH://Íⲿflash
			W25QXX_Init();
			FLASH_SECTOR_COUNT=2048*12;//W25Q1218,Ç°12M×Ö½Ú¸øFATFSÕ¼ÓÃ 
 			break;
		default:
			res=1; 
	}		 
	if(res)return  STA_NOINIT;
	else return 0; //³õʼ»¯³É¹¦
}  

比如这个磁盘初始化这里,文件为diskio.c,这个是连接文件系统和硬盘的中间文件,文件系统内部如何实现的我不去理解,我的工作也不是写文件系统,我只需要知道它提供给我文件操作函数,如何配置硬盘底层硬件,就完事。

到此,文件系统可以完结了,没有过多的内容了,剩下的就是做功能,以后经验积累吧,

附加:我研究生实验台用的无纸记录仪,就是这么做的,功能是插上U盘就可以自动把数据写入U盘里面,形成一个.dat文件,这个就设计到文件系统了,我怀疑它里面跑的是ucos或者FreeRTos,现在看来,我的专业知识可以自己独立完成里面程序的编写了,非常不错,那一个仪表32路的3000块钱呢,老贵了,PCB虽然会画点,还没到能找工作的地步,只能自己看懂罢了,越来越觉得自己有价值,越来越值钱啦,接下来可能会学点WIFI模块,或者图形界面,驱动这一部分感觉自己已经两只脚踏进来了,哈哈哈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值