1、编译新的strace工具分析aplay和amixer应用程序对声卡的调用过程

(1)因为旧的strace工具不能识别不能识别alsa声卡驱动程序里面的ioctrl.

(2)编译过程参考http://blog.csdn.net/qingkongyeyue/article/details/52228729

(3)出现错误

需要建立相关的设备节点

播放声音和调整音量

(4)等待音频播放完,能得到一个完整的log,把log文件拷贝回windows下进行分析

2、调用分析(aplay.log)(搜索设备节点“/dev/snd”)

strace分析: aplay Windows.wav

应用程序打开一个设备 节点的时候,肯定要找到他的file_operation结构体

1. /dev/snd/controlC0(控制节点)对应的file_operations是snd_ctl_f_ops



所以的ioctl都会进入到snd_ctl_ioctl,函数里面对控制链表snd_control_ioctls里面取出某个结构体p,调用它的ioctl函数

open : snd_ctl_open

SNDRV_CTL_IOCTL_PVERSION : snd_ctl_ioctl -> put_user(SNDRV_CTL_VERSION, ip) //把版本号返回给用户空间

SNDRV_CTL_IOCTL_CARD_INFO : snd_ctl_ioctl -> snd_ctl_card_info(card, ctl, cmd, argp);//获取声卡信息返回给用户空间

                                               copy_to_user

                                               

SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE : snd_ctl_ioctl -> snd_pcm_control_ioctl -> control->prefer_pcm_subdevice = val;//记录用户空间传进来的值(想使用的PCM的子设备),在嵌入式系统里面,子设备只有1个,值默认是0或1.

close

上述三个ioctl不涉及硬件操作(意味着以后写驱动程序的时候可能根本不需要管这个设备节点)





2. /dev/snd/pcmC0D0p (播放节点)对应的file_operations是snd_pcm_f_ops[0]

open :  snd_pcm_playback_open

           snd_pcm_open

              snd_pcm_open_file

              struct snd_pcm_substream *substream;//定义一个snd_pcm_substream 结构体

              snd_pcm_open_substream//打开substream结构体

              err = snd_pcm_hw_constraints_init(substream);//初始化substream结构体

              snd_mask_any

              snd_interval_any

              ......

              err = substream->ops->open(substream) // substream->ops : snd_pcm_ops结构体

              soc_pcm_open

              依次调用cpu_dai, dma, codec_dai, machine(三大模块)的open或startup函数

              uda134x_startup 里:snd_pcm_hw_constraint_minmax(SNDRV_PCM_HW_PARAM_RATE),snd_pcm_hw_constraint_minmax(SNDRV_PCM_HW_PARAM_SAMPLE_BITS)

              dma_open里: snd_pcm_hw_constraint_integer,snd_soc_set_runtime_hwparams

                         runtime->hw.info = hw->info; = SNDRV_PCM_INFO_INTERLEAVED |

   SNDRV_PCM_INFO_BLOCK_TRANSFER |

   SNDRV_PCM_INFO_MMAP |

   SNDRV_PCM_INFO_MMAP_VALID |

   SNDRV_PCM_INFO_PAUSE |   //得到PCM设备的一些信息

   SNDRV_PCM_INFO_RESUME,

              snd_pcm_hw_constraints_complete

              pcm_file->substream = substream;

              file->private_data = pcm_file;





注意:substream->ops =  soc_new_pcm函数里的soc_pcm_ops





以下的ioctl入口都是:snd_pcm_playback_ioctl              

SNDRV_PCM_IOCTL_INFO : snd_pcm_info_user(substream, arg);//得到ioctl的信息返回给用户空间

substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info);

 snd_pcm_lib_ioctl

 


SNDRV_PCM_IOCTL_PVERSION : put_user(SNDRV_PCM_VERSION, (int __user *)arg)//lasa声卡驱动的版本号

SNDRV_PCM_IOCTL_TTSTAMP  : snd_pcm_tstamp(substream, arg);

                              

SNDRV_PCM_IOCTL_SYNC_PTR : snd_pcm_sync_ptr(substream, arg); 先不管





SNDRV_PCM_IOCTL_HW_REFINE .... : snd_pcm_hw_refine_user(substream, arg);//硬件参数重新规范

                                    memdup_user   //从用户空间传进来

                                    snd_pcm_hw_refine(substream, params); //修改

                                    copy_to_user //拷回给用户空间

SNDRV_PCM_IOCTL_HW_PARAMS : snd_pcm_hw_params_user(substream, arg);//设置硬件参数

                               snd_pcm_hw_params

                                  substream->ops->hw_params(substream, params);

                                     soc_pcm_hw_params

                                     
依次调用machine,codec_dai,cpu_dai,platform(dma)的hw_params函数

SNDRV_PCM_IOCTL_SYNC_PTR  //同步指针

SNDRV_PCM_IOCTL_SW_PARAMS : snd_pcm_sw_params_user(substream, arg);//软件参数

                               snd_pcm_sw_params 不涉及硬件操作

                                  

SNDRV_PCM_IOCTL_SYNC_PTR//同步指针

SNDRV_PCM_IOCTL_PREPARE  : snd_pcm_prepare(substream, file);//准备操作

                               snd_power_wait // 电源管理相关,先不管

                               .... 调用到platform里的prepare

                                  

SNDRV_PCM_IOCTL_SYNC_PTR

SNDRV_PCM_IOCTL_SW_PARAMS





循环:

SNDRV_PCM_IOCTL_WRITEI_FRAMES : copy_from_user  //从用户空间把音频数据拿过来,从wav文件中读出数据,写多帧数据

                                snd_pcm_lib_write

                                snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_write_transfer)

                                snd_pcm_lib_write_transfer

                                copy_from_user

                                snd_pcm_start(substream); // 启动传输

                                

 

SNDRV_PCM_IOCTL_SYNC_PTR//同步指针





SNDRV_PCM_IOCTL_DRAIN

SNDRV_PCM_IOCTL_DROP

SNDRV_PCM_IOCTL_HW_FREE //硬件释放

close

3、file_operation结构体

第0项对应的是播放,第1项对应的是录音,open对应的是and_pcm_playback_open

4、调用分析

strace分析: amixer cset numid=1 30 (设置音量)

/dev/snd/controlC0

open

SNDRV_CTL_IOCTL_CARD_INFO

SNDRV_CTL_IOCTL_PVERSION

SNDRV_CTL_IOCTL_ELEM_INFO  //元素信息,这个元素可能指音量

SNDRV_CTL_IOCTL_ELEM_READ  //读元素信息

SNDRV_CTL_IOCTL_ELEM_WRITE : snd_ctl_elem_write_user  //写元素

snd_ctl_elem_write

// 找到一个snd_kcontrol

kctl = snd_ctl_find_id(card, &control->id);

// 调用它的put

ALSA声卡07_分析调用过程_学习笔记的更多相关文章

  1. fastdfs集群安装过程_学习笔记

    最终效果 初始化为6个节点 在/usr/local/software 目录下上传需要用到tar包,分别在各个节点上传 使用scp 将本地software目录复制到其他节点上 73.74为 tracke ...

  2. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  3. 《Linux内核分析》第一周学习笔记

    <Linux内核分析>第一周学习笔记 计算机是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/c ...

  4. 《Linux内核分析》第二周学习笔记

    <Linux内核分析>第二周学习笔记 操作系统是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  5. 《Linux内核分析》第四周学习笔记

    <Linux内核分析>第四周学习笔记 扒开系统调用的三层皮(上) 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.c ...

  6. linux内核分析第五周学习笔记

    linux内核分析第五周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  7. Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序

    Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...

  8. Linux 内核分析第八周学习笔记

    Linux 内核分析第八周学习笔记 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10 ...

  9. Linux内核分析第三周学习笔记

    linux内核分析第三周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

随机推荐

  1. location.host 与 location.hostname 的区别

    JavaScript 中,大多数情况下,我们不会发现 location.host 与 location.hostname 的区别,因为大多数情况下,我们的网页用的是 80 端口. 他们的区别: loc ...

  2. Linux下使用Opencv打开笔记本摄像头

    新建test文件夹,文件夹存在test.cpp和CMakeLists.txt test.cpp#include <iostream> #include <string> #in ...

  3. win7下pyhton3.6创建django2的pycharm项目

    1.进入python虚拟环境: workon workon oneenv 2. 在虚拟环境中安装django,也可以使用pycharm上的自动安装,但那个比较慢,所有还是在cmd中安装的好 pip i ...

  4. [置顶] flume高并发优化——(14)解决空行停止收集数据问题,及offsets变小问题

      日志平台运行一段时间,发现日志有部分丢失,通过检查日志,发现有两个问题导致数据丢失,一个是遇到空行后,日志停止收集,还有就是kafka监控offsets时变小,通过分析代码,找到如下方法: 空行问 ...

  5. python3精简笔记(三)——高级特性

    Python中 1行代码能实现的功能,决不写5行代码.请始终牢记,代码越少,开发效率越高. 切片 取一个list或tuple的部分元素是非常常见的操作.Python提供了切片(Slice)操作符 L ...

  6. Lua基础---一维数组与多维数组

    Lua语言中,数组和C还是有区别的,Lua的数组下标从1开始计数,而C语言的数组下标从0开始计数,我想这可能是设计Lua的人想要符合人的思维习惯而去这么设计的. 数组,也就是按相同类型,在内存中顺序排 ...

  7. 使用stringstream类

    当需要格式化int类型为字符串时,可以使用这个类, 需要包含这个文件头: #include <sstream> 然后这样使用: //打开保存进度的RPG文件. std::stringstr ...

  8. windows上操作git基本命令

    今天准备整理一下代码,重温一下Git的基本命令,好久不用忘得差不多了. 1. 进入某个目录: 进入D盘,然后进入D盘的名为git的文件夹: $ cd D: $ cd Git 2. 返回上一级目录: $ ...

  9. java 实现共享锁和排它锁

    一直对多线程有恐惧,在实现共享锁和排它锁之后,感觉好了很多. 共享锁    就是查询的时候,如果没有修改,可以支持多线程查询: 排它锁    就是修改的时候,锁定共享锁,停止查询,同时,锁定排它锁,只 ...

  10. 遍历list方法

    [理论] for(String s : list){   System.out.print(s+"/t");  }    for(int i = 0;i<list.size( ...