MTK Sensor 分析
MTK sensor 基本架构
MTK框架可以分为两部分,AP和SCP。
AP是主芯片,SCP是协处理器,他们一起工作来处理sensor数据。
SCP 是用来处理sensor和audio相关功能和其他客制化需求的一个协处理理器,MTK SCP选择freeRTOS作为操作系统,CHRE是处理传感器相关操作的专门任务。
kernel层负责汇总处理sensor传输上来的数据,以及处理应用层传递下来的指令。
hal层是硬件抽象层,具有硬件供应商实现的标准接口,允许Android不了解低级别的驱动程序实现。sensor service通过动态链接的方式加载hal层模块。经过动态链接,service可以调用hal层的函数,方便将控制传递,也可以从hal层获取数据。这样使用hal就可以在不影响或修改更高级别系统的情况下实现功能。
framework层中sensor service 能创建实例对象,并增加到service manager中,同时可以从驱动中获取原始数据并发送到客户端。
应用层中的应用可以发送调用sensor的指令到下层,同时也可以获得下层传来的传感器数据并进行分析处理。
整个sensor体系中包括:应用层、framework层、jni、hal层、kernel层、SCP/CHRE。
SCP 详解
路径:vendor/vendor/mediatek/proprietary/tinysys/freertos/source/
SCP是处理客制化需求的协处理器。上图是SCP的文件目录,其存放内容如下:
-
build:makefile和编译器标志、选项
-
drivers/CM4_A:针对不同硬件的专有驱动程序代码
-
drivers/common:通用驱动程序代码
-
kernel:FreeRTOS原始代码和和内核服务
-
middleware:各种库
-
project:各种项目的代码
-
tools:各种辅助工具
SCP 代码大小限制机制
memoryReport.py是一个用于在构建时限制代码大小的脚本。
如果代码大小超过了设置,它将会导致构建错误,以警告编码器。
如果你认为代码确实占据了你所看到的大小,你可以修改Setting.ini文件。
如上图,如果代码量确实超出大小可以调大Sensor的限制大小。
位置:
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/tools/memoryReport.py
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/$PLATFORM/platform/Setting.ini
CHRE详解
CHRE是一个事件驱动的体系结构,可以被视作一个操作系统。
-
如上图所示,黄色的部分是事件队列。CHRE只有一个短时间的循环来处理事件队列中的头事件。如果以前的调用尚未完成,则CHRE无法调用队列中的一个任务。因此没有优先级的概念,当前事件队列处理只能被interrupt 中断。
-
默认情况下,CHRE在事件队列中最多支持512个事件。
-
CHRE的目的是实时的和轻量级的,因此在事件队列中调用的所有任务都必须快速运行。
-
CHRE中的驱动程序实现被称为nano hub应用程序。
加载驱动
overlay机制详解
- 一种类型的传感器可能来自两个不同的供应商。
- 如果将两个驱动程序放在SCP SRAM中进行自动检测,它会消耗大量SRAM。
- 因此,MTK解决方案将在DRAM中找到两个驱动程序,并在SCP启动时加载一个驱动程序。
overlay加载流程:
- 内存将SCP loader部分的代码从DRAM复制到SRAM中,同时SCP启动
- SCP loader将Tinysys相同的代码从DRAM复制到SRAM,操作系统启动,同时传感器驱动进行初始化
- OverlayRemap将传感器驱动1复制到SRAM,hw进行验证(主要是sensor的id),如果失败,就复制驱动2,如此往复,如果成功,就remap下一个传感器类型
**一个section表示一个传感器类型(如加速度传感器类型),一个类型中可能有很多个驱动
sensor 加载顺序
不同类型的sensor加载顺序是否可以改变?
上图的一段枚举来自
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/drivers/CM4_A/$PLATFORM/overlay/inc/
目录下的文件mtk_overlay_init.h,它被overlay.c文件引用。
这段枚举,定义了每个sensor类型在overlay时的顺序编号。
上图的代码来自mtk_overlay_init.c文件,里面设置overlay table时使用的switch判断条件就是section的id。
在switch判断完成之后,所有sensor类型的虚拟地址vma,大小size等参数会被复制到table中,之后在进行加载时也是以section的id为判断依据。
理论上不同sensor类型的加载顺序可以改变
但是改变sensor加载顺序需要对后续所有相关代码的id顺序进行修改,修改会非常麻烦,容易出现bug。
所以一般情况下不改变sensor的加载顺序。
加载驱动流程
下面加载驱动的流程都是以挂载在SCP侧的驱动为例:
想要加载一个新的驱动,需要把驱动添加到如下目录中:
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/
P
L
A
T
F
O
R
M
/
PLATFORM/
PLATFORM/PROJECT/cust/
不同的目录是负责加载不同的传感器的:
- accGyro加载加速度、陀螺仪传感器
- alsps负责加载光距感传感器
- barometer加载气压计传感器
- magnetometer加载地磁传感器
- overlay负责加载sensor overlay
添加客制化sensor信息
以加速度传感器为例,将需要添加的传感器添加到文件cust_accGyro.c中
文件路径:vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/ P L A T F O R M / PLATFORM/ PLATFORM/PROJECT/cust/accGyro/
路径中包含的 P L A T F O R M 是指 M T K S O C 平台代码, PLATFORM是指MTK SOC平台代码, PLATFORM是指MTKSOC平台代码,PROJECT是项目代码
配置包含sensor的方向以及i2c地址等等,需要根据实际情况进行修改
补充:对于.direction参数,在目录**/vendor/vendor/mediatek/proprietary/tinysys/freertos/source/middleware/contexthub/**下的hwsen.c文件中有详细体现
参数0-7对应map[]中的8个元素,前面的参数±1表示取该轴的哪个方向为正方向,后面的参数0、1、2分别表示xyz轴,如map[1]表示芯片的正方向为x,-y,z
启用overlay功能,添加sensor编译宏
目录:
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/ P L A T F O R M / PLATFORM/ PLATFORM/PROJECT/
在文件ProjectConfig.mk中添加
将传感器驱动添加到系统编译中
目录:
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/$PLATFORM//platform/feature_config/
在文件chre.mk中添加
判断条件由上一步的编译宏控制
将传感器驱动添加到overlayremap中
目录:
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/ P L A T F O R M / PLATFORM/ PLATFORM/PROJECT/cust/overlay.c
在链接脚本中添加对象,添加到对应传感器区域
如加速度传感器添加到ACC中:
目录:
vendor/vendor/mediatek/proprietary/tinysys/freertos/source/project/CM4_A/ P L A T F O R M / PLATFORM/ PLATFORM/PROJECT/inc/overlay_sensor.c
Log分析
追log可以发现,加载流程就是先发现了一个驱动,然后启动overlay,获取它的信息,之后会将其从dram加载到sram中。overlay table 会获得它的一些基本信息(虚拟地址,大小等等),acc map 会获得sensor的布局情况(前面提到的direction)。
在所有驱动都加载完成之后,就会等待sensor的启动。