返回> 网站首页
linux驱动 - gpio中断
yoours2022-10-30 19:33:25
简介一边听听音乐,一边写写文章。
一、设备树 - GPIO定义
#gpio-cells = <6>;
ant_paen-gpios = <&pio 1 1 1 1 1 0>;
| | | | | | | |--------------表示有效电平
| | | | | | |-----------------上下拉, 0关闭功能, 1上拉, 2下拉, 3保留
| | | | | |---------------------驱动力,电流等级(0 - 3),级别越高,输出电流越大
| | | | |-------------------------gpio功能类型,0输入, 1输出, 6和外部中断,7关闭功能(具体查手册)
| | | |-----------------------------pin bank 内偏移(即组内第几个io口).
| | |---------------------------------哪组gpio, PA(0),PB(1),PC(2),PD(3),PE(4),PF(5),PG(6),PH(7),PI(8),PJ(9),PK(10),PL(11)
| |--------------------------------------指向哪个gpio控制器, pio / r_pio(PL组)
|---------------------------------------------属性名字(随便命名),以-gpios结尾
二、初始化
static irqreturn_t irq_hander(int irq, void *dev_id)
{
printk(KERN_ERR"irq_hander!\n");
return IRQ_HANDLED;
}
static int xxx_probe(struct spi_device *spi)
{
// 设置普通输入输出gpio
struct gpio_desc* ant_paen = devm_gpiod_get(&spi->dev, "ant_paen", GPIOF_OUT_INIT_LOW);
if(IS_ERR(ant_paen))
{
printk(KERN_ERR"Get ant_paen resource failed!\n");
return -1;
}
//gpiod_set_value(ant_paen, 0);//set down level
// 获取中断的gpio
struct gpio_desc* RxInterrupt = devm_gpiod_get(&spi->dev,"RxInterrupt",GPIOF_OUT_INIT_LOW);
if(IS_ERR(RxInterrupt))
{
printk(KERN_ERR"Get RxInterrupt resource failed!\n");
return -1;
}
// 设置中断
int ret = devm_request_irq(&spi->dev, gpiod_to_irq(RxInterrupt), irq_hander, 0, "irq_hander", NULL);
if(ret)
{
printk(KERN_ERR"RxInterruptInit faild\n");
return ret;
}
}
三、GPIO常用api
1. 申请GPIO资源
struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id, enum gpiod_flags flags);
static inline struct gpio_desc *__must_check gpiod_get_index( struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags flags)
struct gpio_desc *__must_check devm_gpiod_get( struct device *dev, const char *con_id, enum gpiod_flags flags)
struct gpio_desc *__must_check devm_gpiod_get_index( struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags flags)
2.设置 GPIO 方向
int gpiod_direction_input(struct gpio_desc *desc)
int gpiod_direction_output(struct gpio_desc *desc, int value)
3.获取 设置 GPIO 输出电平
int gpiod_get_value(const struct gpio_desc *desc)
void gpiod_set_value(struct gpio_desc *desc, int value)
4.释放 GPIO 资源
void gpiod_put(struct gpio_desc *desc)
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
5.GPIO 与中断信号线
int gpiod_to_irq(const struct gpio_desc *desc)
四、常用中断API
1. 中断注册
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
request_threaded_irq(unsigned int irq, irq_handler_t handler,irq_handler_t thread_fn,unsigned long flags, const char *name, void *dev);
中断标志flag:
IRQF_TRIGGER_NONE:无触发中断,指采用默认触发或者之前设置的方式
IRQF_TRIGGER_RISING:上升沿触发
IRQF_TRIGGER_FALLING:下降沿触发
IRQF_TRIGGER_HIGH:高电平触发
IRQF_TRIGGER_LOW:低电平触发
IRQF_TRIGGER_MASK:所有电平都可触发
IRQF_TRIGGER_PROBE:触发式检测中断
IRQF_SHARED:共享中断
devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
devm_request_threaded_irq(struct device *dev, unsigned int irq,irq_handler_t handler, irq_handler_t thread_fn,unsigned long irqflags, const char *devname,void *dev_id);
2. 中断释放
const void *free_irq(unsigned int, void *);
void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
3.关闭和打开指定中断
void disable_irq(unsigned int irq);
void disable_irq_nosync(unsigned int irq);
void enable_irq(unsigned int irq);