----------------------------------------------------------------------------------------------------------------------------
开发板 :NanoPC-T4开发板
eMMC :16GB
LPDDR3 :4GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot :2023.04
linux :6.3
----------------------------------------------------------------------------------------------------------------------------
一、内核配置
1.1 配置内核
修改sound/soc/codecs/Kconfig文件,搜索config SND_SOC_RT5651,将该项修
config SND_SOC_RT5651 tristate depends on I2C
改为,如果不修改的话,make menuconfig是看不到该配置项的;
config SND_SOC_RT5651 tristate "Realtek ALC5651 CODEC" depends on I2C
在linux内核根目录下执行make menuconfig配置以下选项:
Device Drivers ---> <*> Sound card support ---> <*> Advanced Linux Sound Architecture --->
<*> Sequencer support <*> ALSA for SoC audio support ---> <*> ASoC support for Rockchip {*} Rockchip I2S Device Driver CODEC drivers ---> <*> Realtek RT5651 CODEC <*> ASoC Simple sound card support
至于为啥配这些,可以看下面的介绍。
1.1.1 支持simple-audio-card驱动
要想将sound/soc/generic/simple-card.c文件对应的驱动编译到内核,我们需要配置CONFIG_SND_SIMPLE_CARD,我们定位到sound/soc/generic/Makefile文件;
# SPDX-License-Identifier: GPL-3.0 snd-soc-simple-card-utils-objs := simple-card-utils.o snd-soc-simple-card-objs := simple-card.o snd-soc-audio-graph-card-objs := audio-graph-card.o obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_AUDIO_GRAPH_CARD) += snd-soc-audio-graph-card.o
这里定义了snd-soc-simple-card.o的生成规则:
snd-soc-simple-card-objs := simple-card.o
它表示将当前目录下的 simple-card.o文件编译成一个snd-soc-simple-card.o。我们可以查看sound/soc/generic/.snd-soc-simple-card.o.cmd文件找到编译命令:
root@zhengyang:/work/sambashare/rk3399/linux-5.3.8# cat sound/soc/generic/.snd-soc-simple-card.o.cmd cmd_sound/soc/generic/snd-soc-simple-card.o := arm-linux-ld -EL -maarch64elf -r -o sound/soc/generic/snd-soc-simple-card.o sound/soc/generic/simple-card.o
1.1.2 支持I2S驱动
要想将sound/soc/rockchip/rockchip_i2s.c文件对应的驱动编译到内核,我们需要配置CONFIG_SND_SOC_ROCKCHIP_I2S,我们定位到sound/soc/rockchip/Makefile文件;
# SPDX-License-Identifier: GPL-3.0 # ROCKCHIP Platform Support snd-soc-rockchip-i2s-objs := rockchip_i2s.o snd-soc-rockchip-pcm-objs := rockchip_pcm.o snd-soc-rockchip-pdm-objs := rockchip_pdm.o snd-soc-rockchip-spdif-objs := rockchip_spdif.o obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o snd-soc-rockchip-pcm.o obj-$(CONFIG_SND_SOC_ROCKCHIP_PDM) += snd-soc-rockchip-pdm.o obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
这里定义了snd-soc-rockchip-i2s.o的生成规则:
snd-soc-rockchip-i2s-objs := rockchip_i2s.o
它表示将当前目录下的rockchip_i2s.o文件编译成一个snd-soc-rockchip-i2s.o。
1.1.3 支持rt5651驱动
要想将sound/soc/codecs/rt5651.c文件对应的驱动编译到内核,我们需要配置CONFIG_SND_SOC_RT5651,我们定位到sound/soc/codecs/文件;
snd-soc-rt5651-objs := rt5651.o obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
这里定义了snd-soc-rt5651.o的生成规则:
snd-soc-rt5651-objs := rt5651.o
它表示将当前目录下的rt5651.o文件编译成一个snd-soc-rt5651.o。
1.1.4 支持seq
在 sound/core/Makefile文件中,如果配置CONFIG_SND_SEQUENCER,将seq编译到内核,这个文件作用后面有时间再研究;
obj-$(CONFIG_SND_SEQUENCER) += seq/
1.2 保存配置
配置完内核之后记得保存配置:
存档:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# mv rk3399_defconfig ./arch/arm64/configs/
重新配置内核:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# make rk3399_defconfig
1.3 编译内核
在linux内核根目录下执行如下命令进行编译内核:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8
u-boot-2024.04路径下的mkimage工具拷贝过来,然后在命令行使用mkimage工具编译即可:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp ../u-boot-2023.04/tools/mkimage ./ root@zhengyang:/work/sambashare/rk3399/linux-6.3# ./mkimage -f kernel.its kernel.itb
1.4 通过tftp烧录内核
给开发板上电,同时连接上网线,进入uboot命令行。我们将内核拷贝到tftp文件目录:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp kernel.itb /work/tftpboot/
接着给开发板上电。通过uboot命令行将kernel.itb下到内存地址0x10000000处:
=> tftp 0x10000000 kernel.itb
通过mmc write命令将内核镜像烧录到eMMC第0x8000个扇区处:
=> mmc erase 0x8000 0xA000 => mmc write 0x10000000 0x8000 0xA000
1.5 启动内核
我们重新启动开发板,如果声卡驱动正常加载,我们会看到类似下面的日志:
二、查看声卡设备
2.1 查看音频设备节点:
查看音频设备节点:
root@rk3399:/# ll /dev/snd total 0 drwxr-xr-x 2 root root 60 Jul 26 23:31 by-path/ crw-rw---- 1 root audio 116, 4 Jul 26 23:31 controlC0 crw-rw---- 1 root audio 116, 3 Jul 26 23:31 pcmC0D0c crw-rw---- 1 root audio 116, 2 Jul 26 23:31 pcmC0D0p crw-rw---- 1 root audio 116, 1 Jul 26 23:31 seq crw-rw---- 1 root audio 116, 33 Jul 26 23:31 timer
其中:
- controlC0:用于声卡的控制,例如通道选择,混音,麦克控制,音量加减,开关等;
- pcmC0D0c:用于录音的pcm设备;
- pcmC0D0p:用于播放的pcm设备;
- seq:音序器;
- timer:定时器;
C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback,这些都是alsa-driver中的命名规则。
从上面的列表可以看出,我的声卡下挂了5个设备,根据声卡的实际能力,驱动实际上可以挂载更多种类的设备,我们通常更关心的是pcm和control这两种设备,默认一个声卡对应一个Control设备。
2.2 查看所有声卡
查看所有声卡:
root@rk3399:/# cat /proc/asound/cards 0 [realtekrt5651co]: simple-card - realtek,rt5651-codec realtek,rt5651-codec
0为声卡编号,realtekrt5651co为ALSA声卡的唯一标识,因为struct snd_card id字段其长度为16,所以存放的就是realtek,rt5651-codec去除特殊字符之后的的前15个字符。
声卡分两种通道,一种是Capture、一种是Playback。Capture是输入通道,Playback是输出通道;我们以声卡0为例;
root@rk3399:/# ll /proc/asound/card0 -r--r--r-- 1 root root 0 Jul 23 16:02 id dr-xr-xr-x 4 root root 0 Jul 23 16:02 pcm0c/ dr-xr-xr-x 4 root root 0 Jul 23 16:02 pcm0p/ root@rk3399:/# cat /proc/asound/card0/id realtekrt5651co
pcm0p属于声卡0输出通道,pcm0c属于声卡0输入通道。
2.2.1 查看播放设备
root@rk3399:/# aplay -l **** List of PLAYBACK Hardware Devices **** card 0: realtekrt5651co [realtek,rt5651-codec], device 0: ff880000.i2s-rt5651-aif1 rt5651-aif1-0 [ff880000.i2s-rt5651-aif1 rt5651-aif1-0] Subdevices: 1/1 Subdevice #0: subdevice #0
2.2.2 查看录音设备
root@rk3399:/# arecord -l **** List of CAPTURE Hardware Devices **** card 0: realtekrt5651co [realtek,rt5651-codec], device 0: ff880000.i2s-rt5651-aif1 rt5651-aif1-0 [ff880000.i2s-rt5651-aif1 rt5651-aif1-0] Subdevices: 1/1 Subdevice #0: subdevice #0
2.3 查看pcm设备列表
root@rk3399:/# cat /proc/asound/pcm 00-00: ff880000.i2s-rt5651-aif1 rt5651-aif1-0 : ff880000.i2s-rt5651-aif1 rt5651-aif1-0 : playback 1 : capture 1
三、音频调试
3.1 下载工具
播放视频,音频文件时没声音的,需要用alsamixer来配置,过程如下:
root@rk3399:/# apt-get install alsa-base alsa-utils alsa-oss alsa-tools
3.2 amixer 命令
3.2.1 amixer controls
通过amixer controls显示控制接口(这个对应的应该就是我们在声卡驱动中注册的kcontrol):
root@rk3399:/# amixer controls numid=1,iface=CARD,name='Headphones Jack' numid=13,iface=MIXER,name='Mono ADC Capture Volume' numid=6,iface=MIXER,name='Mono DAC Playback Volume' numid=14,iface=MIXER,name='ADC Boost Gain' numid=18,iface=MIXER,name='ADC IF2 Data Switch' numid=11,iface=MIXER,name='ADC Capture Switch' numid=12,iface=MIXER,name='ADC Capture Volume' numid=19,iface=MIXER,name='DAC IF2 Data Switch' numid=51,iface=MIXER,name='DAC L2 Mux' numid=48,iface=MIXER,name='DAC MIXL INF1 Switch' numid=47,iface=MIXER,name='DAC MIXL Stereo ADC Switch' numid=50,iface=MIXER,name='DAC MIXR INF1 Switch' numid=49,iface=MIXER,name='DAC MIXR Stereo ADC Switch' ....
比如我们以DAC MIXR INF1 Switch为例:
numid=50,iface=MIXER,name='DAC MIXR INF1 Switch'
其中INF1 Switch为kcontrol的名称,DAC MIXR为kcontrol所属widget的名称,iface=MIXER表示kcontrol的类型为Mixer、numid为kcontrol的编码;
// kcontrol SOC_DAPM_SINGLE("INF1 Switch", RT5651_AD_DA_MIXER, // 寄存器配置为RT5651_AD_DA_MIXER=0x29,偏移位配置为14 RT5651_M_IF1_DAC_L_SFT, 1, 1) // 输出端widget SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, // 寄存器设置为SND_SOC_NOPM,表示没有寄存器可以控制该widget的上下电 rt5651_dac_l_mix, ARRAY_SIZE(rt5651_dac_l_mix)); // Left DAC Mixer包含2个kcontrol,每个kcontrol控制着Mixer的一个输入端的开启和关闭 // route {"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"}
3.2.2 amixer content
通过amixer contents查看所有的配置参数:
root@rk3399:/# amixer contents numid=1,iface=CARD,name='Headphones Jack' ; type=BOOLEAN,access=r-------,values=1 : values=on numid=13,iface=MIXER,name='Mono ADC Capture Volume' ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0 : values=47,47 | dBminmax-min=-17.62dB,max=30.00dB numid=6,iface=MIXER,name='Mono DAC Playback Volume' ; type=INTEGER,access=rw---R--,values=2,min=0,max=175,step=0 : values=175,175 | dBminmax-min=-65.62dB,max=0.00dB numid=14,iface=MIXER,name='ADC Boost Gain' ; type=INTEGER,access=rw---R--,values=2,min=0,max=3,step=0 : values=3,3 | dBscale-min=0.00dB,step=12.00dB,mute=0 numid=18,iface=MIXER,name='ADC IF2 Data Switch' ; type=ENUMERATED,access=rw------,values=1,items=4 ; Item #0 'Normal' ; Item #1 'Swap' ; Item #2 'left copy to right' ; Item #3 'right copy to left' : values=0 numid=11,iface=MIXER,name='ADC Capture Switch' ; type=BOOLEAN,access=rw------,values=2 : values=on,on numid=12,iface=MIXER,name='ADC Capture Volume' ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0 .......
在Rockchip RK3399 - Codec驱动( Realtek ALC5651)我们分析了音频播放右通道路径:
- AIF1 Playback(snd_soc_dapm_dai_in类型的playback dai widget) --> AIF1RX :AIF表示音频数字接口;
- AIF1RX --> IF1 DAC;
- IF1 DAC --> IF1 DAC1 L;
- IF1 DAC1 L --> DAC MIXL:通过rt5651_dac_l_mix(名称为INF1 Switch)控制通断,由MX29寄存器位14来实现静音控制(0非静音,1静音);
- DAC MIXL --> Stereo DAC MIXR:通过rt5651_sto_dac_r_mix(名称DAC L1 Switch)控制通断,由MX2A寄存器位1来实现静音控制(0非静音,1静音);
- Stereo DAC MIXR --> DAC R1;
- DAC R1 --> OUT MIXR :通过rt5651_out_r_mix(名称为DAC R1 Switch)控制通断,由MX4F寄存器位0来实现静音控制(0非静音,1静音);
- OUT MIXR --> HPOVOL R:通过hpovol_r_control(名称为Switch)控制通断,由MX02寄存器位6来实现静音控制(0非静音,1静音);
- HPOVOL R --> HPOR MIX:通过rt5651_hpo_mix(名称为HPO MIX HPVOL Switch)控制通断,由MX45寄存器位13来实现静音控制(0非静音,1静音);
- HPOR MIX --> HP Amp;
- HP Amp -> HPO R Playback:通过hpo_r_mute_control(名称为Switch)控制通断,由MX02寄存器位7来实现静音控制(0非静音,1静音);
- HPO R Playback --> HPOR ;
- HPOR --> Headphones(最后一个path定义在Machine驱动中);
我们需要设置该条路径上的kcontrol设置为连接状态;
(1) 打开DAC MIXL INF1 Switch、DAC MIXR INF1 Switch:
root@rk3399:/# amixer cset numid=48 1 numid=48,iface=MIXER,name='DAC MIXL INF1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on root@rk3399:/# amixer cset numid=50 1 numid=50,iface=MIXER,name='DAC MIXR INF1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
我们可以查看MX29寄存器位14,看看是不是已经设置为0(非静音);
root@rk3399:/# cat /sys/kernel/debug/regmap/1-001a/registers | grep 029 029: 8080 #1000 0000 1000 0000
如果有兴趣的话,我们可以通过关闭DAC MIXL INF1 Switch,查看MX29寄存器位14是不是已经设置为1(静音);
root@rk3399:/# amixer cset numid=48 0 numid=48,iface=MIXER,name='DAC MIXL INF1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=off root@rk3399:/# cat /sys/kernel/debug/regmap/1-001a/registers | grep 029 029: c080 root@rk3399:/# amixer cset numid=48 1 numid=48,iface=MIXER,name='DAC MIXL INF1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
(2) 打开Stereo DAC MIXR DAC L1 Switch、Stereo DAC MIXL DAC R1 Switch:
root@rk3399:/# amixer cset numid=55 1 numid=55,iface=MIXER,name='Stereo DAC MIXL DAC R1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on root@rk3399:/# amixer cset numid=58 1 numid=58,iface=MIXER,name='Stereo DAC MIXR DAC L1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
(3) 打开OUT MIXR DAC R1 Switch、OUT MIXL DAC L1 Switch:
root@rk3399:/# amixer cset numid=74 1 numid=74,iface=MIXER,name='OUT MIXR DAC R1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on root@rk3399:/# amixer cset numid=69 1 numid=69,iface=MIXER,name='OUT MIXL DAC L1 Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
(4) 打开HPOVOL L Switch、HPOVOL R Switch:
root@rk3399:/# amixer cset numid=77 1 numid=77,iface=MIXER,name='HPOVOL L Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on root@rk3399:/# amixer cset numid=78 1 numid=78,iface=MIXER,name='HPOVOL R Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
(5) 打开HPO MIX HPVOL Switch:
root@rk3399:/# amixer cset numid=80 1 numid=80,iface=MIXER,name='HPO MIX HPVOL Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
(6) 打开HPO L Playback Switch、HPO R Playback Switch:
root@rk3399:/# amixer cset numid=85 1 numid=85,iface=MIXER,name='HPO L Playback Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on root@rk3399:/# amixer cset numid=86 1 numid=86,iface=MIXER,name='HPO R Playback Switch' ; type=BOOLEAN,access=rw------,values=1 : values=on
找到一个音频文件,播放音频:
root@rk3399:/# cd / root@rk3399:/# aplay AbuduOffice.mp3 Playing raw data 'AbuduOffice.mp3' : Signed 16 bit Little Endian, rATE 8000 Hz, Mono
插入耳机,如果我们发现耳机并没有声音,说明音频播放失败,关于问题定位参考Frace调试小节。
3.3 查看寄存器值
3.3.1 查看ALC5651寄存器值
运行如下命令查看ALC5651寄存器值,1-001a中的1为I2C适配器的编号,即I2C1,001a为I2C1总线上的从设备地址;
root@rk3399:/# cat /sys/kernel/debug/regmap/1-001a/registers 000: 0000 002: 81c1 003: c8c8 005: 0000 00d: 0000 00e: 0000 00f: 0808 010: 0808 019: afaf 01a: afaf 01b: 0c00 01c: 2f2f 01d: 2f2f ......
四、Ftrace调试
Ftrace 是一个内核中的追踪器,用于帮助系统开发者或设计者查看内核运行情况,它可以被用来调试或者分析延迟/性能问题。最早ftrace是一个function tracer,仅能够记录内核的函数调用流程。如今ftrace已经成为一个framework,采用plugin的方式支持开发人员添加更多种类的trace功能。
4.1 配置内核
运行make menuconfig,配置以下选项:
Kernel hacking ---> [*] Tracers ---> [*] Kernel Function Tracer [*] Kernel Function Graph Tracer (NEW) -*- enable/disable function tracing dynamically Device Drivers ---> <*> Sound card support ---> <*> Advanced Linux Sound Architecture ---> [*] Debug [*] More verbose debug [*] Enable PCM ring buffer overrun/underrun debugging [*] Validate input data to control API [*] Enable debugging feature for control API [*] Sound jack injection interface via debugfs
编译内核,并烧录到开发板。
4.2 Ftrace使用
Ftrace通过debugfs向用户态提供访问接口。配置内核时激活debugfs后会创建目录/sys/kernel/debug ,debugfs文件系统就是挂载到该目录。
4.2.1 运行时挂载
官方挂载方法 :
root@rk3399:/# mount -t debugfs nodev /sys/kernel/debug mount: /sys/kernel/debug: nodev already mounted or mount point busy. root@rk3399:/# cd /sys/kernel/debug/tracing
debugfs挂载路径下的tracing是ftrace的根路径。
4.2.2 系统启动自动挂载
要在系统启动自动挂载debugfs,需要将如下内容添加到/etc/fstab 文件:
debugfs /sys/kernel/debug debugfs defaults 0 0
4.2.3 选择一种 tracer
查看当前追踪器:
root@rk3399:/sys/kernel/debug/tracing# cat current_tracer nop
查看当前内核中可用跟踪器:
root@rk3399:/sys/kernel/debug/tracing# cat available_tracers function_graph function nop
我们选用 function_graph 追踪器:
root@rk3399:/sys/kernel/debug/tracing# echo function_graph > current_tracer
4.2.4 打开/关闭跟踪
在老一点版本的内核上tracing目录下有tracing_enabled,需要给tracing_enabled和tracing_on同时赋值1才能打开追踪,而在比较新的内核上已经去掉tracing_enabled ,我们只需要控制tracing_on即可打开关闭追踪。
打开跟踪:
root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/tracing_on
关闭跟踪:
root@rk3399:/sys/kernel/debug/tracing# echo 0 > /sys/kernel/debug/tracing/tracing_on
追踪指定的进程:
root@rk3399:/sys/kernel/debug/tracing# echo pid > /sys/kernel/debug/tracing/set_ftrace_pid
我们写程序时可以使用getpid获取进程PID,然后使用write将pid 写入 /sys/kernel/debug/tracing/set_ftrace_pid ,并使用write写1到tracing_on打开追踪(因为在用户空间使用不了tracing_on函数),此时即可追踪当前这个进程。
4.2.5 跟踪事件
首先查看事件文件夹下面有哪些选项:
root@rk3399:/sys/kernel/debug/tracing# ls /sys/kernel/debug/tracing/events/ 9p cros_ec filelock interconnect mdio nfs rcu smbus timer alarmtimer dev filemap io_uring migrate nfs4 regmap sock tlb asoc devfreq ftrace iomap mmap oom regulator spi udp block devlink gadget iommu mmap_lock optee rpcgss spmi ufs bpf_test_run dma_fence gpio ipi mmc page_isolation rpm sunrpc vmalloc bpf_trace dpaa2_eth gpu_scheduler irq module page_pool rpmh swiotlb vmscan bridge dpaa_eth header_event jbd2 mtu3 pagemap rseq task watchdog cgroup drm header_page kmem musb percpu rtc tcp workqueue chipidea dwc3 huge_memory kvm napi power sched tegra_apb_dma writeback clk enable hwmon kyber neigh printk scmi thermal xdp cma error_report i2c libata net qdisc scsi thermal_power_allocator xhci-hcd compaction ext4 i2c_slave lock netfs ras signal thermal_pressure cpuhp fib initcall maple_tree netlink raw_syscalls skb thp root@rk3399:/sys/kernel/debug/tracing# ls /sys/kernel/debug/tracing/events/asoc enable snd_soc_bias_level_start snd_soc_dapm_path snd_soc_dapm_widget_event_done snd_soc_jack_irq filter snd_soc_dapm_connected snd_soc_dapm_start snd_soc_dapm_widget_event_start snd_soc_jack_notify snd_soc_bias_level_done snd_soc_dapm_done snd_soc_dapm_walk_done snd_soc_dapm_widget_power snd_soc_jack_report
关闭所有事件跟踪:
root@rk3399:/sys/kernel/debug/tracing# echo 0 > /sys/kernel/debug/tracing/events/enable
追踪若干事件:
root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_path/enable root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_start/enable root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_walk_done/enable root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable
追踪某一类事件:
root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/enable
4.2.6 查看跟踪结果
ftrace 的输出信息主要保存在3个文件中;
- trace:该文件保存ftrace的输出信息,其内容可以直接阅读;
- trace_pipe:是一个管道文件,主要为了方便应用程序读取trace内容,算是扩展接口吧;
所以可以直接查看trace追踪文件,也可以在追踪之前使用trace_pipe将追踪结果直接导向其他的文件。
比如:cat trace_pipe > /tmp/log & 使用trace_pipe将跟踪结果导入/tmp/log 里,我们可以直接cat /tmp/log” 查看跟踪信息。
当然也可以直接查看trace文件cat trace或者使用cat trace > /tmp/log将跟踪信息导入 /tmp/log。
4.3 跟踪音频
4.3.1 打开trace开关
echo 0 > /sys/kernel/debug/tracing/events/enable echo 1 > /sys/kernel/debug/tracing/tracing_on echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_path/enable echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_start/enable echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_walk_done/enable echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable
4.3.2 激活音频流
找到一个音频文件,播放音频:
root@rk3399:/# cd / root@rk3399:/# aplay AbuduOffice.mp3 Playing raw data 'AbuduOffice.mp3' : Signed 16 bit Little Endian, rATE 8000 Hz, Mono
查看/sys/kernel/debug/tracing/trace:
root@rk3399:/# cat sys/kernel/debug/tracing/trace # tracer: nop # # entries-in-buffer/entries-written: 142/142 #P:6 # # _-----=> irqs-off/BH-disabled # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / _-=> migrate-disable # |||| / delay # TASK-PID CPU# ||||| TIMESTAMP FUNCTION # | | | ||||| | | amixer-4948 [004] ..... 5890.895606: snd_soc_dapm_start: card=realtek,rt5651-codec amixer-4948 [004] ..... 5890.895631: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXR amixer-4948 [004] ..... 5890.895633: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXL amixer-4948 [004] ..... 5890.895636: snd_soc_dapm_path: Stereo DAC MIXL <- DAC R1 Switch <- DAC MIXR amixer-4948 [004] ..... 5890.895638: snd_soc_dapm_path: Stereo DAC MIXL <- DAC L2 Switch <- DAC L2 Volume amixer-4948 [004] ..... 5890.895639: snd_soc_dapm_path: Stereo DAC MIXL <- DAC L1 Switch <- Audio DSP amixer-4948 [004] ..... 5890.895660: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 2 power, 2 path, 7 neighbour amixer-4949 [005] ..... 5893.861746: snd_soc_dapm_start: card=realtek,rt5651-codec amixer-4949 [005] ..... 5893.861788: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 2 power, 0 path, 0 neighbour amixer-4955 [005] ..... 5999.186695: snd_soc_dapm_start: card=realtek,rt5651-codec amixer-4955 [005] ..... 5999.186723: snd_soc_dapm_path: *DAC R1 <- (direct) <- Stereo DAC MIXR amixer-4955 [005] ..... 5999.186726: snd_soc_dapm_path: *Stereo DAC MIXR <- DAC L1 Switch <- DAC MIXL amixer-4955 [005] ..... 5999.186728: snd_soc_dapm_path: Stereo DAC MIXR <- DAC R2 Switch <- DAC R2 Volume amixer-4955 [005] ..... 5999.186730: snd_soc_dapm_path: Stereo DAC MIXR <- DAC R1 Switch <- Audio DSP amixer-4955 [005] ..... 5999.186732: snd_soc_dapm_path: *OUT MIXR <- DAC R1 Switch <- DAC R1 amixer-4955 [005] ..... 5999.186734: snd_soc_dapm_path: OUT MIXR <- REC MIXR Switch <- RECMIXR amixer-4955 [005] ..... 5999.186736: snd_soc_dapm_path: OUT MIXR <- INR1 Switch <- INR1 VOL amixer-4955 [005] ..... 5999.186737: snd_soc_dapm_path: OUT MIXR <- BST1 Switch <- BST1 amixer-4955 [005] ..... 5999.186739: snd_soc_dapm_path: OUT MIXR <- BST2 Switch <- BST2 amixer-4955 [005] ..... 5999.186761: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 2 power, 3 path, 12 neighbour aplay-4959 [004] ..... 6120.491037: snd_soc_dapm_start: card=realtek,rt5651-codec aplay-4959 [004] ..... 6120.491064: snd_soc_dapm_widget_power: widget=Playback val=1 aplay-4959 [004] ..... 6120.491066: snd_soc_dapm_widget_power: widget=AIF1 Playback val=1 aplay-4959 [004] ..... 6120.491069: snd_soc_dapm_path: *AIF1RX <- (direct) <- AIF1 Playback aplay-4959 [004] ..... 6120.491071: snd_soc_dapm_widget_power: widget=AIF1RX val=1 aplay-4959 [004] ..... 6120.491073: snd_soc_dapm_path: *IF1 DAC <- (direct) <- AIF1RX aplay-4959 [004] ..... 6120.491074: snd_soc_dapm_widget_power: widget=IF1 DAC val=1 aplay-4959 [004] ..... 6120.491078: snd_soc_dapm_widget_power: widget=I2S1 val=1 aplay-4959 [004] ..... 6120.491080: snd_soc_dapm_path: *IF1 DAC2 R <- (direct) <- IF1 DAC aplay-4959 [004] ..... 6120.491082: snd_soc_dapm_path: *IF1 DAC2 L <- (direct) <- IF1 DAC aplay-4959 [004] ..... 6120.491084: snd_soc_dapm_path: *IF1 DAC1 R <- (direct) <- IF1 DAC aplay-4959 [004] ..... 6120.491085: snd_soc_dapm_widget_power: widget=IF1 DAC1 R val=1 aplay-4959 [004] ..... 6120.491087: snd_soc_dapm_path: *IF1 DAC1 L <- (direct) <- IF1 DAC aplay-4959 [004] ..... 6120.491088: snd_soc_dapm_widget_power: widget=IF1 DAC1 L val=1 aplay-4959 [004] ..... 6120.491091: snd_soc_dapm_widget_power: widget=I2S1 ASRC val=1 aplay-4959 [004] ..... 6120.491094: snd_soc_dapm_path: *DAC MIXR <- INF1 Switch <- IF1 DAC1 R aplay-4959 [004] ..... 6120.491097: snd_soc_dapm_path: DAC MIXR <- Stereo ADC Switch <- Stereo1 ADC MIXR aplay-4959 [004] ..... 6120.491098: snd_soc_dapm_widget_power: widget=DAC MIXR val=1 aplay-4959 [004] ..... 6120.491100: snd_soc_dapm_path: *DAC MIXL <- INF1 Switch <- IF1 DAC1 L aplay-4959 [004] ..... 6120.491102: snd_soc_dapm_path: DAC MIXL <- Stereo ADC Switch <- Stereo1 ADC MIXL aplay-4959 [004] ..... 6120.491104: snd_soc_dapm_widget_power: widget=DAC MIXL val=1 aplay-4959 [004] ..... 6120.491106: snd_soc_dapm_path: *PDM R Mux <- DD MIX <- DAC MIXR aplay-4959 [004] ..... 6120.491107: snd_soc_dapm_path: PDM R Mux <- Stereo DAC MIX <- Stereo DAC MIXR aplay-4959 [004] ..... 6120.491109: snd_soc_dapm_widget_power: widget=PDM R Mux val=1 aplay-4959 [004] ..... 6120.491111: snd_soc_dapm_path: *Stereo DAC MIXL <- DAC R1 Switch <- DAC MIXR aplay-4959 [004] ..... 6120.491113: snd_soc_dapm_path: Stereo DAC MIXL <- DAC L2 Switch <- DAC L2 Volume aplay-4959 [004] ..... 6120.491114: snd_soc_dapm_path: Stereo DAC MIXL <- DAC L1 Switch <- Audio DSP aplay-4959 [004] ..... 6120.491116: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXR aplay-4959 [004] ..... 6120.491117: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXL aplay-4959 [004] ..... 6120.491119: snd_soc_dapm_path: *PDM L Mux <- DD MIX <- DAC MIXL aplay-4959 [004] ..... 6120.491121: snd_soc_dapm_path: PDM L Mux <- Stereo DAC MIX <- Stereo DAC MIXL aplay-4959 [004] ..... 6120.491122: snd_soc_dapm_widget_power: widget=PDM L Mux val=1 aplay-4959 [004] ..... 6120.491124: snd_soc_dapm_path: *Stereo DAC MIXR <- DAC L1 Switch <- DAC MIXL aplay-4959 [004] ..... 6120.491126: snd_soc_dapm_path: Stereo DAC MIXR <- DAC R2 Switch <- DAC R2 Volume aplay-4959 [004] ..... 6120.491128: snd_soc_dapm_path: Stereo DAC MIXR <- DAC R1 Switch <- Audio DSP aplay-4959 [004] ..... 6120.491129: snd_soc_dapm_path: *PDMR <- (direct) <- PDM R Mux aplay-4959 [004] ..... 6120.491131: snd_soc_dapm_widget_power: widget=PDMR val=1 aplay-4959 [004] ..... 6120.491132: snd_soc_dapm_path: *PDML <- (direct) <- PDM L Mux aplay-4959 [004] ..... 6120.491134: snd_soc_dapm_widget_power: widget=PDML val=1 aplay-4959 [004] ..... 6120.491155: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 19 power, 17 path, 31 neighbour
alsa在录音/播放前会先检查snd_soc_dapm_path(带"*")能否连成一路完整的routing,如果失败,录音/播放的进程会自动停止。
如果录音/播放的trace不完整,检查codec驱动中的snd_soc_dapm_route,从右到左,能否连接成一路complete path。
参考文章:
[1] 如何查看声卡、pcm设备以及tinyplay、tinymix、tinycap的使用
[2] linux音频 DAPM之二:audio paths与dapm kcontrol
[5] Linux音频调试示例
标签:snd,Rockchip,ALC5651,soc,RK3399,rk3399,tracing,root,numid From: https://www.cnblogs.com/zyly/p/17591417.html