前面一节的内容我们提到,ASoC被分为Machine、Platform和Codec三大部分。
其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,再次引用上一节的内容:
Machine驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频时,需要先行打开一个放大器);单独的Platform和Codec驱动是不能工作的,它必须由Machine驱动把它们结合在一起才能完成整个设备的音频处理工作。
ASoC的一切都从Machine驱动开始,包括声卡的注册,绑定Platform和Codec驱动等等,下面就让我们从Machine驱动开始讨论吧
注册Platform Device
ASoC把声卡注册为Platform Device,以WM8960为例 ,涉及文件:sound/soc/imx/imx-wm8960.c
其模块初始化函数为:module_init(imx_asoc_init);
一般来说,底板的千兆网大多选用RGMII和SGMII两种接口,也有可以拓展出更多网口的QSGMII接口。
这一篇文章就是简单解析一下RGMII这种接口的内容。
RGMII均采用4位数据接口,工作时钟125MHz,并且在上升沿和下降沿同时传输数据,因此传输速率可达1000Mbps。
首先是硬件底板连接图。
先是PHY芯片的AR8031的硬件接线图:
其次是网口座子和PHY芯片的模式选择引脚以及PHY地址的接线图:
查阅AR8031的数据手册,先看硬件定义如下:
可见此接口引脚数量为12个。
其中发送端有:(“发送”面向的是MAC,指从MAC向PHY发送数据)
- GTX_CLK:发送端参考时钟,由MAC向PHY提供
- TXD[0:3]:发送数据引脚
- TX_EN:发送控制引脚
TX_EN信号线上传送TX_EN和TX_ER两种信息,在GTX_CLK的上升沿发送TX_EN,下降沿发送TX_ER。
其中接收端有:(“接收”面向的是MAC,指从MAC向PHY接收数据)
- RX_CLK:接收端参考时钟,由PHY向MAC提供
- RXD[0:3]:接收数据引脚
- RX_DV:接收控制引脚
其余有一个管理配置接口,即MDIO接口,有2根线:
- MDC:时钟线
- MDIO:数据线(双向)
补充知识:
MII(Media Independent interface)即介质无关接口,它是IEEE-802.3定义的行业标准,是MAC与PHY之间的接口。MII数据接口包含16个信号和2个管理接口信号
信号名称 | 描述 | 方向 |
---|---|---|
TX_CLK | 发送时钟 | PHY → MAC |
TX_ER | 发送数据错误 | MAC → PHY |
TX_EN | 发送使能 | MAC → PHY |
TXD0 | 发送数据位0(最先传输) | MAC → PHY |
TXD1 | 发送数据位1 | MAC → PHY |
TXD2 | 发送数据位2 | MAC → PHY |
TXD3 | 发送数据位3 | MAC → PHY |
RX_CLK | 接收时钟 | PHY → MAC |
RX_DV | 接收数据有效 | PHY → MAC |
RX_ER | 接收数据错误 | PHY → MAC |
RXD0 | 接收数据位0(最先传输) | PHY → MAC |
RXD1 | 接收数据位1 | PHY → MAC |
RXD2 | 接收数据位2 | PHY → MAC |
RXD3 | 接收数据位3 | PHY → MAC |
CRS | 载波监测 | PHY → MAC |
COL | 冲突碰撞监测 | PHY → MAC |
MDIO | 管理数据 | 双向 |
MDC | 管理数据时钟 | MAC → PHY |
MII以4位半字节方式传送数据双向传输,是一个支持10/100-Mbit/s速度的接口
- 时钟频率为2.5MHz时,对应速率为10Mbit/s
- 时钟速率为25MHz时,对应速率可达100Mbit/s
MII: 10Mbits/s = 2.5MHz x 4(数据位)
100Mbit/s = 25MHz x 4(数据位)
MII接口虽然很灵活但由于信号线太多限制多接口网口的发展,后续又衍生出RMII,SMII等。
RMII(Reduced Media Independant Interface),精简MII接口,节省了一半的数据线。RMII收发使用2位数据进行传输,收发时钟均采用50MHz时钟源。信号定义如下:
信号名称 | 描述 | 方向 |
---|---|---|
REF_CLK | 参考时钟 | MAC→PHY或由外部时钟源提供 |
TX_EN | 发送数据使能 | MAC → PHY |
TXD0 | 发送数据位0(最先传输) | MAC → PHY |
TXD1 | 发送数据位1 | MAC → PHY |
RX_ER | 接收错误 | PHY → MAC |
RXD0 | 接收数据位0(最先传输) | PHY → MAC |
RXD1 | 接收数据1 | PHY → MAC |
CRS_DV | 载波和接收数据有效 | PHY → MAC |
MDIO | 管理数据 | 双向 |
MDC | 管理数据时钟 | MAC → PHY |
其中CRS_DV是MII中RX_DV和CRS两个信号的合并,当物理层接收到载波信号后CRS_DV变得有效,将数据发送给RXD。当载波信号消失后,CRS_DV会变为无效。在100M以太网速率中,MAC层每个时钟采样一次RXD[1:0]上的数据,在10M以太网速率中,MAC层每10个时钟采样一次RXD[1:0]上的数据,此时物理层接收的每个数据会在RXD[1:0]保留10个时钟。
MII以2位字节方式传送数据双向传输,是一个支持10/100-Mbit/s速度的接口
- 无论传输速率为10Mbit/s和100Mbit/s,时钟速率都为为50MHz
RMII: 10Mbits/s = 50MHz / 10(10个时钟采样一次) x 2(数据位)
100Mbit/s = 50MHz x 2(数据位)
SMII(Serial Media Independant Interface),串行MII接口。它包括TXD,RXD,SYNC三个信号线,共用一个时钟信号,此时钟信号是125MHz,信号线与此时钟同步。信号定义如下:
信号名称 | 描述 | 方向 |
---|---|---|
REF_CLK | 参考时钟 | 外部时钟源提供125MHz |
TXD | 发送数据 | MAC → PHY |
RXD | 接收数据 | PHY → MAC |
SYNC | 同步信号 | - |
MDIO | 管理数据 | 双向 |
MDC | 管理数据时钟 | MAC → PHY |
SYNC是数据收发的同步信号,每10个时钟同步置高一次电平,表示同步。TXD和RXD上的数据和控制信息,以10bit为一组。发送部分波形如下:
从波形可以看出,SYNC变高后的10个时钟周期内,TXD依次输出一组10bit的数据即TX_ER,TX_EN,TXD[0:7],这些控制信息和MII接口含义相同。在100M速率中,每一组的内容都是变换的,在10M速率中,每一组数据需要重复10次,采样任一一组都可以。
SMII以1位字节方式传送数据双向传输,是一个支持10/100-Mbit/s速度的接口
- 无论传输速率为10Mbit/s和100Mbit/s,时钟速率都为为125MHz
SMII: 10Mbits/s = 125MHz / 10(一个时钟周期10bit的数据) x 8(10bit的数据中有8位是有效数据)
100Mbit/s = 125MHz / 10(10bit的数据) x 8(8位有效数据) / 10(每组数据重复10次)
GMII(Gigabit Media Independant Interface),千兆MII接口。GMII采用8位接口数据,工作时钟125MHz,因此传输速率可达1000Mbps。同时兼容MII所规定的10/100 Mbps工作方式。GMII接口数据结构符合IEEE以太网标准,该接口定义见IEEE 802.3-2000。信号定义如下:
信号名称 | 描述 | 方向 |
---|---|---|
GTX_CLK | 1000M发送时钟 | MAC → PHY |
TX_CLK | 100/10M发送时钟 | MAC → PHY |
TX_ER | 发送数据错误 | MAC → PHY |
TX_EN | 发送使能 | MAC → PHY |
TX_[7:0] | 发送数据8bit | MAC → PHY |
RX_CLK | 接收时钟 | PHY → MAC |
RX_DV | 接收数据有效 | PHY → MAC |
RX_ER | 接收数据错误 | PHY → MAC |
RX_[7:0] | 接收数据8bit | PHY → MAC |
CRS | 载波监测 | PHY → MAC |
COL | 冲突碰撞监测 | PHY → MAC |
MDIO | 管理数据 | 双向 |
MDC | 管理数据时钟 | MAC → PHY |
GMII以8位半字节方式传送数据双向传输,是一个支持10/100/1000-Mbit/s速度的接口
- 时钟频率为2.5MHz时(使用TX_CLK引脚发送),对应速率为10Mbit/s
- 时钟速率为25MHz时(使用TX_CLK引脚发送),对应速率可达100Mbit/s
- 时钟速率为125MHz时(使用GTX_CLK引脚发送),对应速率可达1000Mbit/s
GMII: 10Mbits/s = 2.5MHz x 4(兼容MII模式,使用4位数据位)
100Mbit/s = 25MHz x 4(兼容MII模式,使用4位数据位)
1000Mbit/s = 125MHz x 8(数据位)
RGMII
RGMII(Reduced Gigabit Media Independant Interface),精简GMII接口。相对于GMII相比,RGMII具有如下特征:
- 发送/接收数据线由8条改为4条
- TX_ER和TX_EN复用,通过TX_CTL传送
- RX_ER与RX_DV复用,通过RX_CTL传送
- 1 Gbit/s速率下,时钟频率为125MHz
- 100 Mbit/s速率下,时钟频率为25MHz
- 10 Mbit/s速率下,时钟频率为2.5MHz
信号定义如下:
信号名称 | 描述 | 方向 |
---|---|---|
TXC | 发送时钟 | MAC→PHY |
TX_CTL | 发送数据控制 | MAC → PHY |
TXD[3:0] | 发送数据4bit | MAC → PHY |
RXC | 接收时钟 | PHY → MAC |
RX_CTL | 接收数据控制 | PHY → MAC |
RXD[3:0] | 接收数据4bit | PHY → MAC |
MDIO | 管理数据 | 双向 |
MDC | 管理数据时钟 | MAC → PHY |
虽然RGMII信号线减半,但TXC/RXC时钟仍为125Mhz,为了达到1000Mbit的传输速率,TXD/RXD信号线在时钟上升沿发送接收GMII接口中的TXD[3:0]/RXD[3:0],在时钟下降沿发送接收TXD[7:4]/RXD[7:4],并且信号TX_CTL反应了TX_EN和TX_ER状态,即在TXC上升沿发送TX_EN,下降沿发送TX_ER,同样的道理试用于RX_CTL,下图为发送接收的时序:
RGMII以4位半字节方式传送数据双向传输,是一个支持10/100/1000-Mbit/s速度的接口
- 时钟频率为2.5MHz时,对应速率为10Mbit/s
- 时钟速率为25MHz时,对应速率可达100Mbit/s
- 时钟速率为125MHz时,对应速率可达1000Mbit/s
RGMII: 10Mbits/s = 2.5MHz x 4(数据位)
100Mbit/s = 25MHz x 4(数据位)
1000Mbit/s = 125MHz x 2(一个时钟上升沿和下降沿共传输两个数据) x 4(数据位)
具体知识的参考链接如下:
我目前手边上有一个7.4v的锂电池,因为不常用,又怕总是搁置着会慢慢给放坏,所以网上查了一下7.4v锂电池的充电注意事项,特此记录一下。
7.4V一般是2串锂电的电池组,这也可以从电池的充电接口看到,一般是一个3p的接口,如果用万用表去测量的话,分别为0v,一串电池的电压,两串电池的电压。
单串电池的充放电范围是4.2V-2.7V,也就是说,如果电池电压一致性比较好的话,充电的满电电压是8.4V,放电的最低电压是5.4V。
如果没有保护板的话在5.4V以下也许用电器还能工作,但电池已经不能再用了,会损失寿命,需要充电再用。
另外锂电池对电压上下限很敏感,经常超高或超低会极大地损失循环寿命。
也就是对于7.4v的锂电池来说
满电 | 标称 | 停止 | 终止 |
---|---|---|---|
8.4v | 7.4v | 7.0v | 6.0v |
在内核驱动文件./drivers/power/supply/da9052-battery.c中,有以下内容
{
{4102, 100}, {4065, 98},
{4048, 96}, {4034, 95},
{4021, 93}, {4011, 92},
{4001, 90}, {3986, 88},
{3968, 87}, {3952, 85},
{3938, 84}, {3926, 82},
{3916, 81}, {3908, 79},
{3900, 77}, {3892, 76},
{3883, 74}, {3874, 73},
{3864, 71}, {3855, 70},
{3846, 68}, {3836, 67},
{3827, 65}, {3819, 64},
{3810, 62}, {3801, 61},
{3793, 59}, {3786, 58},
{3778, 56}, {3772, 55},
{3765, 53}, {3759, 52},
{3754, 50}, {3748, 49},
{3743, 47}, {3738, 46},
{3733, 44}, {3728, 43},
{3724, 41}, {3720, 40},
{3716, 38}, {3712, 37},
{3709, 35}, {3706, 34},
{3703, 33}, {3701, 31},
{3698, 30}, {3696, 28},
{3693, 27}, {3690, 25},
{3687, 24}, {3683, 22},
{3680, 21}, {3675, 19},
{3671, 18}, {3666, 17},
{3660, 15}, {3654, 14},
{3647, 12}, {3639, 11},
{3630, 9}, {3621, 8},
{3613, 6}, {3606, 5},
{3597, 4}, {3582, 2},
{3546, 1}, {2747, 0}
},
由上可以看到,当单串电池电压到3.5v时,电池电量已经接近于0了,所以平时在放电的时候,要注意电池组电压不要低于7v
目前在调试wm8960芯片的时候遇到一个问题,需要能够打印wm8960芯片上的寄存器的值。
但是通过wm8960的手册我们知道,它的寄存器地址是7为,数据是9位,不是标准的i2c协议的情况,只支持了i2c来写寄存器,没有实现i2c读寄存器。
根据网页开发人员工具中的报错
from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow
确定是apache2设置跨域的问题,首先使能apache2的头部请求模块
root@73b0c7f2587a:/var/www/html# a2enmod headers.load
Enabling module headers.
To activate the new configuration, you need to run:
service apache2 restart
root@73b0c7f2587a:/var/www/html# service apache2 restart
其次是修改apache2的配置,修改
/etc/apache2/sites-enabled/000-default.conf
增加
Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Credentials true
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
如果是使用的nginx搭建的网站,则需要修改配置文件,在location关键字下增加
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
}
然后根据网页开发人员工具中的报错
The document is sandboxed and lacks the 'allow-same-origin' flag.
确定是iframe中的sandbox缺少’allow-same-origin’属性的问题
修改Typecho根目录中的
./admin/write-js.php
文件,修改如下
function previewData(cid) {
isFullScreen = $(document.body).hasClass('fullscreen');
$(document.body).addClass('fullscreen preview');
var frame = $('<iframe frameborder="0" class="preview-frame preview-loading"></iframe>')
.attr('src', './preview.php?cid=' + cid)
.attr('sandbox', 'allow-scripts allow-same-origin')
.appendTo(document.body);
frame.load(function () {
frame.removeClass('preview-loading');
});
frame.height($(window).height() - 53);
}
主要是这一句话
.attr('sandbox', 'allow-scripts allow-same-origin')
amixer简介
amixer是命令行形式的配置指令,可以对ALSA(Advanced Linux Sound Architecture)架构类型的声卡驱动提供的接口进行音频参数配置,例如音量调节以及声卡开关。并且该amixer功能指令可以对多种类型声卡驱动接口进行配置。
另外注意还有alsamixer,作用和amixer一样,用于配置ALSA架构声卡各个音频参数,但是以图形界面形式显示,操作方便,显示直观。
amxier可以调节系统对应声卡的音量和选择音频通道。
amixer命令格式
使用 amixer命令如下:
amixer [-option] [cmd]
amixer支持的功能
终端下输入#amixer -h
查看amixer支持的功能和选项:
root@forlinx:~# amixer -h
Usage: amixer <options> [command]
Available options:
-h,--help this help
-c,--card N select the card
-D,--device N select the device, default 'default'
-d,--debug debug mode
-n,--nocheck do not perform range checking
-v,--version print version of this program
-q,--quiet be quiet
-i,--inactive show also inactive controls
-a,--abstract L select abstraction level (none or basic)
-s,--stdin Read and execute commands from stdin sequentially
-R,--raw-volume Use the raw value (default)
-M,--mapped-volume Use the mapped volume
Available commands:
scontrols show all mixer simple controls
scontents show contents of all mixer simple controls (default command)
sset sID P set contents for one mixer simple control
sget sID get contents for one mixer simple control
controls show all controls for given card
contents show contents of all controls for given card
cset cID P set control contents for one control
cget cID get control contents for one control
上述指令对于amixer功能只是一个简单描述输出,具体解释可以输入#man 1 amixer
查询。
自己理解的一些命令区别如下:
“controls”表示输出全部声卡驱动接口列表
“contents”表示输出全部声卡驱动接口列表以及对每个接口属性内容描述,接口的类型,值的大小
“scontrols”表示一些简单的接口的列表
“scontents”表示一些简单的接口的列表以及对每个接口属性内容描述,接口的类型,值的大小
我们已经知道,对于WM8960音频芯片的Codec来说,与SOC连接的一共是有5个引脚:
DACLRC 数字转模拟左右声道时钟
BCLK(Bit Clock) 位时钟
ADCDAT 模拟转数字数据(录音数据)
DACDAT 数字转模拟数据(放音数据)
MCLK 外部24M时钟
关于这些引脚的作用,可以参看文章《音频的IIS引脚的理解》
这篇文章仅仅讨论播放音频文件时候的情况。
当播放音频文件时,使用示波器测量出来的LRC时钟就是音频的采样频率时钟,如果 /etc/asound.conf文件存在的话,那么LRC时钟就是使用的配置文件中设置的时钟,大多数是44.1kHz或者22.05kHz。
否则的话,LRC时钟就等于播放的音频文件的采样率大小。
使用file命令可以查看音频文件的采样率:
从上面的例程中可以发现:
/forlinx/media/test.mp3:采样率:44.1 kHz
/run/media/sda1/ddd/1K_sin.mp3:采样率:48 kHz
/run/media/sda1/ddd/1K_sin.wav:采样率:11.025 kHz
日前,工作中遇到了一个SATA热插拔的需求,客户想要在系统使用过程中能够通过一个开关来做控制,支持在不重启系统的情况下实现SATA硬盘的热插拔。
为了实现此功能,硬件设置如下:
GPIO2_3用于一个船型开关,开关闭合(船型开关置“1”)时与GND短路。
SATA_PWRLED连接LED,指示SATA电源,点亮表示SATA供电。
SATA_STALED连接LED,指示硬盘运行状态。
概况来说,就是有以下资源:
一个DI输入,接了一个船型开关,可以通过拨动开关来获取01值
一个DO输出,控制着SATA硬盘的电源,并连接了一个LED灯
一个DO输出,连接了一个LED灯,可以配置成指示SATA硬盘的读写状态(与实现SATA热插拔功能无关)
软件上想要实现的逻辑如下:
插入硬盘:
在SATA电源灯熄灭状态下,插入硬盘
拨动船型开关置“1”
SATA电源灯亮起,状态灯闪烁
硬盘正常工作
拔出硬盘:
拨动船型开关置“0”
稍等片刻,待SATA电源灯熄灭
拔出硬盘即可
日前在移植LSDK2108的时候,发现在启动weston服务的时候会报以下的错误
root@forlinx:~# weston --tty=1
Date: 2022-04-09 CST
[16:30:47.231] weston 9.0.0
https://wayland.freedesktop.org
Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
Build: lf-5.10.35-2.0.0-rc2-1-gbf611255
[16:30:47.232] Command line: weston --tty=1
[16:30:47.232] OS: Linux, 5.10.35-g46e1a09b0512, #1 SMP PREEMPT Sat Apr 9 13:20:41 CST 2022, aarch64
[16:30:47.233] Using config file '/etc/xdg/weston/weston.ini'
[16:30:47.234] Output repaint window is 7 ms maximum.
[16:30:47.235] Loading module '/usr/lib/libweston-9/drm-backend.so'
[16:30:47.239] initializing drm backend
[16:30:47.244] using /dev/dri/card0
[16:30:47.245] DRM: supports atomic modesetting
[16:30:47.245] DRM: supports GBM modifiers
[16:30:47.245] DRM: supports picture aspect ratio
[16:30:47.245] Loading module '/usr/lib/libweston-9/gl-renderer.so'
[16:30:47.268] Failed to load module: /lib/libEGL.so.1: undefined symbol: gbm_surface_set_in_fence_fd
[16:30:47.268] failed to initialize egl
[16:30:47.269] fatal: failed to create compositor backend
Internal warning: debug scope 'drm-backend' has not been destroyed.
从错误上来看,就是加载/lib/libEGL.so.1模块的时候找不到gbm_surface_set_in_fence_fd符号
我们可以使用ldd -r /lib/libEGL.so.1命令来验证这一问题
root@forlinx:~# ldd -r /lib/libEGL.so.1
linux-vdso.so.1 (0x0000ffff9ae6f000)
libGAL.so => /lib/libGAL.so (0x0000ffff9ac04000)
libwayland-server.so.0 => /lib/aarch64-linux-gnu/libwayland-server.so.0 (0x0000ffff9abe0000)
libwayland-client.so.0 => /lib/aarch64-linux-gnu/libwayland-client.so.0 (0x0000ffff9abc1000)
libdrm.so.2 => /lib/aarch64-linux-gnu/libdrm.so.2 (0x0000ffff9ab9f000)
libgbm.so.1 => /lib/aarch64-linux-gnu/libgbm.so.1 (0x0000ffff9ab81000)
libgbm_viv.so => /lib/libgbm_viv.so (0x0000ffff9ab6c000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff9ab3c000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff9a9c9000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff9ae3f000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff9a91c000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff9a908000)
libffi.so.7 => /lib/aarch64-linux-gnu/libffi.so.7 (0x0000ffff9a8ef000)
libexpat.so.1 => /lib/aarch64-linux-gnu/libexpat.so.1 (0x0000ffff9a8b8000)
undefined symbol: gbm_surface_set_in_fence_fd (/lib/libEGL.so.1)
在上面的打印信息中,我们也看到了/lib/libEGL.so.1所链接的其他动态库