Linux内核中的GPIO驱动
来源:互联网 发布:java身份证工具类 编辑:程序博客网 时间:2024/06/04 19:04
本文参考linux官方文档https://www.kernel.org/doc/Documentation/gpio/consumer.txt进行编写。
头文件
需要首先包含头文件
#include <linux/gpio/consumer.h>
获取&释放
使用一下两个函数获取GPIO设备,多个设备时需要附带index参数。函数返回一个GPIO描述符,或一个错误编码,可以使用IS_ERR()进行检查:
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id, enum gpiod_flags flags)struct gpio_desc *gpiod_get_index(struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags flags)
或者也可以使用如下两个函数获取可用设备:
struct gpio_desc *gpiod_get_optional(struct device *dev, const char *con_id, enum gpiod_flags flags)struct gpio_desc *gpiod_get_index_optional(struct device *dev, const char *con_id, unsigned int index, enum gpiod_flags flags)
使用如下函数同时获取多个设备:
struct gpio_descs *gpiod_get_array(struct device *dev, const char *con_id, enum gpiod_flags flags)
该函数返回一个GPIO描述序列:
struct gpio_descs { unsigned int ndescs; struct gpio_desc *desc[];}
一个GPIO描述符可以使用如下函数释放:
void gpiod_put(struct gpio_desc *desc)void gpiod_put_array(struct gpio_descs *descs)
需要注意GPIO描述符被释放后不可再使用,而且不允许使用第一个函数来释放通过序列获取得到GPIO描述符。
使用GPIO
- 设置方向(Input | Output)
使用如下函数设置一个设备的方向
int gpiod_direction_input(struct gpio_desc *desc)
int gpiod_direction_output(struct gpio_desc *desc, int value)
使用如下函数检查一个设备的方向:int gpiod_get_direction(const struct gpio_desc *desc)
函数返回GPIOF_DIR_IN或者GPIOF_DIR_OUT 访问
访问分为两种,一种是通过储存器读写实现的,这种操作属于原子操作,不需要等待,所以可以在中断处理程序中使用:int gpiod_get_value(const struct gpio_desc *desc);void gpiod_set_value(struct gpio_desc *desc, int value);
还有一种访问必须通过消息总线比如I2C或者SPI,这种访问需要在总线访问队列中等待,所以可能进入睡眠,此类访问不能出现在IRQ handler。
可以使用如下函数分辨这些设备:int gpiod_cansleep(const struct gpio_desc *desc)
使用如下函数读写:
int gpiod_get_value_cansleep(const struct gpio_desc *desc)void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
active-low & raw value
有些设备采用低电平有效的方式输出逻辑信号。此时低电平输出1,高电平输出0。此时可以通过访问raw_value的方式来访问实际电路上的值,与逻辑处理无关:int gpiod_get_raw_value(const struct gpio_desc *desc)void gpiod_set_raw_value(struct gpio_desc *desc, int value)int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
逻辑关系汇总如下:
Function (example) active-low property physical line
gpiod_set_raw_value(desc, 0); don’t care low
gpiod_set_raw_value(desc, 1); don’t care high
gpiod_set_value(desc, 0); default (active-high) low
gpiod_set_value(desc, 1); default (active-high) high
gpiod_set_value(desc, 0); active-low high
gpiod_set_value(desc, 1); active-low low可以使用如下函数判断一个设备是否是低电平有效的设备。
int gpiod_is_active_low(const struct gpio_desc *desc)
- 设置多个输出
使用如下函数设置一组设备的输出值
void gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
void gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
void gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array)
以上函数均可配套gpiod_get_array()使用 - 映射到IRQ
使用如下函数获取一个GPIO设备对应的IRQ中断号
int gpiod_to_irq(const struct gpio_desc *desc)
返回值时一个IRQ number,或者一个负数的错误代码。得到的中断号可以传递给函数request_irq(),free_irq(). - ACPI
在ACPI系统上,GPIO设备在GpioIo()/GpioInt()从_CRS中获得的资源列表中被描述,这些资源不能在系统GPIO中被使用。 - 兼容旧版本
旧的GPIO系统使用基于标号的结构而不是基于描述符。可以使用如下两个函数进行相互转换:
int desc_to_gpio(const struct gpio_desc *desc)
struct gpio_desc *gpio_to_desc(unsigned gpio)
注意不能使用一套API的方法释放另一套API获取的设备
- Linux内核中的GPIO驱动
- Linux驱动编译进内核-GPIO驱动
- Linux 内核设备驱动之GPIO驱动之GPIO API
- linux内核中的GPIO系统
- Linux 内核设备驱动之GPIO驱动之GPIO GPIO描述符到GPIO号
- Linux 内核设备驱动之GPIO驱动之GPIO GPIO描述符到GPIO CHIP
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动之GPIO子系统
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动之GPIO子系统(一)GPIO的使用
- Linux内核驱动之GPIO子系统-GPIO的使用
- Linux内核驱动之GPIO子系统(一)GPIO的使用
- Linux内核驱动之GPIO子系统(一)GPIO的使用
- js ,jsp获取项目应用名
- js,javascript,jquery网页返回顶部代码
- Cydia Substrate Android SO Hook
- 【HDU】 1452 Happy 2004
- 安全密码
- Linux内核中的GPIO驱动
- SVN
- 如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
- 如何在windows下安装cygwin
- MD和MT混用的后果
- 由linux命令行下的两条命令来阐释输出结果和返回值的区别
- 一个难忘而又难以理解的代码
- Cydia substrate Hook 和模拟器安装
- clojure代码迁移到clojurescript过程中踩过的坑