King3399(ubuntu文件系统)iic(i2c)功能测试
0 引言
前面两篇博文简要介绍了板子上uart部分的内容,但在驱动开发时,我们遇到的外设更多的是以i2c或spi进行通信,本文将对king3399的i2c进行测试并对硬件电路、设备树与驱动程序进行分析
如果使用的i2c设备不是mma8452,建议先看看文末枚举中的i2c设备类型,本文可扩展枚举的所有i2c设备
1 i2c接口硬件分析
通过板子电路原理图可以看到板子底板使用了三组i2c接口,这三组接口都已挂载了设备,设备分配如下表所示
i2c | num | chip | note |
---|---|---|---|
i2c1 | U14 | ALC5651 | Audio |
J21 | MIPI | Camera | |
J22 | MIPI | Camera | |
J106 | Pin | Pin | |
i2c3 | J10 | HDMI | Video |
i2c4 | U12 | MMA8452 | Accelerometer |
J33 | MIPI | LCD Video | |
J106 | Pin | Pin | |
U23 | FUSB302MPX | Battery Charge |
由于本人手边没有合适的设备,因此这里以板载加速度传感器(U12 MMA8452)为例进行测试,该传感器挂载在i2c4上,需要注意的是由于使用的是i2c协议通信,因此需要在i2c4的scl和sda引脚上分别接一个上拉电阻,参考MMA8452数据手册,上拉电阻使用4.7kΩ,但在分析板子的原理图时,比较疑惑,由于没有核心板的原理图,只有底板的原理图,在底板的原理图中,i2c4两只引脚网络皆没有连接上拉电阻,i2c1与i2c3网络在底板上也没有连接上拉电阻,猜测i2c的上拉电阻应该都在核心板上(另外,如果注意核心板引出的i2c网络可以看到,其网络名称定义为“GPIO1_B3/I2C4_SDA_u”和“GPIO1_B4/I2C4_SCL_u”,这里的尾缀“u”应该是“up”的缩写,意思应该是上拉,当然这仅仅是我个人猜测),这个需要注意一下,当使用板子引出的i2c端口与我们手中的其他模块进行交互时,就不再需要连接上拉电阻
2 MMA8452设备树分析
打开设备树文件可以看到,i2c4节点下没有设备MMA8452的子节点,(注:此处使用的设备树文件由板子镜像逆向而来,具体来源可参考脚注【a】,板子烧录镜像文件为update-rk3399-king-rk3399-ubuntu-mipi-7-1024-600-20240922-165231.img,该镜像文件由本人编译,具体编译过程可参考脚注【b】)
i2c@ff3d0000 {pinctrl-names = "default";#address-cells = <0x01>;pinctrl-0 = <0x94>;clock-names = "i2c\0pclk";assigned-clocks = <0x86 0x0a>;assigned-clock-rates = <0xbebc200>;interrupts = <0x00 0x38 0x04 0x00>;clocks = <0x86 0x0a 0x86 0x1c>;#size-cells = <0x00>;compatible = "rockchip,rk3399-i2c";status = "okay";reg = <0x00 0xff3d0000 0x00 0x1000>;phandle = <0x130>;// 触摸屏节点goodix_ts@5d {gtp_resolution_x = <0x400>;gtp_overturn_y = <0x00>;goodix_rst_gpio = <0x41 0x04 0x01>;goodix,cfg-group0 = [41 00 04 ...省略... 00 3b 01];gtp_int_tarigger = <0x01>;goodix_irq_gpio = <0x41 0x16 0x01>;goodix,cfg-group5 = [ff 00 04 ...省略... 00 6a 01];gtp_resolution_y = <0x258>;gtp_touch_wakeup = <0x01>;compatible = "goodix,gt9xx";gtp_change_x2y = <0x00>;gtp_overturn_x = <0x00>;reg = <0x5d>;gtp_send_cfg = <0x01>;};// usb充电节点fusb302@22 {pinctrl-names = "default";pinctrl-0 = <0x95>;interrupts = <0x02 0x08>;vbus-supply = <0x96>;interrupt-parent = <0x41>;compatible = "fcs,fusb302";status = "okay";reg = <0x22>;phandle = <0x131>;...省略... };};
打开../03-硬件文档/King3399底板-硬件规格书_20180105.pdf
文档可以看到“重力传感器”仅支持Android系统(如上图所示),而本人所编译的系统为ubuntu,因此设备树中无该设备节点(ubuntu一般用于台式设备,android用于便携手持设备,后者需要判断设备姿态,因此需要启用该传感器)
徒手搓一个设备树节点于我个人而言是有难度的,既然Android系统支持该设备,那么我们就可以将Android系统中的该设备点节拷贝下来,大致思路是从板子的官方Android镜像中逆向完整的设备树文件,从该逆向设备树中查找到需要的节点,步骤如下:
-
下载官方Android镜像文件,这里使用的是
update_king_rp3399_android7.1_hdmi_20200714_171241.img
,(由于本人手中只有一个hdmi接口的显示器,因此选择该镜像,若手中有配套的LCD则可以选择对应的镜像文件) -
将上述镜像文件烧录到板子中,烧录过程可参考脚注【b】
-
将板子设置为“开发者模式”,与手机进入该模式相同,具体操作如下:
-
板子上电后进入主界面,将光标放到底部状态栏
-
光标长按底部状态栏并向上拖拽,此时界面会切换到应用界面
-
找到“设置”应用,点击进入
-
找到“关于平板电脑”选项,点击进入
-
找到“版本号”选项,连续点击多次,此时界面会提示“开发者模式”选项
-
退回到上一层,找到“开发者选项”选项,点击进入并勾选“USB调试”选项
-
回到应用界面,找到“荣品功能测试”应用,点击进入,找到“重力传感器测试”项,此时翻动板子将看到xyz轴数值的变化,该步骤可验证板子上的加速度传感器是否正常工作
-
-
在电脑上安装ADB,安装过程及初步使用可参考脚注【c】
-
将板子与电脑连接,此时电脑会自动识别到板子,在电脑的“Device Manager”可以看到已连接的“Android Device”
-
获取Android设备fdt文件,具体操作如下:(下边的“ & rem ”是cmd的单行注释符,可理解为C语言中的“//”),win + r 并输入 cmd打开windows命令行窗口
- adb version & rem 查看adb版本
- adb devices & rem 查看连接的设备,将板子与电脑使用usb线连接后将会列如出已连接的设备
- adb root & rem 提升操作权限
- adb pull /sys/firmware/fdt & rem 从板子中pull出设备树文件,文件默认保存在电脑 C:\Users\username\fdt
-
将fdt文件反编译为dts文件,参考脚注【d】,具体操作如下:
- 将fdt文件从windows系统中复制到ubuntu系统中
- 在ubuntu 系统中安装反编译dtc工具,“apt install device-tree-compiler”
- 将fdt反编译成dts,在fdt目录执行 “dtc -I dtb -O dts fdt -o fdt.dts”
- 完成上述操作将在当前目录下生成fdt.dts文件,打开该文件,搜索“MMA8452”,可以看到如下节点:
i2c@ff3d0000 {compatible = "rockchip,rk3399-i2c";reg = <0x0 0xff3d0000 0x0 0x1000>;clocks = <0x30 0xa 0x30 0x1c>;clock-names = "i2c", "pclk";interrupts = <0x0 0x38 0x4 0x0>;pinctrl-names = "default";pinctrl-0 = <0x80>;#address-cells = <0x1>;#size-cells = <0x0>;status = "okay";i2c-scl-rising-time-ns = <0x258>;i2c-scl-falling-time-ns = <0x14>;max17047@36 {status = "okay";compatible = "maxim,max17047";reg = <0x36>;charge-detect-gpio = <0x34 0x9 0x0>;battery-full-detect-gpio = <0x34 0xa 0x0>;};sensor@1d {status = "okay";compatible = "gs_mma8452";pinctrl-names = "default";pinctrl-0 = <0x81>;reg = <0x1d>;type = <0x2>;irq-gpio = <0x34 0x17 0x2>;irq_enable = <0x1>;poll_delay_ms = <0x1e>;layout = <0x4>;};fusb30x@22 {compatible = "fairchild,fusb302";reg = <0x22>;pinctrl-names = "default";pinctrl-0 = <0x82>;int-n-gpios = <0x34 0x2 0x0>;vbus-5v-gpios = <0x83 0x1a 0x0>;status = "okay";linux,phandle = <0x27>;phandle = <0x27>;};};
完成上述步骤后就是分析MMA8452节点,在sdk中全局搜索MMA8452(grep -i -r -n "mma8452" /home/username/sdk
)可以看到如下两个相关文件:
../sdk/kernel/Documentation/devicetree/bindings/iio/accel/mma8452.txt
../sdk/kernel/Documentation/devicetree/bindings/input/sensors/rk_sensor.txt
前者为Freescale官方对MMA8452节点的描述,后者为Rockchip官方对MMA8452节点的描述,通过两者综合分析可对逆向的设备树作如下解析:
sensor@1d {// 设备状态,正常启用,Android系统支持重力检测status = "okay";// 设备兼容,用于查找设备可用驱动程序compatible = "gs_mma8452";// 引脚控制// 若 pinctrl-names 的名字被设置为 default 那么该设备的驱动加载后,// 就会将功能脚按照 pinctrl-0 的配置设置,参考脚注【f】pinctrl-names = "default";// 引脚控制,表示MMA8452用到的引脚// 示例:rockchip,pins=<1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;// 原理图中MMA8452使用的引脚为GPIO1_C7(scl、sda引脚属于i2c4总线节点)// 打开从Android逆向生成的fdt.dts,查找mma8452,// 可以看到节点mma8452-irq-gpio的phandle属性值为0x81// 其配置为 rockchip,pins = <0x1 0x17 0x0 0xbf>;// 其中,0x1表示RK_GPIO1,// 该宏定义在../sdk/u-boot/include/dt-bindings/pinctrl/rockchip.h// 0x17表示C7这只引脚,// 打开..sdk/kernel/include/dt-bindings/pinctrl/rockchip.h可以看到// #define RK_PC7 23,23转为十六进制为 0x17// 0x0表示RK_FUNC_GPIO,// 该宏定义在../sdk/kernel/include/dt-bindings/pinctrl/rockchip.h// 0xbf表示pcfg-pull-up,// Android逆向生成的fdt.dts中pcfg-pull-up的phandle值为0xbf// pcfg-pull-up的具体意义可查看../sdk/kernel/drivers/pinctrl/pinconf-generic.c 与// ../sdk/kernel/include/linux/pinctrl/pinconf-generic.hpinctrl-0 = <0x81>;// 设备地址,i2c通信时使用的地址// MMA8452芯片手册中提到可支持的i2c地址为 0011100 或 0011101// 当芯片引脚SA0 (pin 7)为高电平时,i2c地址为 0011101 (0x1d)// 当芯片引脚SA0 (pin 7)为低电平时,i2c地址为 0011100 (0x1c)// 原理图中,引脚SA0 (pin 7)为高电平(VCCA1V8_CODEC),// 因此MMA8452的i2c地址为 0011101 (0x1d)reg = <0x1d>;// 设备类型,0x2表示SENSOR_TYPE_ACCEL,加速度传感器// 该宏定义在../sdk/kernel/Documentation/devicetree/bindings/input/sensors/rk_sensor.txt type = <0x2>;// 中断引脚,用于指定设备的中断引脚// 示例:irq-gpio = <&gpio8 GPIO_A0 IRQ_TYPE_EDGE_FALLING>;// 原理图中MMA8452的中断引脚为GPIO1_C7// 其中,0x34表示GPIO1,打开从Android逆向生成的fdt.dts,查找gpio1,// 可以看到该节点的phandle属性值为0x34,// 0x17表示C7这支引脚,// 打开..sdk/kernel/include/dt-bindings/pinctrl/rockchip.h可以看到// #define RK_PC7 23,23转为十六进制为0x17,// 0x2表示下降沿触发// 打开../sdk/u-boot/include/dt-bindings/interrupt-controller/irq.h可以看到// #define IRQ_TYPE_EDGE_FALLING 2irq-gpio = <0x34 0x17 0x2>;// 中断使能,用于指定设备的中断是否使能// 0x1表示中断(irq),0x0表示上拉(pull mode)irq_enable = <0x1>;// 轮询延迟,用于指定设备的轮询延迟时间,单位为毫秒// 部分设备数据处理较复杂,采样-滤波-平滑等,为保证数据的可靠性// 需要一个最小处理周期,相关示例可参考脚注【e】poll_delay_ms = <0x1e>;// 布局,用于指定设备的参考坐标,这个变量名用的不好,让人不明所以// 通俗的讲就是类似于左手坐标系还是右手坐标系,// 当然实际可取数值为1~9,有9种,定义的比较复杂,下文会给出图示// 打开../sdk/kernel/drivers/input/sensors/sensor-dev.c// 可以看到pdata->layout共有8种情况,默认为0x01layout = <0x4>;
};
在对板子的重力传感器测试时,其设备树中“layout = <0x4>”,结果如下所示
可将程序(…/sdk/kernel/drivers/input/sensors/sensor-dev.c)中orientation数组的9个元素分为三组,分别构成矢量a(0,1,0),b(-1,0,0),c(0,0,1),(注:由于本人板子的z轴数值有问题,不保证此处分析准确性)
case 4:pdata->orientation[0] = 0;pdata->orientation[1] = 1;pdata->orientation[2] = 0;pdata->orientation[3] = -1;pdata->orientation[4] = 0;pdata->orientation[5] = 0;pdata->orientation[6] = 0;pdata->orientation[7] = 0;pdata->orientation[8] = 1;
分析完MMA8452在Android系统中的节点后,就可以尝试将该节点移植到板子的设备树中,在king-rk3399.dts同层目录下(…/sdk/kernel/arch/arm64/boot/dts/rockchip/rk3399)创建mma8452.dtsi子节点文件,添加节点配置如下,最后记得在king-rk3399.dts中引用该子节点文件(#include “mma8452.dtsi”),注:保险起见,在修改king-rk3399.dts前,记得先备份该文件
&i2c4 {status = "okay";mma8452@1d {status = "okay";compatible = "gs_mma8452";pinctrl-names = "default";pinctrl-0 = <&mma8452_int>;reg = <0x1d>;type = <0x2>;irq-gpio = <0x1 RK_PC7 IRQ_TYPE_EDGE_FALLING>;irq_enable = <0x1>;poll_delay_ms = <0x1e>;layout = <0x4>;};
};&pinctrl {g_sensor {mma8452_int:mma8452_int {// rockchip,pins = <0x1 0x17 0x0 0xbf>;rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>;};};
};
保存后在…/sdk/目录下执行./build.sh kernel,完成后将会在…/sdk/kernel/arch/arm64/boot/dts/rockchip/rk3399目录下更新king-rk3399.dtb文件并且还会在/home/username/ws/sdk/rockdev目录下更新boot.img,此时可利用dtc -I dtb -O dts king-rk3399.dtb -o king-rk3399-dtc.dts
将更新的dtb文件反编译为dts查看是否有mma8452的节点,没有问题再将boot.img(其他文件若无改动可只单独烧录boot.img)烧录到king3399并重启
3 驱动分析
打开\02-软件文档\荣品文档\源码文件路径.xlsx可以看到,MMA8452的驱动源码位于:
…/kernel/drivers/input/sensors/accel/mma8452.c
这里主要涉及两个文件:sensor-dev.c 与 mma8452.c,此处以mma8452为切入点,将mma8452的加载流程进入如下梳理,由于SDK适配了很多类型的设备,因此文件的内容很多,框架稍显复杂,但都是常规操作,建议花点时间把整个加载处理流程过一遍,不然后边移植时无从入手(下述表格的阅读顺序为从上到下依次递进,从下依次到上也可)
function | note |
---|---|
sdk/kernel/drivers/input/sensors/sensor-dev.c | |
EXPORT_SYMBOL(sensor_register_device); | 导出符号(函数或变量)的宏,使得这些符号可以被其他内核模块使用 |
int sensor_register_device | 判断传入的设备是否支持加载(存在且支持),只有在/sdk/kernel/include/linux/sensor-dev.h(enum sensor_id)中的设备才支持 |
sensor_probe(client, devid); | 从设备树中获取传感器(设备)硬件参数 |
static int sensor_probe | |
result = sensor_chip_init(sensor->client); | |
static int sensor_chip_init | 内核启动时,I2C 子系统会扫描所有已注册的 I2C 设备与驱动。内核会自动把匹配到的 I2C 设备信息封装到 struct i2c_client 结构体中,将设备 ID 信息封装到 const struct i2c_device_id 结构体里,然后把这两个结构体作为参数传递给 gsensor_mma8452_probe 函数。 而在上一步中从设备树中也读取了相应的参数,只有这两部分参数相吻合才可初始化 |
result = sensor_initial(sensor->client); | |
static int sensor_initial | 初始化 |
result = sensor->ops->init(client); | init()未找到具体的实现方式 |
result = input_register_device(sensor->input_dev); | /sdk/kernel/drivers/input/input.c |
result = sensor_irq_init(sensor->client); | |
static int sensor_irq_init | 配置中断(中断引脚)、触发时间 |
irq = gpio_to_irq(client->irq); | gpio_to_irq()未找到具体的实现方式 |
result = devm_request_threaded_irq | devm_request_threaded_irq()未找到具体的实现方式 /sdk/kernel/include/linux/interrupt.h /sdk/kernel/kernel/irq/devres.c |
result = gpio_request(client->irq, sensor->i2c_id->name); | /sdk/kernel/drivers/gpio/gpiolib-legacy.c |
result = sensor_misc_device_register(sensor, type); | |
static int sensor_misc_device_register | 根据类型(温度、光照或加速度等)指定设备操作函数(open、release) |
sensor->fops.unlocked_ioctl = gsensor_dev_ioctl; | |
static long gsensor_dev_ioctl | |
copy_from_user(&rate, argp, sizeof(rate) | 设定采样频率 |
sensor_enable(sensor, SENSOR_ON); | |
static int sensor_enable | 启停设备 |
result = sensor_reset_rate(client, rate); | |
static int sensor_reset_rate | 设定采样频率 |
memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); | 获取数据 |
sensor_calibration_data_read(&sensor_cali_data) | |
static int sensor_calibration_data_read | 获取数据偏移(标定、补偿) |
copy_to_user(argp, &axis, sizeof(axis) | 获取数据 |
sensor->fops.open = gsensor_dev_open; | |
static int gsensor_dev_open | 无操作(合并到gsensor_dev_ioctl) |
sensor->fops.release = gsensor_dev_release; | |
static int gsensor_dev_release | 无操作(合并到gsensor_dev_ioctl) |
/sdk/kernel/drivers/input/sensors/accel/mma8452.c | |
module_i2c_driver(gsensor_mma8452_driver); | 加载、卸载模块 |
static struct i2c_driver gsensor_mma8452_driver | i2c设备操作函数 |
.probe = gsensor_mma8452_probe, | |
static int gsensor_mma8452_probe | 加载模块 |
return sensor_register_device(client | |
gsensor_mma8452_ops | |
static struct sensor_operate gsensor_mma8452_ops | mma8452操作函数 |
.active = sensor_active, | |
static int sensor_active | 激活mma8452 |
4 驱动移植
如果将上边的加载处理流程过一遍会发现有很多步骤都可以简化,毕竟如此一套框架中适配的设备我们能够遇到的也就寥寥几个,况且框架也没有说明文档,用起来也并不称手,这里参考脚注【g】进行驱动移植,框不框架的都不是重点,得先让设备跑起来才是王道
移植前建议将mma8452手册通读一遍,里边有不少需要注意的地方,同时这个设备也有不少有用的功能值得开发与研究
移植的具体过程不赘述,逻辑都比较简单,而且本人已在程序中添加了大量注释
将文末仓库中的mma8452_module文件夹复制到虚拟机的home目录下,修改Makefile内的KERNEL_DIR 与 CROSS_COMPILE
路径,这两个路径本系列博文之前有提到,可自行查看,修改完后在mma8452_module文件夹内执行 make,稍等片刻后将生成的mma8452_test.ko与mma8452_app传到板子的home目录下
scp mma8452_test.ko mma8452_app username@192.168.aaa.bbb:/home/username/xxx
在ubuntu中打开串口并开启颜色显示(下文会对此处做相关解释)
sudo minicom -s -c on
在板子上将路径切换到上述文件上传路径,并加载模块
sudo /sbin/insmod mma8452_test.ko
在板子上执行应用程序,该程序将读取1000次数据,周期为100ms
sudo ./mma8452_app
此时将会在板子的终端打印AX、AY、AZ三组数据,同时在ubuntu的串口中打印相关日志
此时将会在ubuntu的minicom串口中打印如下信息
到此,设备的驱动就算完成了,当然这个驱动程序不管是驱动部分还是应用部分都略显粗糙,感兴趣的可以结合mma8452芯片手册与SDK的i2c驱动框架进行优化、完善与扩展,毕竟单纯的跑通没有任何实际意义
5 一些有趣的小东西
-
vscode中的跳转
在编辑软件中,我们会经常需要跳转到指定的函数、变量、宏定义等,在vscode中,我们可以使用快捷键Ctrl+鼠标左键进行跳转,同时也可以使用快捷键Alt+方向键反向跳转,这在阅读源码时非常有用,在进行驱动模块开发时可能会涉及到整个kernel下的driver与include下的文件,但是当我们把mma8452的相关文件都打开时,vscode并不能跳转到指定位置(由于本人的电脑性能一般,在开发驱动模块时都是在windows下,编辑完上传到ubuntu中),如果只是单纯地通过在工作空间中进行全局搜索查找效率会非常低,为解决这个问题可以进行如下操作,参考脚注【h】
-
下载并双击 mingw-get-setup0.6.2.exe,勾选mingw32-gcc-bin 与 mingw32-gcc-g+±bin
-
将MinGW添加到环境变量中(如:D:\MinGW\bin 添加到环境变量)
-
在F:\king3399\driver_source\路径下创建工程文件夹modutle_test,将本文提到的mma8452.c、mma8452.h等文件复制到module_test下,把module_test整个文件夹拖到vscode中,在vscode 中 ctrl + shift + P打开 c_cpp_properties.json,添加如下配置
{"configurations": [{"name": "Win32","includePath": ["${workspaceFolder}/**","F:\\king3399\\driver_source\\" // ---添加相应目录---],"defines": ["_DEBUG","UNICODE","_UNICODE"]}],"version": 4 }
其中,在F:\king3399\driver_source\路径下包含linux与driver两个文件夹(也就是module_test同级目录下),这里是直接将ubuntu中的这两个文件夹下载到windows下
linux来源于…/sdk/kernel/include/linux
driver来源于…/sdk/kernel/driver
-
重启电脑,再次vscode打开工程,会报错,但可以正常引用不同目录下的文件并跳转
引用示例如下:
#include <./linux/interrupt.h> #include <./linux/i2c.h> #include <./linux/slab.h> #include <./linux/irq.h> #include <./linux/miscdevice.h> #include <./linux/gpio.h> #include <./linux/uaccess.h> #include <asm/atomic.h> #include <./linux/delay.h> #include <./linux/input.h> #include <linux/workqueue.h> #include <linux/freezer.h> #include <linux/of_gpio.h> #ifdef CONFIG_HAS_EARLYSUSPEND #include <linux/earlysuspend.h> #endif // #include <linux/sensor-dev.h> #include "./linux/sensor-dev.h"
-
-
printk无法显示
参考脚注【i】,出现这个原因是本系列的前一篇文章《King3399(ubuntu文件系统)KGDB配置与功能测试》中修改了…/sdk/kernel/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi中的bootargs,按照脚注中的解释就是“为什么我用telnet不行,而用tty终端就行?答:内核的printk把信息打到哪里去呢?这是在内核的命令行参数console=ttyXXX里指定死了,比如console=ttySAC0表示printk的信息输出到串口0”,解决这个问题的方法有两种,第一是将bootargs修改回来,由于本人需要经常使用kgdb调试,故没有修改,第二就是用串口模块将板子与虚拟机连接,并在虚拟机中打开minicom
-
debug.h优雅地打印
上一篇博文中留下了一个问题“调试卡在 printk”,当时的解决办法就是在模块中不使用printk,但实际我们在驱动模块开发时无法避免printk,在对mma8452的驱动源码进行移植时本人发现在mma8452.c中有一个“DBG(“%s:sensor int status :0x%x\n”,–func–,value);”,这玩意必然是printk套了个壳,但在源码中没有找到具体的实现方法,这样做的目的有二:第一,通过开关控制printk,在调试阶段启用,程序发布后禁用,提升性能,第二,有没有可能官方的SDK在使用kgdb调试时确实会卡在printk?
debug.h文件内容很简单但确很实用,通过DEBUG_LEVEL、DEBUG_PATH与DEBUG_COLOR三个开关控制printk的显示方式,文件中有详细注释与使用方法,这里不再赘述细节,下图为实现效果(其中DEBUG_LEVEL为2,DEBUG_PATH为0,DEBUG_COLOR为1),注:须以
sudo minicom -s -c on
打开minicom -
mma8452关键字
回想写这篇博文的初衷是什么,单纯驱动mma8452?学习i2c驱动框架?貌似都不太准确,应该是通过mma8452学习i2c驱动框架,并积累与分享开发经验,毕竟真正使用mma8452这颗芯片的能有几人,能看到这篇博文有又有几人,以我个人举例,如果使用的芯片不是mma8452那么大概率不会去细读这篇博文
在移植mma8452时在sensor-dev.h中发现一个很有用的枚举sensor_id,枚举中有大量设备型号,
如果你有幸翻到本文 又 没有合适的开发例程 且 设备型号在下述枚举中
,不妨看看文中的内容(其实主要也是怕自己以后遇到这些玩意不会搞)enum sensor_id {ID_INVALID = 0,ANGLE_ID_ALL,ANGLE_ID_KXTIK,ANGLE_ID_LIS3DH,ACCEL_ID_ALL,ACCEL_ID_LIS331,ACCEL_ID_LSM303DLX,ACCEL_ID_LIS3DH,ACCEL_ID_KXSD9,ACCEL_ID_KXTF9,ACCEL_ID_KXTIK,ACCEL_ID_KXTJ9,ACCEL_ID_BMA150,ACCEL_ID_BMA222,ACCEL_ID_BMA250,ACCEL_ID_ADXL34X,ACCEL_ID_MMA8450,ACCEL_ID_MMA845X,ACCEL_ID_MMA7660,ACCEL_ID_SC7660,ACCEL_ID_SC7A20,ACCEL_ID_SC7A30,ACCEL_ID_MPU6050,ACCEL_ID_MXC6225,ACCEL_ID_MXC6655XA,ACCEL_ID_DMARD10,ACCEL_ID_LSM303D,ACCEL_ID_MC3230,ACCEL_ID_MPU6880,ACCEL_ID_MPU6500,ACCEL_ID_LSM330,ACCEL_ID_BMA2XX,ACCEL_ID_STK8BAXX,ACCEL_ID_MIR3DA,ACCEL_ID_ICM2060X,ACCEL_ID_DA215S,ACCEL_ID_DA228E,ACCEL_ID_IAM20680,ACCEL_ID_ICM4260X,COMPASS_ID_ALL,COMPASS_ID_AK8975,COMPASS_ID_AK8963,COMPASS_ID_AK09911,COMPASS_ID_AK8972,COMPASS_ID_AMI30X,COMPASS_ID_AMI306,COMPASS_ID_YAS529,COMPASS_ID_YAS530,COMPASS_ID_HMC5883,COMPASS_ID_LSM303DLH,COMPASS_ID_LSM303DLM,COMPASS_ID_MMC314X,COMPASS_ID_HSCDTD002B,COMPASS_ID_HSCDTD004A,COMPASS_ID_AK09918,GYRO_ID_ALL,GYRO_ID_L3G4200D,GYRO_ID_L3G20D,GYRO_ID_EWTSA,GYRO_ID_K3G,GYRO_ID_MPU6500,GYRO_ID_MPU6880,GYRO_ID_LSM330,GYRO_ID_ICM2060X,GYRO_ID_IAM20680,GYRO_ID_ICM4260X,LIGHT_ID_ALL,LIGHT_ID_CM3217,LIGHT_ID_CM3218,LIGHT_ID_CM3232,LIGHT_ID_AL3006,LIGHT_ID_STK3171,LIGHT_ID_ISL29023,LIGHT_ID_AP321XX,LIGHT_ID_PHOTORESISTOR,LIGHT_ID_US5152,LIGHT_ID_STK3332,LIGHT_ID_STK3410,LIGHT_ID_EM3071X,LIGHT_ID_UCS14620,PROXIMITY_ID_ALL,PROXIMITY_ID_AL3006,PROXIMITY_ID_STK3171,PROXIMITY_ID_AP321XX,PROXIMITY_ID_STK3332,PROXIMITY_ID_STK3410,PROXIMITY_ID_EM3071X,PROXIMITY_ID_UCS14620,TEMPERATURE_ID_ALL,TEMPERATURE_ID_MS5607,PRESSURE_ID_ALL,PRESSURE_ID_BMA085,PRESSURE_ID_MS5607,HALL_ID_ALL,HALL_ID_OCH165T,SENSOR_NUM_ID, };
【a】 King3399(ubuntu文件系统)wifi设备树分析
【b】 King3399 SDK(ubuntu文件系统)编译简明教程
【c】 ADB安装及使用详解
【d】 Android系统中通过fdt文件系统反编译查看设备中真实生效的设备树配置信息
【e】 AL3220光感调试记录
【f】 RK3568 系列 6——Pinctrl 与 GPIO 的理解
【g】[野火]《嵌入式Linux驱动开发实战指南—基于LubanCat RK系列板卡》_20240727.pdf - 第 17 章 I2C 子系统–mpu6050 驱动实验
【h】vscode“检测到 #include 错误,请更新 includepath。”的问题解决办法
【i】printk无法输出到打印台问题和Linux日志文件详解
【j】 项目相关资料 pwd : 7rs4