一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

內(nèi)核里的gpiolib在終端上命令操作gpio口

 slimfeng 2019-09-20

內(nèi)核里的gpiolib除了提供如gpio_request, gpio_direction_input/output, gpio_set_value等操作函數(shù)外,還提供了在終端上用直接操作gpio口的功能.

首先確認(rèn)內(nèi)核里是否已選擇上gpiolib的sysfs接口功能(默認(rèn)是已選擇上的)

make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
  Device Drivers  --->
    *- GPIO Support  --->
        [*]   /sys/class/gpio/... (sysfs interface)

然后確認(rèn)在linux內(nèi)核源碼里gpio口對應(yīng)的序號,這個是由芯片廠家自定義的,通常在”arch/arm/mach-xxx/include/mach/gpio.h”里.
h3的gpio口定義在”arch/arm/mach-sunxi/include/mach/gpio.h”

#define SUNXI_BANK_SIZE 32
#define SUNXI_PA_BASE   0
#define SUNXI_PB_BASE   32
#define SUNXI_PC_BASE   64
#define SUNXI_PD_BASE   96
#define SUNXI_PE_BASE   128
#define SUNXI_PF_BASE   160
#define SUNXI_PG_BASE   192
#define SUNXI_PH_BASE   224
#define SUNXI_PI_BASE   256
#define SUNXI_PJ_BASE   288
#define SUNXI_PK_BASE   320
#define SUNXI_PL_BASE   352
#define SUNXI_PM_BASE   384
#define SUNXI_PN_BASE   416
#define SUNXI_PO_BASE   448
#define AXP_PIN_BASE    1024

#define SUNXI_PIN_NAME_MAX_LEN  8

/* sunxi gpio name space */
#define GPIOA(n)    (SUNXI_PA_BASE + (n))
#define GPIOB(n)    (SUNXI_PB_BASE + (n))
#define GPIOC(n)    (SUNXI_PC_BASE + (n))
#define GPIOD(n)    (SUNXI_PD_BASE + (n))
#define GPIOE(n)    (SUNXI_PE_BASE + (n))
#define GPIOF(n)    (SUNXI_PF_BASE + (n))
#define GPIOG(n)    (SUNXI_PG_BASE + (n))
#define GPIOH(n)    (SUNXI_PH_BASE + (n))
#define GPIOI(n)    (SUNXI_PI_BASE + (n))
#define GPIOJ(n)    (SUNXI_PJ_BASE + (n))
#define GPIOK(n)    (SUNXI_PK_BASE + (n))
#define GPIOL(n)    (SUNXI_PL_BASE + (n))
#define GPIOM(n)    (SUNXI_PM_BASE + (n))
#define GPION(n)    (SUNXI_PN_BASE + (n))
#define GPIOO(n)    (SUNXI_PO_BASE + (n))
#define GPIO_AXP(n) (AXP_PIN_BASE  + (n))

gpio口的操作過程,如控制status-led(接在PA15)的亮滅.

1 讓gpiolib導(dǎo)出PA15的控制文件. 可根據(jù)上面檢出PA15引腳對應(yīng)的gpio口序號為15
    echo 15 > /sys/class/gpio/export

   操作完成后,應(yīng)會在/sys/class/gpio/目錄下生成一個gpio15的子目錄.

2  在/sys/class/gpio/gpio15目錄有文件:
    /mnt/kernel_coding # ls /sys/class/gpio/gpio15/
    active_low  direction  edge   value

   //通過direction文件可控制gpio口是作輸入或輸出功能
    // echo "high" > /sys/class/gpio/gpio15/direction   是讓gpio口作輸出,并輸出高電平
    // echo "out"  > /sys/class/gpio/gpio15/direction   是作輸出功能,并輸出低電平
    // echo "in"   > /sys/class/gpio/gpio15/direction   是作輸入功能
   //通過value文件可以獲取和控制gpio口的電平(當(dāng)gpio口作輸出時(shí),可以通過寫操作改變電平。當(dāng)作輸入時(shí),可以通過讀操作獲取電平) 
    // echo "1" > /sys/class/gpio/gpio15/value    讓gpio口輸出高電平
    // echo "0" > /sys/class/gpio/gpio15/value    讓gpio口輸出低電平
   //通過edge文件, 可以指定gpio作中斷功能,并指定它的觸發(fā)電平和獲取. 觸發(fā)電平方式有("none", "falling", "rising", "both")

   //通過active_low文件,可以指定往value文件寫1時(shí)為有效電平.
    如: echo "1" > /sys/calss/gpio/gpio15/value時(shí)是輸出高電平的
       當(dāng)echo "1" > /sys/calss/gpio/gpio15/active_low后, 再往value寫1是就是輸出低電平了.


工作原理可參考https://blog.csdn.net/jklinux/article/details/73896459

702 static struct class_attribute gpio_class_attrs[] = {
 703     __ATTR(export, 0200, NULL, export_store),  // 當(dāng)對/sys/class/gpio/export進(jìn)行寫操作時(shí),會觸發(fā)調(diào)用export_store函數(shù)
 704     __ATTR(unexport, 0200, NULL, unexport_store),
 705     __ATTR_NULL,
 706 };
 707 
 708 static struct class gpio_class = {
 709     .name =     "gpio",
 710     .owner =    THIS_MODULE,
 711 
 712     .class_attrs =  gpio_class_attrs, //指定了屬性文件. (/sys/class/gpio/export,  /sys/class/gpio/unexport)
 713 };


 997 static int __init gpiolib_sysfs_init(void)
 998 {
        ...
1003     status = class_register(&gpio_class); //注冊class后就會生成/sys/class/gpio目錄,并在目錄下生成gpio_class的屬性文件
        ...
1029 }
1030 postcore_initcall(gpiolib_sysfs_init); //系統(tǒng)初始化時(shí)會調(diào)用

//當(dāng)對"echo gpio口對應(yīng)的序號 > /sys/class/gpio/export"進(jìn)行寫操作時(shí),會觸發(fā)調(diào)用export_store函數(shù)
 637 static ssize_t export_store(struct class *class,
 638                 struct class_attribute *attr,
 639                 const char *buf, size_t len)
 640 {
 641     long    gpio;
 642     int status;
 643 
 644     status = strict_strtol(buf, 0, &gpio); //把字符串buf里描述的gpio口序號轉(zhuǎn)成long類型變量gpio
        ...
 653     status = gpio_request(gpio, "sysfs"); //請求gpio口
        ...
 659     status = gpio_export(gpio, true); //再調(diào)用gpio_export函數(shù)來處理請求的gpio口
        ...
 669 }


 731 int gpio_export(unsigned gpio, bool direction_may_change)
 732 {
        ...
 774     dev = device_create_with_groups(&gpio_class, desc->chip->dev,
 775                     MKDEV(0, 0), desc, gpio_groups,
 776                     ioname ? ioname : "gpio%u", gpio); //會在/sys/class/gpio/目錄下生成一個名為"gpio"+gpio口序號的子目錄(請gpio口為15, 則子目錄名為"gpio15"), 并在子目錄生成"direction, edge,value, active_low"等屬性文件
        ...
 790 }
 791 EXPORT_SYMBOL_GPL(gpio_export);

 571 static struct attribute *gpio_attrs[] = {
 572     &dev_attr_direction.attr,
 573     &dev_attr_edge.attr,
 574     &dev_attr_value.attr,
 575     &dev_attr_active_low.attr,
 576     NULL,
 577 };
 578 
 579 static const struct attribute_group gpio_group = {
 580     .attrs = gpio_attrs,
 581     .is_visible = gpio_is_visible,
 582 };
 583 
 584 static const struct attribute_group *gpio_groups[] = {
 585     &gpio_group,
 586     NULL
 587 };


///////////////////////////////////
 242 static ssize_t gpio_direction_store(struct device *dev,
 243         struct device_attribute *attr, const char *buf, size_t size)
 244 {
 245     const struct gpio_desc  *desc = dev_get_drvdata(dev);
 246     unsigned        gpio = desc - gpio_desc;
 247     ssize_t         status;
 248 
 249     mutex_lock(&sysfs_lock);
 250 
 251     if (!test_bit(FLAG_EXPORT, &desc->flags))
 252         status = -EIO;
 253     else if (sysfs_streq(buf, "high"))
 254         status = gpio_direction_output(gpio, 1);
 255     else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low"))
 256         status = gpio_direction_output(gpio, 0);
 257     else if (sysfs_streq(buf, "in"))
 258         status = gpio_direction_input(gpio);
 259     else
 260         status = -EINVAL;
 261 
 262     mutex_unlock(&sysfs_lock);
 263     return status ? : size;
 264 }
 265 
 266 static DEVICE_ATTR(direction, 0644,
 267         gpio_direction_show, gpio_direction_store); // 當(dāng)對direction屬性文件寫操作時(shí),觸發(fā)調(diào)用gpio_direction_store. 如寫"out"則把gpio口作為輸出,并輸出低電平. 同樣的原理,可以通過value屬性文件操作gpio口的電平狀態(tài).

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    91蜜臀精品一区二区三区| 大香伊蕉欧美一区二区三区| 男女午夜视频在线观看免费| 亚洲中文字幕视频一区二区| 青青操精品视频在线观看| 丝袜破了有美女肉体免费观看| 国产91人妻精品一区二区三区| 国产精品成人一区二区三区夜夜夜| 国产在线成人免费高清观看av| 日本妇女高清一区二区三区| 高潮日韩福利在线观看| 中文字幕亚洲人妻在线视频| 空之色水之色在线播放| 男女午夜福利院在线观看| 中文字幕欧美视频二区| 能在线看的视频你懂的| 成人三级视频在线观看不卡| 日韩精品一区二区毛片| 国产又黄又爽又粗视频在线| 色婷婷成人精品综合一区| 欧美有码黄片免费在线视频| 91福利视频日本免费看看 | 人妻精品一区二区三区视频免精 | 亚洲免费黄色高清在线观看| 青青操在线视频精品视频| 亚洲日本韩国一区二区三区| 视频在线观看色一区二区| 91亚洲精品亚洲国产| 亚洲av一区二区三区精品| 久久少妇诱惑免费视频| 国内女人精品一区二区三区| 日韩精品中文字幕在线视频| 国产精品涩涩成人一区二区三区| 欧美成人免费夜夜黄啪啪| 久久久精品日韩欧美丰满| 国产女性精品一区二区三区 | 樱井知香黑人一区二区| 日本一本在线免费福利| 国产精品午夜一区二区三区| 久久精品国产99精品亚洲| 国产精品香蕉在线的人|