记一次通过udev自动加在i2c接口触摸驱动过程

背景

       触摸屏作为人机交互的关键设备之一,其稳定性对设备的使用至关重要,通常触摸屏的驱动会编进内核中,但是这会导致一个问题,如果触摸芯片概率性工作不正常会导致触摸驱动加载失败,影响设备的使用,所以需要将触摸驱动改成以模块的形式加载,那又引出另外一个问题:如何在开机之后加载触摸驱动?

开机后自动加载驱动的方式无非就是两种:

1、通过脚本加载

        通过脚本加载有一个好处就是可定制化强,不依赖特定的策略和规则,例如,

  • 如果触摸驱动加载失败可以通过脚本控制重复加载
  • 如果在设备使用过程中触摸失灵,可以通过脚本控制触摸驱动重新加载
  • 等等,其他情况
2、通过udev加载
      使用udev的方式加载,从项目整体视角来看有益于标准化,减少重复造轮子,

本次调试的触摸芯片为: ili2131,触摸驱动的版本为:ilitek_limv5_9_0_2

修改内核配置,生成内核驱动模块,为了快速验证,直接修改Makefile:

//修改前
ccflags-y += -Wall
obj-y += ilitek.o

ilitek-y +=     ilitek_main.o \
        ilitek_platform_init.o \
        ilitek_update.o \
        ilitek_tool.o \
        ilitek_protocol.o \
        ilitek_mp.o


//修改后
ccflags-y += -Wall
obj-m += ilitek.o

ilitek-y +=     ilitek_main.o \
        ilitek_platform_init.o \
        ilitek_update.o \
        ilitek_tool.o \
        ilitek_protocol.o \
        ilitek_mp.o

根据设备树配置修改udev规则,设备树配置 i2c 第三通道 地址 0x41 :

/* touch */
&i2c3 {
        clock_frequency = <400000>;
        pinctrl-names = "default";
        status = "okay";

         ili2131: ili2131@41 { 
        compatible = "tchip,ilitek"; 
        reg = <0x41>; 
        pinctrl-names = "default";
        pinctrl-0 = <&ilitek_ili2131_pins>;

        interrupt-parent = <&gpio4>; 
        interrupts = <1 IRQ_TYPE_EDGE_FALLING>; 
        ilitek,irq-gpio = <&gpio4 1 IRQ_TYPE_EDGE_FALLING>; 
        ilitek,reset-gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; 
        ilitek,name = "ilitek_i2c"; 


        touchscreen-swapped-x-y;
        touchscreen-revert-y;
        touchscreen-lcm-resolution;

        touchscreen-lcm-resolution-x = <800>;
        touchscreen-lcm-resolution-y = <1280>;


        }; 
};

udev动态加载规则文件:/lib/udev/rules.d/80-drivers.rules

//修改前
root@myd-imx8mm:/lib/udev/rules.d# cat 80-drivers.rules
# do not edit this file, it will be overwritten on update

ACTION!="add", GOTO="drivers_end"

ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load $env{MODALIAS}"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN{builtin}+="kmod load tifm_sd"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN{builtin}+="kmod load tifm_ms"
SUBSYSTEM=="memstick", RUN{builtin}+="kmod load ms_block mspro_block"
SUBSYSTEM=="i2o", RUN{builtin}+="kmod load i2o_block"
SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}+="kmod load ppdev"
KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", RUN{builtin}+="kmod load sm_ftl"

LABEL="drivers_end"
root@myd-imx8mm:/lib/udev/rules.d#


//添加规则
root@myd-imx8mm:/lib/udev/rules.d# cat 80-drivers.rules
# do not edit this file, it will be overwritten on update

ACTION!="add", GOTO="drivers_end"

ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load $env{MODALIAS}"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN{builtin}+="kmod load tifm_sd"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN{builtin}+="kmod load tifm_ms"
SUBSYSTEM=="memstick", RUN{builtin}+="kmod load ms_block mspro_block"
SUBSYSTEM=="i2o", RUN{builtin}+="kmod load i2o_block"
SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}+="kmod load ppdev"
KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", RUN{builtin}+="kmod load sm_ftl"
SUBSYSTEM=="i2c" KERNEL=="2-0041" RUN{builtin}+="kmod load i2c:ilitek_ts"
SUBSYSTEM=="i2c" KERNEL=="2-0041" RUN{program}+="/bin/mkdir /home/root/i2c -p"

LABEL="drivers_end"
root@myd-imx8mm:/lib/udev/rules.d#

其中,SUBSYSTEM=="i2c" KERNEL=="2-0041" RUN{program}+="/bin/mkdir /home/root/i2c -p" 为测试规则,测试匹配规则是否生效,同时也可以使用udevadm 测试:

root@myd-imx8mm:/lib/udev/rules.d# udevadm   test   /sys/bus/i2c/devices/2-0041
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

Load module index
Skipping empty file: /etc/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /etc/udev/rules.d/10-imx.rules
Configuration file /etc/udev/rules.d/40-libgphoto2.rules is marked executable. Please remove executable permission bits. Proceeding anyway.
Reading rules file: /etc/udev/rules.d/40-libgphoto2.rules
Reading rules file: /lib/udev/rules.d/50-udev-default.rules
Reading rules file: /lib/udev/rules.d/60-block.rules
Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /lib/udev/rules.d/60-drm.rules
Reading rules file: /lib/udev/rules.d/60-evdev.rules
Reading rules file: /lib/udev/rules.d/60-input-id.rules
Reading rules file: /lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /lib/udev/rules.d/60-sensor.rules
Reading rules file: /lib/udev/rules.d/60-serial.rules
Reading rules file: /lib/udev/rules.d/64-btrfs.rules
Reading rules file: /lib/udev/rules.d/70-joystick.rules
Reading rules file: /lib/udev/rules.d/70-mouse.rules
Reading rules file: /lib/udev/rules.d/70-power-switch.rules
Reading rules file: /lib/udev/rules.d/70-touchpad.rules
Reading rules file: /lib/udev/rules.d/70-uaccess.rules
Reading rules file: /lib/udev/rules.d/71-seat.rules
Reading rules file: /etc/udev/rules.d/71-weston-drm.rules
Reading rules file: /lib/udev/rules.d/73-seat-late.rules
Reading rules file: /lib/udev/rules.d/75-net-description.rules
Reading rules file: /lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /lib/udev/rules.d/78-sound-card.rules
Reading rules file: /lib/udev/rules.d/80-drivers.rules
Reading rules file: /lib/udev/rules.d/80-libinput-device-groups.rules
Reading rules file: /lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /lib/udev/rules.d/89-alsa-ucm.rules
Reading rules file: /lib/udev/rules.d/90-alsa-restore.rules
Reading rules file: /lib/udev/rules.d/90-libinput-fuzz-override.rules
Reading rules file: /lib/udev/rules.d/90-pulseaudio.rules
Reading rules file: /lib/udev/rules.d/90-vconsole.rules
Reading rules file: /lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /lib/udev/rules.d/99-systemd.rules
Reading rules file: /etc/udev/rules.d/automount.rules
Reading rules file: /etc/udev/rules.d/autonet.rules
Reading rules file: /etc/udev/rules.d/localextra.rules
Reading rules file: /etc/udev/rules.d/touchscreen.rules
DEVPATH=/devices/platform/soc@0/soc@0:bus@30800000/30a40000.i2c/i2c-2/2-0041
OF_NAME=ili2131
OF_FULLNAME=/soc@0/bus@30800000/i2c@30a40000/ili2131@41
OF_COMPATIBLE_0=tchip,ilitek
OF_COMPATIBLE_N=1
MODALIAS=of:Nili2131T(null)Ctchip,ilitek
ACTION=add
SUBSYSTEM=i2c
USEC_INITIALIZED=9611258939
run: 'kmod load of:Nili2131T(null)Ctchip,ilitek'
Unload module index
Unloaded link configuration context.

如此可以通过udev自动匹配加载驱动

3、修改/etc/modprobe.d,可参考ubuntu系统配置文件如:
richard@ubuntu24:~$ cat /etc/modprobe.d/alsa-base.conf
# autoloader aliases
install sound-slot-0 /sbin/modprobe snd-card-0
install sound-slot-1 /sbin/modprobe snd-card-1
install sound-slot-2 /sbin/modprobe snd-card-2
install sound-slot-3 /sbin/modprobe snd-card-3
install sound-slot-4 /sbin/modprobe snd-card-4
install sound-slot-5 /sbin/modprobe snd-card-5
install sound-slot-6 /sbin/modprobe snd-card-6
install sound-slot-7 /sbin/modprobe snd-card-7

# Cause optional modules to be loaded above generic modules
install snd /sbin/modprobe --ignore-install snd $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-ioctl32 ; /sbin/modprobe --quiet --use-blacklist snd-seq ; }
#
# Workaround at bug #499695 (reverted in Ubuntu see LP #319505)
install snd-pcm /sbin/modprobe --ignore-install snd-pcm $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-pcm-oss ; : ; }
install snd-mixer /sbin/modprobe --ignore-install snd-mixer $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-mixer-oss ; :; }
install snd-seq /sbin/modprobe --ignore-install snd-seq $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-seq-midi ; /sbin/modprobe --quiet --use-blacklist snd-seq-oss ; : ; }
#
install snd-rawmidi /sbin/modprobe --ignore-install snd-rawmidi $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-seq-midi ; : ; }
# Cause optional modules to be loaded above sound card driver modules
install snd-emu10k1 /sbin/modprobe --ignore-install snd-emu10k1 $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-emu10k1-synth ; }
install snd-via82xx /sbin/modprobe --ignore-install snd-via82xx $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-seq ; }

# Load saa7134-alsa instead of saa7134 (which gets dragged in by it anyway)
install saa7134 /sbin/modprobe --ignore-install saa7134 $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist saa7134-alsa ; : ; }
# Prevent abnormal drivers from grabbing index 0
options bt87x index=-2
options cx88_alsa index=-2
options saa7134-alsa index=-2
options snd-atiixp-modem index=-2
options snd-intel8x0m index=-2
options snd-via82xx-modem index=-2
options snd-usb-audio index=-2
options snd-usb-caiaq index=-2
options snd-usb-ua101 index=-2
options snd-usb-us122l index=-2
options snd-usb-usx2y index=-2
# Ubuntu #62691, enable MPU for snd-cmipci
options snd-cmipci mpu_port=0x330 fm_port=0x388
# Keep snd-pcsp from being loaded as first soundcard
options snd-pcsp index=-2
# Keep snd-usb-audio from beeing loaded as first soundcard
options snd-usb-audio index=-2
mkdir /etc/modprobe.d
touch /etc/modprobe.d/ilitek.conf
echo "ilitek" >>ilitek.conf
4、通过systemd-udev加载模块,查看/usr/lib/systemd/system/systemd-modules-load.service服务:
#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Load Kernel Modules
Documentation=man:systemd-modules-load.service(8) man:modules-load.d(5)
DefaultDependencies=no
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
ConditionCapability=CAP_SYS_MODULE
ConditionDirectoryNotEmpty=|/lib/modules-load.d
ConditionDirectoryNotEmpty=|/usr/lib/modules-load.d
ConditionDirectoryNotEmpty=|/usr/local/lib/modules-load.d
ConditionDirectoryNotEmpty=|/etc/modules-load.d
ConditionDirectoryNotEmpty=|/run/modules-load.d
ConditionKernelCommandLine=|modules-load
ConditionKernelCommandLine=|rd.modules-load

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-modules-load
TimeoutSec=90s

在lib/modules-load.d等文件中添加要加载的模块即可

5、参考 /lib/systemd/system/rc-local.service,修改/etc/rc.local即可。
6、通过启动参数加载

除了配置文件,systemd-modules-load.service还支持识别以下的内核引导选项:

modules_load=, rd.modules_load=

  上述选项通过接受一个内核模块列表,表示在系统启动的早期,无条件的加载这些内核模块。以 “rd.” 作为前缀的选项仅作用于 initial RAM disk 环境。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值