linux内核GPIO编程说明
来源:互联网 发布:2016各类案件数据统计 编辑:程序博客网 时间:2024/05/21 11:37
内核GPIO编程说明
参考资料:https://www.kernel.org/doc/Documentation/gpio/
从官方资料来看,linux内核中的gpio接口目前有新旧两个版本,新的版本的接口是descriptor-based的,而旧的是integer-based的。旧的接口已出于兼容性的考虑仍被支持,但已不再建议使用。网上目前大多GPIO编程说明都是旧的版本,所以这篇说明就以介绍新的接口版本为主。
1.驱动首先需要包含头文件:
#include <linux/gpio/consumer.h>
2.调用gpio设备所需函数,函数返回描述符或错误码
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,
enum gpiod_flags flags)
如果设备需要使用多个gpio,则需在函数中添加index参数:
struct gpio_desc *gpiod_get_index(struct device *dev,
const char *con_id, unsigned int idx,
enum gpiod_flags flags)
其中gpiod_flag控制初始化模式,有以下几种:
* GPIOD_ASIS or 0 不进行初始化
* GPIOD_IN 将gpio初始化为input模式
* GPIOD_OUT_LOW 将gpio初始化为低电平output
* GPIOD_OUT_HIGH 将gpio初始化为高电平output
也可以用以下两个函数调用可用gpio。当没有gpio调用成功时,返回null
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)
或者在获取多个gpio时只要调用一个函数即可:
struct gpio_descs *gpiod_get_array(struct device *dev,
const char *con_id,
enum gpiod_flags flags)
该函数返回结构体gpi_descs:
struct gpio_descs {
unsigned int ndescs;
struct gpio_desc *desc[];
}
3. 释放一个gpio使用函数:
void gpiod_put(struct gpio_desc *desc)
或者释放多个gpio使用
void gpiod_put_array(struct gpio_descs *descs)
在调用这些函数后,被释放的描述符不可再被使用。
4.GPIO的设置
调用以下函数来的设置gpio的方向:
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
5.GPIO的访问
GPIO的访问可通过主存的读写指令完成,这种操作不需要sleep,所以在内部硬中断时也可以被调用,安全性较高。使用以下函数来进行该原子访问操作:
int gpiod_get_value(const struct gpio_desc *desc);
void gpiod_set_value(struct gpio_desc *desc, int value);
另一种gpio设备访问必须使用消息总线如I2C或SPI,这种操作需要在队列中等待,所以不再能在IRQ中被调用:
int gpiod_get_value_cansleep(const struct gpio_desc *desc)
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
分辨此类gpio设备:
int gpiod_cansleep(const struct gpio_desc *desc)
6.输出信号
有些设备采用低电平有效的方式输出逻辑信号。此时低电平输出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)
可以通过以下函数对一组GPIO进行输出设置:
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)
7.映射到IRQs
int gpiod_to_irq(const struct gpio_desc *desc)
8.GPIO和ACPI
在ACPI系统上,GPIO设备在GpioIo()/GpioInt()从_CRS中获得的资源列表中被描述,这些资源不能在系统GPIO中被使用。
参考资料:https://www.kernel.org/doc/Documentation/gpio/
从官方资料来看,linux内核中的gpio接口目前有新旧两个版本,新的版本的接口是descriptor-based的,而旧的是integer-based的。旧的接口已出于兼容性的考虑仍被支持,但已不再建议使用。网上目前大多GPIO编程说明都是旧的版本,所以这篇说明就以介绍新的接口版本为主。
1.驱动首先需要包含头文件:
#include <linux/gpio/consumer.h>
2.调用gpio设备所需函数,函数返回描述符或错误码
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,
enum gpiod_flags flags)
如果设备需要使用多个gpio,则需在函数中添加index参数:
struct gpio_desc *gpiod_get_index(struct device *dev,
const char *con_id, unsigned int idx,
enum gpiod_flags flags)
其中gpiod_flag控制初始化模式,有以下几种:
* GPIOD_ASIS or 0 不进行初始化
* GPIOD_IN 将gpio初始化为input模式
* GPIOD_OUT_LOW 将gpio初始化为低电平output
* GPIOD_OUT_HIGH 将gpio初始化为高电平output
也可以用以下两个函数调用可用gpio。当没有gpio调用成功时,返回null
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)
或者在获取多个gpio时只要调用一个函数即可:
struct gpio_descs *gpiod_get_array(struct device *dev,
const char *con_id,
enum gpiod_flags flags)
该函数返回结构体gpi_descs:
struct gpio_descs {
unsigned int ndescs;
struct gpio_desc *desc[];
}
3. 释放一个gpio使用函数:
void gpiod_put(struct gpio_desc *desc)
或者释放多个gpio使用
void gpiod_put_array(struct gpio_descs *descs)
在调用这些函数后,被释放的描述符不可再被使用。
4.GPIO的设置
调用以下函数来的设置gpio的方向:
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
5.GPIO的访问
GPIO的访问可通过主存的读写指令完成,这种操作不需要sleep,所以在内部硬中断时也可以被调用,安全性较高。使用以下函数来进行该原子访问操作:
int gpiod_get_value(const struct gpio_desc *desc);
void gpiod_set_value(struct gpio_desc *desc, int value);
另一种gpio设备访问必须使用消息总线如I2C或SPI,这种操作需要在队列中等待,所以不再能在IRQ中被调用:
int gpiod_get_value_cansleep(const struct gpio_desc *desc)
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
分辨此类gpio设备:
int gpiod_cansleep(const struct gpio_desc *desc)
6.输出信号
有些设备采用低电平有效的方式输出逻辑信号。此时低电平输出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)
可以通过以下函数对一组GPIO进行输出设置:
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)
7.映射到IRQs
int gpiod_to_irq(const struct gpio_desc *desc)
8.GPIO和ACPI
在ACPI系统上,GPIO设备在GpioIo()/GpioInt()从_CRS中获得的资源列表中被描述,这些资源不能在系统GPIO中被使用。
阅读全文
0 0
- linux内核GPIO编程说明
- linux内核GPIO编程说明
- GPIO Linux内核编程
- linux内核 GPIO口编程入门
- linux内核 GPIO口编程入门
- Linux内核操作GPIO
- linux 内核操作GPIO
- Linux 内核gpio模拟I2C
- linux 内核GPIO 模拟 I2C
- LINUX内核GPIO接口解析
- Linux内核中的GPIO驱动
- Linux内核---56.gpio控制
- Linux 内核GPIO的学习
- linux内核中的GPIO系统
- Linux 内核设备驱动之GPIO驱动之GPIO GPIO描述符到GPIO号
- Linux 内核设备驱动之GPIO驱动之GPIO GPIO描述符到GPIO CHIP
- Linux内核驱动之GPIO子系统(一)GPIO的使用
- Linux内核驱动之GPIO子系统-GPIO的使用
- wpf怎么让Textbox只能输入数字?
- python里使用enum库创建枚举类型
- HDOJ 2537 8球胜负
- recyclerview中子布局有编辑框,软键盘定上去
- 大哥教你用minio
- linux内核GPIO编程说明
- 穷举法
- 自顶向下,逐步求精
- WPF中ListBox滚动条自动滚动
- leetcode-65-有效的数字
- 棋牌麻将
- 将S3C2416的RS232改为RS485(修改内核驱动)
- 微信公众号发送模板消息接口
- Angularjs自定义指令(directive)