King3399(ubuntu文件系統)iic(i2c)功能測試

0 引言

前面兩篇博文簡要介紹了板子上uart部分的內容,但在驅動開發時,我們遇到的外設更多的是以i2c或spi進行通信,本文將對king3399的i2c進行測試并對硬件電路、設備樹與驅動程序進行分析

如果使用的i2c設備不是mma8452,建議先看看文末枚舉中的i2c設備類型,本文可擴展枚舉的所有i2c設備

1 i2c接口硬件分析

通過板子電路原理圖可以看到板子底板使用了三組i2c接口,這三組接口都已掛載了設備,設備分配如下表所示

i2cnumchipnote
i2c1U14ALC5651Audio
J21MIPICamera
J22MIPICamera
J106PinPin
i2c3J10HDMIVideo
i2c4U12MMA8452Accelerometer
J33MIPILCD Video
J106PinPin
U23FUSB302MPXBattery 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鏡像中逆向完整的設備樹文件,從該逆向設備樹中查找到需要的節點,步驟如下:

  1. 下載官方Android鏡像文件,這里使用的是update_king_rp3399_android7.1_hdmi_20200714_171241.img,(由于本人手中只有一個hdmi接口的顯示器,因此選擇該鏡像,若手中有配套的LCD則可以選擇對應的鏡像文件)

  2. 將上述鏡像文件燒錄到板子中,燒錄過程可參考腳注【b】

  3. 將板子設置為“開發者模式”,與手機進入該模式相同,具體操作如下:

    1. 板子上電后進入主界面,將光標放到底部狀態欄

      在這里插入圖片描述

    2. 光標長按底部狀態欄并向上拖拽,此時界面會切換到應用界面

      在這里插入圖片描述

    3. 找到“設置”應用,點擊進入
      在這里插入圖片描述

    4. 找到“關于平板電腦”選項,點擊進入
      在這里插入圖片描述

    5. 找到“版本號”選項,連續點擊多次,此時界面會提示“開發者模式”選項
      在這里插入圖片描述
      在這里插入圖片描述

    6. 退回到上一層,找到“開發者選項”選項,點擊進入并勾選“USB調試”選項
      在這里插入圖片描述

    7. 回到應用界面,找到“榮品功能測試”應用,點擊進入,找到“重力傳感器測試”項,此時翻動板子將看到xyz軸數值的變化,該步驟可驗證板子上的加速度傳感器是否正常工作
      在這里插入圖片描述

  4. 在電腦上安裝ADB,安裝過程及初步使用可參考腳注【c】

  5. 將板子與電腦連接,此時電腦會自動識別到板子,在電腦的“Device Manager”可以看到已連接的“Android Device”
    在這里插入圖片描述

  6. 獲取Android設備fdt文件,具體操作如下:(下邊的“ & rem ”是cmd的單行注釋符,可理解為C語言中的“//”),win + r 并輸入 cmd打開windows命令行窗口

    1. adb version & rem 查看adb版本
    2. adb devices & rem 查看連接的設備,將板子與電腦使用usb線連接后將會列如出已連接的設備
    3. adb root & rem 提升操作權限
    4. adb pull /sys/firmware/fdt & rem 從板子中pull出設備樹文件,文件默認保存在電腦 C:\Users\username\fdt
  7. 將fdt文件反編譯為dts文件,參考腳注【d】,具體操作如下:

    1. 將fdt文件從windows系統中復制到ubuntu系統中
    2. 在ubuntu 系統中安裝反編譯dtc工具,“apt install device-tree-compiler”
    3. 將fdt反編譯成dts,在fdt目錄執行 “dtc -I dtb -O dts fdt -o fdt.dts”
    4. 完成上述操作將在當前目錄下生成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適配了很多類型的設備,因此文件的內容很多,框架稍顯復雜,但都是常規操作,建議花點時間把整個加載處理流程過一遍,不然后邊移植時無從入手(下述表格的閱讀順序為從上到下依次遞進,從下依次到上也可)

functionnote
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_irqdevm_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_driveri2c設備操作函數
.probe = gsensor_mma8452_probe,
static int gsensor_mma8452_probe加載模塊
return sensor_register_device(client
gsensor_mma8452_ops
static struct sensor_operate gsensor_mma8452_opsmma8452操作函數
.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 一些有趣的小東西
  1. vscode中的跳轉

    在編輯軟件中,我們會經常需要跳轉到指定的函數、變量、宏定義等,在vscode中,我們可以使用快捷鍵Ctrl+鼠標左鍵進行跳轉,同時也可以使用快捷鍵Alt+方向鍵反向跳轉,這在閱讀源碼時非常有用,在進行驅動模塊開發時可能會涉及到整個kernel下的driver與include下的文件,但是當我們把mma8452的相關文件都打開時,vscode并不能跳轉到指定位置(由于本人的電腦性能一般,在開發驅動模塊時都是在windows下,編輯完上傳到ubuntu中),如果只是單純地通過在工作空間中進行全局搜索查找效率會非常低,為解決這個問題可以進行如下操作,參考腳注【h】

    1. 下載并雙擊 mingw-get-setup0.6.2.exe,勾選mingw32-gcc-bin 與 mingw32-gcc-g+±bin

    2. 將MinGW添加到環境變量中(如:D:\MinGW\bin 添加到環境變量)

    3. 在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

    4. 重啟電腦,再次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"
      
  2. 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

  3. 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

    在這里插入圖片描述

  4. 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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處:https://dhexx.cn/hk/5528819.html

如若內容造成侵權/違法違規/事實不符,請聯系我的編程經驗分享網進行投訴反饋,一經查實,立即刪除!


相關文章:

  • 第五十七節:綜合項目實踐-智能監控系統原型
  • 隨機游動算法解決kSAT問題
  • 基于Doc2Vec的Markdown文檔分類實戰:從預處理到模型評估
  • qt之開發大恒usb3.0相機三
  • rsync使用守護進程啟動服務
  • DeepSeek實戰:打造智能數據分析與可視化系統
  • Linux操作系統 多進程多線程 信號量實現進程同步及共享內存
  • 類和對象(中1)
  • 深度學習入門:從零搭建你的第一個神經網絡
  • 【iOS】源碼閱讀(五)——類類的結構分析
  • Java數值字符串相加
  • c++第二章練習題
  • 【普及?】洛谷P1706 全排列問題
  • 基于GA遺傳優化的FIR濾波器幅頻相頻均衡補償算法matlab仿真
  • 醫院閉環系統業務介紹
  • 前端面經 React常見的生命周期
  • 接地氣的方式認識JVM(一)
  • Python訓練打卡Day36
  • JS逆向 QQ音樂sign簽名|webpack實戰 (上)
  • Prometheus學習之pushgateway和altermanager組件
  • LVS-DR 負載均衡群集
  • Ai書簽管理工具開發全記錄(二):項目基礎框架搭建
  • 低功耗雙目云臺監控設備采用國標控制裝置
  • 【Microsoft 365可用】PPT一鍵取消所有超鏈接
  • SpringBoot Controller接收參數方式
  • 20250528-C#知識:函數簡介及函數重載
  • 【25軟考網工】第九章 網絡管理(1)網絡管理基礎、SNMP
  • 【Linux】分頁式存儲管理:深刻理解頁表映射
  • 【大模型原理與技術-毛玉仁】第二章 大語言模型架構
  • 解決微信小程序中 Flex 布局下 margin-right 不生效的問題
  • Vim 中設置插入模式下輸入中文
  • 嵌入式開發學習(第二階段 C語言筆記)
  • Linux程序與進程
  • vscode 終端 PATH 和python pip 不對
  • Gerapy二次開發:在Ubuntu服務器中利用pyenv+supervisor實現項目部署
  • 74道Node.js高頻題整理(附答案背誦版)
  • 外部訪問可視化監控 Grafana (Windows版本)
  • 960g輕薄本,把科技塞進巧克力盒子
  • 【unity游戲開發——編輯器擴展】EditorUtility編輯器工具類實現如文件操作、進度條、彈窗等操作
  • 基于Qt的MCP LLM代理服務開發實戰:從0到1擴展大語言模型
  • JavaScript 性能優化:從入門到實戰
  • 第一節 51單片機概述
  • 【深度學習-pytorch篇】5. 卷積神經網絡與LLaMA分類模型
  • linux中基礎IO(上)
  • 如何區分防爆手機與普通手機?
  • Spring MVC極簡入門:從@Reuest到Postman的全鏈路開發
  • SpringBoot+tabula+pdfbox解析pdf中的段落和表格數據
  • 用 Appuploader,讓 iOS 上架流程真正“可交接、可記錄、可復用”:我們是這樣實現的
  • 中企出海大會|打造全球化云計算一張網,云網絡助力中企出海和AI創新
  • 【MySQL】第12節|MySQL 8.0 主從復制原理分析與實戰(二)