6月20日作业

news2024/11/24 19:42:23

我实现的功能,执行一次应用程序led灯 亮,再次执行应用程序led灯灭。

内核模块:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/wait.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
unsigned int major;
char kbuf[128] = {0};
struct class *cls;
struct device *dev;


// 设备树
int gpiono;
struct device_node *dnode;
// 新版设备树
struct gpio_desc *gpionn;
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *iof)
{
    int ret;
    // 向用户拷贝
    if (size > sizeof(kbuf))
        size = sizeof(kbuf);
    ret = copy_to_user(ubuf, kbuf, size);
    if (ret)
    {
        printk("copy to user filed\n");
        return -EIO;
    }
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
   
    return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *iof)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    int ret;
    // 从用户拷贝
    if (size > sizeof(kbuf))
        size = sizeof(kbuf);
    ret = copy_from_user(kbuf, ubuf, size);
    if (ret)
    {
        printk("copy from user filed\n");
        return -EIO;
    }
 
    // 开灯
    // 新版设备树
    // gpiod_set_value(gpionn,1);
    // 取反led灯状态
    gpio_set_value(gpiono, !gpio_get_value(gpiono));

    return 0;
}



int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
// 定义一个操作方法结构体变量并且初始化
struct file_operations fops = {
    .open = mycdev_open,
    .read = mycdev_read,
    .write = mycdev_write,
  
    .release = mycdev_close,
};
static int __init mycdev_init(void)
{
    
    // 字符设备驱动的注册
    major = register_chrdev(0, "mycdev", &fops);
    if (major < 0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功major=%d\n", major);
    // 向上提交目录
    cls = class_create(THIS_MODULE, "mycdev");
    if (IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return -PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");
    // 向上提交设备节点信息
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");
    if (IS_ERR(dev))
    {
        printk("向上提交设备节点失败\n");
        return -PTR_ERR(dev);
    }
    printk("向上提交设备节点成功\n");
    // 解析设备树节点
    dnode = of_find_node_by_name(NULL, "myleds");
    if (dnode == NULL)
    {
        printk("解析设备树节点失败\n");
        return -1;
    }
    printk("解析设备树节点成功\n");
    // 根据设备树节点解析出gpio编号
    gpiono = of_get_named_gpio(dnode, "led1", 0);
    if (gpiono < 0)
    {
        printk("解析设备号失败\n");
        return -1;
    }
    printk("解析设备号%d成功\n", gpiono);
    // 设置管脚为输出
    gpio_direction_output(gpiono, 0);
    // 新版设备树
    // 根据设备树节点解析出gpio编号并申请
    /*
    gpionn=gpiod_get_from_of_node(dnode,"led1",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpionn))
    {
        printk("申请设备号失败\n");
        return -1;
    }
    */

    return 0;
}
static void __exit mycdev_exit(void)
{
    // 灭灯
    gpio_set_value(gpiono, 0);
    // 新版设备树
    // gpiod_set_value(gpiono, 0);
    // 释放gpio编号
    gpio_free(gpiono);
    // 新版设备树
    // gpiod_put(gpionn);
    //  销毁设备节点信息
    device_destroy(cls, MKDEV(major, 0));
    // 销毁目录空间
    class_destroy(cls);
    // 字符设备驱动的注销
    unregister_chrdev(major, "mycdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

应用层程序:

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    char buf[128] = "hello  world";
    int fd = open("/dev/mycdev", O_RDWR);
    if (fd < 0)
    {
        printf("设备文件打开失败\n");
        exit(-1);
    }
    write(fd, buf, sizeof(buf));
    return 0;
}

效果图:

 

 

 

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

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

相关文章

中职网络搭建(服务器)—Linux LVM(标准答案)

题目要求如下 使用fdisk-l查看磁盘信息 我们添加的磁盘分别是sdb和sdc Fdisk /dev/sdb 依次输入n,p,1&#xff0c;回车,2G &#xff08;新建2G的主分区&#xff09; 依次输入n,e,2&#xff0c;回车&#xff0c;回车&#xff08;使用剩余的全部空间建立扩展分区&#xff09; 依…

软件工程——第2章可行性研究知识点整理

本专栏是博主个人笔记&#xff0c;主要目的是利用碎片化的时间来记忆软工知识点&#xff0c;特此声明&#xff01; 文章目录 1.可行性研究的目的&#xff1f; 2.可行性研究的实质&#xff1f; 3.从哪些方面研究逻辑模型的解法可行性&#xff1f; 4.可行性研究最根本的任务是…

6个免费音效、配乐素材网站,无版权,可商用。

分享几个网站&#xff0c;配乐、音效素材都有&#xff0c;还是免费可商用的&#xff0c;希望能帮到大家&#xff0c;建议收藏起来~ 菜鸟图库 https://www.sucai999.com/audio.html?vNTYxMjky 虽然这是一个设计素材网站&#xff0c;但涵盖的素材非常广泛&#xff0c;想视频素材…

Git系列:运用Git创建空白分支进行项目相关文档管理

文章目录 起因一、为什么会选择Git分支二、Git分支的简单介绍和好处三、本次的具体操作1.$git checkout --orphan XXX2.删除当前分支里的内容3.提交新的分支 总结 起因 项目管理过程中没有做好相关文档管理&#xff0c;比如需求&#xff0c;开发&#xff0c;测试等文档&#x…

【Mysql】索引数据结构深入研究(一)

索引 1.什么是索引 数据库概论老师说&#xff1a;索引就是教科书的目录页&#xff0c;你要查哪个内容你就去目录页查询内容在哪。Mysql官网&#xff1a;索引是帮助Mysql高效获取数据的排好序的数据结构。 2.索引的数据结构 二叉树红黑树Hash表B-Tree 2.1 二叉树 我们先看…

右向辅助产品需求及交互策略说明书

介绍 Introduction 此文档的范围和目的 Scope and Purpose of This Document 定义并描述功能&#xff0c;功能逻辑&#xff0c;功能与驾驶员、环境和其它要素的依赖性和相互影响。为充分理解功能提供支持&#xff0c;以便支持后续阶段的研发活动。 To define and describe …

Prompt的技巧持续总结

Prompt 有很多网站已经收录了&#xff0c;比如&#xff1a;aimappro 有些直接抄上述网站的作业即可&#xff0c;不过也来看看&#xff0c; 有一些日常提问大概的咒语该怎么写。 1 三种微调下的提示写法 chatgpt时代的创新&#xff1a;LLM的应用模式比较 实际案例说明AI时代大…

在 Navicat Premium 中管理 MySQL 用户-第 1 部分:保护 Root 帐号

第 1 部分&#xff1a;保护 Root 帐号 管理数据库用户是数据库管理员&#xff08;DBA&#xff09;的主要职责之一。协调组织中的用户访问数据库的方式通常需要执行许多单独的任务&#xff0c;包括添加新用户&#xff0c;阻止已离开组织的用户的访问权限以及帮助无法登录的用户…

三、MNIST手写数字分类任务项目实战

分类任务和回归任务本质上并没有太大的区别&#xff0c;只是最终得到的结果和损失函数不同而已。 MNIST手写数字分类任务&#xff0c;最终得到的是10个值&#xff0c;也类似一个one-hot编码格式&#xff0c;表示该图片是0-9数字的概率&#xff0c;概率值最大的就是预测的最终结…

如何搭建企业内部Wiki?

企业内部wiki是一种基于web的知识管理系统&#xff0c;它可以帮助企业高效地管理和分享内部的知识和信息。搭建一个企业内部wiki需要考虑很多方面&#xff0c;包括选择合适的wiki软件、搭建服务器、设置权限、培训员工等。本文将介绍如何搭建企业内部wiki&#xff0c;以及如何管…

在职读研填充知识库,人大女王金融硕士项目是获取知识的有效途径

在工作中忙忙碌碌&#xff0c;等休息放空时&#xff0c;反而发现没有以前的快乐了。认识的人越来越多&#xff0c;反而觉得越来越孤独。或许这就是成长的代价。身在职场的我们距退休还有好久&#xff0c;这么漫长的时间不获取新知识怎么能行呢&#xff0c;让我们打开探索的窗户…

IO流(C++)

IO流C C语言的输入与输出流是什么CIO流C标准IO流C文件IO流二进制读写文本读写 stringstream的简单介绍 C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键 盘)读取数据&#xff0c;并将值存放在变量中。printf():…

QtCreator屏蔽指定警告:如C4819等

QtCreator 频繁报出warning: C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失。 方法一&#xff1a;&#xff08;屏蔽此警告&#xff09; 在工程文件.pro里面添加 # disable C4819 warning QMAKE_CXXFLAGS_WARN_ON -wd481…

【Linux】常用指令快速掌握

Linux常用指令 指令登录添加和删除普通用户ls 指令pwd & cd 指令touch 指令mkdir 指令tree 指令rm 指令man 指令nano 指令cp 指令mv 指令cat & tac 指令echo 指令more 指令less 指令head & tail 指令date & cal 指令find 指令which & whereis 指令alias 指…

【正项级数】敛散性判别(二)

【正项级数】敛散性判别&#xff08;二&#xff09; 比值判别法和根植判别法比值判别法和根植判别法例题比值/根植判别法失效时&#xff0c;该怎么处理&#xff1f;例题 比值判别法和根植判别法 比值判别法和根植判别法 例题 例1 一般遇到阶乘&#xff0c;为了方便约分&…

Java凉了吗?还能不能学Java?过来人谈谈看法!

别说Java&#xff0c;前端、python、C、C&#xff0c;哪一个没被提过“凉”&#xff1f;归根结底问题始终都只是一个&#xff1a;人确实改变了行业标准&#xff0c;但是人才过剩并不会造成行业衰退。 不可否认&#xff0c;现在Java技术栈相比前几年确实被不断拉长&#xff0c;难…

解决Tomcat控制台乱码、HTML乱码、system.out.println输出乱码、out.print乱码

开发环境 JDK8、IDEA 2023.1.2 (Ultimate Edition)、Tomcat 9.0.71 Tomcat控制台乱码 第一步&#xff1a;修改Tomcat目录下的 ./conf/logging.properties 文件&#xff0c;将3处UTF-8改为GBK&#xff0c;分别对应下图 IDEA 中的3个控制台的输出 第二步&#xff1a;删掉无用…

MySQL8.0与5.7版本的下载、安装与配置(atguigu)(史上最全最详细)

MySQL8.0与5.7版本的下载、安装与配置&#xff08;atguigu&#xff09;&#xff08;史上最全最详细&#xff09; 目录 MySQL8.0与5.7版本的下载、安装与配置&#xff08;atguigu&#xff09;&#xff08;史上最全最详细&#xff09;MySQL 8.0的下载MySQL5.7的下载MySQL8.0的安装…

01-初识threejs

基本概念 场景&#xff08;Scene&#xff09;&#xff1a;场景是 three.js 中所有 3D 对象的容器。它包含了所有的相机、灯光、几何体、材质、纹理等对象。相机&#xff08;Camera&#xff09;&#xff1a;相机定义了场景中的视角。它控制了场景中哪些部分会被渲染出来&#x…

逍遥自在学C语言 | 指针和数组的关联

前言 指针和数组之间存在着紧密的关系。在本文中&#xff0c;我们将探讨指针和数组的关系、指针算术和数组遍历、多维数组与指针以及指针数组和数组指针。 一、人物简介 第一位闪亮登场&#xff0c;有请今后会一直教我们C语言的老师 —— 自在。 第二位上场的是和我们一起学…