• 【linux】gpio子系统



    前言

    linux子系统

    • 在 Linux 系统中
      • 绝大多数硬件设备都有非常成熟的驱动框架
      • 驱动工程师使用这些框架添加与板子相关的硬件支持
        • 建立硬件与Linux内核的联系
      • 内核再通过统一文件系统接口呈现给用户
      • 用户通过对应的设备文件控制硬件。

    gpio子系统

    • gpio子系统相关描述可在内核源码 Documentation/gpio 了解。
      • 但是新版本(linux4.19左右)不再维护这个路径的ABI
      • ABI文档已经移动到 Documentation/ABI/obsolete/sysfs-gpio
    • gpio子系统 ,在目录 /sys/class/gpio 下展示该子系统设备。
      • export 和 unexport:把某个GPIO导出用户空间和取消导出用户空间

        • echo 19 > export
          • 就把gpio19导出到用户空间
      • gpioN:GPIOs 本身,N为索引号,根据不同的开发芯片而有不同的计算

        • 例子:N = index = GPIO1_19 = (1-1)*32 +19 = 19
          • 一组端口有 32 个gpio
        • 该目录下有三个属性文件
          • direction
            • gpio端口的方向,内容可以是 in 或者 out
              • 读取
              • 写入
                • 例子:echo out > /sys/class/gpio/gpio19/direction
            • 如果写入 low 或者 hight,则不仅设置为输出,还同时设置了输出电平(本小点要了解当前内核是否支持
          • value
            • gpio引脚的电平
              • 0:低电平
              • 非0:高电平(高电平建议使用 1
            • 如果配置为输入,则该文件可写
            • 如果配置为中断,则可以调用poll(2)函数监听该中断,中断触发后poll(2)函数就会返回。
          • edge
            • 中断的触发方式,该文件有4个值
              • none:输入,非中断
              • rising:中断输入,上升沿触发
              • falling:中断输入,下降沿触发
              • both:中断输入,边沿触发
          • active_low
      • GPIO控制器(“gpio_chip”instances)(此处没有体现)。

    • gpio子系统与led子系统是不同,但是类似
      • led只能输出,gpio能输出也能输入
        • gpio输入还支持中断功能
      • 使用gpio前,需要从内核空间暴露到用户空间
    • 注意
      • 在用户空间控制使用gpio时,注意不要滥用和内核一些绑定好、已经有合适内核启动的引脚冲突。
        • 参考 Documentation/driver-api/gpio/drivers-on-gpio.rst

    gpio子系统实战-系统调用

    • 源码简单,下面贴出野火的源码仅做参考
    • main.c
    /** @file         main.c
     *  @brief        简要说明
     *  @details      详细说明
     *  @author       
     *  @date         2020-11-11 19:18:20
     *  @version      v1.0
     *  @copyright    Copyright By  , All Rights Reserved
     *
     **********************************************************
     *  @LOG 修改日志:
     **********************************************************
    */
    
    #include <stdio.h>
    #include <unistd.h>
    #include "bsp_beep.h"
    
    /**
     * @brief  主函数
     * @param  无
     * @retval 无
     */
    int main(int argc, char *argv[])
    {
    	char buf[10];
    	int res;
    	printf("This is the beep demo
    ");
    	
    	res = beep_init();
    	if(res){
    		printf("beep init error,code = %d",res);
    		return 0;
    	}
    
    	while(1){
    		printf("Please input the value : 0--off 1--on q--exit
    ");
    		scanf("%10s", buf);
    
    		switch (buf[0]){
    			case '0':
    				beep_off();
    				break;
    
    			case '1':
    				beep_on();
    				break;
    
    			case 'q':
    				beep_deinit();
    				printf("Exit
    ");
    				return 0;
    
    			default:
    				break;
    		}
    	}
    }
    
    • bsp_beep.c
    /** @file         bsp_beep.c
     *  @brief        简要说明
     *  @details      详细说明
     *  @author       
     *  @date         2020-11-11 13:57:52
     *  @version      v1.0
     *  @copyright    Copyright By  , All Rights Reserved
     *
     **********************************************************
     *  @LOG 修改日志:
     **********************************************************
    */
    
    #include <stdio.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include "bsp_beep.h"
    
    int beep_init(void)
    {
        int fd;
        fd = open("/sys/class/gpio/export",O_WRONLY);
        if(fd < 0)
        {
            return 1;
        }
        write(fd, BEEP_GPIO_INDEX, strlen(BEEP_GPIO_INDEX));
        close(fd);
        //direction config
        fd = open("/sys/class/gpio/gpio" BEEP_GPIO_INDEX "/direction", O_WRONLY);
        if(fd < 0)
           return 2;
    
        write(fd, "out", strlen("out"));
        close(fd);
    
        return 0;
    }
    
    
    int beep_deinit(void)
    {
       int fd;
       fd = open("/sys/class/gpio/unexport", O_WRONLY);
       if(fd < 0)
          return 1;
    
       write(fd, BEEP_GPIO_INDEX, strlen(BEEP_GPIO_INDEX));
       close(fd);
    
       return 0;
    }
    
    
    int beep_on(void)
    {
       int fd;
    
       fd = open("/sys/class/gpio/gpio" BEEP_GPIO_INDEX "/value", O_WRONLY);
       if(fd < 0)
          return 1;
    
       write(fd, "1", 1);
       close(fd);
    
       return 0;
    }
    
    int beep_off(void)
    {
       int fd;
    
       fd = open("/sys/class/gpio/gpio" BEEP_GPIO_INDEX "/value", O_WRONLY);
       if(fd < 0)
          return 1;
    
       write(fd, "0", 1);
       close(fd);
    
       return 0;
    }
    
    
    • bsp_beep.h
    /** @file         bsp_beep.h
     *  @brief        简要说明
     *  @details      详细说明
     *  @author       
     *  @date         2020-11-11 19:13:47
     *  @version      v1.0
     *  @copyright    Copyright By  , All Rights Reserved
     *
     **********************************************************
     *  @LOG 修改日志:
     **********************************************************
    */
    
    #ifndef __bsp_beep__
    #define __bsp_beep__
    //蜂鸣器的GPIO引脚号
    //imx6的计算方式,GPIOn_IOx = (n-1)*32 + x
    //如GPIO1_IO19 = (1-1)*32 + 19 = 19
    #define BEEP_GPIO_INDEX 	"19"
    /**
     * @brief  初始化蜂鸣器gpio相关
     * @return 
     *     @arg 0,正常
     *     @arg 1,export文件打开错误
     *     @arg 2,direction文件打开错误
     */
    extern int beep_init(void);
    /**
     * @brief  关闭蜂鸣器gpio的export输出
     * @return 0正常,非0,value文件打开错误
     */
    extern int beep_deinit(void);
    /**
     * @brief  蜂鸣器响
     * @return 0正常,非0,value文件打开错误
     */
    extern int beep_on(void);
    /**
     * @brief  关闭蜂鸣器gpio的export输出
     * @return 0正常,非0,unexport文件打开错误
     */
    extern int beep_off(void);
    #endif /* Head define end*/
    
    
    
  • 相关阅读:
    time和/usr/bin/time
    Linux系统-real/user/sys time
    PL/SQL:集合类型 (定义,分类,使用场景,集合方法)
    关于Android开发中使用的XML
    Android Studio 常用快捷键
    Android中Adapter总结
    Android 中的 Context
    Android Studio 项目结构
    Android Studio 连接真机调试
    Android Studio 入门
  • 原文地址:https://www.cnblogs.com/lizhuming/p/14002125.html
Copyright © 2020-2023  润新知