驱动开发--day2

实现三盏灯的控制,编写应用程序测试
head.h

#ifndef __HEAD_H__
#define __HEAD_H__#define LED1_MODER 0X50006000
#define LED1_ODR 0X50006014
#define LED1_RCC 0X50000A28#define LED2_MODER 0X50007000
#define LED2_ODR 0X50007014#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"//保存主设备号
unsigned int major;char kbuf[128]={0};unsigned int* vir_moder;
unsigned int* vir_odr;
unsigned int* vir_rcc;unsigned int* vir_moder_F;
unsigned int* vir_odr_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'){//开灯逻辑if(kbuf[1]=='1'){(*vir_odr) |= (0x1<<10);}else if(kbuf[1]=='2'){(*vir_odr_F) |= (0x1<<10);}else if(kbuf[1]=='3'){(*vir_odr) |= (0x1<<8);}}else if(kbuf[0]=='0'){//关灯逻辑if(kbuf[1]=='1'){(*vir_odr) &= (~(0x1<<10));}else if(kbuf[1]=='2'){(*vir_odr_F) &= (~(0x1<<10));}else if(kbuf[1]=='3'){(*vir_odr) &= (~(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);//进行相关寄存器的内存映射vir_odr=ioremap(LED1_ODR,4);if(vir_odr==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_rcc=ioremap(LED1_RCC,4);if(vir_rcc==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_moder=ioremap(LED1_MODER,4);if(vir_moder==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");vir_moder_F=ioremap(LED2_MODER,4);if(vir_moder_F==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");vir_odr_F=ioremap(LED2_ODR,4);if(vir_odr_F==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");//硬件寄存器的初始化//RCC使能(*vir_rcc) |= (0x1<<4);(*vir_rcc) |= (0x1<<5);//设置PE10为输出(*vir_moder) &= (~(0x3<<20));(*vir_moder) |= (0x1<<20);//设置PF8为输出(*vir_moder_F) &= (~(0x3<<20));(*vir_moder_F) |= (0x1<<20);//设置PE8为输出(*vir_moder) &= (~(0x3<<16));(*vir_moder) |= (0x1<<16);//默认关灯(*vir_odr) &= (~(0X1<<10));(*vir_odr_F) &= (~(0X1<<10));(*vir_odr) &= (~(0X1<<8));return 0;
}
static void __exit mycdev_exit(void)
{//取消物理内存映射iounmap(vir_moder);iounmap(vir_odr);iounmap(vir_rcc);iounmap(vir_moder_F);iounmap(vir_odr_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(int argc,char const *argv[])
{char buf[128]={0};int fd=open("/dev/mychrdev",O_RDWR);if(fd<0){printf("设备文件打开失败\n");exit(-1);}while(1){memset(buf,0,sizeof(buf));printf("请输入对LED1的控制命令11(开灯) 01(关灯)>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));memset(buf,0,sizeof(buf));printf("请输入对LED2的控制命令12(开灯) 02(关灯)>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));memset(buf,0,sizeof(buf));printf("请输入对LED3的控制命令13(开灯) 03(关灯)>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));}close(fd);
}

测试过程及现象:

1.编译>>>

2.测试>>>

3.现象>>>

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

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

相关文章

LeetCode刷题笔记【30】:动态规划专题-2(不同路径、不同路径 II)

文章目录 前置知识62.不同路径题目描述解题思路代码 63. 不同路径 II题目描述障碍信息传递法(比较复杂)被障碍物阻挡后直接清空计数法(更简洁) 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【29】&#xff1a;动态规划专题-1&#xff08;斐波那契数、爬楼梯…

【深入理解Linux内核锁】七、互斥体

我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1、互斥体API2、API实现2.1 mutex2.2 mutex_init2.3 mutex_lock2.4 mutex_un…

2023外贸SEO推广怎么做?

答案是&#xff1a;2023外贸SEO推广可以选择谷歌SEO谷歌Ads双向运营。 外贸SEO的核心要素 外贸SEO不仅仅是关于关键词排名&#xff0c;它更多的是关于品牌建设和目标受众的吸引。 要想成功&#xff0c;必须认识到几个关键要素。 了解目标市场 首先&#xff0c;要深入了解目…

vue3+ts+vite项目引入echarts,vue3项目echarts组件封装

概述 技术栈&#xff1a;Vue3 Ts Vite Echarts 简介&#xff1a; 图文详解&#xff0c;教你如何在Vue3项目中引入Echarts&#xff0c;封装Echarts组件&#xff0c;并实现常用Echarts图例 文章目录 概述一、先看效果1.1 静态效果1.2 动态效果 二、话不多数&#xff0c;引入 …

redis持久化

Redis高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证提供…

ARM的异常处理

概念 处理器在正常执行程序的过程中可能会遇到一些不正常的事件发生 这时处理器就要将当前的程序暂停下来转而去处理这个异常的事件 异常事件处理完成之后再返回到被异常打断的点继续执行程序 异常处理机制 不同的处理器对异常的处理的流程大体相似&#xff0c;但是不同的处理器…

面试如何回答弹性盒子布局这个问题呢?

在我们面试中如果被问道css方面的面试题 那么极有可能被问到的一道面试题就是弹性盒子&#xff0c;本篇文章通过一张图带你拿捏这道面试题。 1、首先需要说一说弹性盒子的基本概念&#xff1a;弹性盒子是一种用于网页布局中创建灵活和响应式设计的CSS布局模型。 2、其次需要说…

IDEA找不到Maven窗口

有时候导入项目或者创建项目时候Maven窗口找不到了 然后指定项目的pom.xml文件

力扣(LeetCode)算法_C++——有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#xff09; …

JMeter压力测试 5分钟让你学会如何并发压测接口

文章目录 地址下载启动 使用 地址 JMeter官网下载&#xff1a;https://jmeter.apache.org/download_jmeter.cgi 下载 最新款的jmeter需要java8的支持&#xff0c;请自行安装jdk8或以上的版本 根据系统不同系统下载zip或者是tgz格式的压缩包&#xff0c;并解压&#xff0c;博…

错误: 找不到或无法加载主类 Main

在用git回退到上个版本后发现&#xff0c;无法运行项目并提示 错误: 找不到或无法加载主类 Main 可以看到Main前面的图标也是号。 查了半天没有解决&#xff0c;问了个大佬&#xff0c;大佬一下就解决掉了&#xff0c;本文记录下解决过程。 错误原因是编辑器无法找到代码位置&…

D361周赛复盘:模拟分割整数⭐+变为整除的最小次数⭐

文章目录 2843.统计对称整数的数目&#xff08;模拟&#xff0c;分割整数为两部分&#xff09;思路1.整数换成字符串版本2.直接用整数的版本 2844.生成特殊数字的最小操作(模拟&#xff0c;x能被Num整除的条件)思路完整版 2843.统计对称整数的数目&#xff08;模拟&#xff0c;…

能直接运营的发接任务平台小程序搭建开发演示

有个项目估计做过互联网的小伙伴都听说过——发接任务平台。 基本每年都有发接任务平台关站&#xff0c;但又有新的平台出来&#xff0c;往复循环&#xff0c;无比热闹。这在互联网圈不常见&#xff0c;互联网项目很多都是风头过去了就结束了&#xff0c;但发接任务年年似乎都…

【django】Forbidden (CSRF cookie not set.)

CSRF 表示django全局发送post请求均需要字符串验证 功能&#xff1a; 防止跨站请求伪造的功能 工作原理&#xff1a; 客户端访问服务器端&#xff0c;在服务器端正常返回给客户端数据的时候&#xff0c;而外返回给客户端一段字符串&#xff0c;等到客户端下次访问服务器端时…

云计算在智能制造中的应用与前景

文章目录 云计算的基本概念智能制造的基本概念云计算在智能制造中的应用1. 数据存储和管理2. 大数据分析3. 机器学习和预测维护4. 跨地理分布的协作5. 资源弹性和成本优化 未来前景1. 智能工厂2. 预测性维护3. 定制化生产4. 绿色生产5. 全球制造协作 结论 &#x1f389;欢迎来到…

JavaWeb | 常用的HTML(JavaWeb)标签

目录&#xff1a; HTML简介HTML的基本结构HTML的常用标签&#xff1a;“标题” 标签“换行” 标签“段落” 标签“水平线” 标签“文字” 标签“粗体” 标签“下划线” 标签“斜体” 标签“上标” 标签“下标” 标签“闪烁” 标签表示 “空格”“列表” 标签&#xff1a;无序列…

mojo初体验

目录标题 mojo初体验试用地址变量定义参数可变性和所有权Structures后续 mojo初体验 试用地址 https://www.modular.com/get-started 与python基础语法很相似。 变量定义 let定义不可变变量var定义可变变量 参数可变性和所有权 下面是一个基本的函数&#xff1a; fn add…

软考:中级软件设计师:程序语言基础:表达式,标准分类,法律法规,程序语言特点,函数传值传址

软考&#xff1a;中级软件设计师:程序语言基础&#xff1a;表达式 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都…

无涯教程-JavaScript - BIN2DEC函数

描述 BIN2DEC函数将二进制数字转换为十进制。 语法 BIN2DEC (number)争论 Argument描述Required/Optionalnumber 您要转换的二进制数。 Number cannot contain more than 10 characters (10 bits). 数字的最高有效位是符号位。其余的9位是幅度位。 负数使用二进制补码表示。…

NUC980webServer开发

目录 1.RTL8189FTV驱动移植 2.wifi配置工具hostapd移植 1.openssl-1.0.2r交叉编译 2.libnl-3.2.25.tar.gz交叉编译 3.hostapd-2.9.tar.gz交叉编译 4.移植相关工具到开发板 1.RTL8189FTV驱动移植 1. 把驱动文件源码放在linux源码的drivers/net/wireless/realtek/rtlwifi/目录…