s3c2440 UDA1341声卡驱动与madplay播放器移植,

本文允许转载,但请注明出处:http://blog.csdn.net/u010944778/article/details/45246307

1.配置声卡UDA1341驱动

/* 首先通过s3c2440原理图确认管脚。*/

s3c2440 UDA1341声卡驱动与madplay播放器移植,_第1张图片

又因为linux3.0内核中还有mini2440的初始化文件,于是直接进入/arch/arm/mach-s3c2440/mach-mini2440.c中查看后修改得到

--- mach-smdk2440_o.c   2015-04-24 11:39:20.492017397 +0800
+++ mach-smdk2440.c     2015-04-24 12:26:01.457015793 +0800
@@ -45,6 +45,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 
+#include <sound/s3c24xx_uda134x.h>
+#include <mach/gpio-nrs.h>
 #include <plat/common-smdk.h>
 
 static struct map_desc smdk2440_iodesc[] __initdata = {
@@ -155,8 +156,32 @@
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
+       &uda1340_codec,
+       &s3c2440_audio,
+       &samsung_asoc_dma,
 };
+/* add by handy */
+/* AUDIO */
 
+static struct s3c24xx_uda134x_platform_data s3c2440_audio_pins = {
+       .l3_clk = S3C2410_GPB(4),
+       .l3_mode = S3C2410_GPB(2),
+       .l3_data = S3C2410_GPB(3),
+       .model = UDA134X_UDA1341
+};
+
+static struct platform_device s3c2440_audio = {
+       .name           = "s3c24xx_uda134x",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &s3c2440_audio_pins,
+       },
+};
+static struct platform_device uda1340_codec = {
+               .name = "uda134x-codec",
+               .id = -1,
+};
+/* add by handy */
 static void __init smdk2440_map_io(void)
 {
        s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc))

然后直接make menuconfig即可;  PS: 上述添加的各类结构体均要放在添加设备的devices[ ]结构体数组之前,否则会出现未定义,以及定义了没使用等错误。因为编译器是按顺序编译,所以声明必须放在结构体或者函数之前。

首先进入 Device Drivers -->

s3c2440 UDA1341声卡驱动与madplay播放器移植,_第2张图片

s3c2440 UDA1341声卡驱动与madplay播放器移植,_第3张图片

s3c2440 UDA1341声卡驱动与madplay播放器移植,_第4张图片

s3c2440 UDA1341声卡驱动与madplay播放器移植,_第5张图片

make之后烧录到板子上,若最后打印的一长串信息里找到上述打印出的信息则表示成功 。

2.madplay在S3c2440上移植,顺利播放mp3音乐

交叉编译器环境:arm-linux-gcc-4.5.4
开发板平台: FL2440        
Linux内核版本: 3.0

() madplay移植前的准备:
所需源码包:

madplay-0.15.2b.tar.gz, //播放程序的压缩包,MP3播放器的源码
libmad-0.15.1b.tar.gz,    //madplay的库文件
libid3tag-0.15.1b.tar.gz    //mp3的解码库
zlib-1.1.4.tar.gz      //用于文件的压缩与解压
新建文件目录并上传源码包到madplay目录并解压
[pikaqiu@centos6 ~]$  mkdir madplay
[pikaqiu@centos6 ~]$  mkdir madplay/mad
[pikaqiu@centos6 madplay]$ ls
libid3tag-0.15.1b  libmad-0.15.1b  mad  madplay-0.15.2b  zlib-1.1.4

移植第三方程序的主要步骤分别为:解压缩、配置(./configure)、编译(make)、安装(make install);

一般源码包解压缩之后,若已经存在Makefile则可以直接make编译;但大多数情况下需要使用源码包目录下的./configure脚本来配置源码包生成Makefile文件;
我们通常可以使用./configure --help来查看配置选项。

这里我们必须知道以下几个配置参数:

   --host:   用于指定平台;如: --host==arm-linux

   --prefix: 用于指定文件的安装路径;   如:--prefix=/home/pikaqiu/madplay/mad

   -I     指定头文件的路径;  如:-I/home/pikaqiu/madplay/mad/include/

   -L    指定库文件的路径;如:-L/home/pikaqiu/madplay/mad/lib

   --disable-shared      使用静态库编译;        

如果是要编译到arm板子上跑则在make的时候还需要加上AR(将.o文件打包生成.a的静态库文件)=   LD(所链接)=     CC(交叉编译器)= 

(二)下面开始正式配置,编译:
注意:以下的步骤不能打乱,因为其中有依赖关系;还有每次都需要使用sudo权限,否则可能因权限不够而出错。

1.首先编译zlib-1.1.4

[pikaqiu@centos6 madplay]$ cd zlib-1.1.4/
(1)配置configure文件,生成Makefile
[pikaqiu@centos6 zlib-1.1.4]$sudo ./configure --prefix=home/pikaqiu/madplay/mad      
(2)修改Makefile文件
[pikaqiu@centos6 zlib-1.1.4]$ vim Makefile
修改以下三项:
             CC=gcc 修改为CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
             AR=ar rc   修改为AR=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-ar rc
             RANLIB=ranlib  修改为RANLIB=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-ranlib

(三)编译make
[pikaqiu@centos6 zlib-1.1.4]$ sudo make
若没有错误便是make成功,可以继续下一步
(四)安装make install

2.编译libid3tag-0.15.1b

[pikaqiu@centos6 madplay]$ cd libid3tag-0.15.1b/
(1)配置configure文件,生成Makefile
[pikaqiu@centos6 libid3tag-0.15.1b]$sudo ./configure CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc --host=arm-linux --disable-shared --prefix=/home/pikaqiu/madplay/mad CPPFLAGS=-I/home/pikaqiu/madplay/mad/include/ LDFLAGS=-L/home/pikaqiu/madplay/mad/lib
(2)编译make
[pikaqiu@centos6 libid3tag-0.15.1b]$ sudo make
若没有错误便是make成功,可以继续下一步
(四)安装make install

3.编译libmad-0.15.1b

[pikaqiu@centos6 madplay]$cd libmad-0.15.1b/

(1)配置configure文件,生成Makefile

[pikaqiu@centos6 libmad-0.15.1b]$sudo ./configure CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc --host=arm-linux --disable-shared --prefix=/home/pikaqiu/madplay/mad CPPFLAGS=-I/home/pikaqiu/madplay/mad/include/ LDFLAGS=-L/home/pikaqiu/madplay/mad/lib

(2)编译make

(3)安装make install
此时出现一个错误:cc1: error: unrecognized command line option “-fforce-mem”

解决方式:vim Makefile 

大概在129行左右找到包含的"-fforce-mem"字符串,将其删除,即可。
原因:是gcc 3.4 或者更高版本,已经将其去除了,所以会出现上面的错误。

4.安装madplay

[pikaqiu@centos6 madplay]$cd madplay-0.15.2b/

(1)配置configure文件,生成Makefile
[pikaqiu@centos6 madplay-0.15.2b]$sudo ./configure CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc --host=arm-linux --disable-shared --prefix=/home/pikaqiu/madplay/mad CPPFLAGS=-I/home/pikaqiu/madplay/mad/include/ LDFLAGS=-L/home/pikaqiu/madplay/mad/lib

我在此时又出现了一个错误:
configure: error: mad.h was not found
*** You must first install libmad before you can build this package.
*** If libmad is already installed, you may need to use the CPPFLAGS
*** environment variable to specify its installed location, e.g. -I

原因:提示说缺少头文件,即提醒我们要用-I 指令来指定头文件所在路径。
解决方法:因为我指令上面已经有存在-L与-I 来指定库与头文件目录,于是我先回到mad/include下查看,发现是真的没有mad.h这个头文件,于是我返回到顶层目录madplay采用指令查找。
[pikaqiu@centos6 madplay]$ find -name "mad.h"
./libmad-0.15.1b/mad.h 然后将此拷贝到/mad/include目录下后解决。

而在接下来又出现了这样的错误:
configure: error: libmad was not found
*** You must first install libmad before you can build this package.
*** If libmad is already installed, you may need to use the LDFLAGS
*** environment variable to specify its installed location, e.g. -L
原因:缺少库文件,即提醒我们要用-L来指定库文件所在路径。
解决方法:在/mad/lib/目录下我又没有找到我的libmad.a文件
[pikaqiu@centos6 madplay]$ find -name "libmad.*"
./mad/lib/libmad.la
./mad/lib/.libs/libmad.a
./mad/lib/libmad.a
./libmad-0.15.1b/libmad.list
./libmad-0.15.1b/msvc++/libmad.dsp
./libmad-0.15.1b/libmad.list.in
./libmad-0.15.1b/libmad.la
./libmad-0.15.1b/.libs/libmad.lai
./libmad-0.15.1b/.libs/libmad.la
./libmad-0.15.1b/.libs/libmad.a
./madplay-0.15.2b/.libs/libmad.la
./madplay-0.15.2b/.libs/libmad.a         (这是我成功之后的find,但之前只有libmad-0.15.1b/.libs中有)
因为不晓得是需要.a还是.la,索性将之都拷贝到相应路径,解决之。

(2)编译make

满心欢喜的以为问题解决,以为能够make了么,这时我又出现了一个问题。
....
arm-linux-gcc: /home/pikaqiu/madplay/mad/lib/.libs/libmad.a: No such file or directory
make[2]: *** [madplay] 错误 1
make[2]: Leaving directory `/home/pikaqiu/madplay/madplay-0.15.2b'
make[1]: *** [all-recursive] 错误 1
make[1]: Leaving directory `/home/pikaqiu/madplay/madplay-0.15.2b'
make: *** [all] 错误 2
解决办法:自己手动创建mad/lib/.libs/ 并将libmad.a文件拷贝到其目录中后解决。

至此,终于make成功生成madplay的绿色可执行程序了.又因为我使用的是静态编译。此时可不用再make install,直接将 madplay下载到开发板后给予权限即可。

chmod 777 madplay

./madplay xxx.mp3 就能够听音乐了,博主亲测!

madpaly还有一些快捷键,比如:增大/减小音量(+/-),暂停(b),停止(ESC)
没看手册,我胡乱测试了一下,发现按键盘的减号可以减小音量,shift+可以增大音量,shift-瞬间恢复满音量,s键停止。


学习小结:
1、所有的第三方应用程序移植到开发板上使用,几乎都会联系上动态库,静态库。所以需要熟悉这一方面的知识,比如如何链接动态库静态库;如何指定头文件路径以及静态链接,静态编译的参数等;
静态编译与动态编译区别:
  动态编译的可执行文件需要附带一个动态链接库,在执行时,需要调用其对应动态链接库中的命令。所以其优点是缩小了执行文件本身的大小,并加快了编译速度,节省了系统资源。但缺点也很明显,就是只要用到了库文件就需要带上相应的函数库,无论怎样都要带着一个小尾巴。这对我们移植比较小的程序的时候略微麻烦。 

  静态编译就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so)中的部分提取出来链接到可执行文件中去,因为包含了动态库中的文件所以可执行文件会比较臃肿,也就是占空间资源。但是却可以直接运行。所以其优缺点与动态编译的可执行文件正好互补,就看具体情况来取舍了。

2、还要学会利用linux内核本身其他驱动的代码进行驱动修改,比如smdk2440的dm9000网卡驱动你就可以去mini2440里面寻找同样支持的dm9000驱动代码,但要注意查看芯片手册。以此类推。


由图可知我静态编译生成的可执行文件才672K并且not stripped表示没有使用strip去掉部分的调试信息。所以我并没有再次动态编译。
但有一个问题:我明明可以直接把可执行文件烧录到开发板上运行,而且一开始都指定了--disable-shard禁用共享库。我file后的madplay居然显示使用动态库。求解(下面已解决)

最后:在此也感谢所有前辈在网上分享的各种解决方法。在移植应用程序的过程中遇到的问题都需要自己耐心根据提示解决。

PS:make虐我千万遍,我待make如初恋 !


这5月份的武汉还瞬间降温暴风真是醉了,感冒头痛鼻塞真是难受。不过还好这前面遗留的问题得到了解决让我心里有那么一丝愉悦。步入正题:上面那个问题让我觉得自己静态编译,静态链接,动态链接还不是很明白,于是乎我查了资料参考之后总结出了以下这些个人的理解,我觉得算是比较清楚的解决了上面那个问题。顺便给自己复习下知识。

Make和makefile是帮助编译的工具。Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。平常总说make编译生成可执行文件是因为makefile中有gcc -o 这些个命令。即make实际上是用gcc编译器编译生成可执行文件。而gcc编译器生成可执行文件有预处理,编译,汇编,链接这几个步骤。而make是根据makefile所来执行的,makefile又是运行./configure所产生的。所以我们在这之前就需要把后面生成可执行文件前最后一步链接所要选择的是链接动态库还是链接静态库以及这些库在哪个地方即路径所指明出来。并且我们一旦使用静态链接库,那么它所生成的可执行文件中就会包含原本运行所需要的函数,即不再需要可执行程序带着库文件这个尾巴走。如果要问静态库怎么来的呢,这就跟编译时候的产物有关了,编译产生目标文件.o然后ar命令就可将好多个.o融合就生成.a静态库文件。至于.so动态库文件的生成,这就需要在多个.c文件和.h头文件通过gcc编译器来生成。参数--static是说在编译那一步时生成的.o只能用于构建静态库文件。这里要说明的是将目标链接成的可执行文件ELF类型中包括目标文件.o和共享目标文件.so当然还有.elf可执行文件。我--disable-shared实际实现的是gcc不编译生成.so动态库,但是具体的链接那一步我并没有使用静态链接,所以最终生成的mad play可执行文件依旧显示动态链接。 

s3c2440 UDA1341声卡驱动与madplay播放器移植,_第6张图片

我自己做了同名的静态库和动态库,在同名情况下让库与.c链接生成可执行文件的情况下会优先链接动态库。且不论是静态库还是动态库都是由编译生成的目标文件.o组成的,但是生成动态库我只能一步产生动态库,不能先编译.c生成.o后再生成动态库。或许这是潜规则吧- 。- 另外,动态链接生成的可执行文件真是小极了。


你可能感兴趣的:(linux,linux音频驱动,UDA1341声卡驱动)