嵌入式:驱动开发 Day2

news2025/1/18 11:54:14

作业:字符设备驱动,完成三盏LED灯的控制

驱动代码: 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"

unsigned int major;   //保存主设备号
char kbuf[128] = "";

unsigned int *vir_moder_e;
unsigned int *vir_odr_e;
unsigned int *vir_rcc_e;

unsigned int *vir_moder_f;
unsigned int *vir_odr_f;
unsigned int *vir_rcc_f;

//封装操作方法
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){
	int ret;
	ret = copy_to_user(ubuf, kbuf, size);
	if(ret){
		printk("copy_to_user err\n");
		return -EIO;
	}
	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 err\n");
		return -EIO;
	}
	if(kbuf[0] == '1')  	//led1开灯
	{
		//开灯逻辑
		(*vir_odr_e) |= (0x1 << 10);
	}else if(kbuf[0] == '2'){   //led1关灯
		//关灯逻辑
		(*vir_odr_e) &= (~(0x1 << 10));
	}else if(kbuf[0] == '3'){   //led2开灯
		//开灯逻辑
		(*vir_odr_f) |= (0x1 << 10);
	}else if(kbuf[0] == '4'){   //led2关灯
		//关灯逻辑
		(*vir_odr_f) &= (~(0x1 << 10));
	}else if(kbuf[0] == '5'){   //led3开灯
		//开灯逻辑
		(*vir_odr_e) |= (0x1 << 8);
	}else if(kbuf[0] == '6'){   //led3关灯
		//关灯逻辑
		(*vir_odr_e) &= (~(0x1 << 8));
	}
	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, "mychrdev", &fops);
	if(major < 0){
		printk("字符设备驱动注册失败\n");
		return major;
	}
	printk("字符设备驱动注册成功 major = %d\n", major);

	//进行相关寄存器的内存映射
	//GPIOE组寄存器内存映射
	vir_odr_e = ioremap(GPIOE_ODR, 4);
	if(vir_odr_e == NULL){
		printk("物理内存映射失败%d\n", __LINE__);
		return -EFAULT;
	}
	vir_rcc_e = ioremap(GPIOE_RCC, 4);
	if(vir_rcc_e == NULL){
		printk("物理内存映射失败%d\n", __LINE__);
		return -EFAULT;
	}
	vir_moder_e = ioremap(GPIOE_MODER, 4);
	if(vir_moder_e == NULL){
		printk("物理内存映射失败%d\n", __LINE__);
		return -EFAULT;
	}

	//GPIOF组寄存器内存映射
	vir_odr_f = ioremap(GPIOF_ODR, 4);
	if(vir_odr_f == NULL){
		printk("物理内存映射失败%d\n", __LINE__);
		return -EFAULT;
	}
	vir_rcc_f = ioremap(GPIOF_RCC, 4);
	if(vir_rcc_f == NULL){
		printk("物理内存映射失败%d\n", __LINE__);
		return -EFAULT;
	}
	vir_moder_f = ioremap(GPIOF_MODER, 4);
	if(vir_moder_f == NULL){
		printk("物理内存映射失败%d\n", __LINE__);
		return -EFAULT;
	}
	printk("寄存器内存映射成功\n");

	//硬件寄存器的初始化
	//RCC使能
	(*vir_rcc_e) |= (0x1 << 4);     //GPIOE(PE10 PE8)使能
	(*vir_rcc_f) |= (0x1 << 5);     //GPIOF(PF10)使能

	//设置PE10为输出模式 --> LED1
	(*vir_moder_e) &= (~(0x3 << 20));
	(*vir_moder_e) |= (0x1 << 20);
	//设置PF10为输出模式 --> LED2
	(*vir_moder_f) &= (~(0x3 << 20));
	(*vir_moder_f) |= (0x1 << 20);
	//设置PE8为输出模式 --> LED3
	(*vir_moder_e) &= (~(0x3 << 16));
	(*vir_moder_e) |= (0x1 << 16);

	//默认LED1关灯
	(*vir_odr_e) &= (~(0x1 << 10));
	//默认LED2关灯
	(*vir_odr_f) &= (~(0x1 << 10));
	//默认LED1关灯
	(*vir_odr_e) &= (~(0x1 << 8));
	return 0;
}

static void __exit mycdev_exit(void){
	//取消物理内存映射
	iounmap(vir_moder_e);
	iounmap(vir_odr_e);
	iounmap(vir_rcc_e);

	iounmap(vir_moder_f);
	iounmap(vir_odr_f);
	iounmap(vir_rcc_f);

	//字符设备驱动注销
	unregister_chrdev(major, "mychrdev");
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

应用代码:test.c

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

int main(){
	char buf[128] = "";
	int fd = open("/dev/mychrdev", O_RDWR);
	if(fd < 0){
		printf("设备文件打开失败\n");
		exit(-1);
	}

	while(1){
		printf("请输入对LED的控制命令:1(LED1开灯) 2(LED1关灯) 3(LED2开灯) 4(LED2关灯) 5(LED3开灯) 6(LED3关灯) >");
		fgets(buf, sizeof(buf), stdin); //在终端输入数据传递到buf
		buf[strlen(buf) - 1] = '\0'; 	//替换末尾的'\n'
		write(fd, buf, sizeof(buf));
	}

	close(fd);

	return 0;
}

头文件:head.h

#ifndef __HEAD_H__
#define __HEAD_H__

#define GPIOE_MODER 0x50006000
#define GPIOE_ODR 0x50006014
#define GPIOE_RCC 0x50000A28

#define GPIOF_MODER 0x50007000
#define GPIOF_ODR 0x50007014
#define GPIOF_RCC 0x50000A28

#endif

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

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

相关文章

oracle表空间释放

oracle表空间释放 1&#xff09;查询表空间信息2&#xff09;查询指定表空间下各个表的表空间使用情况3-1&#xff09;可以直接释放3-2) 可以move3-3&#xff09;重新排列 1&#xff09;查询表空间信息 selecta.tablespace_name as "表空间名",total as "表空间…

初识Java 7-1 多态

目录 向上转型 难点 方法调用绑定 产生正确的行为 可扩展性 陷阱&#xff1a;“重写”private方法 陷阱&#xff1a;字段与静态方法 构造器和多态 构造器的调用顺序 继承和清理 构造器内部的多态方法行为 协变返回类型 使用继承的设计 替换和扩展 向下转型和反射…

Java开发之Mysql【面试篇 完结版】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、知识体系二、Mysql-优化1. 优化-如何定位慢查询① 问题引入② 解决方案③ 问题总结④ 实战面试 2. 优化-sql执行很慢&#xff0c;如何解决① 问题引入② 解…

AI项目五:结印动作识别

若该文为原创文章&#xff0c;转载请注明原文出处。 感谢恩培大佬对项目进行了完整的实现&#xff0c;并将代码进行开源&#xff0c;供大家交流学习。 恩培大佬开源地址&#xff0c;有兴趣的可以去复现一下。GitHub - enpeizhao/CVprojects: computer vision projects | 计算机…

计算机网路学习-time_wait过多

四次挥手 调试命令 netstat -an|awk ‘/tcp/ {print $6}’|sort|uniq -c netstat -an 列出系统中所有处于活动状态的网络连接信息&#xff0c;包括 IP 地址、端口号、协议等。 其中&#xff0c;第六列是tcp的状态。 Proto Recv-Q Send-Q Local Address Foreign Addr…

Aidlux工业视觉缺陷检测

Aidlux工业视觉缺陷检测 1. AidLux简介 AidLux是成都阿加犀智能科技有限公司自主研发的融合架构平台&#xff0c;提供Android&#xff0f;鸿蒙&#xff0b;Linux融合系统&#xff0c; 双系统既能独立使用又能相互通信。 阿加犀致力于人工智能核心技术持续创新&#xff0c; 独…

CSS元素浮动

概述 浮动简介 在最初&#xff0c;浮动是用来实现文字环绕图片效果的&#xff0c;现在浮动是主流的页面布局方式之一。 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff0c;默认宽与高都是被内容撑开的&#xff08;尽可能小&#xff09;&am…

AKF拆分原则

在分布式软件环境下&#xff0c;为了保障分布式架构的可靠性、可扩展、高性能&#xff0c;通常会通过集群、扩容、数据分治等思想来实现&#xff0c;比如很多中间件的使用Redis、ZK、Kafka等&#xff0c;都可以通过这种设计思想来提高系统架构吞吐量。AKF是一个系统化的拓展思想…

Vue框架+Element组件库学习笔记

一、Vue框架 vue&#xff1a;是一款前端框架&#xff0c;免除原生JavaScript中的DOM操作&#xff08;如document.getElementById("文本输入框名").value&#xff09;&#xff0c;简化书写。基于MVVM&#xff08;Model-View-ViewModel&#xff09;思想&#xff0c;实…

YApi 新版如何查看 http 请求数据

YApi 新版如何查看 http 请求数据 因chrome 安全策略限制&#xff0c;在 cross-request 升级到 3.0 后&#xff0c; 不再支持文件上传功能&#xff0c;并且需要通过以下方法查看 network:1.首先在chrome 输入 > chrome://extensions打开扩展页2.开启开发者模式3.点击 cross…

震惊:QGroupBox在linux下居然不显示边框

1、linux系统下GroupBox默认无边框&#xff0c;如需添加&#xff0c;需要通过style来修改 下面介绍几个例子&#xff1a; QGroupBox {background: transparent;border: 1px solid rgb(130, 130, 130);border-radius: 6px;}QGroupBox::title {subcontrol-origin: margin;subcont…

RegShot – 注册表比较工具

RegShot 是一种注册表比较工具&#xff0c;它通过两次抓取注册表而快速地比较出答案。它还可以将您的注册表以纯文本方式记录下来&#xff0c;便于浏览&#xff1b;还可以监察 Win.ini&#xff0c;System.ini 中的键值&#xff1b;还可以监察您Windows目录和 System 目录中文件…

比较聚合模型实战文本匹配

引言 本文我们采用比较聚合模型来实现文本匹配任务。 数据准备 数据准备包括 构建词表(Vocabulary)构建数据集(Dataset) 本次用的是LCQMC通用领域问题匹配数据集&#xff0c;它已经分好了训练、验证和测试集。 我们通过pandas来加载一下。 import pandas as pdtrain_df …

diskqueue第五篇 - 追尾检测,错误处理,如何正常关闭

diskqueue是nsq消息持久化的核心&#xff0c;内容较多&#xff0c;故分为多篇 1. diskqueue第一篇 - 是什么&#xff0c;为什么需要它&#xff0c;整体架构图&#xff0c;对外接口 2. diskqueue第二篇 - 元数据文件&#xff0c;数据文件&#xff0c;启动入口&#xff0c;元数…

熟悉Redis6

NoSQL数据库简介 技术发展 技术的分类 1、解决功能性的问题&#xff1a;Java、Jsp、RDBMS、Tomcat、HTML、Linux、JDBC、SVN 2、解决扩展性的问题&#xff1a;Struts、Spring、SpringMVC、Hibernate、Mybatis 3、解决性能的问题&#xff1a;NoSQL、Java线程、Hadoop、Nginx…

嵌入式-Linux基本操作 pwd cd ls touch clear mkdir rm cp mv

目录 一.Linux文件系统 二.Linux目录结构 三.Linux基本命令 3.1shell脚本 3.2pwd命令 3.3cd命令 3.4ls命令 3.5touch命令 3.6clear命令 3.7mkdir命令 3.8rm命令 3.9cp命令 3.10mv命令 一.Linux文件系统 Linux文件系统是Linux操作系统中用于组织和管理文件和目录的…

【算法训练-链表 六】【查找】:链表中倒数第k个节点

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【查找链表】&#xff0c;使用【链表】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

C盘清理教程

C盘清理教程 首先使用space Sniffer 扫一下c盘&#xff0c;然后看一下到底是哪个文件这么大 第二步&#xff0c;创建软链接。 首先将我们需要移动的文件的当前路径拷贝下来&#xff1a;C:\Users\Tom\Desktop\test-link\abc\ghi.txt 然后假设剪切到D盘下&#xff1a;D:\ghi.…

MOOC软件系统外包开发

MOOC&#xff08;大规模开放在线课程&#xff09;系统是用于创建、管理和交付在线教育课程的软件平台。这些系统通常具有多种功能&#xff0c;旨在支持大规模的在线学习。以下是MOOC系统主要实现的功能以及一些常见的开源系统&#xff0c;希望对大家有所帮助。北京木奇移动技术…

vite项目框架搭建

vite项目框架搭建 1. 使用vite初始化项目 开始 | Vite 官方中文文档 (vitejs.dev) pnpm create vite # 依次设置项目名称、选择框架【vue】、选择语言【typescript】 √ Project name: ... vite-project √ Select a framework: Vue √ Select a variant: TypeScript2. ele…