日期: 月 日
一、题目
1. 用三个按键中断实现三个灯的亮灭
代码实现:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
//定义指针指向获取的设备树节点信息
struct device_node* node1;
struct device_node* node2;
int ret,i;
unsigned int irqno[3];
struct gpio_desc* gpio[3];
char *arr[3] = {"myled0","myled1","myled3"};
char *brr[3] = {"key1_inte","key2_inte","key3_inte"};
//中断处理函数
irqreturn_t irq_handler(int irq,void* dev)
{
if(irq == irqno[0])
{
gpiod_set_value(gpio[0],!gpiod_get_value(gpio[0]));
}
if(irq == irqno[1])
{
gpiod_set_value(gpio[1],!gpiod_get_value(gpio[1]));
}
if(irq == irqno[2])
{
gpiod_set_value(gpio[2],!gpiod_get_value(gpio[2]));
}
return IRQ_HANDLED;
}
static int __init mycdev_init(void)
{
node2 = of_find_node_by_name(NULL,"myleds");
if(NULL == node2)
{
printk("通过名字解析设备树节点失败\n");
return -EFAULT;
}
printk("成功解析到设备树节点\n");
//获取并申请GPIO编号
for(i=0;i<3;i++)
{
gpio[i] = gpiod_get_from_of_node(node2,arr[i],0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpio))
{
printk("获取gpio编号失败\n");
return PTR_ERR(gpio[i]);
}
printk("获取gpio[%d]编号成功\n",i);
}
node1 = of_find_node_by_name(NULL,"myirq");
if(NULL == node1)
{
printk("通过名字解析设备树节点失败\n");
return -EFAULT;
}
printk("通过名字解析设备树节点成功\n");
//根据节点设备信息获取软中断号
for(i=0;i<3;i++)
{
irqno[i] = irq_of_parse_and_map(node1,i);
if(irqno[i] == 0)
{
printk("irqno获取软中断失败\n");
return -EINVAL;
}
printk("irqno获取中断成功\n");
//注册中断进内核
ret = request_irq(irqno[i],irq_handler,IRQF_TRIGGER_FALLING,brr[i],NULL);
if(ret)
{
printk("irqno注册中断失败\n");
return ret;
}
printk("irqno注册中断成功\n");
}
//led初始化
for(i=0;i<3;i++)
{
gpiod_set_value(gpio[i],0);
}
return 0;
}
static void __exit mycdev_exit(void)
{
for(i=0;i<3;i++)
{
gpiod_set_value(gpio[i],0);
gpiod_put(gpio[i]);
free_irq(irqno[i],NULL);
}
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
现象实现: