ps怎么在dw上做网站,建设网站最好的,淘宝联盟里的网站推广怎么做,青岛哪家做网站好在linux里面使用GPIO的一些知识点记录如下#xff1a;
一、驱动里面操作GPIO 在linux内核里面如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话#xff0c;那么就可以用gpio 子系统提供的 API 函数操做gpio#xff0c;比如设置 GPIO为输入输出#xff0c;读取 GPIO 的值等… 在linux里面使用GPIO的一些知识点记录如下
一、驱动里面操作GPIO 在linux内核里面如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话那么就可以用gpio 子系统提供的 API 函数操做gpio比如设置 GPIO为输入输出读取 GPIO 的值等。gpio 子系统的主要目的就是方便驱动开发者使用 gpio驱动开发者在设备树中添加 gpio 相关信息然后就可以在驱动程序中使用 gpio 子系统提供的 API函数来操作 GPIO。
1.1、从设备树上查找节点的 OF 函数 设备都是以节点的形式“挂”到设备树上的因此要想获取这个设备的其他属性信息必须先获取到这个设备的节点。Linux 内核使用 device_node 结构体来描述一个节点此结构体定义在文件 include/linux/of.h 中与查找节点有关的 OF 函数有 5 个。
1.1.1、of_find_node_by_name 函数 of_find_node_by_name 函数通过节点名字查找指定的节点函数原型如下
struct device_node *of_find_node_by_name(struct device_node *from,const char *name);函数参数和返回值含义如下 from开始查找的节点如果为 NULL 表示从根节点开始查找整个设备树。 name要查找的节点名字。 返回值找到的节点如果为 NULL 表示查找失败。
1.1.2、of_find_node_by_type 函数 of_find_node_by_type 函数通过 device_type 属性查找指定的节点函数原型如下
struct device_node *of_find_node_by_type(struct device_node *from, const char *type)函数参数和返回值含义如下 from开始查找的节点如果为 NULL 表示从根节点开始查找整个设备树。 type要查找的节点对应的 type 字符串也就是 device_type 属性值。 返回值找到的节点如果为 NULL 表示查找失败。
1.1.3、of_find_compatible_node 函数 of_find_compatible_node 函数根据 device_type 和 compatible 这两个属性查找指定的节点 函数原型如下
struct device_node *of_find_compatible_node(struct device_node *from,const char *type, const char *compatible)函数参数和返回值含义如下 from开始查找的节点如果为 NULL 表示从根节点开始查找整个设备树。 type要查找的节点对应的 type 字符串也就是 device_type 属性值可以为 NULL表示忽略掉 device_type 属性。 compatible要查找的节点所对应的 compatible 属性列表。 返回值找到的节点如果为 NULL 表示查找失败
1.1.4、of_find_matching_node_and_match 函数 of_find_matching_node_and_match 函数通过 of_device_id 匹配表来查找指定的节点函数原型如下
struct device_node *of_find_matching_node_and_match(struct device_node *from,const struct of_device_id *matches,const struct of_device_id **match)函数参数和返回值含义如下 from开始查找的节点如果为 NULL 表示从根节点开始查找整个设备树。 matchesof_device_id 匹配表也就是在此匹配表里面查找节点。 match找到的匹配的 of_device_id。 返回值找到的节点如果为 NULL 表示查找失败
1.1.5、of_find_node_by_path 函数 of_find_node_by_path 函数通过路径来查找指定的节点函数原型如下
inline struct device_node *of_find_node_by_path(const char *path)函数参数和返回值含义如下 path带有全路径的节点名可以使用节点的别名比如“/backlight”就是 backlight 这个节点的全路径。 返回值找到的节点如果为 NULL 表示查找失败
1.2、与 gpio 相关的 OF 函数
1.2.1、of_get_named_gpio 函数 此函数获取 GPIO 编号因为 Linux 内核中关于 GPIO 的 API 函数都要使用 GPIO 编号此函数会将设备树中类似gpio5 7 GPIO_ACTIVE_LOW的属性信息转换为对应的 GPIO 编号此函数在驱动中使用很频繁函数原型如下
int of_get_named_gpio(struct device_node *np,const char *propname, int index)函数参数和返回值含义如下 np设备节点。例如从of_find_node_by_path函数获取的设备节点。 propname包含要获取 GPIO 信息的属性名。 indexGPIO 索引因为一个属性里面可能包含多个 GPIO此参数指定要获取哪个 GPIO的编号如果只有一个 GPIO 信息的话此参数为 0。 返回值正值获取到的 GPIO 编号负值失败。
1.3、gpio 子系统 API 函数 对于驱动开发人员设置好设备树以后就可以使用 gpio 子系统提供的 API 函数来操作指定的 GPIOgpio 子系统向驱动开发人员屏蔽了具体的读写寄存器过程。gpio 子系统提供的常用的 API 函数有下面几个
1.3.1、gpio_request 函数 gpio_request 函数用于申请一个 GPIO 管脚在使用一个 GPIO 之前一定要使用 gpio_request进行申请函数原型如下
int gpio_request(unsigned gpio, const char *label)函数参数和返回值含义如下 gpio要申请的 gpio 标号使用 of_get_named_gpio 函数从设备树获取指定 GPIO 属性信息此函数会返回这个 GPIO 的标号。 label给 gpio 设置个名字。 返回值0申请成功其他值申请失败。 一般来说一个GPIO只是分配给一个设备的所以这个设备的驱动会请求这个GPIO。这样在其他的设备也想请求这个GPIO的时候会返回失败。事实上gpio_request只是给这个GPIO做一个标示并没有什么实质的作用。操作GPIO是通过gpio_set_value、gpio_direction_output之类的函数去做的即便没有request一样可以设置GPIO的电平。对于设备驱动来说应该保证每一个在初始化的时候一般是probe对和设备有关的GPIO都进行一次gpio_request在remove时候时候使用gpio_free。当然如果probe失败应该在probe里面free掉已经request过的GPIO。每次使用的时候不需要再request和free了只需要直接gpio_set_value就可以了。关于gpio_request函数的具体介绍可以在linux内核文件kernel/Documentation/gpio/gpio-legacy.txt查看。
1.3.2、gpio_free 函数 如果不使用某个 GPIO 了那么就可以调用 gpio_free 函数进行释放。函数原型如下
void gpio_free(unsigned gpio)函数参数和返回值含义如下 gpio要释放的 gpio 标号。 返回值无。
1.3.3、gpio_direction_input 函数 此函数用于设置某个 GPIO 为输入函数原型如下所示
int gpio_direction_input(unsigned gpio)函数参数和返回值含义如下 gpio要设置为输入的 GPIO 标号。 返回值0设置成功负值设置失败。
1.3.4、gpio_direction_output 函数 此函数用于设置某个 GPIO 为输出并且设置默认输出值函数原型如下
int gpio_direction_output(unsigned gpio, int value)函数参数和返回值含义如下 gpio要设置为输出的 GPIO 标号。 valueGPIO 默认输出值。 返回值0设置成功负值设置失败。
1.3.5、gpio_get_value 函数 此函数用于获取某个 GPIO 的值(0 或 1)此函数是个宏定义所示
#define gpio_get_value __gpio_get_value
int __gpio_get_value(unsigned gpio)函数参数和返回值含义如下 gpio要获取的 GPIO 标号。 返回值非负值得到的 GPIO 值负值获取失败。
1.3.6、gpio_set_value 函数 此函数用于设置某个 GPIO 的值此函数是个宏定义如下
#define gpio_set_value __gpio_set_value
void __gpio_set_value(unsigned gpio, int value)函数参数和返回值含义如下 gpio要设置的 GPIO 标号。 value要设置的值。 返回值无
1.4、使用MISC 驱动gpio的实例 所有的 MISC 设备驱动的主设备号都为 10不同的设备使用不同的从设备号。MISC 设备会自动创建 cdev不需手动创建因此采用 MISC 设备驱动可以简化字符设备驱动的编写。
#include linux/types.h
#include linux/kernel.h
#include linux/delay.h
#include linux/ide.h
#include linux/init.h
#include linux/module.h
#include linux/errno.h
#include linux/gpio.h
#include linux/cdev.h
#include linux/device.h
#include linux/of.h
#include linux/of_address.h
#include linux/of_gpio.h
#include linux/platform_device.h
#include linux/miscdevice.h
#include asm/mach/map.h
#include asm/uaccess.h
#include asm/io.h#define MISCBEEP_NAME miscbeep /* 名字 在/dev目录下生成的文件应用层根据此名字操作驱动程序 */
#define BEEPOFF 0 /* 关蜂鸣器 */
#define BEEPON 1 /* 开蜂鸣器 *//* miscbeep设备结构体 */
struct miscbeep_dev
{struct device_node *nd; /* 设备节点 */int beep_gpio; /* beep所使用的GPIO编号 */
};struct miscbeep_dev miscbeep; /* beep设备 *//** description : 打开设备* param - inode : 传递给驱动的inode* param - filp : 设备文件file结构体有个叫做private_data的成员变量* 一般在open的时候将private_data指向设备结构体。* return : 0 成功;其他 失败*/
static int miscbeep_open(struct inode *inode, struct file *filp)
{filp-private_data miscbeep; /* 设置私有数据 */return 0;
}/** description : 向设备写数据 * param - filp : 设备文件表示打开的文件描述符* param - buf : 要写给设备写入的数据* param - cnt : 要写入的数据长度* param - offt : 相对于文件首地址的偏移* return : 写入的字节数如果为负值表示写入失败*/
static ssize_t miscbeep_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{int retvalue;unsigned char databuf[1];unsigned char beepstat;struct miscbeep_dev *dev filp-private_data;retvalue copy_from_user(databuf, buf, cnt);if(retvalue 0) {printk(kernel write failed!\r\n);return -EFAULT;}beepstat databuf[0]; /* 获取状态值 */if(beepstat BEEPON) { gpio_set_value(dev-beep_gpio, 0); /* 打开蜂鸣器 */} else if(beepstat BEEPOFF) {gpio_set_value(dev-beep_gpio, 1); /* 关闭蜂鸣器 */}return 0;
}/* 设备操作函数 */
static struct file_operations miscbeep_fops {.owner THIS_MODULE,.open miscbeep_open,.write miscbeep_write,
};/* MISC设备结构体 */
static struct miscdevice beep_miscdev {.minor MISC_DYNAMIC_MINOR,//动态生成次设备号.name MISCBEEP_NAME,.fops miscbeep_fops,
};/** description : flatform驱动的probe函数当驱动与* 设备匹配以后此函数就会执行* param - dev : platform设备* return : 0成功;其他负值,失败*/
static int miscbeep_probe(struct platform_device *dev)
{int ret 0;printk(beep driver and device was matched!\r\n);/* 设置BEEP所使用的GPIO *//* 1、获取设备节点beep */miscbeep.nd of_find_node_by_path(/beep);if(miscbeep.nd NULL) {printk(beep node not find!\r\n);return -EINVAL;} /* 2、 获取设备树中的gpio属性得到BEEP所使用的BEEP编号 */miscbeep.beep_gpio of_get_named_gpio(miscbeep.nd, beep-gpio, 0);if(miscbeep.beep_gpio 0) {printk(cant get beep-gpio);return -EINVAL;}retgpio_request(miscbeep.beep_gpio, beep); /* 请求IO */if(ret 0) {printk(gpio_request error!\r\n);}/* 3、设置GPIO5_IO01为输出并且输出高电平默认关闭BEEP */ret gpio_direction_output(miscbeep.beep_gpio, 1);if(ret 0) {printk(cant set gpio!\r\n);}/* 一般情况下会注册对应的字符设备但是这里我们使用MISC设备* 所以我们不需要自己注册字符设备驱动只需要注册misc设备驱动即可*/ret misc_register(beep_miscdev);if(ret 0){printk(misc device register failed!\r\n);return -EFAULT;}return 0;
}/** description : platform驱动的remove函数移除platform驱动的时候此函数会执行* param - dev : platform设备* return : 0成功;其他负值,失败*/
static int miscbeep_remove(struct platform_device *dev)
{/* 注销设备的时候关闭LED灯 */gpio_set_value(miscbeep.beep_gpio, 1);/* 注销misc设备 */misc_deregister(beep_miscdev);return 0;
}/* 匹配列表 */static const struct of_device_id beep_of_match[] {{ .compatible atkalpha-beep },{ /* Sentinel */ }};/* platform驱动结构体 */
static struct platform_driver beep_driver {.driver {.name imx6ul-beep, /* 驱动名字用于和设备匹配 */.of_match_table beep_of_match, /* 设备树匹配表 */},.probe miscbeep_probe,.remove miscbeep_remove,
};/** description : 驱动出口函数* param : 无* return : 无*/
static int __init miscbeep_init(void)
{return platform_driver_register(beep_driver);
}/** description : 驱动出口函数* param : 无* return : 无*/
static void __exit miscbeep_exit(void)
{platform_driver_unregister(beep_driver);
}module_init(miscbeep_init);
module_exit(miscbeep_exit);
MODULE_LICENSE(GPL);
二、Linux不通过驱动直接控制GPIO GPIO 可以通过 sysfs 方式进行操控进入到/sys/class/gpio 目录下可以看到该目录下包含两个文件 export、unexport 以及 5 个 gpiochipXX 等于 0、32、64、96、128命名的文件夹。 gpiochipX当前 SoC 所包含的 GPIO 控制器我们知道 I.MX6UL/I.MX6ULL 一共包含了 5 个 GPIO控制器分别为 GPIO1、GPIO2、GPIO3、GPIO4、GPIO5在这里分别对应 gpiochip0、gpiochip32、gpiochip64、gpiochip96、gpiochip128 这 5 个文件夹每一个 gpiochipX 文件夹用来管理一组 GPIO。 对于给定的一个 GPIO 引脚如何计算它在 sysfs 中对应的编号呢其实非常简单譬如给定一个 GPIO引脚为 GPIO4_IO16那它对应的编号是多少呢首先我们要确定 GPIO4 对应于 gpiochip96该组 GPIO 引脚的最小编号是 96对应于 GPIO4_IO0所以 GPIO4_IO16 对应的编号自然是 96 16 112同理GPIO3_IO20 对应的编号是 64 20 84。 export用于将指定编号的 GPIO 引脚导出。在使用 GPIO 引脚之前需要将其导出导出成功之后才能使用它。注意 export 文件是只写文件不能读取将一个指定的编号写入到 export 文件中即可将对应的 GPIO 引脚导出 如果没有相应的GPIO则需要向export文件写入要操作的GPIO编号使得该GPIO的操作接口从内核空间暴露到用户空间。 下面一个shell脚本可以读出相应的GPIO编号
#! /bin/sh
for i in /sys/class/gpio/gpiochip*
do
echo cat $i/label: cat $i/base
done导出之后就可以两种方法进行操作
2.1、直接读写
2.1.1、在shell里面可以 导出110号GPIO /sys/class/gpio# echo 110 export 设置方向为输出 /sys/class/gpio/gpio110# echo out direction 设置输出高电平 /sys/class/gpio/gpio110# echo 1 value 取消导出110号GPIO /sys/class/gpio# echo 110 unexport
2.1.1、在应用程序里面里面可以 导出110号GPIO system(“echo 110 /sys/class/gpio/export”); 设置方向为输出 system(“echo out /sys/class/gpio/gpio110/direction”); 设置输出高电平 system(“echo 1 /sys/class/gpio/gpio110/value”); 取消导出110号GPIO system(“echo 110 /sys/class/gpio/unexport”);
2.2、通过文件形式读写
static int GPIOConfig(const char *attr, const char *val)
{char file_path[100];int len;int fd;char *gpiopath /sys/class/gpio/gpio110;sprintf(file_path, %s/%s, gpiopath, attr);if (0 (fd open(file_path, O_WRONLY))) {perror(open error);return fd;}len strlen(val);if (len ! write(fd, val, len)) {perror(write error);close(fd);return -1;}close(fd); //关闭文件return 0;
}
int GPIOInit(void)
{int fd;char gpiopath[] /sys/class/gpio/gpio110;if (access(gpiopath, F_OK)) //如果目录不存在 则需要导出{if (0 (fd open(/sys/class/gpio/export, O_WRONLY))) //打开export{printf(open error: %s,strerror(errno));return -1;}if (3 ! write(fd, 110, 3))//导出GPIO{printf(write error: %s,strerror(errno));close(fd);return -1;}close(fd); //关闭文件sleep(1);//延时1S防止还没有导出GPIO就对GPIO进行操作} if (GPIOConfig(direction, out)) return -1;/* 配置为输出模式 */if (GPIOConfig(active_low, 0)) return -1; /* 配置极性为0 */if (GPIOConfig(value, 1)) return -1; /* 输出高电平 */return 0;
}
文章转载自: http://www.morning.gwsdt.cn.gov.cn.gwsdt.cn http://www.morning.hqwxm.cn.gov.cn.hqwxm.cn http://www.morning.ghrhb.cn.gov.cn.ghrhb.cn http://www.morning.rgsgk.cn.gov.cn.rgsgk.cn http://www.morning.rfpq.cn.gov.cn.rfpq.cn http://www.morning.ldzss.cn.gov.cn.ldzss.cn http://www.morning.yhtnr.cn.gov.cn.yhtnr.cn http://www.morning.gxtfk.cn.gov.cn.gxtfk.cn http://www.morning.jzklb.cn.gov.cn.jzklb.cn http://www.morning.kjkml.cn.gov.cn.kjkml.cn http://www.morning.yrdkl.cn.gov.cn.yrdkl.cn http://www.morning.mftzm.cn.gov.cn.mftzm.cn http://www.morning.tfpmf.cn.gov.cn.tfpmf.cn http://www.morning.krtcjc.cn.gov.cn.krtcjc.cn http://www.morning.wgdnd.cn.gov.cn.wgdnd.cn http://www.morning.qcsbs.cn.gov.cn.qcsbs.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.gtbjf.cn.gov.cn.gtbjf.cn http://www.morning.fbdtd.cn.gov.cn.fbdtd.cn http://www.morning.pzbqm.cn.gov.cn.pzbqm.cn http://www.morning.rdnjc.cn.gov.cn.rdnjc.cn http://www.morning.gpcy.cn.gov.cn.gpcy.cn http://www.morning.hytr.cn.gov.cn.hytr.cn http://www.morning.rfwrn.cn.gov.cn.rfwrn.cn http://www.morning.jhrtq.cn.gov.cn.jhrtq.cn http://www.morning.qwmdx.cn.gov.cn.qwmdx.cn http://www.morning.fyxr.cn.gov.cn.fyxr.cn http://www.morning.ymwcs.cn.gov.cn.ymwcs.cn http://www.morning.yfmlj.cn.gov.cn.yfmlj.cn http://www.morning.rblqk.cn.gov.cn.rblqk.cn http://www.morning.glnxd.cn.gov.cn.glnxd.cn http://www.morning.rjrnx.cn.gov.cn.rjrnx.cn http://www.morning.qcbhb.cn.gov.cn.qcbhb.cn http://www.morning.cqwb25.cn.gov.cn.cqwb25.cn http://www.morning.wnrcj.cn.gov.cn.wnrcj.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.ctlbf.cn.gov.cn.ctlbf.cn http://www.morning.snygg.cn.gov.cn.snygg.cn http://www.morning.pjtnk.cn.gov.cn.pjtnk.cn http://www.morning.gwwtm.cn.gov.cn.gwwtm.cn http://www.morning.nsrlb.cn.gov.cn.nsrlb.cn http://www.morning.lnfkd.cn.gov.cn.lnfkd.cn http://www.morning.buyid.com.cn.gov.cn.buyid.com.cn http://www.morning.zrpys.cn.gov.cn.zrpys.cn http://www.morning.mgwpy.cn.gov.cn.mgwpy.cn http://www.morning.czgtt.cn.gov.cn.czgtt.cn http://www.morning.ptwzy.cn.gov.cn.ptwzy.cn http://www.morning.qkrqt.cn.gov.cn.qkrqt.cn http://www.morning.gyqnc.cn.gov.cn.gyqnc.cn http://www.morning.mslsn.cn.gov.cn.mslsn.cn http://www.morning.btnmj.cn.gov.cn.btnmj.cn http://www.morning.dwzwm.cn.gov.cn.dwzwm.cn http://www.morning.qblcm.cn.gov.cn.qblcm.cn http://www.morning.hrnrx.cn.gov.cn.hrnrx.cn http://www.morning.xmnlc.cn.gov.cn.xmnlc.cn http://www.morning.slnz.cn.gov.cn.slnz.cn http://www.morning.ljzss.cn.gov.cn.ljzss.cn http://www.morning.clkyw.cn.gov.cn.clkyw.cn http://www.morning.kjrlp.cn.gov.cn.kjrlp.cn http://www.morning.pngph.cn.gov.cn.pngph.cn http://www.morning.qpqb.cn.gov.cn.qpqb.cn http://www.morning.wwxg.cn.gov.cn.wwxg.cn http://www.morning.xqgh.cn.gov.cn.xqgh.cn http://www.morning.wjqyt.cn.gov.cn.wjqyt.cn http://www.morning.qfrsm.cn.gov.cn.qfrsm.cn http://www.morning.nmymn.cn.gov.cn.nmymn.cn http://www.morning.qjrjs.cn.gov.cn.qjrjs.cn http://www.morning.lqffg.cn.gov.cn.lqffg.cn http://www.morning.mdlqf.cn.gov.cn.mdlqf.cn http://www.morning.rqqlp.cn.gov.cn.rqqlp.cn http://www.morning.aswev.com.gov.cn.aswev.com http://www.morning.mtzyr.cn.gov.cn.mtzyr.cn http://www.morning.jbpdk.cn.gov.cn.jbpdk.cn http://www.morning.rkjz.cn.gov.cn.rkjz.cn http://www.morning.tqrbl.cn.gov.cn.tqrbl.cn http://www.morning.qdbcd.cn.gov.cn.qdbcd.cn http://www.morning.lwgrf.cn.gov.cn.lwgrf.cn http://www.morning.hphrz.cn.gov.cn.hphrz.cn http://www.morning.jcyyh.cn.gov.cn.jcyyh.cn http://www.morning.jlktz.cn.gov.cn.jlktz.cn