嵌入式 pcm音频三

4.3 层层深入,从应用程序到驱动层pcm


4.3.1 字符设备注册

在sound/core/sound.c中有alsa_sound_init()函数,定义如下:

 

[c-sharp]   view plain copy
  1. static int __init alsa_sound_init(void 
  2.  
  3.     snd_major major;  
  4.     snd_ecards_limit cards_limit;  
  5.     if (register_chrdev(major, "alsa"&snd_fops))  
  6.         snd_printk(KERN_ERR "unable to register native major device number %d/n"major);  
  7.         return -EIO;  
  8.      
  9.     if (snd_info_init() 0)  
  10.         unregister_chrdev(major, "alsa");  
  11.         return -ENOMEM;  
  12.      
  13.     snd_info_minor_register();  
  14.     return 0;  
  15.  

register_chrdev中的参数major与之前创建pcm设备是device_create时的major是同一个,这样的结果是,当应用程序open设备文件/dev/snd/pcmCxDxp时,会进入snd_fops的open回调函数,我们将在下一节中讲述open的过程。

4.3.2 打开pcm设备

从上一节中我们得知,open一个pcm设备时,将会调用snd_fops的open回调函数,我们先看看snd_fops的定义:

 

[c-sharp]   view plain copy
  1. static const struct file_operations snd_fops  
  2.  
  3.     .owner    THIS_MODULE,  
  4.     .open     snd_open  
  5. };  

跟入snd_open函数,它首先从inode中取出此设备号,然后以次设备号为索引,从snd_minors全局数组中取出当初注册pcm设备时填充的snd_minor结构(参看4.1节的内容),然后从snd_minor结构中取出pcm设备的f_ops,并且把file->f_op替换为pcm设备的f_ops,紧接着直接调用pcm设备的f_ops->open(),然后返回。因为file->f_op已经被替换,以后,应用程序的所有read/write/ioctl调用都会进入pcm设备自己的回调函数中,也就是4.2节中提到的snd_pcm_f_ops结构中定义的回调。

 

[c-sharp]   view plain copy
  1. static int snd_open(struct inode *inode, struct file *file)  
  2.  
  3.     unsigned int minor iminor(inode);  
  4.     struct snd_minor *mptr NULL;  
  5.     const struct file_operations *old_fops;  
  6.     int err 0;  
  7.   
  8.     if (minor >= ARRAY_SIZE(snd_minors))  
  9.         return -ENODEV;  
  10.     mutex_lock(&sound_mutex);  
  11.     mptr snd_minors[minor];  
  12.     if (mptr == NULL)  
  13.         mptr autoload_device(minor);  
  14.         if (!mptr)  
  15.             mutex_unlock(&sound_mutex);  
  16.             return -ENODEV;  
  17.          
  18.      
  19.     old_fops file->f_op;  
  20.     file->f_op fops_get(mptr->f_ops);  
  21.     if (file->f_op == NULL)  
  22.         file->f_op old_fops;  
  23.         err -ENODEV;  
  24.      
  25.     mutex_unlock(&sound_mutex);  
  26.     if (err 0)  
  27.         return err;  
  28.   
  29.     if (file->f_op->open)  
  30.         err file->f_op->open(inode, file);  
  31.         if (err)  
  32.             fops_put(file->f_op);  
  33.             file->f_op fops_get(old_fops);  
  34.          
  35.      
  36.     fops_put(old_fops);  
  37.     return err;  
  38.  

 

下面的序列图展示了应用程序如何最终调用到snd_pcm_f_ops结构中的回调函数:

                                                               图4.3.2.1    应用程序操作pcm设备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值