当前位置: 首页 > 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请求…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.

这个警告表明您在使用Vue的esm-bundler构建版本时&#xff0c;未明确定义编译时特性标志。以下是详细解释和解决方案&#xff1a; ‌问题原因‌&#xff1a; 该标志是Vue 3.4引入的编译时特性标志&#xff0c;用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...