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

工业智能网关解决方案:物联网仓储环境监测系统

仓储是连接生产、供应和销售的中转系统&#xff0c;对于促进生产、提高效率有着重要的辅助作用。对于很多大型工厂或食品厂来说&#xff0c;需要对仓储环境进行严控的控制&#xff0c;以确保产品或食品的质量&#xff0c;避免不必要的产品损耗&#xff0c;提高产品存管的水平。…...

Linux进程线程管理

目录 存储管理 linux内存管理基本框架 系统空间管理和用户空间管理 进程与进程调度 进程四要素 用户堆栈的扩展 进程三部曲&#xff1a;创建&#xff0c;执行&#xff0c;消亡 系统调用exit(),wait() 内核中的互斥操作 存储管理 linux内存管理基本框架 系统空间管理…...

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

分享111个HTML电子商务模板&#xff0c;总有一款适合您 111个HTML电子商务模板下载链接&#xff1a;https://pan.baidu.com/s/1e8Wp1Rl9RaFrcW0bilIatg?pwdc97h 提取码&#xff1a;c97h Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 HTML5家居家具电子商务网…...

百度前端必会手写面试题整理

请实现一个 add 函数&#xff0c;满足以下功能 add(1); // 1 add(1)(2); // 3 add(1)(2)(3)&#xff1b;// 6 add(1)(2, 3); // 6 add(1, 2)(3); // 6 add(1, 2, 3); // 6function add(...args) {// 在内部声明一个函数&#xff0c;利用闭包的特性保存并收集…...

ubuntu 安装支持GPU的Docker详细步骤

安装依赖项 sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common 添加 Docker GPG 密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo apt-key fingerpr…...

usbmon+tcpdump+wireshark USB抓包

文章目录usbmon抓包及配合wireshark解析usbmon抓包及配合wireshark解析 usbmon首先编译为内核模块&#xff0c;然后通过modprobe usbmon加载到linux sys文件系统中 rootroot-PC:~# modprobe usbmon​ 而后 linux系统下安装 tcpdump rootroot-PC:~# apt-get install tcpdump​…...

【LeetCode】剑指 Offer 04. 二维数组中的查找 p44 -- Java Version

题目链接&#xff1a; https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/ 1. 题目介绍&#xff08;04. 二维数组中的查找&#xff09; 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递…...

TDengine 3.0.2.5 查询再优化!揭秘索引文件的工作原理

TDengine 3.0 虽然对底层做了大规模的优化重构&#xff0c;但是相对于数据文件的工作逻辑和 2.0 相比是整体保持不变的。本系列文章的主旨在于帮助用户深入理解产品&#xff0c;并且拥有基本的性能调试思路&#xff0c;从而获得更好的产品体验。本期文章会在讲解 TDengine 时序…...

蓝牙耳机哪个品牌性价比高?性价比高的无线蓝牙耳机

现如今耳机已经十分普及&#xff0c;大多数人会随身佩戴蓝牙耳机&#xff0c;相较于传统耳机&#xff0c;无线耳机不仅携带方便&#xff0c;舒适度上也更加出色。不过市面上的无线耳机种类繁多&#xff0c;很多朋友不知道该如何挑选&#xff0c;所以小编特意整理了一期性价比高…...

python的disutils创建分发包

python中的distutils包主要用创建共享包&#xff0c;安装包&#xff0c;在平时安装python模块的时候&#xff0c;使用的命令如下&#xff1a; python setup.py install 其实以上代码就是distuitls包提供的功能&#xff0c;直接使用setup.py来进行安装一个包&#xff0c;在用这种…...

江门当地的免费网站优化/百度排名点击

「范式大学」由第四范式发起&#xff0c;致力于成为“数据科学家”的黄埔军校&#xff0c;校长为第四范式首席科学家&#xff0c;华人界首个国际人工智能协会AAAI Fellow、唯一的AAAI 华人执委杨强教授。 &#xff3b;范式大学&#xff3d;在探索AI工业化的同时&#xff0c;也关…...

一个网站多个数据库/建个人网站的详细步骤

企业实施BPR 要用弹性策略(转)企业实施BPR 要用弹性策略95%的企业信息主管都表示&#xff0c;实际上业务重组是管理层的事&#xff0c;只有管理层重视了&#xff0c;才能顺利推动。而曾经是黑龙江龙迪集团人力资源部主任&#xff0c;现任集团总经理的赵洪俊对此有更深的感悟&am…...

做网站什么主题比较好/浏览器广告投放

1.抽象类 为什么会有抽象类&#xff1a; 抽象类的写法&#xff1a;abstract关键字 Animal定义为抽象类后&#xff0c;Animal animal new Animal();会报错&#xff1b;但&#xff0c;Animal one new Cat()依旧是可以的。 抽象类或是&#xff0c;保证“逻辑意义”完美、提高ja…...

平面设计资料网站/百度统计平台

python限定方法参数类型、返回值类型、变量类型等 typing模块的作用 自python3.5开始&#xff0c;PEP484为python引入了类型注解(type hints) 类型检查&#xff0c;防止运行时出现参数和返回值类型、变量类型不符合。作为开发文档附加说明&#xff0c;方便使用者调用时传入和…...

网页设计心得体会600/seo标题优化是什么意思

校验规则 rules: {dateRange: [{type: array,required: true,message: 请选择日期区间,fields: {0: {// type: string, //tpye类型试情况而定,所以如果返回的是date就改成daterequired: true,trigger: "change",message: 请选择开始日期},1: {type: string,required…...

常州做网站的公司/免费引流推广的方法

首先&#xff1a;为什么需要动态定义数组呢&#xff1f; 这是因为&#xff0c;很多情况下&#xff0c;在预编译过程阶段&#xff0c;数组的长度是不能预先知道的&#xff0c;必须在程序运行时动态的给出 但是问题是&#xff0c;c要求定义数组时&#xff0c;必须明确给定数组的…...