• 最新的kernel中的gpio的使用方法


    最新的kernel中的gpio的使用方法

    目录

    1. 背景 1

    2. 当前gpio在kernel的架构 2

    3. 调试调用方法 3

    4. 交叉编译方法 3

    4.1 Linux下交叉编译 3

    4.2 Android下面交叉编译 4

    (1) 修改源码 4

    (2) Android NDK下面进行交叉编译 4

    (3) 放在Android源码中进行交叉编译 4

    5. gpiotool 在android下面的使用 6

    5.1 gpiodetect使用 6

    5.2 gpioinfo使用 6

    5.3 gpiofind使用 8

    5.4 gpioget使用 8

    5.5 gpioset使用 9

    5.6 gpiomon使用 9

    1. 背景

    最近在从4.x的内核移到5.4内核上的时候发现,原来的GPIO进行request所使用的GPIOF_EXPORT突然不能用了。上网上找发现,/sys/classs/gpio已经被最新的内核废弃了。

    https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

    查阅相关的资料发现,这个改动是从2015年开始逐渐发从linux kernel 4.6到4.8 引入的。到了2020年,正式废弃。提交的代码记录如下:

    kernel/git/torvalds/linux.git - Linux kernel source tree

    但是虽然/sys/classs/gpio已经不能用了,但是还是可以通过打开CONFIG_GPIO_SYSFS,再加回来,

    由于这个模块相对独立,当前使用还不会造成任何问题。但是不能确定主线内核到时候,会不会把这个也移除。

    但是打开这个CONFIG_GPIO_SYSFS,也不能像以前一样看到GPIO的设备节点。

    2. 当前gpiokernel的架构

    当前的GPIO在内核中,会使能CONFIG_GPIOLIB, 会以一个chardev的方式出现. 这样对于所有注册的GPIO可以通过通用的通用的gpio访问的库libgpiod来对GPIO进行操作,操作的方法是通过IOCTL的接口来进行。而这个设备会在/dev下面,如:

    1. /dev/gpiochip0
    2. /dev/gpiochip1
    3. /dev/gpiochip2

    3. 调试调用方法

    想要调用,可以通过libgpiod来进行。下载地址如下:

    libgpiod/libgpiod.git - C library and tools for interacting with the linux GPIO character device

    这个工具提供了调用库文件libgpiod,还提供了调试的工具,不过想要用到android上面,还需要进行交叉编译。

    下载:

    https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/snapshot/libgpiod-1.6.3.tar.gz

    4. 交叉编译方法

    编译前,ubuntu16.04下,需要安装libtool, autoconf

    sudo apt install -y libtool autoconf

    4.1  Linux下交叉编译

    arm64的编译器可以使用linaro的,比如:gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu, 和在如下目录:

    /opt/arm-gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc

    先配置环境变量:

    export PATH=$PATH:/opt/arm-gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/

    然后通过如下命令配置后,生成编译Makefile:

    ./autogen.sh --enable-tools=yes --host=armv8 CC=aarch64-linux-gnu-gcc --enable-static --prefix=/work/kernel/out

    然后:

    1. make
    2. make install

    4.2  Android下面交叉编译

    (1). 修改源码

    在Android下编译,有两个地方,需要修改size_t改成ssize_t, 第二个就是去掉program_invocation_name

    这个是glibc提供的用法。android下面不改编译不过。

    (2). Android NDK下面进行交叉编译

    下载android 的最新的NDK

    NDK 下载  |  Android NDK  |  Android Developers

    在这里下载linux版本最新的NKD就可以。

    https://dl.google.com/android/repository/android-ndk-r23c-linux.zip

    解压后,打开终端,输入下面命令,加入到终端环境变量:

    export PATH=$PATH:/work/Android/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin

    然后使用编译器:aarch64-linux-android24-clang 进行编译,进行配置如下:

    ./autogen.sh --enable-tools=yes --host=armv8 CC=aarch64-linux-android24-clang --with-sysroot=/work/Android/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/sysroot --prefix=/work/kernel/out

    然后输入:

    make all install

    编译完成后,会生成:

    1. gpiodetect
    2. gpiofind
    3. gpioget
    4. gpioinfo
    5. gpiomon
    6. gpioset

    这个有一点类似于i2ctools.

    (3). 放在Android源码中进行交叉编译

    这个就需要书写Android.mk, 把tools, lib,及include下面的文件都入在一起。然后,lib的部分,可以编译成

    一个静太库,或动态库。如果是动态库需要 push到android目录下面:

    如果需要编成动态静态库,libgpiod的Android.mk如下:

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_SRC_FILES:= \
    4. core.c \
    5. ctxless.c \
    6. misc.c \
    7. helpers.c \
    8. iter.c
    9. LOCAL_MODULE_TAGS := optional
    10. LOCAL_MODULE := libgpiod
    11. LOCAL_VENDOR_MODULE := true
    12. include $(BUILD_SHARED_LIBRARY)

    编译gpiod的工具的Android.mk如下:

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_SRC_FILES:= \
    4. gpiodetect.c \
    5. tools-common.c
    6. LOCAL_MODULE_TAGS := optional
    7. LOCAL_MODULE := gpiodetect
    8. LOCAL_SHARED_LIBRARIES += libgpiod
    9. LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES)
    10. include $(BUILD_EXECUTABLE)

    如果需要编成静态库,libgpiod的Android.mk如下:

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_SRC_FILES:= \
    4. core.c \
    5. ctxless.c \
    6. misc.c \
    7. helpers.c \
    8. iter.c
    9. LOCAL_MODULE_TAGS := optional
    10. LOCAL_MODULE := libgpiod
    11. LOCAL_VENDOR_MODULE := true
    12. include $(BUILD_STATIC_LIBRARY)

    编译gpiod的工具的Android.mk如下:

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_SRC_FILES:= \
    4. gpiodetect.c \
    5. tools-common.c
    6. LOCAL_MODULE_TAGS := optional
    7. LOCAL_MODULE := gpiodetect
    8. LOCAL_STATIC_LIBRARIES += libgpiod
    9. LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES)
    10. include $(BUILD_EXECUTABLE)

    然后进入目前,使用mm编译就可以了。gpio tools有六个,除了gpiodetect,还有gpioget, gpiofind, gpioinfo, gpiomon, gpioset。也需要按gpiodetect一样增加mk的内容。编译成完会生成在/vendor/bin下面。

    5. gpiotool android下面的使用

    编译完成后,push进android系统的/vendor/bin下面。

    5.1 gpiodetect使用

    1. msmnile_au:/ # gpiodetect
    2. gpiochip0 [3100000.pinctrl] (176 lines)
    3. gpiochip1 [c440000.qcom,spmi:qcom,pm8150@0] (10 lines)
    4. gpiochip2 [c440000.qcom,spmi:qcom,pm8150@4] (10 lines)

    直接输入,就可以,可以列出当前的有几个gpio控制器,分别有几个GPIO.

    5.2 gpioinfo使用

    输入gpioinfo,可以看到所有的gpio的使用情况:

    1. msmnile_au:/ # gpioinfo
    2. gpiochip0 - 176 lines:
    3. line 0: unnamed unused input active-high
    4. line 1: unnamed unused input active-high
    5. line 2: unnamed unused input active-high
    6. line 3: unnamed unused input active-high
    7. line 4: unnamed unused input active-high
    8. line 5: unnamed unused input active-high
    9. line 6: unnamed unused input active-high
    10. line 7: unnamed unused input active-high
    11. line 8: unnamed unused input active-high
    12. line 9: unnamed unused input active-high
    13. line 10: unnamed unused input active-high
    14. line 11: unnamed "ssVreset-gpio" output active-high [used]
    15. line 12: unnamed unused input active-high
    16. line 13: unnamed "interrupt" input active-high [used]
    17. line 14: unnamed unused input active-high
    18. line 15: unnamed unused input active-high
    19. line 16: unnamed unused input active-high
    20. line 17: unnamed "CCI_I2C_DATA0" input active-high [used]
    21. line 18: unnamed "CCI_I2C_CLK0" input active-high [used]
    22. line 19: unnamed "CCI_I2C_DATA1" input active-high [used]
    23. line 20: unnamed "CCI_I2C_CLK1" input active-high [used]
    24. line 21: unnamed "CAM_RESET0" output active-high [used]
    25. line 22: unnamed unused output active-high
    26. line 23: unnamed unused output active-high

    第一列是gpio的编号,第二行,是一个叫line-name的东西,可以在dts里配置的时候通过gpio-line-names来进行指定,如:

    1. &gpio1 {
    2. gpio-line-names = "red_led", "blue_led", "green_led";
    3. };

    这样通过gpioinfo查看的时候,会出现:

    1. $ gpioinfo
    2. gpiochip0 - 32 lines:
    3. line 0: "red_led" unused input active-high
    4. line 1: "blue_led" unused input active-high
    5. line 2: "green_led" unused input active-high
    6. line 3: unnamed "interrupt" input active-high [used]
    7. line 4: unnamed unused output active-high
    8. line 5: unnamed "status" output active-high [used]
    9. line 6: unnamed unused input active-high
    10. line 7: unnamed "reset" input active-high [used]
    11. line 8: unnamed unused input active-high
    12. ...

    不带命令是查看所有的,还可以指定控制器:

    gpioinfo gpiochip0

    或通过设备名:

    gpioinfo 3100000.pinctrl

    在高通平台上:

    1. &tlmm {
    2. gpio-line-names =
    3. "",
    4. "",
    5. "",
    6. "",
    7. "",
    8. "",
    9. "",
    10. "",
    11. "",
    12. "",
    13. "",
    14. "line12",
    15. "",
    16. "line14",
    17. "",
    18. "";
    19. };

    再通过gpioinfo查看,就可以看到:

    5.3 gpiofind使用

    这个工具是通过上面所说的gpio-line-names, 如果没有指定gpio-line-names的话,是无法查找的。如上面提到的例子:

    1. gpiofind blue_led
    2. gpiochip0 1
    3. gpioset gpiochip0 1=1

    如高通平台:

    5.4 gpioget使用

    用法如下:

    1. msmnile_au:/ # gpioget gpiochip0 78
    2. 0

    5.5. gpioset使用
     

    1. gpioset --mode=wait gpiochip0 12=0
    2. gpioset gpiochip0 1=1

    5.6 . gpiomon使用

    gpiomon --silent --num-events=1 gpiochip0 24 25 31

  • 相关阅读:
    【Java基础】数据输入、顺序结构及分支结构之if语句
    五个与iOS基础开发相关的案例:
    C. Card Game(dp&组合数)
    【JavaScript】相等运算符(== 和 ===)
    Mybatis核心配置文件详解
    【附源码】Python计算机毕业设计面向老年群体的健康养生系统
    C【数组】
    智慧校园管理系统全套源码 智慧学校源码(小程序端、电子班牌、人脸识别系统)
    SpringCloudAlibaba整合Sentinel使用
    zabbix6.0 部署配置
  • 原文地址:https://blog.csdn.net/semilog/article/details/125477819