华清远见嵌入式学习——春节作业——2.15日

作业要求:

编写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] = {0}; // 用于保存向内核中传输的消息
// 用来接收映射成功的内存首地址
unsigned int *moder_e;
unsigned int *odr_e;
unsigned int *moder_f;
unsigned int *odr_f;
unsigned int *rcc;/*
// 延时函数
void delay(int ms)
{int i, j;for (i = 0; i < ms; i++){for (j = 0; j < 2000; j++){}}
}
*/// 封装常用的操作方法
int mychrdev_open(struct inode *inode, struct file *file)
{printk("调用mychrdev_open成功,%d\n", __LINE__);return 0;
}ssize_t mychrdev_read(struct file *file, char __user *ubuf, size_t size, loff_t *lof)
{printk("调用成功mychrdev_read,%d\n", __LINE__);// 用户调用了read后会调用这个函数// 所以是从内核空间向用户空间写unsigned int ret; // 用于接收返回值,判断是否成功ret = copy_to_user(ubuf, kbuf, size);if (ret){printk("数据拷贝失败\n");return -ret;}return 0;
}ssize_t mychrdev_write(struct file *file, const char __user *ubuf, size_t size, loff_t *lof)
{printk("调用mychrdev_write成功,%d\n", __LINE__);// 用户调用了write后会调用这个函数// 所以是从用户空间向内核空间写unsigned int ret; // 用于接收返回值,判断是否成功ret = copy_from_user(kbuf, ubuf, size);if (ret){printk("数据拷贝失败\n");return -ret;}if (kbuf[0] == '0') // 开1号灯{(*odr_e) |= (0x1 << 10);}else if (kbuf[0] == '1') // 开2号灯{(*odr_f) |= (0x1 << 10);}else if (kbuf[0] == '2') // 开3号灯{(*odr_e) |= (0x1 << 8);}else if (kbuf[0] == '3') // 开三个灯{(*odr_e) |= (0x1 << 10);(*odr_f) |= (0x1 << 10);(*odr_e) |= (0x1 << 8);}else if (kbuf[0] == '4') // 关1号灯{(*odr_e) &= (~(0x1 << 10));}else if (kbuf[0] == '5') // 关2号灯{(*odr_f) &= (~(0x1 << 10));}else if (kbuf[0] == '6') // 关3号灯{(*odr_e) &= (~(0x1 << 8));}else if (kbuf[0] == '7') // 关三个灯{(*odr_e) &= (~(0x1 << 10));(*odr_f) &= (~(0x1 << 10));(*odr_e) &= (~(0x1 << 8));}return 0;
}int mychrdev_close(struct inode *inode, struct file *file)
{printk("调用mychrdev_close成功,%d\n", __LINE__);return 0;
}// 定义操作方法指针
struct file_operations fops = {.open = mychrdev_open,.read = mychrdev_read,.write = mychrdev_write,.release = mychrdev_close};static int __init mycdev_init(void)
{// 注册字符设备驱动// 填0代表动态申请主设备号major = register_chrdev(0, "mychrdev", &fops);// 申请失败if (major < 0){printk("注册字符设备驱动失败 %d\n", __LINE__);}printk("注册字符设备驱动成功 major = %d\n", major);// 进行LED寄存器的地址映射moder_e = ioremap(GPIOE_MODER, 4);if (moder_e == NULL){printk("地址映射失败%d\n", __LINE__);return 0;}moder_f = ioremap(GPIOF_MODER, 4);if (moder_f == NULL){printk("地址映射失败%d\n", __LINE__);return 0;}odr_e = ioremap(GPIOE_ODR, 4);if (odr_e == NULL){printk("地址映射失败%d\n", __LINE__);return 0;}odr_f = ioremap(GPIOF_ODR, 4);if (odr_f == NULL){printk("地址映射失败%d\n", __LINE__);return 0;}rcc = ioremap(RCC_GPIO, 4);if (rcc == NULL){printk("地址映射失败%d\n", __LINE__);return 0;}printk("地址映射成功\n");// 硬件初始化// 使能时钟(*rcc) |= (0X3 << 4);// 设置PE10、PF10、PE8为输出(*moder_e) &= (~(0X3 << 20));(*moder_e) |= (0X1 << 20);(*moder_f) &= (~(0X3 << 20));(*moder_f) |= (0X1 << 20);(*moder_e) &= (~(0X3 << 16));(*moder_e) |= (0X1 << 16);// 默认输出低电平(*odr_e) &= (~(0x1 << 10));(*odr_f) &= (~(0x1 << 10));(*odr_e) &= (~(0x1 << 8));return 0;
}
static void __exit mycdev_exit(void)
{// 取消内存映射iounmap(moder_e);iounmap(odr_e);iounmap(moder_f);iounmap(odr_f);iounmap(rcc);// 注销字符设备驱动unregister_chrdev(major, "mychrdev");printk("注销字符设备驱动成功 %d\n", __LINE__);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

led.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc,const char * argv[])
{//用于接收读取到的数据char buf[128] = {};//打开自定义字符设备文件int fd = open("/dev/mychrdev",O_RDWR);//当打开失败时if(fd < 0){printf("打开自定义字符设备文件失败\n");return -1;}//开关灯的逻辑控制while (1){printf("请输入控制码:0(开1号灯) 1(开2号灯) 2(开3号灯) \3(开三个灯) 4(关1号灯) 5(关2号灯) \6(关3号灯) 7(关三个灯)>");fgets(buf, sizeof(buf), stdin); // 从终端输入一个数据buf[strlen(buf) - 1] = '\0';write(fd, buf, sizeof(buf));}//关闭close(fd);return 0;
}

head.h

#ifndef __HEAD_H__
#define __HEAD_H__#define GPIOE_MODER 0X50006000
#define GPIOF_MODER 0X50007000
#define GPIOE_ODR   0X50006014
#define GPIOF_ODR   0X50007014
#define RCC_GPIO    0X50000A28#endif

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

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

相关文章

基于GPT-4一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

医卫答案在哪搜?九个公众号和软件推荐清单! #笔记#笔记#微信

在这个信息爆炸的时代&#xff0c;合理利用学习工具可以帮助我们过滤和获取有用的知识。 1.粉鹿搜题 这是一个公众号 题库包括四六级答案、各学校往期课后答案、期末考试题等&#xff0c;使用比较简单。 下方附上一些测试的试题及答案 1、最有可能担任债券发行受托人的个人…

装饰工程|装饰工程管理系统-项目立项子系统的设计与实现|基于Springboot的装饰工程管理系统设计与实现(源码+数据库+文档)

装饰工程管理系统-项目立项子系统目录 目录 基于Springboot的装饰工程管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 &#xff08;2&#xff09;合同报价管理 &#xff08;3&#xff09;装饰材料总计划管理 &#xff08;4&#xff0…

Java与JavaScript的区别与联系

Java是目前编程领域使用非常广泛的编程语言&#xff0c;相较于JavaScript&#xff0c;Java更被人们熟知。很多Java程序员想学门脚本语言&#xff0c;一看JavaScript和Java这么像&#xff0c;很有亲切感&#xff0c;那干脆就学它了&#xff0c;这也间接的帮助了JavaScript的发展…

OLED显示红外遥控键码

基本原理 本遥控器的编码是NEC编码&#xff0c;为PWM&#xff08;脉冲宽度调制&#xff09;。 发射红外载波的时间固定&#xff0c;通过改变不发射载波的时间来改变占空比。 逻辑“0”是由0.56ms的38KHZ载波和0.560ms的无载波间隔组成&#xff1b;逻辑“1”是由0.56ms的38KHZ…

LabVIEW高效电磁阀性能测试

LabVIEW高效电磁阀性能测试 在核电站的安全运营中&#xff0c;电磁阀作为关键组件&#xff0c;其性能的可靠性至关重要。设计一套基于LabVIEW的电磁阀测试平台&#xff0c;既能精准测试电磁阀的多项性能指标&#xff0c;又能提高检修效率与准确性&#xff0c;进而保障核电站的…

接口测试全流程扫盲

扫盲内容&#xff1a; 1.什么是接口&#xff1f; 2.接口都有哪些类型&#xff1f; 3.接口的本质是什么&#xff1f; 4.什么是接口测试&#xff1f; 5.问什么要做接口测试&#xff1f; 6.怎样做接口测试&#xff1f; 7.接口测测试点是什么&#xff1f; 8.接口测试都要掌…

​StableSwarmUI#超越文本的prompt

今天看到一个新的webui方案&#xff0c;是Stability-AI开源的&#xff1a; StableSwarmUI 是一个模块化的稳定扩散web用户界面&#xff0c;着重于使强大的工具易于访问、高性能和可扩展性。 由于项目还在开发中&#xff0c;我们可以先了解下&#xff0c;翻看了它的特点&#xf…

ELAdmin 发送邮件

邮箱配置 ELAdmin目录中选择系统工具->邮件工具。 发件人邮箱&#xff1a;发送者的邮箱地址发件用户名&#xff1a;一般都是发件人邮箱前面的部分&#xff0c;也可以任意写邮箱密码&#xff1a;如果是 qq 邮箱或者腾讯企业邮箱&#xff0c;需要使用授权码。SMTP地址&…

表的连接

目录 内连接实现效果 使用左外连接&#xff0c;将所有的员工信息都显示出来&#xff0c;即便他没有对应的部门 使用右外连接&#xff0c;将所有的部门信息都显示出来 查询每个员工的编号、姓名、职位&#xff0c;以及所在各部门的领导姓名、领导职位 确定所需要的数据表 确…

多模态基础--- word Embedding

1 word Embedding 原始的单词编码方式&#xff1a; one-hot&#xff0c;维度太大&#xff0c;不同单词之间相互独立&#xff0c;没有远近关系区分。 wordclass&#xff0c;将同一类单词编码在一起&#xff0c;此时丢失了类别和类别间的相关信息&#xff0c;比如class1和class3…

应急响应实战笔记02日志分析篇(3)

第3篇:Web日志分析 ox01 Web日志 Web访问日志记录了Web服务器接收处理请求及运行时错误等各种原始信息。通过对WEB日志进行的安全分析&#xff0c;不仅可以帮助我们定位攻击者&#xff0c;还可以帮助我们还原攻击路径&#xff0c;找到网站存在的安全漏洞并进行修复。 我们来…

【牛客面试必刷TOP101】Day21.BM11 链表相加(二)和BM12 单链表的排序

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…

算法详解:滑动窗口-- 最大连续1的个数 III

题目来源:力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 本期讲解滑动窗口经典例题,我会从三个点开始讲解题目1.题目解析2.算法原理 3.编写代码 1.题目解析 这道题目理解起来还是比较简单的,我们简单分析一下,也就是给定一个数组,数组是由1和0组成…

红日靶场2学习

靶场下载来自&#xff1a; http://vulnstack.qiyuanxuetang.net/vuln/detail/3/ 靶场统一登录密码&#xff1a;1qazWSX 按大佬的说法是 环境需要模拟内网和外网两个网段&#xff0c;PC端虚拟机相当于网关服务器&#xff0c;所以需要两张网卡&#xff0c;一个用来向外网提供web…

LEETCODE 315. 计算右侧小于当前元素的个数(归并)

class Solution { public: // 将count声明为publicvector<int> count; vector<int> indexs,tmp;public:vector<int> countSmaller(vector<int>& nums) {//归并int left0;int rightnums.size()-1;//计数// vector<int> count(nums.size()); …

【web | CTF】BUUCTF [护网杯 2018] easy_tornado

天命&#xff1a;这题是框架性的漏洞&#xff0c;Python的web服务器框架&#xff0c;应该已经比较古老了 开局先看一下三个文件 简单阅读后会发现&#xff0c;这里存在文件包含漏洞&#xff0c;可以直接读取文件&#xff0c;但是有一个哈希值校验 一开始我以为是扫描文件后得到…

学习笔记17:AtCoder Beginner Contest 340

C C - Divide and Divide (atcoder.jp) 1e17暴力肯定不行 模拟暴力的过程我们发现很多运算是重复的 记忆化一下 #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> #incl…

关于npmlink的问题

深入浅出关于Npm linl的问题 关键词&#xff1a; vue3报错 Uncaught TypeError: Cannot read properties of null (reading ‘isCE‘) at renderSlot npm link 无法实现热更新 我的开发环境是 “vue”: “^3.2.13” 今天在使用 rollup搭建组件库的时候我发现我的组件库不能…

第22讲基于springboot+vue权限系统二次开发环境准备

基于springbootvue权限系统二次开发环境准备 基于这个系统二次开发&#xff0c;不重复造轮子&#xff1b; 基于这个系统二次开发&#xff0c;不重复造轮子&#xff1b; 一&#xff0c;权限系统环境准备 二&#xff0c;数据库表整合投票系统数据库 二&#xff0c;修改标题&a…