eCos Disk与文件系统框架示意图

前一节,主要着重理论知识,讲述了eCos disk驱动的体系框架并大概分析了SPI接口SD/MMC卡驱动的组成,让大家对eCos的块设备(disk)系统有一个大概的了解,避免只见树木不见森林。

由于STM32 SD卡驱动代码编写工作量非常大,因此本节主要讲述如何编写STM32 SD卡驱动代码以及简单介绍下如何使用图形配置工具进行相关配置。

构建目录结构image

前一节分析可知,eCos STM32 SD卡驱动划分在disk驱动体系中,因此,在devs/disk目录下新建目录路径:cortexm/stm32/mmc/current。然后在这个路径的current目录下分别新建cdl、include、src三个文件夹和ChangeLog文件,如右图所示。

cdl目录下建立mmc_stm32.cdl文件;

include目录下建立mmc_stm32.h文件;

src目录下建立mmc_stm32.c文件;

其中,cdl文件可以其它某个驱动的cdl文件作为模板,然后在此基础上进行修改,这样简单省事。cdl文件怎么编写和修改在这里就不详细叙述。最主要是确定驱动需要哪些配置项和所依赖的组件。

添加STM32 SD卡驱动组件

假设你完成了上述操作,并把cdl文件编写好了。这时就可以把STM32 SD卡驱动组件添加到ecos.db文件中,如下代码所示。

package CYGPKG_DEVS_DISK_CORTEXM_STM32_MMC {
    alias { "Disk driver for MMC cards for STM32" stm32_mmc_disk_driver }
    directory devs/disk/cortexm/stm32/mmc
    script mmc_stm32.cdl
    hardware
    description "MMC driver for STM32 family of CortexM controllers"
}

然后把这个驱动组件添加你的目标板中(Add Target)。

配置STM32 SD卡驱动组件

如果要在eCos中正常操作SD卡的话,仅有STM32 SD卡驱动是不够的。一般SD卡都是格式化为FAT文件系统,所以我们还需要FAT System组件,而这个组件又需要其它2个组件的支持。它们的关系描述如下:

与应用相关的组件:
>>> CYGPKG_FS_FAT — FAT Filesystem组件包;
>>> CYGPKG_BLOCK_LIB — CYGPKG_FS_FAT 依赖的组件包;
>>> CYGPKG_LINUX_COMPAT — CYGPKG_BLOCK_LIB 依赖的组件包;

也许你会问,这些组件事先是怎么知道的呢?实际上,事先我也不知道,但我们至少知道需要FAT System组件,当你添加这个组件时,eCos图形配置工具会告诉你缺少依赖的组件,这时你只需要按照提示添加相应组件即可。

STM32 SD卡组件配置,如下图所示:

image

其它3个与应用相关的组件采用默认配置即可。

image

image

STM32 SD卡驱动代码编写

前一节分析得知,SD卡驱动由3部分组成,分别是:设备入口定义、设备接口实现和SD/MMC卡底层操作。其中,前2个部分可以直接借鉴mmc_spi.c中的实现。可能最大不同是,init()函数添加了SD卡相关引脚的初始化和DMA stream(DMA流)的配置及其相关变量的初始化。具体代码就不贴出来了,可自行从http://52ecos.net/thread-600-1-1.html下载源码,注意mmc_stm32_disk_init()函数中的实现。

SD/MMC卡底层操作 代码编写

这部分代码则需要自己实现,也是工作量最大的一部分。实际上,这部分代码主要借鉴ST官方库中SD卡驱动的实现。从我提供的代码中可知,大部分函数实现、SD卡初始化流程、SD卡读写操作等都是参考ST官方库的。区别可能在于函数名、变量、数据类型定义等的不同。

综上所述,这部分代码主要是依据ST官方库中SD卡驱动进行重构的。所以如果你熟悉ST官方库的话,理解eCos STM32 SD卡驱动不是难事,同时,该驱动再次诠释了在eCos中如何借鉴其它现有代码(第三方代码)来实现自己的驱动。此外,编写eCos驱动时,不管你是新手还是老手,都不推荐从空白开始着手。

跟着SD卡操作流程简要分析下这部分代码的结构。

mmc_stm32_disk_init()函数

系统启动时,自动执行该函数,完成SD卡相关引脚和DMA stream等的初始化。

mmc_stm32_disk_lookup()函数

用户应用程序操作SD卡之前,必须先mount,才能进行数据读写等操作。该函数就是mount操作的具体实现。主要完成SD卡检测、卡识别及其初始化等。

stm32_mmc_disk_changed()函数

如果SD卡已经mount,当再次进行mount时,则会调用该函数,主要用于检测SD卡是否还在卡槽中或者是否同一张SD卡。

stm32_mmc_check_for_disk()函数

SD卡识别及其初始化的入口函数。它调用stm32_mmc_init()函数来实现卡识别及其初始化。

stm32_mmc_init()函数

这个函数对应ST官方库SD_Init()函数。也就是,该函数的实现、其调用函数顺序、执行流程完全遵照ST官方库的实现。所不同的无非就是函数名、变量名、局部实现细节优化和重构(ST官方库中的一些函数实现有些地方比较冗余,所以进行了重构和优化)等等。

STM32 DMA操作

SD卡STM32 DMA操作函数由stm32_dma_打头的一些函数组成。它们分别是:

  • stm32_dma_channel_setup(),       用于设置SDIO DMA通道并启动DMA stream;
  • stm32_dma_callback(),                     DMA stream传输完成时的回调函数;
  • stm32_dma_transaction_begin(),DMA stream传输开始函数,主要是调用stm32_dma_channel_setup()函数;
  • stm32_dma_transaction(),              DMA stream传输并等待传输完成的函数;
  • stm32_dma_transaction_end,       DMA stream传输结束函数,主要完成数据拷贝函数;

刚开始编写代码的时候,DMA操作是参考spi_stm32.c中的DMA实现的。但调试的时候,DMA传输时老是出问题,所以最终实现与spi的DMA有所区别。

总体上来说,eCos的DMA还是很好操作的。总结如下:

  1. 定义DMA缓存区、DMA stream传输优先级等;
  2. 在驱动初始化函数中,初始化DMA相关变量,启动对应DMA stream通道;
  3. 定义DMA传输完成回调函数;
  4. 便能外设DMA功能;
  5. 设置DMA通道并启动传输;
  6. 等待DMA传输完成;

驱动测试程序

可以直接使用ecos/packages/fs/fat/current/tests下面的fatfs1.c测试程序,或者借鉴该测试程序自行编写。

» 文章出处: reille博客—http://velep.com , 如果没有特别声明,文章均为reille博客原创作品
» 郑重声明: 原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)
分享到:

 Leave a Reply

(必须)

(我会替您保密的)(必须)

*

   
© 2012 velep.com | reille blog | 管理| 粤ICP备12094833号-2| 谷歌地图| 百度地图| Suffusion theme|Sayontan Sinha

无觅相关文章插件,快速提升流量