alsa驱动解析
文章平均质量分 83
junguo
这个作者很懒,什么都没留下…
展开
-
6. 播放音频(第六部分)
之前已经提到过,中断由azx_interrupt来处理。再来看一个寄存器:* INTSTS(Interrupt Status Register)中断状态寄存器,32位。第31位,Global Interrupt Status (GIS),全局中断状态,只要有中断,它就会被置1。第30位,Controller Interrupt Status (CIS),控制器中断状态,用来标记RIRB对应的中断,代码里看起来,并没有被用到。其它位用来标记流的中断,根据流的数量来决定要使用的位数。以上函数的目的确原创 2022-06-11 11:39:39 · 763 阅读 · 0 评论 -
6. 播放音频(第五部分)
这段代码其实与prepare的代码流程很相似,也是通过action_ops来完成函数内容,以下是这部分代码:这段代码中,最需要理解的是trigger的回调函数。这里涉及到一些寄存器,还是先看以下具体内容。*SSYNC(Stream Synchronization) 流的同步信号,可以用来控制多个流同时开始传送数据。每一位代表一个流,如果你要同步的流是1和3,那么可以将1和3位设置为1。然后再启动DMA引擎。当DMA引擎启动后,可以再将所有的为置为0。这也是在这段代码中看到两次调用snd_hdac原创 2022-06-11 11:28:10 · 737 阅读 · 0 评论 -
6. 播放音频(第四部分)
理解这段代码,理解以下几个函数。这段代码是针对stream 寄存器中控制寄存器的处理。每个stream都有自己对应的寄存器,控制寄存器位于这些寄存器的开始位置。该寄存器暂用3个字节,其中0 bit位表示SRST(Stream Reset)。SRST的用法如下。1 bit 位表示RUN(Stream Run),当它置1时,表示DMA引擎使能,可以用来传送数据,0的时候表示DMA引擎停止使用。当在Reset的时候,RUN bit位必须被清除。代码基本上就是对这些要求的实现。在了解snd_hdac_stre原创 2022-06-11 11:24:54 · 562 阅读 · 0 评论 -
6. 播放音频(第三部分)
在tinyalsa中,写数据之前需要调用到pcm_prepare,需要向内核发送一条SNDRV_PCM_IOCTL_PREPARE命令。来看一下,在内核中的具体实现,这段代码集中在一块,集中看一下。实际动作前的预处理,这段代码的其实就是判断当前的状态,用来确定是否可以进行prepare操作。snd_pcm_sync_stop是用来等待中断结束的处理。通过substream->ops->prepare来调用驱动中的具体动作,snd_pcm_do_reset主要是用来设置runtime中的一些状态。原创 2022-06-11 11:16:44 · 910 阅读 · 0 评论 -
6. 播放音频(第二部分)
内存映射,可用于用户空间与内核空间之间共享数据,也可用于进程间共享数据。以下的内容的使用方法是前者,主要意图是提高系统性能。以下简单的看看原因:比如以上的代码,用户空间希望得到substream中的软件参数,通过ioctl发送SNDRV_PCM_IOCTL_SW_PARAMS命令,会调用到以上函数。内核中时常看到的两个函数copy_from_user和copy_to_user,分别读取和写数据到用户空间。内存映射可以帮助省去这些操作,通过mmap函数映射空间后,用户空间就可以直接读取或者写入内核的数据原创 2022-06-11 11:10:20 · 1023 阅读 · 0 评论 -
6.播放音频(第一部分)
这一章将对播放音频的具体内容做讲解。我的想法是按照tinyalsa中的例子作为讲解的范本,因为tinyalsa足够简单,很多时候都忽略了它的细节。趁着这个机会再整理一下tinyalsa的内容。我使用的tinyalsa从https://github.com/tinyalsa/tinyalsa下载,从examples/writei.c开始。其中函数read_file从指定的文件中读取pcm数据到frames。这个函数里通过pcm_open打开设备,后面通过pcm_writei去写数据。这里先注意一下原创 2022-06-11 10:59:15 · 1917 阅读 · 1 评论 -
5. 打开设备(第三部分)
这个函数的主要作用是为pcm_hw_constraints进行初始化的操作。找一个例子,看看rule的具体实现:还以声道数为例子,来看看snd_pcm_hw_rule_div做了什么:针对例子,a 可以理解为帧bit数,b就是采样bit数,而c就是要返回的声道的区间值。代码里的细节,自行理解吧,算不上难。snd_interval_refine将新值赋予对应的参数。关于snd_pcm_hw_constraints的使用,是一个比较好玩的事情,这里索性一起看了吧。参数由用户空间通过ioctl传入:原创 2022-06-11 00:58:41 · 770 阅读 · 0 评论 -
5. 打开设备(第二部分)
名字类型作用举例trigger_mastersnd_pcm_substream指向所属的substream对象trigger_tstamptimespec64当音频开始,暂停,停止的时候都会记录时间trigger_tstamp_latchedbool是否要从底层的硬件得到时间overrangeint录制过程中,ADC转换超出范围的次数好像没几个硬件支持该功能avail_maxsnd_pcm_uframes_t记录avail的最大值返回给用户空间的状态有该值,不是太明白有什么用hw_ptr_basesnd_p原创 2022-06-11 00:49:04 · 848 阅读 · 0 评论 -
5.打开设备(第一部分)
在文件相关的章节中,已经介绍过打开文件的过程。但还没介绍完,这一章将继续这个话题,具体看看还有哪些操作原创 2022-06-11 00:35:29 · 1323 阅读 · 0 评论 -
4.hda设备中的pcm文件 (第七部分)
接着上节的内容,现在来看看构建pcm的过程。原创 2022-06-09 10:46:13 · 500 阅读 · 1 评论 -
4. hda设备中的pcm文件 (第六部分)
hda_codec对象构建成功后,并没有直接为它构建pcm文件,而是放到codec的驱动中去完成。这样做的目的,可能是为了能方便的替换不同的驱动程序,就可以少一些在代码中的硬编码。原创 2022-06-09 10:38:41 · 768 阅读 · 0 评论 -
4. hda设备中的pcm文件 (第五部分)
理解Codec的概念后,接着看构建Codec的代码。在azx_probe_continue的代码中,调用了azx_probe_codecs。原创 2022-06-09 10:16:40 · 397 阅读 · 0 评论 -
4. hda设备中的pcm文件(第四部分)
之前介绍过,codec支持一定数量的命令,在每个帧周期中SDO中的前40bit都会保留下来作为发送给codec的命令,而SDI中也保留了36bit作为codec对命令的响应。这一切都需要controller的参与,命令是由软件以DMA的方式传到controller。我们在之前也看到了帮hdac_bus中分配了DMA内存rb。这一小节,我们具体看看这一部分的内容。CORB(Command Outbound Ring Buffer)用来保存发送到codec的命令。CORB是分配在系统内存上(DMA类型的),当有原创 2022-06-09 10:09:32 · 640 阅读 · 0 评论 -
4. hda设备中的pcm文件 (第三部分)
回顾一下azx_create中最后部分的一行代码:INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);初始化了一个延时work。原创 2022-06-07 20:37:21 · 1055 阅读 · 0 评论 -
4. hda设备中的pcm文件(第二部分)
上一小节,我们看了硬件的简图,现在要看它们如何被组织成软件视图。snd_card的框架简图基本就是一个软件的视图。下面我们去了解它们的组织过程,以及各个模块的作用。这部分涉及到代码,都在 sound/pci/hda和sound/hda下。之所以有两个目录,是因为hda其实也可以连接到其它总线上。在pc上一般都是用pci总线来连接的,我们也以这部分代码来展开。我们首先看hda_intel.c中的代码,虽说命名是intel,其实其它厂商的实现也在这儿,源于hda是统一标准,大部分的接口其实是通用的。但是文不尽意原创 2022-06-07 17:17:50 · 1016 阅读 · 0 评论 -
4. hda设备中的pcm文件(第一部分)
这节开始介绍hda中如何组织pcm文件,从理解hda结构开始。之前介绍的内容,基本属于框架结构的内容,并不涉及硬件。从这里开始会介绍一些硬件相关的内容,但基本限于对流程有影响的部分,更详细的内容到intel网站下载High Definition Audio Specification。 ...原创 2022-06-07 17:05:00 · 858 阅读 · 0 评论 -
3. alsa中的文件(第三部分)
在pcm 文件结构简图中,可以看到与pcm相关的一些结构snd_pcm、snd_pcm_str、snd_pcm_substream。以下将去整理这部分的内容,看看它们是如何生成,怎么去使用的。如果把alsa理解为一个框架(主要是sound/core下的代码),如简图中所表示的一样,其实有一个整体的模型在哪儿,驱动开发者需要构建这个模型。而框架的另一个功能就是提供构建模型的工具,其实就是一些导出函数。snd_pcm_new就是这么一个函数:这里的参数snd_card,我们后面再展开。id和device其原创 2022-06-07 15:30:27 · 605 阅读 · 0 评论 -
3. alsa中的文件(第二部分)
我们先辨别两个函数:snd_register_device 与snd_device_register。snd_register_device在前面已经介绍过了,负责保存snd_minor对象。snd_device_register其实里也是为这个目的存在的,最后它会调用到snd_register_device。直接调用snd_register_device有以下一些函数:snd_pcm_dev_register注册pcm设备snd_ctl_dev_register注册control设备snd_rawmidi原创 2022-06-07 15:17:53 · 465 阅读 · 0 评论 -
3. alsa中的文件(第一部分)
这里以pcm文件在hda(High Definition Audio architecture)协议中的实现给出一个简图。选择hda的原因是intel给出的文档比较详细,而且是公开的。而其它一些硬件,没办法得到说明书,有代码也很难理解其中的一些内容。 ...原创 2022-06-07 15:11:34 · 925 阅读 · 0 评论 -
2. 关于文件(第三部分)
先来整理一下打开文件的基本过程: 以上是打开文件时候需要用到的函数的基本调用流程,从系统调用开始,这些函数集中在fs/open.c 和 fs/namei.c中。原创 2022-06-06 23:03:38 · 408 阅读 · 0 评论 -
2. 关于文件(第二部分)
之前提到过,音频相关的文件保存在/dev/snd目录下。dev 目录是基于ramfs文件系统构建的,是一个纯内存的文件系统。它的实现与磁盘文件系统比起来并不完全相同,不过会更简单一些。ramfs的代码在fs/ramfs目录下。而具体构建工作在driver/base/devtmpfs.c中完成,另外它提供了一些结口去生成子目录文件等。以上是devtmpfs.c中的代码,在系统启动过程中,会被调用到它负责文件系统初始化的一些工作,比如通过vfs_kern_mou...原创 2022-06-06 22:49:39 · 374 阅读 · 0 评论 -
2. 关于文件 (第一部分)
文件系统也是一个复杂的话题,这部分的内容是希望能勾勒出一个简单的模型,便于理解在alsa中碰到的文件相关的内容。原创 2022-06-06 22:39:37 · 316 阅读 · 0 评论 -
1. 从文件开始
Linux设计哲学之,一切皆是文件。感觉上这个论点更多的是针对驱动来说的,从使用者的角度来说,大多的驱动程序的使用与操作文件的方式类似,也就是使用open,read,write,ioctl这些通用的文件操作接口来操作驱动。而对于驱动开发者来说,就需要按照文件的方式来组织驱动接口,以文件的形式来呈现驱动程序。以下我们来具体看看ALSA所呈现的形式......原创 2022-06-06 22:18:13 · 514 阅读 · 0 评论