用 ADB 去控制 GPIO

作者: SayidZhong | 来源:发表于2017-11-25 10:03 被阅读64次

觉得为时已晚的时候,恰恰是最早的时候

用 ADB 操作 GPIO

转载请注明出处 https://sayid95.github.io/
背景介绍:mt8167 安卓7.0

我们经常会在底层驱动里面去操作gpio,进而去控制硬件。如果驱动层面去操作io出现问题的时候,我们不知道是不是硬件的问题,今天就来说下怎么用ADB去控制gpio。

首先

打开很难用的 Windows 的cmd.exe (推荐 一款替代品 Cmder ),adb shell连接上设备以后,输入下面的命令,

cd /sys/devices/platform/soc/1000b000.pinctrl/

进入到1000b000.pinctrl/ 的目录下,然后就可以去操作 io 口了,如下:

echo mode 66 0 > mt_gpio   /*设置66号 io 的模式*/
echo dir 66 1 > mt_gpio    /*设置66号 io 的输入,输出方向*/
echo out 66 1 > mt_gpio    /*设置66号 io 为输出*/

接着

就可以用下面的命令去看我们上面用 ADB 设置的 gpio 状态了

cat   /sys/devices/platform/soc/1000b000.pinctrl/mt_gpio

来看下mtk 这部分操作的源码

kernel-4.4/drivers/pinctrl/mediatek/pinctrl-mtk-common.c 这个文件里,下面代码就是adb 直接操作gpio的函数:

static ssize_t mt_gpio_show_pin(struct device *dev, struct device_attribute *attr, char *buf)
{
    int len = 0;
    int bufLen = PAGE_SIZE;
    struct mtk_pinctrl *pctl = dev_get_drvdata(dev);
    struct gpio_chip *chip = pctl->chip;
    unsigned        i;
    int         pull_val;

    len += snprintf(buf+len, bufLen-len,
        "PIN: [MODE] [DIR] [DOUT] [DIN] [PULL_EN] [PULL_SEL] [IES] [SMT] [DRIVE] ( [R1] [R0] )\n");

    for (i = 0; i < chip->ngpio; i++) {
        pull_val = mtk_pullsel_get(chip, i);

        len += snprintf(buf+len, bufLen-len, "%4d:% d% d% d% d% d% d% d% d% d",
                i,
                mtk_pinmux_get(chip, i),
                mtk_gpio_get_direction(chip, i),
                mtk_gpio_get_out(chip, i),
                mtk_gpio_get_in(chip, i),
                mtk_pullen_get(chip, i),
                (pull_val >= 0) ? (pull_val&1) : -1,
                mtk_ies_get(chip, i),
                mtk_smt_get(chip, i),
                mtk_driving_get(chip, i));
        if ((pull_val & 8) && (pull_val >= 0))
            len += snprintf(buf+len, bufLen-len, " %d %d", !!(pull_val&4), !!(pull_val&2));
        len += snprintf(buf+len, bufLen-len, "\n");
    }
    return len;
}

static ssize_t mt_gpio_store_pin(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    int pin, val;
    int val_set;
    struct mtk_pinctrl *pctl = dev_get_drvdata(dev);
    struct pinctrl_dev *pctldev = pctl->pctl_dev;

    if (!strncmp(buf, "mode", 4) && (sscanf(buf+4, "%d %d", &pin, &val) == 2)) {
        val_set = mtk_pmx_set_mode(pctldev, pin, val);
    } else if (!strncmp(buf, "dir", 3) && (sscanf(buf+3, "%d %d", &pin, &val) == 2)) {
        val_set  = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, !val);
    } else if (!strncmp(buf, "out", 3) && (sscanf(buf+3, "%d %d", &pin, &val) == 2)) {
        mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false);
        mtk_gpio_set(pctl->chip, pin, val);
    } else if (!strncmp(buf, "pullen", 6) && (sscanf(buf+6, "%d %d", &pin, &val) == 2)) {
        val_set = mtk_pconf_set_pull_select(pctl, pin, !!val,
            false, MTK_PUPD_SET_R1R0_00 + val);
    } else if (!strncmp(buf, "pullsel", 7) && (sscanf(buf+7, "%d %d", &pin, &val) == 2)) {
        val_set = mtk_pconf_set_pull_select(pctl, pin, true, !!val, MTK_PUPD_SET_R1R0_01);
    } else if (!strncmp(buf, "ies", 3) && (sscanf(buf+3, "%d %d", &pin, &val) == 2)) {
        val_set = mtk_pconf_set_ies_smt(pctl, pin, val, PIN_CONFIG_INPUT_ENABLE);
    } else if (!strncmp(buf, "smt", 3) && (sscanf(buf+3, "%d %d", &pin, &val) == 2)) {
        val_set = mtk_pconf_set_ies_smt(pctl, pin, val, PIN_CONFIG_INPUT_SCHMITT_ENABLE);
    }

    return count;
}

static DEVICE_ATTR(mt_gpio, 0664, mt_gpio_show_pin, mt_gpio_store_pin);

static struct device_attribute *gpio_attr_list[] = {
    &dev_attr_mt_gpio,
};

static int mt_gpio_create_attr(struct device *dev)
{
    int idx, err = 0;
    int num = (int)(ARRAY_SIZE(gpio_attr_list));

    if (!dev)
        return -EINVAL;

    for (idx = 0; idx < num; idx++) {
        err = device_create_file(dev, gpio_attr_list[idx]);
        if (err)
            break;
    }

    return err;
}

看到源码 static DEVICE_ATTR(mt_gpio, 0664, mt_gpio_show_pin, mt_gpio_store_pin);,我们就知道其实就是利用 device_create_file 函数可以在 /sys/ 下创建对应的属性文件,从而通过对该文件的读写实现特定的数据操作。

可能不同的内核对应的节点不一样,这个例子是在 Linux 4.4下进行的,现在就去试试吧!

相关文章

  • 用 ADB 去控制 GPIO

    觉得为时已晚的时候,恰恰是最早的时候 用 ADB 操作 GPIO 转载请注明出处 https://s...

  • RK3288 查看/控制 GPIO 状态

    查看GPIO adb remount adb shell cd data && mkdir debugfs mou...

  • adb shell GPIO

    1、adb 如何获取GPIO状态adb shell "cat /sys/devices/virtual/misc/...

  • 项目环境配置

    一、adb使用 USB host和device模式切换:echo 1 > /sys/class/gpio/gpio...

  • GPIO笔记

    查看管脚状态 cat /sys/kernel/debug/gpio 用/sys/class/gpio方式控制GPI...

  • android gpio口控制

    android gpio口控制  GPIO口控制方式是在jni层控制的方式实现高低电平输出,类似linux的控制句...

  • Raspberry PI——GPIO

    在config.txt中GPIO的控制 gpio gpio指令允许GPIO引脚在引导时设置为特定模式和值,代替之前...

  • 【C】通过linux文件系统操作GPIO

    本文描述如果通过文件IO sysfs方式控制树莓派 GPIO端口。通过sysfs方式控制GPIO,先访问/sys/...

  • 树莓派3B+ GPIO输入输出使用

    下图中的40个引脚就是 GPIO ,可以参考官方文档 python3 程序控制GPIO GPIO (General...

  • openwrt 命令行控制GPIO

    一、在openwrt文件系统中通过内核提供的接口操作GPIO 1、导出GPIO11目录 控制GPIO 1).cd ...

网友评论

    本文标题:用 ADB 去控制 GPIO

    本文链接:https://www.haomeiwen.com/subject/aqnqbxtx.html