海南高端网站建设无忧网站建设多少钱
news/
2025/9/23 23:40:42/
文章来源:
海南高端网站建设,无忧网站建设多少钱,网络推广思路,网站title修改编写LED灯的驱动#xff0c;使用GPIO子系统#xff0c;里面添加按键的中断处理
1.应用程序发送指令控制发光二极管亮灭
2.按键1按下#xff0c;led1电位反转#xff1b;按键2按下#xff0c;led2电位反转#xff1b;按键3按下#xff0c;led3电位反转
//头文件
#i…编写LED灯的驱动使用GPIO子系统里面添加按键的中断处理
1.应用程序发送指令控制发光二极管亮灭
2.按键1按下led1电位反转按键2按下led2电位反转按键3按下led3电位反转
//头文件
#ifndef __LED_H__
#define __LED_H__//功能码
#define LED_ON _IOW(l,1,int)
#define LED_OFF _IOW(l,0,int)
#endif//应用程序实现LED的亮灭
#include stdio.h
#include string.h
#include stdlib.h
#include sys/types.h
#include sys/stat.h
#include sys/ioctl.h
#include fcntl.h
#include unistd.h
#include led.h
int main(int argc, const char *argv[])
{int a,b;while(1){int fd_led open(/dev/myled0,O_RDWR); if(fd_led 0){printf(打开设备文件失败\n);exit(-1);}printf(请输入要控制的灯:1 2 3);scanf(%d,b);printf(输入控制命令:0熄灭 1开灯);scanf(%d,a);switch(a){case 1:ioctl(fd_led,LED_ON,b);break;case 0:ioctl(fd_led,LED_OFF,b);break;}close(fd_led);}return 0;
}//驱动程序
#include linux/init.h
#include linux/module.h
#include linux/of.h
#include linux/of_gpio.h
#include linux/gpio.h
#include linux/device.h
#include linux/cdev.h
#include linux/slab.h
#include linux/fs.h
#include linux/io.h
#includelinux/of_irq.h
#includelinux/interrupt.h
#include led.h
/* leds{led1-gpiosgpioe 10 0;//10表示引脚编号 0表示默认led2-gpiosgpiof 10 0;led3-gpiosgpioe 8 0;};*/
struct device_node *dnode1;
struct device_node *dnode2;
struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;
struct cdev *cdev;
int major168;
int minor0;
struct class *cls;
struct device *dev;
dev_t devno;
int i;
unsigned int irqno[3]; //软中断号//中断处理函数
irqreturn_t myirq_handler(int irqno, void *dev_id)
{unsigned int id(unsigned int)dev_id;switch(id){case 0:printk(KEY1_INTERRUPT\n);gpiod_set_value(gpiono1,!gpiod_get_value(gpiono1));break;case 1:printk(KEY2_INTERRUPT\n);gpiod_set_value(gpiono2,!gpiod_get_value(gpiono2));break;case 2:printk(KEY3_INTERRUPT\n);gpiod_set_value(gpiono3,!gpiod_get_value(gpiono3));break;}return IRQ_HANDLED;
}
/*********************封装操作方法***************************/
int mycdev_open(struct inode *inode, struct file *file)
{//printk(%s:%s:%d\n, __FILE__, __func__, __LINE__);return 0;
}long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{int which;copy_from_user(which,(void *)arg,4);switch(cmd){case LED_ON: // 亮灯switch(which){case 1: gpiod_set_value(gpiono1, 1);break;case 2:gpiod_set_value(gpiono2, 1);break;case 3:gpiod_set_value(gpiono3, 1);break;}break;case LED_OFF:switch(which){case 1:gpiod_set_value(gpiono1, 0);break;case 2:gpiod_set_value(gpiono2, 0);break;case 3:gpiod_set_value(gpiono3, 0);}break;}//printk(%s:%s:%d\n, __FILE__, __func__, __LINE__);return 0;
}int mycdev_close(struct inode *inode, struct file *file)
{//printk(%s:%s:%d\n, __FILE__, __func__, __LINE__);return 0;
}
/***********************************************************************///定义一个操作方法结构体变量并初始化
struct file_operations fops
{.open mycdev_open,.release mycdev_close,.unlocked_ioctl mycdev_ioctl,
};
static int __init mycdev_init(void)
{int ret,i;//1.申请对象空间 cdev_alloccdev cdev_alloc();if(cdev NULL){printk(申请对象空间失败\n);ret-EFAULT;goto out1;}printk(申请对象空间成功\n);//2.初始化对象 cdev_initcdev_init(cdev,fops);printk(初始化对象成功\n);//3.申请设备号 register_chrdev_region()或clloc_chrdev_region()if(major ! 0) //静态申请{retregister_chrdev_region(MKDEV(major,minor),3,myled);if(ret){printk(申请静态设备号失败\n);goto out2;}printk(申请静态设备号成功major%d\n,major);}else //动态申请{retalloc_chrdev_region(devno,minor,3,myled);if(ret){printk(申请动态设备号失败\n);goto out2;}majorMAJOR(devno);minorMINOR(devno);printk(申请动态设备号成功major%d\n,major);}//4.注册驱动对象 cdev_add()retcdev_add(cdev,MKDEV(major,minor),3);if(ret){printk(注册驱动对象失败\n);goto out3;}printk(注册驱动对象成功\n);//5.向上提交目录 class_create()clsclass_create(THIS_MODULE,myled);if(IS_ERR(cls)){printk(向上提交目录失败\n);ret -PTR_ERR(cls);goto out4;}printk(向上提交目录成功\n);//6.向上提交设备信息 device_create()for(i0;i3;i){devdevice_create(cls,NULL,MKDEV(major,i),NULL,myled%d,i);if(IS_ERR(dev)){printk(向上提交设备节点失败\n);ret -PTR_ERR(dev);goto out5;}}printk(向上提交设备信息成功\n);// 根据设备树节点的路径解析设备树信息dnode1 of_find_node_by_path(/leds);if (dnode1 NULL){printk(解析设备树节点led失败\n);return -EFAULT;}printk(解析设备树节点led成功\n);// 申请gpio_desc对象并设置输出为低电平gpiono1 gpiod_get_from_of_node(dnode1, led1-gpios, 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono1)){printk(申请gpio1对象失败\n);return -PTR_ERR(gpiono1);}printk(申请gpio1对象成功\n);gpiono2 gpiod_get_from_of_node(dnode1, led2-gpios, 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono2)){printk(申请gpio2对象失败\n);return -PTR_ERR(gpiono2);}printk(申请gpio2对象成功\n);gpiono3 gpiod_get_from_of_node(dnode1, led3-gpios, 0, GPIOD_OUT_LOW, NULL);if (IS_ERR(gpiono3)){printk(申请gpio3对象失败\n);return -PTR_ERR(gpiono3);}printk(申请gpio3对象成功\n);// 根据设备树节点的路径解析设备树信息dnode2 of_find_node_by_path(/myirq);if (dnode2 NULL){printk(解析设备树节点myirq失败\n);return -EFAULT;}printk(解析设备树节点myirq成功\n);for(i0;i3;i){//获取软中断号irqno[i]irq_of_parse_and_map(dnode2,i);if(!irqno[i]){printk(软中断号irqno[%d]获取失败\n,i);return -ENXIO;}printk(软中断号获取成功irqno[%d]%d\n,i,irqno[i]);//注册中断retrequest_irq(irqno[i],myirq_handler,IRQF_TRIGGER_FALLING,key,(void *)i);if(ret){printk(注册驱动失败\n);return ret;}printk(key%d中断注册成功\n,i);}return 0;
out5:for(--i;i0;i--){//销毁上面提交的设备信息device_destroy(cls,MKDEV(major,i));}class_destroy(cls);
out4:cdev_del(cdev);
out3:unregister_chrdev_region(MKDEV(major,minor),3);
out2:kfree(cdev);
out1:return ret;
}
static void __exit mycdev_exit(void)
{// 灭灯gpiod_set_value(gpiono1, 0);gpiod_set_value(gpiono2, 0);gpiod_set_value(gpiono3, 0);// 释放gpio编号gpiod_put(gpiono1);gpiod_put(gpiono2);gpiod_put(gpiono3);//注销中断for(i0;i3;i){free_irq(irqno[i],NULL);}
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE(GPL);
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914258.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!