【树莓派驱动验证步骤】

终端操作和输出:

清理项目
ada@raspberrypi:~/mt3502 $ make clean
make -C /lib/modules/6.6.51+rpt-rpi-v8/build M=/home/ada/mt3502 clean
make[1]: 进入目录“/usr/src/linux-headers-6.6.51+rpt-rpi-v8”
  CLEAN   /home/ada/mt3502/Module.symvers
make[1]: 离开目录“/usr/src/linux-headers-6.6.51+rpt-rpi-v8”

编译模块

ada@raspberrypi:~/mt3502 $ make
make -C /lib/modules/6.6.51+rpt-rpi-v8/build M=/home/ada/mt3502 modules
make[1]: 进入目录“/usr/src/linux-headers-6.6.51+rpt-rpi-v8”
  CC [M]  /home/ada/mt3502/mt350x.o
  MODPOST /home/ada/mt3502/Module.symvers
  CC [M]  /home/ada/mt3502/mt350x.mod.o
  LD [M]  /home/ada/mt3502/mt350x.ko
make[1]: 离开目录“/usr/src/linux-headers-6.6.51+rpt-rpi-v8”

卸载模块(未加载)

ada@raspberrypi:~/mt3502 $ sudo rmmod mt350x
rmmod: ERROR: Module mt350x is not currently loaded

编译设备树源文件

ada@raspberrypi:~/mt3502 $ dtc -@ -I dts -O dtb -o mt350x.dtbo mt350x.dts

加载设备树覆盖层

ada@raspberrypi:~/mt3502 $ sudo dtoverlay -l | grep mt350x
ada@raspberrypi:~/mt3502 $ sudo dtoverlay mt350x.dtbo
ada@raspberrypi:~/mt3502 $ sudo dtoverlay -l | grep mt350x
0:  mt350x

加载内核模块

ada@raspberrypi:~/mt3502 $ lsmod | grep mt350x
ada@raspberrypi:~/mt3502 $ sudo insmod mt350x.ko
ada@raspberrypi:~/mt3502 $ lsmod | grep mt350x
mt350x                 16384  0

说明

  • make clean:清理项目中的编译生成文件。
  • make:编译内核模块。
  • sudo rmmod mt350x:尝试卸载模块(模块未加载时会报错)。
  • dtc:编译设备树源文件为 .dtbo 文件。
  • sudo dtoverlay:加载设备树覆盖层。
  • sudo insmod mt350x.ko:加载内核模块。
    • lsmod | grep mt350x:检查模块是否已加载。

更新su密码

ada@raspberrypi:/ $ sudo passwd root
新的密码:
重新输入新的密码:
passwd:已成功更新密码
ada@raspberrypi:/ $ su
密码:

寻找节点路径

root@raspberrypi:/# cd /sys/class/i2c-dev/
root@raspberrypi:/sys/class/i2c-dev# ls
i2c-1  i2c-2
root@raspberrypi:/sys/class/i2c-dev# cd i2c-1
root@raspberrypi:/sys/class/i2c-dev/i2c-1# ls
dev  device  name  power  subsystem  uevent
root@raspberrypi:/sys/class/i2c-dev/i2c-1# cd device
root@raspberrypi:/sys/class/i2c-dev/i2c-1/device# ls
1-0075  delete_device  device  i2c-dev  name  new_device  of_node  power  subsystem  uevent
root@raspberrypi:/sys/class/i2c-dev/i2c-1/device# cd 1-0075

节点目录

root@raspberrypi:/sys/class/i2c-dev/i2c-1/device/1-0075# ls
calibrate  displacement  driver  modalias  name  of_node  power  subsystem  sum_delta  uevent

读取数据

root@raspberrypi:/sys/class/i2c-dev/i2c-1/device/1-0075# cat displacement
delta_x: 0, delta_y: 0
root@raspberrypi:/sys/class/i2c-dev/i2c-1/device/1-0075# cat sum_delta
sum_delta_x: 846, sum_delta_y: 0

执行校准命令

root@raspberrypi:/sys/class/i2c-dev/i2c-1/device/1-0075# echo 1 > calibrate
1


解决方案

  • 设备树内容示例
    设备树中需声明 I2C 设备地址和兼容性字符串,例如:
    / {
        compatible = "raspberrypi,model";
        fragment@0 {
            target = <&i2c1>;
            __overlay__ {
                #address-cells = <1>;
                #size-cells = <0>;
                mt350x: mt350x@50 {
                    compatible = "your-company,mt350x";
                    reg = <0x50>;  // I2C 设备地址
                };
            };
        };
    };
    
    • 关键点
      • compatible 必须与驱动代码中的 of_match_table 匹配。
      • reg 指定设备的 I2C 地址(如 0x50)。

2. 检查驱动代码

驱动代码(mt350x.c)需要包含以下关键逻辑:

  • 绑定设备树的 compatible

    static const struct of_device_id mt350x_of_match[] = {
        { .compatible = "your-company,mt350x" },
        {},
    };
    MODULE_DEVICE_TABLE(of, mt350x_of_match);
    
  • 注册 I2C 驱动

    static struct i2c_driver mt350x_driver = {
        .driver = {
            .name = "mt350x",
            .of_match_table = mt350x_of_match,
        },
        .probe = mt350x_probe,
        .remove = mt350x_remove,
    };
    module_i2c_driver(mt350x_driver);
    
  • probe() 中创建设备节点

    static int mt350x_probe(struct i2c_client *client, const struct i2c_device_id *id) {
        // 创建设备节点(例如 /dev/mt350x)
        dev = device_create(class, NULL, dev_num, NULL, "mt350x");
        // 初始化 I2C 通信
        ...
        return 0;
    }
    

操作流程总结

  1. 设备树编译

    编译增量设备树源文件

    安装设备树编译工具

    sudo apt-get install device-tree-compiler
    

    使用 dtc 进行编译

    dtc -@ -I dts -O dtb -o mt350x.dtbo mt350x.dts
    

    分析步骤

    检查设备树配置
    • 确认是否已添加设备树覆盖
      如果你有 .dts.dtbo 文件(如 mt350x.dtbo),需确保它已正确应用到系统中:
      # 查看已加载的设备树覆盖
      sudo dtoverlay -l | grep mt350x
      
      • 如果未加载,手动加载:
        sudo dtoverlay mt350x.dtbo
        
  2. 加载驱动模块

    sudo rmmod mt350x
    sudo insmod mt350x.ko
    

    分析步骤

    1. 检查模块是否已加载
      运行以下命令,查看模块是否在已加载列表中:

      lsmod | grep mt350x
      
      • 如果看到输出结果,说明模块已加载。
    2. 卸载已存在的模块
      如果模块已加载,使用 rmmod 卸载它:

      sudo rmmod mt350x
      
      • 注意:模块名可能不包含 .ko 后缀,直接使用 mt350x
    3. 重新加载模块
      卸载成功后,再次尝试加载:

      sudo insmod mt350x.ko
      

    验证模块是否正常工作

    虽然模块已加载,但你可能需要确认它是否按预期工作。以下是验证步骤:

    1. 查看内核日志
      运行以下命令,检查模块加载时的输出(可能有初始化信息或错误):

      dmesg | grep mt350x
      
      • 如果看到类似 mt350x: module loaded successfully 的日志,说明一切正常。
    2. 检查设备节点或接口

      • 如果这是一个设备驱动(例如字符设备),检查 /dev/ 下是否生成了对应的设备文件:
        ls -l /dev/mt350x*  # 替换为你的设备名
        
      • 如果涉及网络或硬件接口,检查相关工具的输出(如 ifconfigi2cdetect 等)。

    总结

    • 当前状态正常,模块已成功加载。
    • 无需再次执行 insmod,除非你修改了模块代码需要重新加载。
    • 如需调试,优先通过 dmesg 查看内核日志。
  3. 验证设备节点和 I2C 地址

    ls /dev/mt350x*       # 检查设备节点
    sudo i2cdetect -y 1   # 检查 I2C 设备是否存在
    

常见问题

  • 设备树未生效:确保 .dtbo 文件已复制到 /boot/overlays/ 并在 /boot/config.txt 中添加 dtoverlay=mt350x
  • 驱动未绑定设备树:检查驱动代码中的 compatible 字符串是否与设备树一致。
  • 权限问题:如果设备节点已创建但无访问权限,使用 sudo chmod 666 /dev/mt350x

调试步骤

1. 验证 I2C 设备是否被识别
  • 检查 I2C 总线上的设备

    # 安装 i2c 工具
    sudo apt install i2c-tools
    # 扫描 I2C 总线(假设设备挂在 i2c-1)
    sudo i2cdetect -y 1
    
    • 输出中应显示设备地址(如 0x50)为 UU 或具体值。
  • 查看 sysfs 中的设备

    ls /sys/bus/i2c/devices/  # 查找类似 "1-0050" 的条目
    

2. 检查内核日志

即使 dmesg | grep mt350x 无输出,也可能有其他错误:

dmesg | tail -n 30  # 查看最近 30 条日志,搜索 "error" 或 "i2c"


问题原因分析

  1. 仅加载内核模块不足以创建设备节点

    • I2C 设备通常需要 设备树(Device Tree)手动注册 来声明设备地址和配置。
    • 如果模块未绑定到具体的 I2C 设备节点,驱动可能无法触发 probe() 函数,导致设备节点未生成。
  2. 可能缺失的环节

    • 设备树中未定义该 I2C 设备的节点。
    • 内核模块未正确关联到设备树的 compatible 字符串。
    • 驱动代码中未注册字符设备或未调用创建设备节点的接口(如 device_create)。

你可以通过以下命令让内核日志(包括你的驱动输出)持续实时显示


1. 使用 dmesg 的 follow 模式

sudo dmesg -w
  • 效果:实时显示新增的内核日志(按 Ctrl+C 退出)。
  • 过滤特定关键字(如 mt350x
    sudo dmesg -w | grep mt350x
    
    • 如果 grep 导致输出延迟,添加 --line-buffered 参数:
      sudo dmesg -w | grep --line-buffered mt350x
      

2. 使用 tail 跟踪日志文件

Debian 系统的内核日志通常保存在 /var/log/kern.log/var/log/syslog

sudo tail -f /var/log/kern.log | grep mt350x

sudo tail -f /var/log/syslog | grep mt350x

3. 使用 journalctl(systemd 系统)

sudo journalctl -f -k | grep mt350x
  • 参数解释
    • -f:实时跟踪新日志。
    • -k:仅显示内核日志。

4. 在驱动代码中增加调试日志(可选)

如果日志输出频率不够,可以修改驱动代码(mt350x.c)中的 printk 语句:

// 示例:在 mt350x_read_displacement 函数中添加更多信息
printk(KERN_INFO "mt350x: displacement=%d, direction=%d, steps=%d\n", 
       displacement, motion_direction, motion_steps_detected);

重新编译并加载模块后,日志会更详细。


5. 调整日志级别(可选)

如果日志被屏蔽(如 printk 级别低于当前控制台日志级别),可以临时调整:

# 允许所有级别的日志显示
sudo dmesg -n debug

操作示例

# 终端1:持续跟踪内核日志并过滤 mt350x
sudo dmesg -w | grep --line-buffered mt350x

# 终端2:触发传感器动作(例如移动设备)
# 观察终端1的输出是否变化

常见问题

  • 无实时输出:确保传感器正在被物理操作(例如移动),或检查驱动代码中 printk 的触发条件。
  • 日志过多:调整驱动代码中的打印频率(例如减少 msleep(512) 的间隔)。
  • 权限问题:使用 sudo 执行命令。

如果问题依旧,建议检查驱动代码中的数据处理逻辑(例如 motion_directionmotion_steps_detected 是否被正确更新)。



20250325更新:

1、发现居然可以一条命令执行,比较省事,感觉发现新大陆,
2、可以持久化设备树覆盖


编译命令

make clean && make && sudo rmmod mt350x.ko && sudo insmod mt350x.ko

检查并加载设备树覆盖

用一条命令来完成检查设备树覆盖是否加载,如果没有加载则自动加载它:

dtc -@ -I dts -O dtb -o mt350x.dtbo mt350x.dts && sudo dtoverlay -l | grep -q mt350x || sudo dtoverlay mt350x.dtbo

命令解释:

sudo dtoverlay -l:列出当前已加载的所有设备树覆盖。

| grep -q mt350x:在输出中查找mt350x-q参数表示安静模式,不输出任何内容,只返回状态码(0表示找到,1表示未找到)。

||:逻辑“或”操作符。如果前面的命令返回非零状态码(即mt350x未加载),则执行后面的命令。

sudo dtoverlay mt350x.dtbo:加载mt350x.dtbo设备树覆盖文件。

使用场景:

• 如果mt350x已经加载,grep会返回 0,命令链停止,不会尝试重新加载。

• 如果mt350x未加载,grep会返回 1,触发加载命令。


在用户空间手动创建目录并设置权限

sudo mkdir -p /data/calibration
sudo chmod 777 /data/calibration

查看校准数据

root@raspberrypi:/sys/bus/i2c/devices/1-0075# ls
calibrate  driver  modalias  name  of_node  power  read_calibrate  read_displacement  read_sum_delta  subsystem  uevent
root@raspberrypi:/sys/bus/i2c/devices/1-0075# cat read_calibrate
calibrate_data: 73
root@raspberrypi:/sys/bus/i2c/devices/1-0075# cat read_sum_delta
sum_delta_x: 333, sum_delta_y: 0
root@raspberrypi:/sys/bus/i2c/devices/1-0075# echo 1 > calibrate
root@raspberrypi:/sys/bus/i2c/devices/1-0075# cat read_calibrate
calibrate_data: 59
root@raspberrypi:/sys/bus/i2c/devices/1-0075#

校准后查看校准数据

root@raspberrypi:/home/ada# cd /
root@raspberrypi:/# ls
bin  boot  data  dev  etc  home  lib  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@raspberrypi:/# cd data
root@raspberrypi:/data# ls
calibration
root@raspberrypi:/data# cd calibration
root@raspberrypi:/data/calibration# ls
mt350x_calibration_data.dat
root@raspberrypi:/data/calibration# cat mt350x_calibration_data.dat
59
root@raspberrypi:/data/calibration#


持久化设备树覆盖

如果你希望设备树覆盖在系统重启后仍然生效,可以将其添加到/boot/config.txt文件中。

1.将编译后的.dtbo文件复制到正确的目录

sudo cp mt350x.dtbo /boot/overlays/

2.加载增量设备树

编辑/boot/config.txt文件:

sudo nano /boot/config.txt

或者,如果你的系统使用的是/boot/firmware/config.txt,则编辑该文件:

sudo nano /boot/firmware/config.txt

在文件末尾添加以下内容:

dtoverlay=mt350x

保存并退出。


3.重启树莓派

sudo reboot

确认设备树覆盖是否持久化

4.重启后,运行以下命令来确认设备树覆盖是否仍然加载:

sudo dtoverlay -l | grep mt350x

如果输出中包含mt350x,则说明设备树覆盖已经正确持久化。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值