一.编写设备数
1.创建新的节点。
打开内核文件.dtsi文件,在文件中创建test节点。
2.配置节点属性。
3.进行编译烧写进入板子。
二.编写驱动程序
#include<linux/init.h>
#include<linux/module.h>
#include<linux/platform_device.h>
#include<linux/of.h>
#include<linux/of_address.h>
#include<liunx/gpio.h>
#include<linux/of_gpio.h>
#include<linux/interrupt.h>
#include<linux/of_irq.h>
#include<linux/workqueue.h>
struct device_node *test_device_node;
struct property *test_node_property;
struct work_struct key_test;
int irq;
int gpio_nu;
//工作队列处理函数
void test(struct work_struct *data)
{
int i = 100;
printk("i is %d \n",i);
while(i--)
printk("test_key is %d \n",i);
}
//中断处理函数
irqreturn_t test_key(int irq,void *args)
{
printk("start\n");
schedule_work(&key_test);
printk("end\n");
return IRQ_HANDLED;
}
int beep_probe(struct platform_device *pdev)
{
int ret = 0;
printk("beep_probe\n");
test_device_node = of_find_node_by_path("/test");
if (test_device_node == NULL)
{
printk("of_find_node_by_path is error\n");
return -1;
}
//of_get_named_gpio 函数获取 GPIO 编号
gpio_nu = of_get_named_gpio(test_device_node, "touch-gpio", 0);
if (gpio_nu < 0)
{
printk("of_get_named_gpio is error\n");
return -1;
}
//设置 GPIO 为输入模式
gpio_direction_input(gpio_nu);
//获得中断号
irq = irq_of_parse_and_map(test_device_node, 0);
printk("irq is %d \n", irq);
//申请中断
ret = request_irq(irq, test_key, IRQF_TRIGGER_RISING, "test_key", NULL);
if (ret < 0)
{
printk("request_irq \n");
return -1;
}
INIT_WORK(&key_test,test);
return 0;
}
int beep_remove(struct platform_device *pdev)
{
printk("beep_remove \n");
return 0;
}
const struct platform_device_id beep_idtable = {
.name = "beep_test",
};
const struct of_device_id of_match_table_test[] = {
{.compatible = "keys"},
{},
};
struct platform_driver beep_driver = {
.probe = beep_probe,
.remove = beep_remove,
.driver = {
.owner = THIS_MODULE,
.name = "beep_test",
.of_match_table = of_match_table_test
},
.id_table = &beep_idtable
};
static int beep_driver_init(void)
{
int ret = 0;
ret = platform_driver_register(&beep_driver);
if(ret < 0)
{
printk("platform_driver_register error \n");
}
printk("platform_driver_register ok \n");
return 0;
}
static void beep_driver_exit(void)
{
free_irq(irq,NULL);
platform_driver_unregister(&beep_driver);
printk("goodbye! \n");
}
module_init(beep_driver_init);
module_exit(beep_driver_exit);
MODULE_LICENSE("GPL");