发布时间:2022-08-19 12:35
博主主页:Systemcall小酒屋
博主简介:Neutionwei,C站嵌入式领域优质创作者之一,一枚热爱开源技术、喜欢分享技术心得的极客,注重简约风格,热衷于用简单的案例讲述复杂的技术,“假传万卷书,真传一案例”,这是厦大一位教数学的院士说过的一句话,另外“成就是最好的老师”,技术既要沉淀,也得分享,成就感的正反馈是支持我持续耕耘的动力!
专栏目录:Firefly-RK356x板卡
专栏说明:本专栏主要基于Firefly旗下的RK356x板卡进行入门篇讲述,欢迎订阅,博主会持续更新!
上一节主要讲述了普通GPIO的使用:
[ROC-RK3568-PC] [Firefly-Android] 10min带你了解普通GPIO的使用
在 Firefly 的例子程序中还包含了一个中断引脚,GPIO 口的中断使用与 GPIO 的输入输出类似,首先在 DTS 文件中增加驱动的资源描述:
kernel/arch/arm64/boot/dts/rockchip/rk356x-firefly-demo.dtsi
gpio {
compatible = "firefly-gpio";
firefly-irq-gpio = <&gpio4 29 IRQ_TYPE_EDGE_RISING>; /* GPIO4_D5 */
};
其中IRQ_TYPE_EDGE_RISING
表示中断由上升沿触发,当该引脚接收到上升沿信号时可以触发中断函数。 这里还可以配置成如下:
IRQ_TYPE_NONE //默认值,无定义中断触发类型
IRQ_TYPE_EDGE_RISING //上升沿触发
IRQ_TYPE_EDGE_FALLING //下降沿触发
IRQ_TYPE_EDGE_BOTH //上升沿和下降沿都触发
IRQ_TYPE_LEVEL_HIGH //高电平触发
IRQ_TYPE_LEVEL_LOW //低电平触发
然后在驱动的 probe
函数中对 DTS 所添加的资源进行解析,再做中断的注册申请:
static int firefly_gpio_probe(struct platform_device *pdev)
{
int ret;
int gpio;
enum of_gpio_flags flag;
struct firefly_gpio_info *gpio_info;
struct device_node *firefly_gpio_node = pdev->dev.of_node;
...
gpio_info->firefly_irq_gpio = gpio;
gpio_info->firefly_irq_mode = flag;
gpio_info->firefly_irq = gpio_to_irq(gpio_info->firefly_irq_gpio); // 调用 gpio_to_irq 把 GPIO 的 PIN 值转换为相应的 IRQ 值
if (gpio_info->firefly_irq) {
if (gpio_request(gpio, "firefly-irq-gpio")) { // 调用 gpio_request 申请占用该 IO 口
printk("gpio %d request failed!\n", gpio);
gpio_free(gpio);
return IRQ_NONE;
}
ret = request_irq(gpio_info->firefly_irq, firefly_gpio_irq, flag, "firefly-gpio", gpio_info); // 调用 request_irq 申请中断,
if (ret != 0) {
free_irq(gpio_info->firefly_irq, gpio_info);
dev_err(&pdev->dev, "Failed to request IRQ: %d\n", ret);
return ret;
}
}
return 0;
}
static irqreturn_t firefly_gpio_irq(int irq, void *dev_id) // 中断函数
{
printk("Enter firefly gpio irq test program!\n");
return IRQ_HANDLED;
}
request_irq
函数中 gpio_info->firefly_irq
是要申请的硬件中断号,firefly_gpio_irq
是中断函数,gpio_info->firefly_irq_mode
是中断处理的属性,firefly-gpio
是设备驱动程序名称,gpio_info
是该设备的 device 结构,在注册共享中断时会用到。