当前位置: 首页 > news >正文

【驱动开发day4作业】

头文件代码

#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 ODR;
}gpio_t;
#define PHY_LED1_ADDR 0X50006000
#define PHY_LED2_ADDR 0X50007000
#define PHY_LED3_ADDR 0X50006000
#define PHY_RCC_ADDR  0X50000A28
//功能码
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)#endif 

 应用层代码

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include "head.h"int main(int argc, char const *argv[])
{char buf[128] = {0};int a, b;int fd;while (1){// 从终端读取printf("请输入要打开哪个设备>");printf("0:LED1 1:LED2 2:LED3\n");printf("请输入>");scanf("%d", &b);if (b == 0){fd = open("/dev/mycdev0", O_RDWR);}else if (b == 1){fd = open("/dev/mycdev1", O_RDWR);}else if (b == 2){fd = open("/dev/mycdev2", O_RDWR);}if (fd < 0){printf("打开设备文件失败\n");exit(-1);}printf("请输入指令\n");printf("0(关灯) 1(开灯)\n");printf("请输入>");scanf("%d", &a);switch (a){case 1:ioctl(fd, LED_ON); // 开灯break;case 0:ioctl(fd, LED_OFF);break;}close(fd);}return 0;
}

 驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include<linux/slab.h>
#include<linux/cdev.h>
#include "head.h"dev_t devid;
struct cdev *cdev;
unsigned int major = 500;
unsigned int minor = 0;
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
unsigned int *vir_rcc;
struct class *cls;
struct device *dev;
int mycdev_open(struct inode *inode, struct file *file)
{//获取当前设备文件对应的设备号int which_dev = inode->i_rdev;//将次设备号保存到当前文件的file结构中file->private_data = (void *)MINOR(which_dev);printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{unsigned int which_dev = (unsigned int)file->private_data; switch(which_dev){case 0://LED1控制逻辑;if(cmd == LED_ON){vir_led1->ODR |= (0x1 << 10); // LED1开灯}else if(cmd == LED_OFF){vir_led1->ODR &= (~(0X1 << 10));}break;   case 1://LED2控制逻辑;if(cmd == LED_ON){vir_led2->ODR |= (0x1 << 10); // LED2开灯}else if(cmd == LED_OFF){vir_led2->ODR &= (~(0X1 << 10));}break; case 2://LED3控制逻辑;if(cmd == LED_ON){vir_led3->ODR |= (0x1 << 8); // LED3开灯}else if(cmd == LED_OFF){vir_led3->ODR &= (~(0X1 << 8));}break;                          }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__);return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);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,.unlocked_ioctl = mycdev_ioctl,.release = mycdev_close,.read = mycdev_read,.write = mycdev_write,
};// 灯的寄存器映射以及初始化
int all_led_init(void)
{// 寄存器地址的映射vir_led1 = ioremap(PHY_LED1_ADDR, sizeof(gpio_t));if (vir_led1 == NULL){printk("ioremap filed:%d\n", __LINE__);return -ENOMEM;}vir_led2 = ioremap(PHY_LED2_ADDR, sizeof(gpio_t));if (vir_led2 == NULL){printk("ioremap filed:%d\n", __LINE__);return -ENOMEM;}vir_led3 = vir_led1;vir_rcc = ioremap(PHY_RCC_ADDR, 4);if (vir_rcc == NULL){printk("ioremap filed:%d\n", __LINE__);return -ENOMEM;}printk("物理地址映射成功\n");// 寄存器的初始化// rcc(*vir_rcc) |= (3 << 4);// led1vir_led1->MODER &= (~(3 << 20));vir_led1->MODER |= (1 << 20);vir_led1->ODR &= (~(1 << 10));// led2vir_led2->MODER &= (~(3 << 20));vir_led2->MODER |= (1 << 20);vir_led2->ODR &= (~(1 << 10));// led3vir_led3->MODER &= (~(3 << 16));vir_led1->MODER |= (1 << 16);vir_led1->ODR &= (~(1 << 8));printk("灯的寄存器初始化成功\n");return 0;
}static int __init mycdev_init(void)
{int ret;// 1.申请对象空间 cdev_alloccdev = cdev_alloc();if (cdev == NULL){printk("申请驱动对象空间失败\n");ret = -EFAULT;goto OUT1;}printk("申请驱动对象空间成功\n");// 2.初始化对象  cdev_initcdev_init(cdev, &fops);// 3.申请设备号  register_chrdev_region()/alloc_chrdev_region()// 动态申请if (major == 0){ret = alloc_chrdev_region(&devid, minor, 3, "mycdev");if (ret != 0){printk("动态申请设备号失败\n");goto OUT2;}//统一后面的操作major = MAJOR(devid); //根据设备号获取主设备号minor = MINOR(devid);}//静态指定申请else{ret = register_chrdev_region(MKDEV(major,minor),3,"mycdev");if(ret != 0){printk("静态指定设备号失败\n");goto OUT2;}}printk("申请设备号成功\n");// 4.注册驱动对象 cdev_add()ret = cdev_add(cdev, MKDEV(major,minor), 3);if (ret != 0){printk("注册设备驱动对象失败\n");goto OUT3;}printk("注册设备驱动对象成功\n");// 5.向上提交目录  class_create()cls = class_create(THIS_MODULE, "mycdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");goto OUT4;}printk("向上提交目录成功\n");// 6.向上提交设备信息 device_create()int i;for (i = 0; i < 3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "mycdev%d",i);}if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");goto OUT5;}printk("向上提交设备节点信息成功\n");// 灯的寄存器映射以及初始化all_led_init();return 0;
OUT5:
//将提交成功的设备信息销毁
for(--i;i>=0;i--)
{device_destroy(cls,MKDEV(major,i));
}
OUT4:class_destroy(cls);
OUT3:unregister_chrdev_region(MKDEV(major,minor), 3);
OUT2:kfree(cdev);
OUT1:return ret;
}static void __exit mycdev_exit(void)
{// 取消地址映射iounmap(vir_led1);iounmap(vir_led2);iounmap(vir_rcc);// 1.销毁设备信息  device_destroyint i;for(i=0;i<3;i++){device_destroy(cls,MKDEV(major,i));}// 2.销毁目录    class_destroyclass_destroy(cls);// 3.注销驱动对象  cdev_delcdev_del(cdev);// 4.释放设备号   unregister_chrdev_region()unregister_chrdev_region(MKDEV(major,minor),3);// 5.释放对象空间   kfree()kfree(cdev);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

相关文章:

【驱动开发day4作业】

头文件代码 #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 ODR; }gpio_t; #define PHY_LED1_ADDR 0X50006000 #define PHY_LED2_ADDR 0X50007000 #…...

Ubuntu 20.04 Ubuntu18.04安装录屏软件Kazam

1.在Ubuntu Software里面输入Kazam&#xff0c;就可以找不到这个软件&#xff0c;直接点击install就可以了 2.使用方法&#xff1a; 选择Screencast&#xff08;录屏&#xff09; Fullscreen&#xff08;全屏&#xff09;-----Windows&#xff08;窗口&#xff09;--------Ar…...

ADC 的初识

ADC介绍 Q: ADC是什么&#xff1f; A: 全称&#xff1a;Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 ADC的性能指标 量程&#xff1a;能测量的电压范围分辨率&#xff1a;ADC能辨别的最小模拟量&#xff0c;通常以输出二进制数的位数表示&#xff0c;比如&am…...

MMdetection框架速成系列 第07部分:数据增强的N种方法

MMdetection框架实现数据增强的N种方法 1 为什么要进行数据增强2 数据增强的常见误区3 常见的六种数据增强方式3.1 随机翻转&#xff08;RandomFlip&#xff09;3.2 随机裁剪&#xff08;RandomCrop&#xff09;3.3 随机比例裁剪并缩放&#xff08;RandomResizedCrop&#xff0…...

基于Kitti数据集的智能驾驶目标检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于Kitti数据集的智能驾驶目标检测系统可用于日常生活中检测与定位行人&#xff08;Pedestrian&#xff09;、面包车&#xff08;Van&#xff09;、坐着的人&#xff08;Person Sitting&#xff09;、汽车&#xff08;Car&#xff09;、卡车&#xff08;Truck…...

4.4. 深拷贝 vs 浅拷贝

文章目录 浅拷贝&#xff1a;对基本数据类型进行值传递&#xff0c;对引用数据类型进行引用传递般的拷贝&#xff0c;此为浅拷贝。深拷贝&#xff1a;对基本数据类型进行值传递&#xff0c;对引用数据类型&#xff0c;创建一个新的对象&#xff0c;并复制其内容&#xff0c;此为…...

网络安全(黑客)自学建议笔记

前言 网络安全&#xff0c;顾名思义&#xff0c;无安全&#xff0c;不网络。现如今&#xff0c;安全行业飞速发展&#xff0c;我们呼吁专业化的 就职人员与大学生 &#xff0c;而你&#xff0c;认为自己有资格当黑客吗&#xff1f; 本文面向所有信息安全领域的初学者和从业人员…...

Linux CentOS快速安装VNC并开启服务

以下是在 CentOS 上安装并开启 VNC 服务的步骤&#xff1a; 安装 VNC 服务器软件包。运行以下命令&#xff1a; sudo yum install tigervnc-server 输出 $ sudo yum install tigervnc-server Loaded plugins: fastestmirror, langpacks Repository epel is missing name i…...

redis到底几个线程?

通常我们说redis是单线程指的是从接收客户端请求->解析请求->读写->响应客户端这整个过程是由一个线程来完成的。这并不意味着redis在任何场景、任何版本下都只有一个线程 为何用单线程处理数据读写&#xff1f; 内存数据储存已经很快了 redis相比于mysql等数据库是…...

mysql修改UUID

mysql修改UUID 问题描述&#xff1a;集群搭建时克隆主服务的镜像导致所有节点的服务UUID都一致&#xff0c;此时在集群中添加节点时会提示UUID冲突报错。 解决方案 1、利用uuid函数生成新的uuid mysql> select uuid(); -------------------------------------- | uuid() …...

NoSQL之redis配置与优化

NoSQL之redis配置与优化 高可用持久化功能Redis提供两种方式进行持久化1.触发条件手动触发自动触发 执行流程优缺点缺点&#xff1a;优势AOF出发规则&#xff1a; AOF流程AOF缺陷和优点 NoSQL之redis配置与优化 mysql优化 1线程池优化 2硬件优化 3索引优化 4慢查询优化 5内…...

Python单例模式介绍、使用

一、单例模式介绍 概念&#xff1a;单例模式是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供访问该实例的全局访问点。 功能&#xff1a;单例模式的主要功能是确保在应用程序中只有一个实例存在。 优势&#xff1a; 节省系统资源&#xff1a;由…...

1334179-85-9,BTTAA,是各种化学生物学实验中生物偶联所需

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ BTTAA试剂 | 基础知识概述&#xff08;部分&#xff09;: 中文名称&#xff1a;2-[4-({双[(1-叔丁基-1H-1,2,3-三唑-4-基)甲基]氨基}甲基)-1H-1,2,3-三唑-1-基]乙酸 英文名称&#xff1a;BTTAA CAS号&#xff1a;1334179-8…...

Linux系统中的SQL语句

本节主要学习&#xff0c;SQL语句的语句类型&#xff0c;数据库操作&#xff0c;数据表操作&#xff0c;和数据操作等。 文章目录 一、SQL语句类型 DDL DML DCL DQL 二、数据库操作 1.查看 2.创建 默认字符集 指定字符集 3.进入 4.删除 5.更改 库名称 字符集 6…...

力扣27 26 283 844 977 移除数组

给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的…...

【沐风老师】3DMAX自动材质插件使用方法教程

3DMAX自动材质插件使用方法教程 3DMAX自动材质工具用于在将纹理加载到3dsax中时快速创建简单的材质&#xff0c;并具有一些很酷的材质功能。 这个插件可以根据真正制造商的纹理&#xff08;通常比例为2:1&#xff09;快速创建简单的木材材质&#xff0c;并根据板材的长度自动对…...

让你 React 组件水平暴增的 5 个技巧

目录 透传 className、style 通过 forwardRef 暴露一些方法 useCallback、useMemo 用 Context 来跨组件传递值 React.Children、React.cloneElement 总结 最近看了一些 Ant Design 的组件源码&#xff0c;学到一些很实用的技巧&#xff0c;这篇文章来分享一下。 首先&am…...

阿里云部署 ChatGLM2-6B 与 langchain+ChatGLM

1.ChatGLM2-6B 部署 更新系统 apt-get update 安装git apt-get install git-lfs git init git lfs install 克隆 ChatGLM2-6B 源码 git clone https://github.com/THUDM/ChatGLM2-6B.git 克隆 chatglm2-6b 模型 #进入目录 cd ChatGLM2-6B #创建目录 mkdir model #进入目录 cd m…...

F12开发者工具的简单应用

目录 elements 元素 1、元素的定位和修改 2、UI自动化应用 console 控制台 sources 源代码 network 网络 1、定位问题 2、接口测试 3、弱网测试 performance 性能 memory 存储 application 应用 recorder 记录器 界面展示如下&#xff08;设置中可以切换中英文&am…...

【 Python 全栈开发 - 人工智能篇 - 45 】决策树与随机森林

文章目录 一、概念与原理1.1 决策树1.1.1 概念1.1.2 原理特征选择分割方法 1.1.3 优点与缺点1.1.4 Python常用决策树算法 1.2 随机森林1.2.1 概念1.2.2 原理1.2.3 优点与缺点1.2.4 Python常用随机森林算法 1.3 决策树与随机森林的比较1.3.1 相同之处1.3.2 不同之处 二、决策树算…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

什么是Ansible Jinja2

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

Mobile ALOHA全身模仿学习

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

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...

【若依】框架项目部署笔记

参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作&#xff1a; 压缩包下载&#xff1a;http://download.redis.io/releases 1. 上传压缩包&#xff0c;并进入压缩包所在目录&#xff0c;解压到目标…...