当前位置: 首页 > news >正文

arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭

中断控制led灯亮灭
驱动文件源码
led-key.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
#include<linux/of_irq.h>
#include<linux/interrupt.h>
struct device_node *led_dev;
struct device_node *key_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
unsigned int irqno_1;
unsigned int irqno_2;
unsigned int irqno_3;
irqreturn_t myirq_handler(int irq, void *dev){printk("irq=%d\n",irq);switch (irq){case 71:gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));break;case 72:gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));break;case 73:gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));break;} return IRQ_HANDLED;
}
static int __init mycdev_init(void){ int ret;led_dev = of_find_node_by_path("/leds");if(led_dev == NULL){printk("解析led灯设备树节点失败\n");return -EFAULT;}printk("解析led灯设备树成功\n");key_dev = of_find_node_by_path("/myirq");if(key_dev == NULL){printk("解析中断设备树节点失败\n");return -EFAULT;}printk("解析中断设备树成功\n");gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_1)){printk("获取GPIO号失败\n");return -PTR_ERR(gpiono_led_1);}gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_2)){printk("获取GPIO号失败\n");return -PTR_ERR(gpiono_led_2);}gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_3)){printk("获取GPIO号失败\n");return -PTR_ERR(gpiono_led_3);}printk("申请GPIO编号成功\n");irqno_1 = irq_of_parse_and_map(key_dev,0);if(!irqno_1){printk("解析中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d\n",irqno_1);irqno_2 = irq_of_parse_and_map(key_dev,1);if(!irqno_2){printk("解析中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d\n",irqno_2);irqno_3 = irq_of_parse_and_map(key_dev,2);if(!irqno_3){printk("解析中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d\n",irqno_3);//注册中断ret = request_irq(irqno_1,myirq_handler,IRQF_TRIGGER_FALLING,"key1",NULL);if(ret){printk("注册中断1失败\n");return ret;}//注册中断ret = request_irq(irqno_2,myirq_handler,IRQF_TRIGGER_FALLING,"key2",NULL);if(ret){printk("注册中断2失败\n");return ret;}//注册中断ret = request_irq(irqno_3,myirq_handler,IRQF_TRIGGER_FALLING,"key3",NULL);if(ret){printk("注册中断3失败\n");return ret;}printk("注册中断成功\n");return 0;
}
static void __exit mycdev_exit(void){free_irq(irqno_1,NULL);free_irq(irqno_2,NULL);free_irq(irqno_3,NULL);gpiod_set_value(gpiono_led_1,0);gpiod_put(gpiono_led_1);gpiod_set_value(gpiono_led_2,0);gpiod_put(gpiono_led_2);gpiod_set_value(gpiono_led_3,0);gpiod_put(gpiono_led_3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

字符设备指令控制led灯亮灭
驱动文件
led-cmd.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include<linux/fs.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
struct device_node *led_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
struct class *cls;
struct device *dev;
char kbuf[128]={0};
unsigned int major;//定义一个变量保存主设备号
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);long ret;ret=copy_from_user(kbuf,ubuf,size);switch (kbuf[0]){case '1':gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));break;case '2':gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));break;case '3':gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));break;} return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
void all_led_init(void){int ret;led_dev = of_find_node_by_path("/leds");if(led_dev == NULL){printk("解析led灯设备树节点失败\n");//return -EFAULT;}gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_1)){printk("获取GPIO号失败\n");//return -PTR_ERR(gpiono_led_1);}gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_2)){printk("获取GPIO号失败\n");//return -PTR_ERR(gpiono_led_2);}gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_3)){printk("获取GPIO号失败\n");// return -PTR_ERR(gpiono_led_3);}printk("申请GPIO编号成功\n");
}
//定义一个操作方法结构体变量并且初始化
struct file_operations fops={.open=mycdev_open,.release=mycdev_close,.read=mycdev_read,.write=mycdev_write,
};
static int __init mycdev_init(void){ //注册字符设备驱动major=register_chrdev(0,"mychrdev",&fops);if(major<0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功major=%d\n",major);// 向上提交目录cls = class_create(THIS_MODULE, "mycdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");// 向上提交设备节点信息dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(dev);}printk("向上提交设备节点成功\n");all_led_init();return 0;
}
static void __exit mycdev_exit(void){gpiod_set_value(gpiono_led_1,0);gpiod_put(gpiono_led_1);gpiod_set_value(gpiono_led_2,0);gpiod_put(gpiono_led_2);gpiod_set_value(gpiono_led_3,0);gpiod_put(gpiono_led_3);//注销字符设备驱动//销毁节点信息device_destroy(cls,MKDEV(major,0));//销毁目录信息class_destroy(cls);unregister_chrdev(major,"mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

应用文件
led.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{char buf[128] = {0};int fd = open("/dev/mycdev", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入控制命令:1(led1关灯/开灯)2(led2关灯/开灯)3(led3关灯/开灯)>");fgets(buf, sizeof(buf), stdin); // 从终端输入数据到bufbuf[strlen(buf) - 1] = '\0';    // 将buf末尾的'\n'切换为'\0'write(fd, buf, sizeof(buf));    }close(fd);return 0;
}
http://www.lryc.cn/news/105093.html

相关文章:

  • 快速开发框架若依的基础使用详解
  • RabbitMQ 教程 | 第4章 RabbitMQ 进阶
  • 小程序如何从分类中移除商品
  • P1219 [USACO1.5] 八皇后 Checker Challenge
  • 如何在不使用脚本和插件的情况下手动删除 3Ds Max 中的病毒?
  • SpringCloud Gateway 在微服务架构下的最佳实践
  • Android studio修改app图标
  • <C++> 三、内存管理
  • 大模型开发(十五):从0到1构建一个高度自动化的AI项目开发流程(上)
  • HarmonyOS 开发基础(二)组件拼凑简单登录页面
  • flutter minio
  • ChatGPT:人工智能交互的新时代
  • C. Binary String Copying - 思维
  • 哈工大计算机网络课程网络安全基本原理详解之:密钥分发中心与公钥认证中心
  • md5sum
  • 图文档数字化:实现高效管理的几大步骤
  • 服务器磁盘占用过高分析
  • 【C语言】通讯录3.0 (文件存储版)
  • 【C#常用操作】
  • 深入理解CountDownLatch计数器
  • 从SQL注入绕过最新安全狗WAF中学习fuzz
  • C语言每日一题:12《数据结构》相交链表。
  • 【Spring框架】SpringMVC
  • HDFS中namenode安全模式
  • blender凹凸感和置换形变
  • 力扣 343. 整数拆分
  • 【JavaWeb】正则表达式
  • Vue中常用到的标签和指令
  • C++设计模式之访问者模式
  • Java8的stream常用的操作