知识分享

这篇文章主要分3部分(是个人在公司做知识分享的内容)
1:Android/Linux SDK的组成部分
2:linux/Android 的驱动存在形式与内核模型 以及应用层是如何一步步调用到驱动层
3:前端声学部分 指标的定义与解读

1、RK平台Android/linux sdk系统

推荐: Android 源码 查看网站:http://androidxref.com/
C++api接口查询:http://www.cplusplus.com
kernel源码下载:https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/
fire3308-linux源码:https://gitlab.com/TeeFirefly/rk3308-linux/-/tree/firefly
fire3399-android源码:https://gitlab.com/TeeFirefly/firenow-oreo-rk3399/-/tree/firefly-rk3399/

一:Linux SDK: bootloader + kernel + filesystm

Linux可以分为两部分,分别为用户空间和内核空间具体如下图:
在这里插入图片描述

Linux_SDK 目录介绍
目录:

├── linux_sdk
│   ├── app
│   ├── buildroot                                               根文件系统的编译目录
│   ├── build.sh -> device/rockchip/common/build.sh              全自动编译脚本
│   ├── device                                                   编译相关配置文件
│   ├── distro debian                                            根文件系统生成目录
│   ├── docs                                                     文档
│   ├── envsetup.sh -> buildroot/build/envsetup.sh
│   ├── external                                                第三方软件工具集
│   ├── kernel                                                   内核
│   ├── Makefile -> buildroot/build/Makefile
│   ├── mkfirmware.sh -> device/rockchip/common/mkfirmware.sh    rockdev链接更新脚本
│   ├── prebuilts                                                交叉编译工具
│   ├── rkbin                                                        存放RK平台执行文件
│   ├── rkflash.sh -> device/rockchip/common/rkflash.sh          烧写脚本
│   ├── rootfs                                                  根文件系统编译目录
│   ├── tools                                                    烧写、打包工具
│   └── u-boot                                                bootloader;构建硬件环境、c运行环境

1)uboot

底层开发者需要了解上层应用之下的系统部分:
一个嵌入式Linux系统从软件角度看可以分为四个部分:引导加载程序(Bootloader),Linux内核,文件系统,应用程序。
bootloader的种类(uboot为最常见):

在这里插入图片描述
在这里插入图片描述

bootloader作用:
1、除了建立了适当的系统软硬件环境、搭建C语言运行的环境
2、为最终调用操作系统内核做好准备,

linux的内核是由uboot装载到内存中的;
uboot的启动log:

在这里插入图片描述

2) kernel

其源码主要有以下目录(介绍重要目录):
a) Arch目录:存放处理器相关的代码。下设子目录,分别对应具体的CPU,每个子目录有boot,mm,以及kernel三个子目录,分别对应系统引导以及存储管理,和底层的系统调用函数

b) Include目录:内核所需要的大部分头文件目录。与平台无关的在include/linux子目录下,与平台相关的则放在include相应的子目录中。

c) fs目录:存放各种文件系统的实现代码。

d) init目录:init子目录包含核心的初始化代码(不是系统的引导代码)。其包含两个文件main.c和version.c,可以用来研究核心如何工作。

e) ipc目录:包含核心进程间的通信代码。

f) kernel目录:包含内核管理的核心代码。与硬件相关代码放在arch/*/kernel目录下。

g) mm目录:包含了所有的内存管理代码。与硬件相关的内存管理代码位于arch/*/mm目录下。

h) scripts目录:包含用于配置核心的脚本文件。

i) lib目录:包含了核心的库代码,与硬件相关的库代码被放在arch//lib/目录下

j)driver目录: 包含了驱动核心代码

3)filesystem

fire3308-linux源码:https://gitlab.com/TeeFirefly/rk3308-linux/-/tree/firefly
buildroot
1、根文件系统的编译目录
2、buildroot是Linux平台上一个构建嵌入式Linux系统的框架。整个Buildroot是由Makefile脚本和Kconfig配置文件构成的
目录结构:


```c
├── arch: 存放CPU架构相关的配置脚本,如arm/mips/x86,这些CPU相关的配置,在制作工具链时,编译uboot和kernel时很关键.
├── board
├── boot
├── CHANGES
├── Config.in
├── Config.in.legacy
├── configs: 放置开发板的一些配置参数.
├── COPYING
├── DEVELOPERS
├── dl: 存放下载的源代码及应用软件的压缩包. 
├── docs: 存放相关的参考文档. 
├── fs: 放各种文件系统的源代码. 
├── linux: 存放着Linux kernel的自动构建脚本. 
├── Makefile
├── Makefile.legacy
├── output: 是编译出来的输出文件夹. 
│   ├── build: 存放解压后的各种软件包编译完成后的现场.
│   ├── host: 存放着制作好的编译工具链,如gcc、arm-linux-gcc等工具.
│   ├── images: 存放着编译好的uboot.bin, zImage, rootfs等镜像文件,可烧写到板子里, 让linux系统跑起来.
│   ├── staging
│   └── target: 用来制作rootfs文件系统,里面放着Linux系统基本的目录结构,以及编译好的应用库和bin可执行文件. (buildroot根据用户配置把.ko .so .bin文件安装到对应的目录下去,根据用户的配置安装指定位置)
├── package:下面放着应用软件的配置文件,每个应用软件的配置文件有Config.in和soft_name.mk。
├── README
├── support
├── system
└── toolchain
2)Android SDK:    bootloader + kernel + android_system
1、android_system
fire3399-android源码:https://gitlab.com/TeeFirefly/firenow-oreo-rk3399/-/tree/firefly-rk3399/
|-- FFTools
|-- Makefile
|-- RKNPUTools
|-- RKTools
|-- art
|-- bionic
|-- bootable
|-- bootstrap.bash -> build/soong/bootstrap.bash
|-- build
|-- build.sh
|-- buildspec.mk
|-- compatibility
|-- cts
|-- dalvik
|-- developers
|-- development
|-- device
|-- external
|-- frameworks
|-- hardware
|-- kernel
|-- libcore
|-- libnativehelper
|-- mkimage.sh
|-- out
|-- packages
|-- parameter.txt
|-- pdk
|-- platform_testing
|-- prebuilts
|-- restore_patches.sh
|-- rkbin
|-- rknn-toolkit
|-- rkst
|-- rockdev
|-- sdk
|-- system
|-- test
|-- toolchain
|-- tools
|-- u-boot
-- vendor

4)编译烧写

1、fastboot工具(如TI-J6平台 三星S3C2440)
2、平台烧写工具(如瑞星微平台直接提供烧写工具)
在这里插入图片描述

linux烧写分区镜像

uboot 分区: 烧写 uboot 编译出来的 uboot.img。
trust 分区: 烧写 uboot 编译出来的 trust.img。
misc 分区: 烧写 misc.img。开机检测进入 recovery 模式。(可省略)
boot 分区: 烧写 kernel 编译出来的 boot.img 包含 kernel 和设备树信息。
recovery 分区: 烧写 recovery.img。(可省略)
backup 分区: 预留,暂时没有用。后续跟 android 一样作为 recovery 的 backup 使用。(可省略)
oem 分区: 给厂家使用,存放厂家的 app 或数据。只读。代替原来音箱的 data 分区。挂载在/oem 目录。(可省略)
rootfs 分区: 存放 buildroot 编出来的 rootfs.img,只读.
userdata 分 区 : 存放 app 临时生成的文件或者是给最终用户使用。可读写,挂载在 /userdata 目录下。(可省略)
Android烧写分区映像
编译的时候执行 ./mkimage.sh 会重新打包 boot.img 和 system.img, 并将其它相关的映像文件拷贝到目录 rockdev/Image-rk3399_firefly/ 中。以下列出一般固件用到的映像文件:
• boot.img :Android 的初始文件映像,负责初始化并加载 system 分区。
• kernel.img :内核映像。
• misc.img :misc 分区映像,负责启动模式切换和急救模式的参数传递。
• parameter.txt :emmc的分区信息
• recovery.img :急救模式映像。
• resource.img :资源映像,内含开机图片和内核的设备树信息。
• system.img :Android 的 system 分区映像,ext4 文件系统格式。
• trust.img :休眠唤醒相关的文件
• rk3399_loader_v1.08.106.bin :Loader文件
• uboot.img :uboot文件*

2、驱动移植开发

一:linux内核模块

1、什么是linux内核模块

在linux中,驱动程序是以内核模块的形式存在的,驱动程序是放在module中的。每个驱动程序都是一个个独立的module,一般情况下,各个module是无关的。在设计linux驱动的时候,首先需要设计一个module。

2、module编译好以后生成一个*.ko

module可以安装,可以卸载
#insmod led_drv.ko
#rmmod led_drv.ko
#lsmod ----->显示所有的使用#insmod安装的module
3、 设计linux的驱动程序,需要阅读linux源码
下载sourceinsight 阅读linux内核源码:或在gitlab上查看源码(见最上方网址)

二:linux一个简单的驱动的设计

1、编译成ko方式

//头文件来源于linux内核源码
#include <linux/kernel.h>
#include <linux/module.h>
//驱动的安装函数
static int __init S3C2440_led_init(void)
{
	printk(KERN_INFO "S3C2440_led_init\n");
	return 0;
}
//驱动的卸载函数
static void __exit S3C2440_led_exit(void)
{
	printk(KERN_INFO "S3C2440_led_exit\n");  
}
//module的入口和出口函数
#insmod led_drv.ko --->module_init()--->驱动程序的安装函数S3C2440_led_init()
module_init(S3C2440_led_init);//入口函数
#rmmod led_drv.ko --->module_exit()--->驱动程序的卸载函数S3C2440_led_exit()
module_exit(S3C2440_led_exit);//出口函数
//module的描述,不是必需的。#modinfo led_drv.ko
MODULE_AUTHOR("dexing@163.com");
MODULE_DESCRIPTION("led driver for S3C2440");
MODULE_LICENSE("GPL"); //符合GPL协议
MODULE_VERSION("V1.0");

2、嵌入在SDK中的驱动

驱动走向:
Devices Tree -> driver -->系统调用函数(open/close/write/read/ioctl…) --> app
例子一:如下图,简单的调用方式

在这里插入图片描述
在这里插入图片描述
例子二:led驱动(从DTS定义开始,到驱动)

3、介绍android SDK中的驱动存在方式

学习Linux驱动方面的知识之后,因为工作的需要,又接触Android 底层的调试。在接触Android底层之后,曾一度陷在其中,理不清Android底层与Linux驱动之间的联系。

一:Android底层与Linux驱动有什么不同呢?

之前一直在学的都是Linux驱动方面的知识,当接触Android底层时,一时转不过来,怎么Android底层就变得辣么复杂呢?什么是HAL?还有JNI?多了这两个货,一时转不过了,懵懵懂懂的学习了一段时间,感觉不对,总是连不成串。于是退出来,结合Linux系统捋一捋,终于有了发现,下面对比着来看。
1、通常所说的Android系统包括了Android源码和Linux内核两部分
2、而Linux系统也包含两部分 FileSystem 和 Linux内核两部分

二:什么是JNI?

这样对比着看起来一切就变得一目了然了,这样就可以把Android的源码部分想象成是Linux系统中的FileSystem部分。但是Android上层应用是使用java语言写的,不能直接调用C语言实现的系统接口,而Linux系统中可以用C语言调用系统接口来与内核进行通信,于是Android系统中就有了一个叫做JNI的概念,用实现java与C/C程序之间的信息交互。
由于Android系统和Linux内核(GPL)采用的开源协议不同,Android系统为了保护硬件厂商的知识产权,将驱动发杂的实现部分抽取发到Android源码中去实现,因此就有了HAL的概念了(暂时是这么理解的)。
NDK:作为C、C++和JAVA的桥梁,快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK

三:什么是HAL?

在这里插入图片描述

HAL:Hardware Abstract Layer 硬件抽象层,由于Linux Kernel需要遵循GPL开源协议,硬件厂商为了保护自己硬件方面的各项参数不被外泄,而一个设备的驱动程序包含了硬件的一些重要参数,所以驱动的开源势必会使硬件厂商蒙受损失,Google为了保护硬件厂商的利益,所以在Android系统中加入了HAL层,在HAL层中不必遵循GPL协议,所以代码可以封闭。 1、(AUDIO HAL 、CAMERA HAL 、graphic HAL)(例子:免驱摄像头) 2、
Android开源是不是意味着可以看到它所有的源代码?Android是一个开源系统,至少说是大部分开源的,但在HAL层里 很多没有遵循GPL协议,保护商家利益。
所以如果硬件驱动开源的写在Kernel里,Framework直接调用,而不愿意开源的就写在HAL层里,实现闭源。
那究竟HAL怎样实现闭源的呢?我们来画个简图.

在这里插入图片描述

4、前端声学相关

一、测试指标的作用以及影响的点
1、MIC密封性
定义:
MIC密封性,指待测设备MIC孔处通过物理密封隔绝外界噪声的能力,通常以物理密封MIC前后录到的音频平均振幅差表征,单位为dB。
测试目的:
MIC密封性会影响MIC接收声信号的传播路径,MIC密封不好会影响声源定位。
2、时延一致性
定义:
时延,指参考信号和MIC信号的时延差。时延稳定性即参考信号和MIC信号的时延差随时间变化保持稳定的能力。
测试目的:
判断MIC信号和参考信号之间测得信号的时间差是否随时间发生波动。
3、回声消除(AEC)
定义:
回声消除:待测设备在播放声音时,通过声学回路又被自身麦克风采集到的信号,在接收信号中减去该信号称为回声消除。
ERLE:反映的是原回声信号与剩余回声残差的比值,单位为dB。
测试目的:
测试MIC阵列消除自身设备扬声器输出信号的能力。
4、MIC相干一致性
定义:
衡量两个变量之间的相关程度叫做相干性。相干性衡量各MIC通道和REF通道之间的相关程度。
测试目的:
测试MIC信号和REF信号之间的相关程度,相关程度越小,说明MIC信号失真越大,噪音越多,AEC越差。
5、声源定位同步性
定义:
声源定位同步性本质即MIC信号间的同步性,指各MIC之间接收信号的时间差随时间变化的稳定性。
测试目的:
1.测试多个MIC之间接收同一信号的时间差是否稳定
2.测试角度信息是否准确
示例: 假设线阵180°方向播放音频,使用2mic设备,mic间距7cm
声速340m/s = 0.34m/毫秒 = 34cm /毫秒
移动7cm距离耗时= 7/34=0.205毫秒
6、信噪比
定义:
音源产生最大不失真声音信号强度与同时发出噪音强度之间的比率称为信号噪声比(SNR),单位为dB。
测试目的:
设备的信噪比越高表明它产生的噪声越少。信噪比越大,信号对算法的影响越小。
二、术语定义
1) 声压(sound pressure) p
瞬时压强与静压强之差。单位为帕斯卡(Pa)。
2) 声压级(sound pressure level) Lp
声压平方与基准声压平方之比,取以10为底的对数的10倍,用分贝(dB)表示。
(1.1)
式中,p0为基准值,p0=20uPa。
3) MIC(Microphone)
指麦克风,将声音信号转换为电信号。
4) 灵敏度(Sensitivity)
单通道的输出电压与无干扰时校准位置处声压的比值为灵敏度。
5) 频率响应(Frequency Response)
单通道灵敏度级随频率的变化关系曲线为频率响应,标识为FR,单位为dB。
灵敏度以10为底的对数乘以20为灵敏度级(Sensitivity Level),标识为S,单位dB。
(1.2)
式中,V指采集信号输出电压有效值,P指校准位置处声压有效值。
6) MIC同步性
指各个MIC通道间接收到同一信号的时间差的稳定性。
7) 时延 (Delay)
任意两个通道间接收到同一信号的时间差,单位为采样点数,1秒有16000个采样点。
8) 参考信号时延稳定性
参考信号和MIC信号的时延差随时间变化保持稳定的能力。
9) 总谐波失真(THD)
输出电信号中谐波余量的有效值与谐波和基频的总的比值为总谐波失真。
10) 截幅
因信号波形的幅度太大,而超出系统的线性范围的现象。
11) 回声消除(AEC)
待测设备在播放声音时,通过声学回路又被自身麦克风采集到的信号,在接收信号中减去该信号称为回声消除。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漂泊在海上的星星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值