draapho 发表于 2011-12-8 13:32:25

火牛板学习RT-Thread Step by Step——第五篇:基于SD卡的文件系统,使用SPI模式,支持中文长文

RT-Thread的文件系统基本框架如下:

Device Filesystem,文件系统设备,属于RT-Thread的设备管理
在filesystem\dfs\src下面的文件
------------------------------------------------------------
然后是DFS系统和Fatfs中间的一个转接文件,如下:
filesystem\dfs\filesystems\elmfat\dfs_elm.c
------------------------------------------------------------
然后就是fatfs文件系统。已经不需要移植diskio的相关函数了。



用户自己移植底层驱动的话,关键是添加RT-Thread的设备。
见rt_sd.c文件。
需要重写 rt_sd_read, rt_sd_write, rt_hw_sd_init几个函数。

如何支持时间。
在dfs_elm.c文件中,找到 rt_time_t get_fattime(),范例中直接return 0;
查找fatfs的源代码,可以知道其时间格式为:
/* User defined function to give a current time to fatfs module          */
/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
STM32自己支持RTC,我的工程模板里直接有RTC的驱动,做个格式转换即可,因此移植如下:
#include "drv_rtc_time.h"
rt_time_t get_fattime()
{
struct tm time;

time = TimeGetCalendarTime();
time.tm_year -= 1980;                                                    // ff文件系统年份起始值1980年
time.tm_sec >>= 1;                                                       // 秒除以2, 已符合ff文件系统时间格式要求

return( ((DWORD)time.tm_year << 25) |                                    // 时间格式转换
          ((DWORD)time.tm_mon<< 21) |
          ((DWORD)time.tm_mday << 16) |
          ((DWORD)time.tm_hour << 11) |
          ((DWORD)time.tm_min<< 5 ) |
          ((DWORD)time.tm_sec)      );
}

如何支持中文和长文件名。
在ffconf.h中,
#define _CODE_PAGE       936 //使用GBK编码
#define _USE_LFN         2   //支持长文件名,2表示可重入,1不可重入
#define _WORD_ACCESS   0
#define _FS_REENTRANT    0   //此项不太能理解,配置为0是不可重入的,但配为1出现错误。
// 范例代码里也确实是配置为0的,RT_DFS_ELM_REENTRANT这个宏定义从来没有被定义过。
在编译器里加入 cc936.c 文件。

该工程模板提供了SD卡的写入文件,以及读取文件,并测试了读写速度。
通过串口终端,执行结果如下:
Asserted by user
info: File System initialized!// SD卡初始化成功
para: 0

sd test application    // 进入SD卡测试线程
sd opened test.bin
sd write 1M byte used 6410 ms   // 写入1M的时间用了6.5s,约150Kbyte/s
sd write speed test finished. close test.bin
sd opened test.bin
sd read 1M byte used 5570 ms// 去读1M的时间用了5.5s,约180Kbyte/s
sd read speed test finished. close test.bin



说说官方范例及此驱动的区别。
官方范例的 msd.c 文件就是SD、MMC等卡的SPI模式读写。但是它不支持SDHC卡。msd就是memory sd的意思......
官方范例的 sdcard.c 文件是用SDIO模式读写的,硬件支持的话,用此驱动较好。
此范例中的 drv_sd.c 文件使用SPI模式进行读写的,测试过的卡包括 SanDisk的SDHC, 创建的SD_V2卡, 不知名的卡若干张, 容量最大测试到8GB。
而 rt_sd.c 就是底层驱动和 RT-Thread 设备管理系统的接口文件。



学习RT-Thread一周半,学写驱动两次,关于IO管理模块
RT-Thread的IO设备管理模块的目的:将设备的硬件代码 与 应用层代码 隔离开来。
让软件人员可专注于软件应用开发,驱动人员专注于硬件驱动。让软件人员对设备的操作有一个统一的平台,无需去关注底层硬件驱动的写法。
如果严格一点来说。应用层应该不允许直接调用驱动层的函数,而必须通过IO管理模块的接口进行操作。对标准的操作系统来说,本应如此。。。
但在需求千变万化的嵌入式应用,这一点就较难做到了。

我们有必要把 LED灯、按钮、开关控制信号、SPI通讯、I2C通讯都打包成RT-Thread的设备管理模块吗?
至少LED灯的范例作者自己也没进行打包,I2C通讯有人想打包却比较困难。

我个人观点是,具体应用具体分析。

如果是一个大公司大应用,完全可以充分利用起设备管理模块的优势,一部分人写底层驱动,另外一部分人关注与上层应用。
其好处是写上层应用的人员无需去考虑硬件驱动的写法、实现等技术细节。

如果是小公司小应用,一个项目就一二个软件人员的,驱动也自己写,应用也自己写,那完全可以根据情况决定是否使用设备管理模块。
对已有的设备管理模块——使用之,
通用型或常用的,如SD卡文件系统,网络,标准键盘输入,可以写成设备管理模块。
非常简单的硬件,如LED灯、IO口开关量,不用写了,使用起来也直观方便。
非标准应用,不写了。直接在应用层使用底层驱动。

对个人学习,那非常有必要学习书写一二个设备的驱动,将其加入到设备管理中。在上层应用中能用起来。



最后有二个疑惑:
1.在ffconf.h中,
#define _FS_REENTRANT    0   //此项不太能理解,配置为0是不可重入的,但配为1出现错误。
按照fatfs作者的本意,此处必须配置为1才,表示可重入才对。当然也有可能更上层的dfs系统对此做了相关的线程安全工作。
2.SD卡初始化设备时,为何不用指明设备类型。
设备类型指:
        RT_Device_Class_Char = 0,                                                /* character device                        RT_Device_Class_Block,                                                        /* block device                         RT_Device_Class_NetIf,                                                        /* net interface                         RT_Device_Class_MTD,                                                        /* memory device                                 RT_Device_Class_CAN,                                                        /* CAN device                                 RT_Device_Class_RTC,                                                        /* RTC device                                 RT_Device_Class_Sound,                                                        /* Sound device                         RT_Device_Class_Unknown                                                        /* unknown device        

RT-Thread文件系统工程目标V021ourdev_702717OZ2I3J.rar(文件大小:3.32M) (原文件名:STM32_RTThread_V021.rar)

draapho 发表于 2011-12-8 13:39:29

amork删了它吧,发错论坛分区了。

fenglove 发表于 2013-7-6 15:20:08

学习了谢谢
页: [1]
查看完整版本: 火牛板学习RT-Thread Step by Step——第五篇:基于SD卡的文件系统,使用SPI模式,支持中文长文