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

2.14作业【GPIIO控制LED】

设备树

     myleds{
         myled1 = <&gpioe 10 0>;
         myled2 = <&gpiof 10 0>;
         myled3 = <&gpioe 8 0>;        
     };

驱动代码

    #include<linux/init.h>
    #include<linux/module.h>
    #include<linux/of.h>
    #include<linux/of_gpio.h>
    #include<linux/gpio.h>
    #include<linux/fs.h>
    #include<linux/uaccess.h>
    #include<linux/io.h>
    #include<linux/cdev.h>
    #include<linux/slab.h>
    #include"./six.h"
    /*
      myleds{                       
          myled1 = <&gpioe 10 0>;
          myled2 = <&gpiof 10 0>;
          myled3 = <&gpioe 8 0>;
    */
    #define GNAME "mydev"
    unsigned int major =0;
    char kbuf[128]={0};
    struct cdev* cdev;
    struct class * cls;
    struct device *devic;
    dev_t dev1;
    int minor = 0;
    unsigned count=6;
    wait_queue_head_t wq;
    int condition=0;
     
    int mydev_open(struct inode *inode, struct file *file)
    {
        printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
        return 0;
    }
    long mydev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
    {
        int addr;
        switch(cmd)
        {
            case LED_ON:
            {
                    ret = copy_from_user(&addr,(void*)arg,sizeof(int));
                        if(ret)
                        {
                            printk("copy from user on is error\n");
                            return -EIO;
                        }
                        switch(addr)
                        {
                            case LED1:
                            {
                                gpiod_set_value(gpiono1,1);
                                break;
                            }
                            case LED2:
                            {
                                gpiod_set_value(gpiono2,1);
                                break;
                            }
                            case LED3:
                            {
                                gpiod_set_value(gpiono3,1);
                                break;
                            }
                        }    
                break;
            }
            case LED_OFF:
            {
                 ret = copy_from_user(&addr,(void*)arg,sizeof(int));
                        if(ret)
                        {
                            printk("copy from user on is error\n");
                            return -EIO;
                        }
                        switch(addr)
                        {
                            case LED1:
                            {
                                gpiod_set_value(gpiono1,0);
                                break;
                            }
                            case LED2:
                            {
                                gpiod_set_value(gpiono2,0);
                                break;
                            }
                            case LED3:
                            {
                                gpiod_set_value(gpiono3,0);
                                break;
                            }
                        }    
            break;
            }
        }
        return 0;
    }
    int mydev_close(struct inode *inode, struct file *file)
    {
        printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
        return 0;
    }
    struct file_operations fops={
        .open=mydev_open,
        .unlocked_ioctl=mydev_ioctl,
        .release=mydev_close,
    };
    static int __init mynode_init(void)
    {
        int i;
        int ret;
        //分配字符设备驱动
        cdev=cdev_alloc();
        if(NULL==cdev)
        {
            printk("cdev alloc error\n");
            goto ERR1;
        }
        //设备驱动初始化
        cdev_init(cdev,&fops);
        //申请设备号
        if(major>0)
        {
            ret=register_chrdev_region(MKDEV(major,minor),count,GNAME);
            if(ret!=0)
            {
                printk("register chrdev region error\n");
                ret = -ENOMEM;
                goto ERR2;
            }
        }
        else
        {
            ret=alloc_chrdev_region(&dev1,0,count,GNAME);
            if(ret!=0)
            {
                printk("alloc chrdev region error\n");
                ret = -ENOMEM;
                goto ERR2;
            }
            major = MAJOR(dev1);
            minor = MINOR(dev1);
        }
     
        //驱动的注册
        ret = cdev_add(cdev,MKDEV(major,minor),count);
        if(ret!=0)
        {
            printk("cdev add error\n");
            ret = -EIO;
            goto ERR3;
        }
        //通过名字获取设备树节点信息
        node = of_find_node_by_name(NULL,"myleds");
        if(NULL == node)
        {
            printk("of find node by name error\n");
            return -EFAULT;
        }
        //获取并申请LED1的gpio编号
        gpiono1 = gpiod_get_from_of_node(node,"myled1",0,GPIOD_OUT_LOW,NULL);
        if(IS_ERR(gpiono1))
        {
            printk("1gpiod get from of node error\n");
            return PTR_ERR(gpiono1);
        }
        //获取并申请LED2的gpio编号
         gpiono2 = gpiod_get_from_of_node(node,"myled2",0,GPIOD_OUT_LOW,NULL);
        if(IS_ERR(gpiono2))
        {
            printk("2gpiod get from of node error\n");
            return PTR_ERR(gpiono2);
        }
        //获取并申请LED3的gpio编号
         gpiono3 = gpiod_get_from_of_node(node,"myled3",0,GPIOD_OUT_LOW,NULL);
        if(IS_ERR(gpiono3))
        {
            printk("3gpiod get from of node error\n");
            return PTR_ERR(gpiono3);
        }

        //设置LED1管脚为输出
        gpiod_direction_output(gpiono1,0);
         //设置LED2管脚为输出
        gpiod_direction_output(gpiono2,0);
         //设置LED3管脚为输出
        gpiod_direction_output(gpiono3,0);

        //自动创建设备节点  
        cls = class_create(THIS_MODULE,GNAME);
        if(IS_ERR(cls))
        {
            ret = PTR_ERR(cls);
            goto ERR4;
        }
        for(i=0;i<count;i++)
        {
        devic = device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
        if(IS_ERR(devic))
        {
            ret = PTR_ERR(devic);
            goto ERR5;
        }
        }
        init_waitqueue_head(&wq);
        return 0;
    ERR5:
        for(--i;i>=0;i--)
        {
            device_destroy(cls,MKDEV(major,i));
        }
        class_destroy(cls);
    ERR4:
        cdev_del(cdev);
    ERR3:
        unregister_chrdev_region(MKDEV(major,minor),count);
    ERR2:
        kfree(cdev);
    ERR1:
        return -EIO;
        
    }
     
    static void __exit mynode_exit(void)
    {
        int i;
        //卸载驱动前熄灭灯LED1
        gpiod_set_value(gpiono1,0);
            //卸载驱动前熄灭灯LED2
        gpiod_set_value(gpiono2,0);
            //卸载驱动前熄灭灯LED3
        gpiod_set_value(gpiono3,0);
            //卸载驱动前熄灭灯LED1

        //释放申请得到的LED1gpio编号
        gpiod_put(gpiono1);
            //释放申请得到的LED2gpio编号
        gpiod_put(gpiono2);
            //释放申请得到的LED3gpio编号
        gpiod_put(gpiono3);

     
        //销毁设备节点信息
        for(i=0;i<count;i++)
        {
        device_destroy(cls,MKDEV(major,i));
        }
        class_destroy(cls);
        //释放驱动
        cdev_del(cdev);
        //释放设备号
        unregister_chrdev_region(MKDEV(major,minor),count);
        //注销字符设备驱动
        
        kfree(cdev);
     
    }
     
    module_init(mynode_init);
    module_exit(mynode_exit);
     
    MODULE_LICENSE("GPL");

应用层代码

   #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/ioctl.h>
    #include"./six.h"
     
    int main(int argc, char const *argv[])
    {
        int fd1 = -1;
        int fd2 = -1;
        int fd3 = -1;

        int i=0;
        int whitch;
        fd1 = open("/dev/myled1",O_RDWR);
        if(-1 == fd1)
        {
            perror("open is error");
            exit(1);
        }
        fd2 = open("/dev/myled2",O_RDWR);
        if(-1 == fd2)
        {
            perror("open is error");
            exit(1);
        }
        fd3 = open("/dev/myled3",O_RDWR);
        if(-1 == fd3)
        {
            perror("open is error");
            exit(1);
        }

        while(1)
        {
            whitch=LED1;
            ioctl(fd1,LED_ON,&whitch);
            sleep(1);
            ioctl(fd1,LED_OFF,&whitch);
            whitch=LED2;
            ioctl(fd2,LED_ON,&whitch);
            sleep(1);
            ioctl(fd2,LED_OFF,&whitch);
            whitch=LED3;
            ioctl(fd3,LED_ON,&whitch);
            sleep(1);
            ioctl(fd3,LED_OFF,&whitch);
            sleep(1);
        }
        close(fd1);
        close(fd2);
        close(fd3);

        return 0;
    }

相关文章:

2.14作业【GPIIO控制LED】

设备树 myleds{ myled1 <&gpioe 10 0>; myled2 <&gpiof 10 0>; myled3 <&gpioe 8 0>; }; 驱动代码 #include<linux/init.h> #include<linux/module.h> #include<linux/of.h&…...

5min搞定linux环境Jenkins的安装

5min搞定linux环境Jenkins的安装 安装Jenkinsstep1: 使用wget 命令下载Jenkinsstep2、创建Jenkins日志目录并运行jekinsstep3、访问jenkins并解锁jenkins,安装插件以及创建管理员用户step4、到此,就完成了Finish、以上步骤中遇到的问题1、 jenkins启动不了2、jenkins无法访问…...

Cortex-M0存储器系统

目录1.概述2.存储器映射3.程序存储器、Boot Loader和存储器重映射4.数据存储器5.支持小端和大端数据类型数据对齐访问非法地址多寄存器加载和存储指令的使用6.存储器属性1.概述 Cortex-M0处理器具有32位系统总线接口&#xff0c;以及32位地址线&#xff08;4GB的地址空间&…...

软件测试——测试用例之场景法

一、场景法的应用场合 场景法主要用于测试软件的业务流程和业务逻辑。场景法是基于软件业务的测试方法。在场景法中测试人员把自己当成最终用户&#xff0c;尽可能真实的模拟用户在使用此软件的操作情景&#xff1a; 重点模拟两类操作&#xff1a; 1&#xff09;模拟用户正确…...

英文写作中的常用的衔接词

1. 增补 (Addition) in addition, furthermore, again, also, besides, moreover, whats more, similarly, next, finally 2.比较&#xff08;Comparision&#xff09; in the same way, similarly, equally, in comparison, just as 3. 对照 (Contrast) in contrast, on …...

新库上线 | CnOpenData中国地方政府债券信息数据

中国地方政府债券信息数据 一、数据简介 地方政府债券 指某一国家中有财政收入的地方政府地方公共机构发行的债券。地方政府债券一般用于交通、通讯、住宅、教育、医院和污水处理系统等地方性公共设施的建设。地方政府债券一般也是以当地政府的税收能力作为还本付息的担保。地…...

Python 条件语句

Python条件语句是通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非0和非空&#xff08;null&#xff09;值为true&#xff0c;0 或者 null为false。 Python 编…...

C语言思维导图大总结 可用于期末考试 C语言期末考试题库

目录 一.C语言思维导图 二.C语言期末考试题库 一.C语言思维导图 导出的图可能有点糊&#xff0c;或者查看链接&#xff1a;https://share.weiyun.com/uhf1y2mp 其实原图是彩色的不知道为什么导出时颜色就没了 部分原图&#xff1a; 也可私信我要全图哦。 图里的链接可能点不…...

从零实现深度学习框架——再探多层双向RNN的实现

来源&#xff1a;投稿 作者&#xff1a;175 编辑&#xff1a;学姐 往期内容&#xff1a; 从零实现深度学习框架1&#xff1a;RNN从理论到实战&#xff08;理论篇&#xff09; 从零实现深度学习框架2&#xff1a;RNN从理论到实战&#xff08;实战篇&#xff09; 从零实现深度…...

Flink 连接流详解

连接流 1 Union 最简单的合流操作&#xff0c;就是直接将多条流合在一起&#xff0c;叫作流的“联合”&#xff08;union&#xff09;。联合操作要求必须流中的数据类型必须相同&#xff0c;合并之后的新流会包括所有流中的元素&#xff0c;数据类型不变。这种合流方式非常简…...

分享112个HTML电子商务模板,总有一款适合您

分享112个HTML电子商务模板&#xff0c;总有一款适合您 112个HTML电子商务模板下载链接&#xff1a;https://pan.baidu.com/s/13wf9C9NtaJz67ZqwQyo74w?pwdzt4a 提取码&#xff1a;zt4a Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 有机蔬菜水果食品商城网…...

2023备战金三银四,Python自动化软件测试面试宝典合集(八)

马上就又到了程序员们躁动不安&#xff0c;蠢蠢欲动的季节~这不&#xff0c;金三银四已然到了家门口&#xff0c;元宵节一过后台就有不少人问我&#xff1a;现在外边大厂面试都问啥想去大厂又怕面试挂面试应该怎么准备测试开发前景如何面试&#xff0c;一个程序员成长之路永恒绕…...

J-Link RTT Viewer使用教程(附代码)

目录 RTT(Real Time Transfer)简介 使用教程 常用API介绍 RTT缓冲大小修改 使用printf重定向 官方例程 RTT(Real Time Transfer)简介 平常调试代码中使用串口打印log&#xff0c;往往需要接出串口引脚&#xff0c;比较麻烦&#xff0c;并且串口打印速度较慢&#xff0c;串…...

C语言——指针、数组的经典笔试题目

文章目录前言1.一维数组2.字符数组3.二维数组4.经典指针试题前言 1、数组名通常表示首元素地址&#xff0c;sizeof(数组名)和&数组名两种情况下&#xff0c;数组名表示整个数组。 2、地址在内存中唯一标识一块空间&#xff0c;大小是4/8字节。32位平台4字节&#xff0c;64位…...

【C语言】程序环境和预处理|预处理详解|定义宏(上)

主页&#xff1a;114514的代码大冒险 qq:2188956112&#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ &#xff09; Gitee&#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、程序的翻译环境和执行环境 二、详解编译和链接 1.翻译环境 2.编…...

上海霄腾自动化装备盛装亮相2023生物发酵展

上海霄腾自动化携液体膏体粉剂颗粒等灌装生产线解决方案亮相2023生物发酵展BIO CHINA2023生物发酵展&#xff0c;作为生物发酵产业一年一度行业盛会&#xff0c;由中国生物发酵产业协会主办&#xff0c;上海信世展览服务有限公司承办&#xff0c;2023第10届国际生物发酵产品与技…...

python+flask开发mock服务

目录 什么是mock&#xff1f; 什么时候需要用到mock&#xff1f; 如何实现&#xff1f; pythonflask自定义mock服务的步骤 一、环境搭建 1、安装flask插件 2、验证插件 二、mock案例 1、模拟 返回结果 2、模拟 异常响应状态码 3、模拟登录&#xff0c;从jmeter中获取…...

数据库(三)

第三章 MySQL库表操作 3.1 SQL语句基础 3.1.1 SQL简介 SQL&#xff1a;结构化查询语言(Structured Query Language)&#xff0c;在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。使用SQL语句&#xff0c;程序员和数据库管理员可以完成如下的任务。 改变数据…...

2023软考纸质证书领取通知来了!

不少同学都在关注2022下半年软考证书领取时间&#xff0c;截止至目前&#xff0c;上海、湖北、江苏、南京、安徽、山东、浙江、宁波、江西、贵州、云南、辽宁、大连、吉林、广西地区的纸质证书可以领取了。将持续更新2022下半年软考纸质证书领取时间&#xff0c;请同学们在证书…...

Python requests模块

一、requests模块简介 requests模块是一个第三方模块&#xff0c;需要在python环境中安装&#xff1a; pip install requests 该模块主要用来发送 HTTP 请求&#xff0c;requests 模块比 urllib 模块更简洁。 requests模块支持&#xff1a; 自动处理url编码自动处理post请求…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...