• 【技术分享】RK356X Android 使用 libgpiod 测试gpio


    前言

    libgpiod 是用于与 Linux GPIO 字符设备交互的 C 库和工具库;此项目包含六种命令行工具(gpiodetect、gpioinfo、gpioset、gpioget、gpiomon),使用这些工具可以在命令行设置和获取GPIO的状态信息;在程序开发中也可以调用库提供的API接口来控制GPIO。本文内容可适用于RK3566系列开发板 Android11 系统上添加libgpiod库和使用API来测试GPIO。

    Purple Pi OH作为一款兼容树莓派的开源主板,采用瑞芯微RK3566 (Cortex-A55) 四核64位超强CPU,主频最高达1.8 GHz,算力高达1Tops,支持INT8/INT16,支持TensorFlow/MXNet/PyTorch/Caffe框架,多路视频输出和输入,支持4K、H.265/H.264视频解码,接口丰富。    

    玩法丰富,支持Android 11、Debian 10、OpenHarmony3.2、Ubuntu、麒麟OS等多种系统,提供丰富开源资料。

    产品规格书查看深圳触觉智能官网-产品中心

    Android 移植 libgpiod 库和测试工具

    1. 下载源码到 external目录下:

    1. cd external
    2. git clone https://github.com/technexion-android/platform_external_libgpiod.git
    3. #git clone https://kernel.googlesource.com/pub/scm/libs/libgpiod/libgpiod

    仓库链接:platform_external_libgpiod

    1. 添加到 PRODUCT_PACKAGES

    在mk文件中添加编译 libgpiod及工具

    1. PRODUCT_PACKAGES += \
    2.     RockchipPinnerService \
    3.        gpioset \
    4.        gpiomon \
    5.        gpioinfo \
    6.        gpioget \
    7.        gpiofind \
    8.        gpiodetect \
    9.        libgpiod

    源码

    libgpiod-git.7z

    命令行工具使用测试

    使用gpioget 获取 GPIO0_A6 的电平状态

    1. # gpioget gpiochip0 6
    2. 1

    程序中调用库的接口使用测试

    编写gpiotest.c 实现多组GPIO之间的输入输出对测功能

    • src/tools/gpiotest.h

    • src/tools/gpiotest.c 函数简单说明,#define LEN 45需要修改

    1. #include <stdio.h>
    2. #include <unistd.h>
    3. #include <gpiod.h>
    4. #include "gpiotest.h"
    5. #define LEN 45 // GPIO 数组总数,可以用sizeof获取数组大小
    6. #define HIGH 1
    7. int main()
    8. {
    9.   struct gpiod_chip *input_chip, *output_chip;
    10.   struct gpiod_line *input_line, *output_line;
    11.   bool output_value, input_value;
    12.     int ret,test_res = 0, total = 0;
    13.     for (int num = 0; num < 2; num++ ){
    14.         int in_chip = 0;
    15.         int in_line = 1;
    16.         int out_chip = 2;
    17.         int out_line = 3;
    18.       // 反转测试,将原来输出改为输入
    19.         if ( 1 == num ){
    20.           in_chip = 2;
    21.           in_line = 3;
    22.           out_chip = 0;
    23.           out_line = 1;
    24.         }
    25.         for (int i = 0; i < LEN; i++){
    26.          // 将 GPIO 配置为 输入
    27.           input_chip = gpiod_chip_open_by_number(test_gpio[i][in_chip]);
    28.           if(!input_chip)
    29.               return -1;
    30.           input_line = gpiod_chip_get_line(input_chip,test_gpio[i][in_line]);
    31.           if(!input_line){
    32.               gpiod_chip_close(input_chip);
    33.               return -1;
    34.           }
    35.           ret = gpiod_line_request_input(input_line,"input");
    36.           if(ret){
    37.               gpiod_chip_close(input_chip);
    38.               return -1;
    39.           }
    40.          // 将 GPIO 配置为 输出
    41.           output_chip = gpiod_chip_open_by_number(test_gpio[i][out_chip]);
    42.           if(!output_chip)
    43.               return -1;
    44.           output_line = gpiod_chip_get_line(output_chip,test_gpio[i][out_line]);
    45.           if(!output_line){
    46.               gpiod_chip_close(output_chip);
    47.               return -1;
    48.           }
    49.           ret = gpiod_line_request_output(output_line,"output",HIGH);
    50.           if(ret){
    51.               gpiod_chip_close(output_chip);
    52.               return -1;
    53.           }
    54.           test_res = 1;
    55.           for(int j = 0;j < 2; j++){
    56.               output_value = gpiod_line_get_value(output_line);
    57.               
    58.               //测试拉高、拉低
    59.               gpiod_line_set_value(output_line, !output_value);
    60.               //printf("output gpio[%d]: %d\t",i, !output_value);
    61.               sleep(1);
    62.               input_value = gpiod_line_get_value(input_line);
    63.               //printf("input gpio[%d]: %d\n",i, input_value);
    64.               //用输入 GPIO 验证拉高、拉低
    65.               if ( output_value != !input_value){
    66.                   printf("test fail array [%d]\n",i);
    67.                   test_res = -1;
    68.                   break;
    69.               }
    70.           }
    71.           if ( 1 == test_res ){
    72.             printf("PASS gpio array %d\n",i);
    73.             total += 1;
    74.           }
    75.           // release gpio
    76.           gpiod_chip_close(input_chip);
    77.           gpiod_chip_close(output_chip);
    78.         }
    79.     }
    80.     printf("total pass gpio number %d\n",total);
    81.   return 0;
    82. }

    程序编译

    使用mmm 命令指定目录编译

    $ mmm external/libgpiod/

    编译完成后,可执行文件产生的路径为out/target/product/rk3566_r/system/bin/gpiotest

    将程序push到主板中使用

    1. adb root
    2. adb remount
    3. adb push out/target/product/rk3566_r/system/bin/gpiotest /system/bin
    4. adb shell chmod +/system/bin/gpiotest

    gpiotest 使用

    • 数组第十项测试失败,其余通过,通过gpiotest.h可以找到对应的 GPIO

  • 相关阅读:
    【WALT】scale_exec_time() 代码详解
    嵌入式中I2C 相关的硬件问题汇总及死锁解决办法
    Unity界面介绍:场景视图
    想要精通算法和SQL的成长之路 - 最长等差数列
    rust 初识基础: 变量、数据类型、函数、所有权、枚举
    开源LIMS系统miso LIMS(适用于NGS基因测序)
    【狂神】SpringMVC笔记(一)之详细版
    星际编码:Swifter.Json,.NET宇宙中的数据处理新星
    MySQL高级篇——锁
    【C++】内联函数的原理及使用
  • 原文地址:https://blog.csdn.net/Industio_CSDN/article/details/134202889