上一节,介绍了eCos音频驱动的设计框架以及简单介绍了其实现方式。由于音频驱动分为两部分:STM32 I2S驱动和WM8978驱动,为介绍方便,把这两部分分开来介绍,而且描述的侧重点是不一样的。
本节重点介绍WM8978驱动的实现,侧重点介绍如何在eCos中添加一个新的驱动组件和驱动依赖模式的实现。
这里仅简单介绍下eCos驱动架构。 如右图所示。
所有eCos设备驱动都放在eCos/Packages/devs目录下。eCos/Packages/IO目录存放对应设备驱动的IO子系统。我理解它为一个IO适配层或者中间件,用来适配devs目录下对应的某类型所有设备驱动。
添加新的驱动组件
在eCos中添加一个新的驱动组件,有两种情况,一种是eCos中存在类似器件的驱动组件;另一种是没有类似器件驱动的参考,完全添加一个新的驱动组件。这两种情况下添加新驱动组件的方法是类似的。区别是:
前一种情况有一个具体框架约束你,简单地说就是提供了一个IO层给你,你只需要模仿即可。比如添加一个flash驱动,eCos里提供了flash IO子系统,那么添加时,按照某款类似的flash芯片驱动编写代码即可。
后一种情况,没有可供参考的IO子系统,要么你参考其它IO子系统自己写一个IO子系统,要么就是最简单的实现方法,直接使用eCos IO common提供的接口实现。
添加WM8978驱动驱动组件
驱动归类
WM8978采用I2C接口控制,按理来说,WM8978驱动应该把它放到devs/i2c目录下。但是观察发现,该目录全是处理器I2C接口的驱动,没有涉及具体I2C器件。所以最后我按照linux下的结构进行了归类。如右图所示。
驱动组成
eCos中,一个设备驱动一般由cdl文件、头文件、源文件、ChangeLog文件、测试例程等5个部分组成。其中,测试例程可以不需要。
我写驱动的时候,喜欢选择一个设计比较接近的驱动作为模板,然后在此基础上进行修改。
驱动实现
wm8978驱动源程序包括一个CDL文件,一个.h文件,一个.inl内联文件,一个.c源文件。其中,.h文件定义需要的结构体、宏定义等;.inl内联文件主要定义了设备IO(使用IO层提供的一般IO接口)和设备表,以及一个I2C设备。如下图所示(这里就不贴代码了,自己可以去eCos技术网上下载)。
注意代码所选中部分(84行),CYGDAT_DEVS_SOUND_I2C_WM8978_USE_I2S_DEV宏定义了WM8978所依赖的I2S设备。看下设备表结构体cyg_devtab_entry_t的定义:
对于大部分的设备驱动,dep_name成员一般赋值为NULL,表明本设备不依赖于其它设备实现。如果dep_name赋值为某设备名称,则表明本设备要依赖其它设备的实现。
eCos中tty驱动就充分使用了这个机制。我们知道,tty只是个虚拟的数据传输通道,最终走的实际物理通道还是串口。所以,tty驱动的实现依赖于serial设备驱动。
所以说,eCos音频驱动在设计的时候是借鉴了eCos中tty驱动来实现的。
所以我们可以看到,wm8978驱动的read、write函数的实现非常简单,它就是把音频数据流发给stm32 i2s驱动,让它去传输音频数据流。
wm8978的控制
WM8978的控制主要由snd_wm8978_set_config()函数实现。这个API函数类似于linux中的ioctl函数实现。
从代码中可看到,WM8978控制部分实现的源码大部分都是从安富莱开发板中拷贝过来的(有些函数我改为了用宏实现,如:WM8978_MIC_2_ADC 等宏定义这部分代码)。这也展示了如何在eCos驱动中充分使用第三方驱动源码的方法。这种方法,大家一定要学会,不仅省事,而且减少出错的机会!
eCos音频驱动配置
eCos音频驱动配置包含两个组件包的配置,如下图所示:
配置的时候,主要注意下Bounce buffer size的配置。该配置项对应DMA缓存的大小,配置小了会导致音频流输出不连续从而出现噪音。在这里我配置为1024字节大小。关于这部分,请看下节的关于I2S驱动的介绍。
推荐阅读相关文章:
- stm32移植ecos #34,ecos sd driver,SD卡驱动(4)
- stm32移植ecos #33,ecos sd driver,SD卡驱动(3)
- stm32移植ecos #31,ecos sd driver,SD卡驱动(1)
- stm32移植ecos #30,ecos i2s driver,音频驱动(下)
- stm32移植ecos #28,ecos i2s driver,音频驱动(上)
- stm32移植ecos #27,串行SPI flash驱动移植(下)
- stm32移植ecos #26,串行SPI flash驱动移植(上)
- stm32移植ecos #25,eCos i2c driver for stm32