驱动代码
#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/of_irq.h>
#include <linux/interrupt.h>
/*
myled{
led1-gpio=<&gpioe 10 0>;
led2-gpio=<&gpiof 10 0>;
led3-gpio=<&gpioe 8 0>;
};
*/
struct device_node *dnode; //设备树节点对象指针
struct gpio_desc *gpiono; //gpio描述信息属性名
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;
struct timer_list mytimer;
//定时器处理函数
void mytimer_function(struct timer_list *timer)
{
//LED1状态取反
printk("hello world\n");
gpiod_set_value(gpiono,!gpiod_get_value(gpiono));
gpiod_set_value(gpiono2,!gpiod_get_value(gpiono2));
gpiod_set_value(gpiono3,!gpiod_get_value(gpiono3));
//再次启动定时器
mod_timer(timer, jiffies + 5 * HZ);
}
static int __init mycdev_init(void)
{
//解析设备树节点信息
dnode = of_find_node_by_path("/myled");
if(dnode == NULL)
{
printk("解析设备树节点失败\n");
return -ENXIO;
}
//获取LED1 GPIO编号
gpiono = gpiod_get_from_of_node(dnode,"led1-gpio",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono))
{
printk("获取GPIO编号失败\n");
return -PTR_ERR(gpiono);
}
//获取LED2 GPIO编号
gpiono2 = gpiod_get_from_of_node(dnode,"led2-gpio",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono2))
{
printk("获取GPIO编号失败\n");
return -PTR_ERR(gpiono2);
}
//获取LED3 GPIO编号
gpiono3 = gpiod_get_from_of_node(dnode,"led3-gpio",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono3))
{
printk("获取GPIO编号失败\n");
return -PTR_ERR(gpiono3);
}
//初始化定时器对象
timer_setup(&mytimer,mytimer_function,0);
mytimer.expires=jiffies+HZ; //定时1s
//注册定时器
add_timer(&mytimer);
return 0;
}
static void __exit mycdev_exit(void)
{
//注销定时器
del_timer(&mytimer);
//灯灭
gpiod_set_value(gpiono,0);
gpiod_set_value(gpiono2,0);
gpiod_set_value(gpiono3,0);
//释放GPIO编号
gpiod_put(gpiono);
gpiod_put(gpiono2);
gpiod_put(gpiono3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
效果演示