2.22驱动作业

news2024/11/14 18:06:32

1.使用GPIO子系统编写LED灯驱动,应用程序测试

2.注册三个按键的中断,只需要写内核代码

1.代码

应用程序:

#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
#include<sys/ioctl.h>
#include"head.h"
 
 
int main(int argc, char const *argv[])
{
    int a,b;
    int fd=open("/dev/myled0",O_RDWR);
    if(fd<0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    while(1)
    {
        //从终端读取
        printf("请输入要实现的功能\n");
        printf("0(关灯) 1(开灯)\n");
        scanf("%d",&b);
        printf("请输入>");
        scanf("%d",&a);
        printf("请选择LED1(1,LED2(2),LED3(3)\n");
        scanf("%d",&b);
        
        switch(a)
        {
            case 1:
                ioctl(fd,LED_ON,&b);
                break;
            case 0:
                ioctl(fd,LED_OFF,&b);
                break;
        }
    }
 
    
    close(fd);
 
    return 0;
}

头文件:

#ifndef __HEAD_H__
#define __HEAD_H__

#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)

#endif

驱动代码:

#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/interrupt.h>
#include <linux/of_irq.h>
#include <linux/uaccess.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include "head.h"
#include <linux/device.h>

struct class *cls;
struct device *dev;
struct device_node *dnone;
struct property *pr;
struct gpio_desc *gpio_node1;
struct gpio_desc *gpio_node2;
struct gpio_desc *gpio_node3;
struct timer_list timer;
int length;
int count;
u32 irqon;
u32 major;
char buf[128]={0};

ssize_t my_read (struct file *file, char  *kbuf, size_t size, loff_t *loff)
{
   unsigned long ret;
    if(size>sizeof(buf)){
        size=sizeof(buf);
    }
    ret=copy_to_user(kbuf,buf,size);
    if(ret){
        printk("读取失败\n");
        return ret;
    }
    
    return 0;
}
ssize_t my_write (struct file *file, const char  *kbuf, size_t size, loff_t *loff)
{
    unsigned long ret;   
    if(size>sizeof(buf)){
        size=sizeof(buf);
    }
    ret=copy_from_user(buf,kbuf,size);
    if(ret){
        printk("写入失败\n");
        return ret;
    }
    return 0;
}

int my_open (struct inode *inode, struct file *file)
{
    return 0;
}
int my_release (struct inode *inode, struct file *file)
{
    return 0;
}

long my_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
    int wh;
    int ret=copy_from_user(&wh,(void *)arg,4);
    if(ret<0){
        printk("copy_from_user error\n");
        return ret;
    }
    switch (cmd)
    {
    case LED_ON:
        switch (wh)
        {
        case 1:
            gpiod_set_value(gpio_node1,1);
            break;
        case 2:
            gpiod_set_value(gpio_node2,1);
            break;
        case 3:
            gpiod_set_value(gpio_node3,1);
            break;
        }
        break;
    case LED_OFF:
        switch (wh)
        {
        case 1:
            gpiod_set_value(gpio_node1,0);
            break;
        case 2:
            gpiod_set_value(gpio_node2,0);
            break;
        case 3:
            gpiod_set_value(gpio_node3,0);
            break;
        }
        break;
    }
    return 0;
}

struct file_operations fops={
    .read=my_read,
    .write=my_write,
    .open=my_open,
    .release=my_release,
    .unlocked_ioctl=my_ioctl,
};
static int __init mycdev_init(void)
{
    major=register_chrdev(0,"myled",&fops);
    if(major<0){
        printk("申请设备号失败\n");
        return -EIO;
    }
    printk("申请设备号成功 major=%d\n",major);

    cls=class_create(THIS_MODULE,"myled");
    if(IS_ERR(cls)){
        printk("向上提交目录失败\n");
        return -PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");
    int i;
    for(i=0;i<3;i++){
        dev=device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
        if(IS_ERR(dev)){
            printk("向上提交设备信息失败\n");
            return -PTR_ERR(dev);
        }
    }
    printk("向上提交设备信息成功\n");

    dnone=of_find_node_by_path("/leds");
    if(dnone<0){
        printk("error\n");
        return -ENXIO;
    }
    printk("解析设备树节点成功\n");
    gpio_node1=gpiod_get_from_of_node(dnone,"led-gpios",0,GPIOD_OUT_LOW,NULL);
    if(gpio_node1<0){
        printk("led1获取gpio失败\n");
        return -1;
    }

    gpio_node2=gpiod_get_from_of_node(dnone,"led-gpios",1,GPIOD_OUT_LOW,NULL);
    if(gpio_node2<0){
        printk("led2获取gpio失败\n");
        return -1;
    }

    gpio_node3=gpiod_get_from_of_node(dnone,"led-gpios",2,GPIOD_OUT_LOW,NULL);
    if(gpio_node3<0){
        printk("led3获取gpio失败\n");
        return -1;
    }
    gpiod_set_value(gpio_node1,1);
    return 0;
}
static void __exit mycdev_exit(void)
{
    gpiod_put(gpio_node1);
    gpiod_put(gpio_node2);
    gpiod_put(gpio_node3);
    int i;
    for(i=0;i<3;i++){
        device_destroy(cls,MKDEV(major,i));
    }
    class_destroy(cls);
    unregister_chrdev(major,"myled");

}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

2.代码

#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/interrupt.h>
#include <linux/of_irq.h>
/*myirq{
    compatible = "hqyj,myirq";
    interrupt-parent = <&gpiof>;
    interrupts=<9 0>,<7 0>,<8 0>;
};
*/
 
struct device_node *dnode;//保存解析到的设备树节点地址
unsigned int irqno;
unsigned int irqno2;
unsigned int irqno3;
unsigned int gpiono;
unsigned int gpiono2;
unsigned int gpiono3;
//中断处理函数
irqreturn_t myirq_handler(int irq , void *dev)
{
    printk("key1_intc\n");
    return IRQ_HANDLED;
}

irqreturn_t myirq_handler2(int irq , void *dev)
{
    printk("key2_intc\n");
    return IRQ_HANDLED;
}

irqreturn_t myirq_handler3(int irq , void *dev)
{
    printk("key3_intc\n");
    return IRQ_HANDLED;
}
 
static int __init mycdev_init(void)
{
    //解析按键的设备树节点
    dnode=of_find_compatible_node(NULL,NULL,"hqyj,myirq");
    if(dnode==NULL)
    {
        printk("解析按键设备树节点失败\n");
        return -ENXIO;
    }
    printk("解析按键设备树节点成功\n");


    //解析按键1的软中断号
    irqno=irq_of_parse_and_map(dnode,0);
    if(!irqno)
    {
        printk("解析软中断号失败\n");
        return -ENXIO;
    }
    printk("解析软中断号成功%d\n",irqno);
    //解析按键2的软中断号
    irqno2=irq_of_parse_and_map(dnode,1);
    if(!irqno)
    {
        printk("解析软中断号失败\n");
        return -ENXIO;
    }
    printk("解析软中断号成功%d\n",irqno2);
    //解析按键3的软中断号
    irqno3=irq_of_parse_and_map(dnode,2);
    if(!irqno)
    {
        printk("解析软中断号失败\n");
        return -ENXIO;
    }
    printk("解析软中断号成功%d\n",irqno3);
    //注册按键1中断
    int ret=request_irq(irqno,myirq_handler,IRQF_TRIGGER_FALLING,"key1",(void *)1);
    if(ret)
    {
        printk("中断注册失败\n");
        return ret;
    }
    printk("中断注册成功\n");

    //注册按键2中断
    int ret2=request_irq(irqno2,myirq_handler2,IRQF_TRIGGER_FALLING,"key2",(void *)2);
    if(ret2)
    {
        printk("中断注册失败\n");
        return ret;
    }
    printk("中断注册成功\n");

    //注册按键1中断
    int ret3=request_irq(irqno3,myirq_handler3,IRQF_TRIGGER_FALLING,"key3",(void *)3);
    if(ret3)
    {
        printk("中断注册失败\n");
        return ret;
    }
    printk("中断注册成功\n");
    return 0;
}
static void __exit mycdev_exit(void)
{
    free_irq(irqno,(void *)1);
    free_irq(irqno2,(void *)2);
    free_irq(irqno3,(void *)3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1464370.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Maven depoly:Skipping artifact deployment

问题描述&#xff1a; 使用IDEA执行mvn depoly将本地开发的模块发布到Maven私服时&#xff0c;一直提示&#xff1a;Skipping artifact deployment&#xff0c;自动跳过了depoly部署阶段。 问题分析 Maven构建生命周期中的每一个阶段都是由对应的maven插件执行具体工作的。既然…

Spring AOP 实现原理详解之 CGLIB 动态代理

目录 一. 前言 1.1. Spring AOP 和 CGLIB 是什么关系&#xff1f; 二. CGLIB 代理示例 2.1. pom 包依赖 2.2. 定义实体 2.3. 被代理的类 2.4. CGLIB 代理 2.5. 使用代理 三. CGLIB 代理的流程 四. Spring AOP 中 CGLIB 代理的实现 一. 前言 CGLIB 是一个强大的高性能…

Portraiture有哪些版本?2024最新版本如何下载

Portraiture有多个版本&#xff0c;其中常用的版本包括Portraiture 3和Portraiture 4。 Portraiture 3&#xff1a;该版本支持Adobe Photoshop CC 2019以上版本和Lightroom CC 2015以上版本&#xff0c;适用于Windows 11/10和macOS 11 Big Sur、12 Monterey、13 Ventura等操作…

Java字符集【ASCII,GBK,Unicode】

1.常见字符集 1.标准ASCII字符集 美国信息交换标准代码&#xff0c;包括了英文、符号等。 标准ASCII使用1个字节存储一个字符&#xff0c;首位是0&#xff0c;总共可表示128个字符&#xff0c;对美国人来说完全够用。 2.GBK&#xff08;汉字内码扩展规范&#xff0c;国标&#…

时域相位分析技术 和空域相位分析技术

l) 时域相位分析技术 在光 学测量 的许 多情况 下 &#xff0c; 时变图像信 号 的背景光 强 与调制 度可 以看作是 常 数 &#xff0c;并且 其光 强 随时 间 的变化也满足 正 弦条件 。 那 么针 对某 一 空 间采样 点 (x &#xff0c;y) &#xff0c; 某时刻 采 集到 的光 强 可…

PYTHON-使用正则表达式进行模式匹配

目录 Python 正则表达式Finding Patterns of Text Without Regular ExpressionsFinding Patterns of Text with Regular ExpressionsCreating Regex ObjectsMatching Regex ObjectsReview of Regular Expression MatchingMore Pattern Matching with Regular ExpressionsGroupi…

基于springboot+vue的酒店客房管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

【数据结构初阶 6】二叉树:堆的基本操作 + 堆排序的实现

文章目录 &#x1f308; Ⅰ 二叉树的顺序结构&#x1f308; Ⅱ 堆的概念与性质&#x1f308; Ⅲ 堆的基本操作01. 堆的定义02. 初始化堆03. 堆的销毁04. 堆的插入05. 向上调整堆06. 堆的创建07. 获取堆顶数据08. 堆的删除09. 向下调整堆10. 判断堆空 &#x1f308; Ⅳ 堆的基本…

【Git企业实战开发】Git常用开发流操作总结

【Git企业实战开发】Git常用开发流操作总结 大家好 我是寸铁&#x1f44a; 总结了一篇Git常用开发流操作总结的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 现在刚做项目的伙伴&#xff0c;可能你之前学过git&#xff0c;但是一实战发现不熟悉 没关系&#xff0c;看寸铁这篇…

色彩搭配:打造视觉吸引力与用户体验的关键

title: 色彩搭配&#xff1a;打造视觉吸引力与用户体验的关键 date: 2024/2/22 12:01:11 updated: 2024/2/22 12:01:11 tags: 网站色彩搭配视觉吸引力品牌形象用户体验设计色彩心理学配色技巧色轮互补 在当今数字化时代&#xff0c;网站已经成为了人们获取信息、进行交流和进行…

fatal error: costmap_2d/keepOutZone.h

fatal error: costmap_2d/keepOutZone.h: No such file or directory 7 | #include "costmap_2d/keepOutZone.h" 解决&#xff1a; #include "costmap_plugins/keepOutZone.h"代码中搜索 costmap_2d&#xff0c;全部替换成costmap_plugins&#xff1b…

【Unity】Unity与安卓交互

问题描述 Unity和安卓手机进行交互&#xff0c;是我们开发游戏中最常见的场景。本教程将从一个简单的例子来演示一下。 本教程需要用到Android Studio2021.1.1 1.Android Studio新建一个工程 2.选择Empty Activity 然后点击Next 3.点击Finish完成创建 4.选择File-New-New Mo…

Less预处理器教程

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈 一、Less介绍 less官方文档 lesscss.org/ less中文文档 less.bootcss.com/ less是一种css预处理器&#xff0c;它扩展了css语言&#xff0c…

用Python插入页码到PDF文档

页码是许多类型文件中的重要内容&#xff0c;它能方便读者在文档中的导航。在创建PDF文档时&#xff0c;添加页码对于组织和引用内容特别有用。在本文中&#xff0c;我们将探讨如何利用Python程序高效地插入页码到PDF文档中&#xff0c;简化工作流程并创建出精美、结构合理的PD…

Eureka注册中心(黑马学习笔记)

Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 大家思考几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f; 有多个user-service实例地址&#xff0c…

从 Elasticsearch 到 Apache Doris,统一日志检索与报表分析,360 企业安全浏览器的数据架构升级实践

导读&#xff1a;随着 360 企业安全浏览器用户规模的不断扩张&#xff0c;浏览器短时间内会产生大量的日志数据。为了提供更好的日志数据服务&#xff0c;360 企业安全浏览器设计了统一运维管理平台&#xff0c;并引入 Apache Doris 替代了 Elasticsearch&#xff0c;实现日志检…

Sulfo Cyanine3 dCTP,磺化-Cy3-dCTP,可以实时监测DNA的合成过程

Sulfo-Cy3-dCTP&#xff0c;Sulfo Cyanine3 dCTP&#xff0c;磺化-Cy3-dCTP&#xff0c;可以实时监测DNA的合成过程 您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;Sulfo-Cy3-dCTP&#xff0c;Sulfo Cyanine3 dCTP&#xff0c;磺化-Cy3-dCTP 一、基本信息 产品简…

隐藏饿了么el-select组件的el-select-dropdown部分,只使用el-select的显示框

隐藏饿了么el-select组件的el-select-dropdown部分,只使用el-select的显示框 问题: 由于el-select组件的el-select-dropdown部分是自动插入在最外层Body上的&#xff0c;所以在当前组件的scoped中让el-select-dropdown组件display:none不会生效所以需要&#xff1a; :popper-…

企业数字化转型必备:大数据如何助力企业腾飞?

随着数字技术的迅猛发展&#xff0c;企业数字化转型已经成为一种不可逆转的趋势。在这个过程中&#xff0c;大数据扮演了至关重要的角色。那么&#xff0c;大数据究竟如何助力企业腾飞呢&#xff1f;接下来&#xff0c;我们将从多个角度深入剖析。 一、大数据助力企业精准决策 …

【MySQL】数据库索引详解 | 聚簇索引 | 最左匹配原则 | 索引的优缺点

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…