文件系统二
20191129
今天又学了一天的文件系统,写了写一些函数的使用,比如
if(read_write_flag == 1)//дÎļþ
{
//len = f_open( fp, "1:/text", FA_READ | FA_WRITE|FA_CREATE_ALWAYS);
len = f_mkdir("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(path));
LED1 = !LED1;
delay_ms(1000);
LED1 = !LED1;
read_write_flag = 0;
}
如果串口1读到0x31,就建个文件夹,然后串口发送个数字,灯闪一秒证明文件夹创建成功,然后再给他删除了
如果串口1读到0x32,就查找当前目录下的文件,然后串口打印
char readdir_list( const u8 *path )
{
DIR dp;
FILINFO fno;
printf("%p\r\n",&dp);
if (f_opendir (&dp, "1:/") == 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;
}
这代码是看着网上的例程,自己写了个,这其中有个c语言基础的问题,就是子函数中关于数据的定义,如果我这样定义
DIR dp;
FILINFO fno;
子函数中就会给dp和fno分配空间,并且&取地址的话也有固定地址
但是我如果定义一个指针类型,这个指针就是空的!
DIR *dp;
FILINFO *fno;
这样定义的话,dp和fno都是0,虽然给指针分配了内存空间,&dp和&fno都是有地址的,但是dp和fno指向的内容还没给它,所以它无处可指,就是0,还有可能是其他值,子函数里说不准。
要想传参数,也得传一个有值的数据结构,不能传空的啊,开始我这么做的
DIR *dp;
FILINFO *fno;
f_readdir ( dp , fno ) ;
这时候指针是0,传进去也没用,后来还是乖乖看例程
DIR dp;
FILINFO fno;
f_readdir ( &dp , &fno );
这样f_readdir里面参数才是有内容的有地址的,指针不能瞎定义,得有内容可指再用它,不然如果想用数据的话还是乖乖定义原本的类型吧。
放个结果图,虽然不太好看
LCD ID:5510
函数错误!
2001c5a4
SYSTEM
测试用~1
text
1
函数错误是usmart不认识我的0x31才报的,2001c5a4是我定义的结构体的地址,传入f_readdir里的dp的值,有地址有数据空间,才能操作。下面就是当先目录下的文件,再次说明一下,它每个文件都有自己的各种属性,大小,文件名,长度等等在这个里面
FILINFO fno;
/* File status structure (FILINFO) */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
#if _USE_LFN
TCHAR* lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif
} FILINFO;
这里面啥都有,fname就是名字,有13个字节的长度,那个fattrib就是属性,应该就是文件属于目录还是普通文件还是其他文件这种的,中间_USE_LFN就是long file name的简称吧,如果使用长文件名,就有下面的定义了。
要注意的点是文件系统内打开任何东西都得手动关闭,目录,文件,自己申请的内存空间,指针,更得记得要关闭,不然内存泄漏了就不好了。
总之今天的内容学到了文件的操作,打开关闭,文件夹的建立删除,目录的操作,现在可以对文件进行一定的编程操作了,然后如果有需要再学学SD卡硬件层,或者其他硬盘类的硬件层,把接口函数写好,就能对一般的存储介质进行文件操作了。
这些估计就足够使用文件系统了,日常使用应该没啥问题了,除非想自己写个文件系统,不然只需要知道这些函数咋用就行,看码:
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
FRESULT f_truncate (FIL* fp); /* Truncate file */
FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
这就是文件系统基本的一些函数,足够使用了,
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
文件夹操作
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
我感觉这些挺重要的,知道啥意思知道咋用就OK。不懂的看后面注释。