驱动day3

思维导图

在这里插入图片描述

练习

1.编写LED灯的驱动,可以控制三个灯,应用程序中编写控制灯的逻辑,要使用自动创建设备节点机制
head.h

#ifndef __HEAD_H__
#define __HEAD_H__typedef struct 
{unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ORD;
}gpio_t;#define GPIOE 0x50006000
#define GPIOF 0x50007000
#define RCC   0x50000A28#endif

mychrdev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"
#include <linux/device.h>unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};unsigned int *rcc;
gpio_t *led1;
gpio_t *led2;
gpio_t *led3;struct class *cls;
struct device *dev;// 封装操作方法
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 *lof)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);int ret;ret = copy_to_user(ubuf, kbuf, size);if (ret){printk("copy_to_user failed\n");return ret;}return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{int ret;ret = copy_from_user(kbuf, ubuf, size);if (ret){printk("copy_from_user failed\n");return ret;}switch (kbuf[0])//选灯{case '1':if (kbuf[1] == '1')//开灯led1->ORD |= (0x1 << 10);else if (kbuf[1] == '0')//关灯led1->ORD &= (~(0x1 << 10));break;case '2':if (kbuf[1] == '1')led2->ORD |= (0x1 << 10);else if (kbuf[1] == '0')led2->ORD &= (~(0x1 << 10));break;case '3':if (kbuf[1] == '1')led3->ORD |= (0x1 << 8);else if (kbuf[1] == '0')led3->ORD &= (~(0x1 << 8));break;}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,.release = mycdev_close,.read = mycdev_read,.write = mycdev_write,
};static int __init mycdev_init(void)
{int i;// 注册字符设备驱动major = register_chrdev(0, "mychrdev", &fops);if (major < 0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功major=%d\n", major);//向上提交目录信息cls = class_create(THIS_MODULE, "mychrdev");if(IS_ERR(cls)){printk("向上提交目录信息失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");//向上提交设备信息for (i=0; i<3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "mychrdev%d", i);if (IS_ERR(dev)){printk("向上提交设备节点失败\n");return -PTR_ERR(cls);}}printk("向上提交设备节点成功\n");// 完成硬件寄存器物理内存的映射led1 = ioremap(GPIOE, sizeof(gpio_t));if (led1 == NULL){printk("led1物理内存映射失败\n");return -EFAULT;}led2 = ioremap(GPIOF, sizeof(gpio_t));if (led2 == NULL){printk("led2物理内存映射失败\n");return -EFAULT;}led3 = ioremap(GPIOE, sizeof(gpio_t));if (led3 == NULL){printk("led3物理内存映射失败\n");return -EFAULT;}rcc = ioremap(RCC, 4);if (rcc == NULL){printk("rcc物理内存映射失败\n");return -EFAULT;}printk("物理内存映射成功\n");//rcc使能(*rcc) |= (0x3 << 4);//硬件寄存器初始化led1->MODER &= (~(0x3 << 20));led1->MODER |= (0x1 << 20);led2->MODER &= (~(0x3 << 20));led2->MODER |= (0x1 << 20);led3->MODER &= (~(0x3 << 16));led3->MODER |= (0x1 << 16);//默认关灯led1->ORD &= (~(0x1 << 10));led2->ORD &= (~(0x1 << 10));led3->ORD &= (~(0x1 << 8));return 0;
}static void __exit mycdev_exit(void)
{int i;// 取消物理内存的映射iounmap(rcc);iounmap(led1);iounmap(led2);iounmap(led3);//销毁设备信息for(i=0; i<3; i++)device_destroy(cls, MKDEV(major, i));//销毁目录信息class_destroy(cls);// 注销字符设备驱动unregister_chrdev(major, "mychrdev");
}module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

test.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char const *agrv[])
{char buf[128] = {0};int fd = open("/dev/mychrdev0", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入LED控制方式:(11(LED1开))> ");fgets(buf, sizeof(buf), stdin); // 从终端输入数据到bufbuf[strlen(buf) - 1] = '\0';    // 将buf末尾的'\n'切换为'\0'write(fd, buf, sizeof(buf));}close(fd);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SharkTeam:Worldcoin运营数据及业务安全分析

Worldcoin的白皮书中声明&#xff0c;Worldcoin旨在构建一个连接全球人类的新型数字经济系统&#xff0c;由OpenAI创始人Sam Altman于2020年发起。通过区块链技术在Web3世界中实现更加公平、开放和包容的经济体系&#xff0c;并将所有权赋予每个人。并且希望让全世界每一个人都…

Android中如何不编译源生模块

如果想让自己的app 替换系统的app 比如使用闪电浏览器替换系统的Browser 首先把闪电浏览器放到 vendor/rockchip/common/apps Android.mk LOCAL_PATH : $(call my-dir) include $(CLEAR_VARS)LOCAL_MODULE : Lightning LOCAL_SRC_FILES : $(LOCAL_MODULE).apk LOCAL_MODULE_C…

Unity如何把游戏导出成手机安装包

文章目录 前言使用环境步骤添加场景构建APK 前言 本文章主要演示了&#xff0c;如何将制作好的游戏&#xff0c;导出成APK&#xff0c;安装到手机上。 使用环境 Unity2022。 步骤 首先打开你的项目&#xff0c;然后选择菜单栏的“File” > “Build Settings…”&#xf…

windows权限维持—SSPHOOKDSRMSIDhistorySkeletonKey

windows权限维持—SSP&HOOK&DSRM&SIDhistory&SkeletonKey 1. 权限维持介绍1.1. 其他 2. 基于验证DLL加载—SPP2.1. 操作演示—临时生效2.1.1. 执行命令2.1.2. 切换用户 2.2. 操作演示—永久生效2.2.1. 上传文件2.2.2. 执行命令2.2.3. 重启生效 2.3. 总结 3. 基…

c语言每日一练(8)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

日常BUG——SpringBoot模糊映射

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 SpringBoot在启动时报出如下错误&#xff1a; Caused by: java.lang.IllegalStateExceptio…

springboot启动忽略某些类

springboot启动忽略某些类 描述解决方案单拉一个提交&#xff0c;把所有的涉及kafka消费的都不注入容器通过配置ComponentScan的excludeFilters配置了不生效后续处理改之前改之后解释 总结 拆分环境 感触解决实现demo参考 描述 目前我这的开发环境和测试环境数据库是两份&#…

Java真实面试题,offer已到手

关于学习 在黑马程序员刚刚开始的时候学习尽头非常足&#xff0c;到后面逐渐失去了一些兴趣&#xff0c;以至于后面上课会出现走神等问题&#xff0c;但是毕业时后悔晚矣。等到开始学习项目一的时候&#xff0c;思路总会比别人慢一些&#xff0c;不看讲义写不出来代码。 建议…

virtualBox桥接模式下openEuler镜像修改IP地址、openEule修改IP地址、openEule设置IP地址

安装好openEuler后,设置远程登入前,必不可少的一步,主机与虚拟机之间的通信要解决,下面给出详细步骤: 第一步:检查虚拟机适配器模式:桥接模式 第二步:登入虚拟机修改IP cd /etc/sysconfig/network-scripts vim ifcfg-enpgs3 没有vim的安装或者用vi代替:sudo dnf …

设计模式(6)原型模式

一、介绍 Java中自带的原型模式是clone()方法。该方法是Object的方法&#xff0c;native类型。他的作用就是将对象的在内存的那一块内存数据一字不差地再复制一个。我们写简单类的时候只需要实现Cloneable接口&#xff0c;然后调用Object::clone方法就可实现克隆功能。这样实现…

[oneAPI] 图像分类CIFAR-10

[oneAPI] 图像分类CIFAR-10 图像分类参数与包加载数据模型训练过程结果 oneAPI 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel DevCloud for oneAPI&#xff1a;https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSam…

解决内网GitLab 社区版 15.11.13项目拉取失败

问题描述 GitLab 社区版 发布不久&#xff0c;搭建在内网拉取项目报错&#xff0c;可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…

【学会动态规划】乘积为正数的最长子数组长度(21)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

《系统架构设计师教程》重点章节思维导图

内容来自《系统架构设计师教程》&#xff0c;筛选系统架构设计师考试中分值重点分布的章节&#xff0c;根据章节的内容整理出相关思维导图。 重点章节 第2章&#xff1a;计算机系统知识第5章&#xff1a;软件工程基础知识第7章&#xff1a;系统架构设计基础知识第8章&#xff1…

常见程序搜索关键字转码

个别搜索类的网站因为用户恶意搜索出现误拦截情况&#xff0c;这类网站本身没有非法信息&#xff0c;只是因为把搜索关键字显示在网页中&#xff08;如下图&#xff09;&#xff0c;可以参考下面方法对输出的关键字进行转码 DEDECMS程序 本文针对Dedecms程序进行搜索转码&…

XXL-JOB任务调度平台的安装使用教程

首先从GitHub上面将项目clone下来。 GitHub地址&#xff1a;https://gitee.com/xuxueli0323/xxl-job.git 下载好之后&#xff0c;然后通过IDEA打开&#xff0c;将Maven编译好后项目结构如下 在数据库中运行这个SQL文件 &#xff0c;将基础表创建出来。就可以得到左边图中那些表…

复合 类型

字符串和切片 切片 切片的作用是允许你引用集合中部分连续的元素序列&#xff0c;而不是引用整个集合。 例如&#xff1a; let s String::from("hello world");let hello &s[0..5]; // 切片 [0,5) 等效于&s[..5] let world &s[6..11]; // 切片…

电脑缺失msvcp140.dll怎么办?解决msvcp140.dll缺失问题

msvcp140.dll是Microsoft Visual C Redistributable中的一个动态链接库文件&#xff0c;用于提供运行时支持。它的主要作用是为应用程序提供必要的函数和组件&#xff0c;以便在运行时执行特定的任务。当系统中缺少msvcp140.dll文件时&#xff0c;我们打开游戏或许软件时候就会…

Wordcloud | 风中有朵雨做的‘词云‘哦!~

1写在前面 今天可算把key搞好了&#xff0c;不得不说&#x1f3e5;里手握生杀大权的人&#xff0c;都在自己的能力范围内尽可能的难为你。&#x1f602; 我等小大夫也是很无奈&#xff0c;毕竟奔波霸、霸波奔是要去抓唐僧的。 &#x1f910; 好吧&#xff0c;今天是词云&#x…

使用selenium如何实现自动登录

回顾使用requests如何实现自动登录一文中&#xff0c;提到好多网站在我们登录过后&#xff0c;在之后的某段时间内访问该网页时&#xff0c;不会给出请登录的提示&#xff0c;时间到期后就会提示请登录&#xff01;这样在使用爬虫访问网页时还要登录&#xff0c;打乱我们的节奏…