当前位置: 首页 > 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;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...