驱动开发,stm32mp157a开发板的led灯控制实验
1.实验目的
编写LED灯的驱动,在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制;
2.LED灯相关寄存器分析
LED1->PE10 LED1亮灭:
RCC寄存器[4]->1 0X50000A28
GPIOE_MODER[21:20]->01 (输出) 0X50006000
GPIOE_ODR[10]->1(输出高电平) 0(输出低电平)0X50006014
LED2->PF10 LED2亮灭:
RCC寄存器[5]->1 0X50000A28
GPIOE_MODER[21:20]->01 (输出) 0X50006000
GPIOE_ODR[10]->1(输出高电平) 0(输出低电平)0X50006014
LED3->PE8 LED3亮灭:
RCC寄存器[4]->1 0X50000A28
GPIOE_MODER[17:16]->01 (输出) 0X50006000
GPIOE_ODR[8]->1(输出高电平) 0(输出低电平)0X50006014
GPIOE_OTYPER默认为00
GPIOE_PUPDR默认为0
GPIOE_OSPEEDR默认为00
3.编写代码
---Makefile---工程管理文件
modname?=demo
arch?=arm
ifeq ($(arch),arm)
KERNELDIR:= /home/ubuntu/FSMP1A/linux-stm32mp-5.10.61-stm32mp-r2-r0/linux-5.10.61 #编译生成ARM架构
else
KERNELDIR:=/lib/modules/$(shell uname -r)/build #编译生成X86架构
endifPWD:=$(shell pwd) #模块化编译文件路径
all:make -C $(KERNELDIR) M=$(PWD) modules
clean:make -C $(KERNELDIR) M=$(PWD) cleanobj-m:=$(modname).o
---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 ODR;
}gpio_t;//LED1和LED3寄存器地址
#define LED1_ADDR 0x50006000
#define LED2_ADDR 0x50007000
#define LED3_ADDR 0x50006000
#define RCC_ADDR 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>char kbuf[128] = {0};
unsigned int major;
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)
{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;if(size > sizeof(kbuf)){size = sizeof(kbuf);}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)
{unsigned long ret;if(size > sizeof(kbuf)){size = sizeof(kbuf);}ret = copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user err\n"); return -EIO; }switch(kbuf[0]){case '1':if(kbuf[1] == '1') //开灯vir_led1->ODR |= (0x1 << 10);else if(kbuf[1] == '0') //关灯vir_led1->ODR &= (~(0x1 << 10));break;case '2':if(kbuf[1] == '1') //开灯vir_led2->ODR |= (0x1 << 10);else if(kbuf[1] == '0') //关灯vir_led2->ODR &= (~(0x1 << 10));break;case '3':if(kbuf[1] == '1') //开灯vir_led3->ODR |= (0x1 << 8);else if(kbuf[1] == '0') //关灯vir_led3->ODR &= (~(0x1 << 8));break;default:printk("输入错误\n"); }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,
};//相关寄存器地址映射及初始化
int all_led_init(void)
{//相关寄存器的内存映射vir_led1=ioremap(LED1_ADDR,sizeof(gpio_t));if(vir_led1 == NULL){printk("物理内存映射失败%d\n",__LINE__);return -ENOMEM;}vir_led2=ioremap(LED2_ADDR,sizeof(gpio_t));if(vir_led2 == NULL){printk("物理内存映射失败%d\n",__LINE__);return -ENOMEM;}vir_led3 = vir_led1;vir_rcc=ioremap(RCC_ADDR,4);if(vir_rcc == NULL){printk("物理内存映射失败%d\n",__LINE__);return -ENOMEM;}printk("寄存器内存映射成功\n");//硬件寄存器的初始化(*vir_rcc) |= (0x3 << 4);//LED1vir_led1->MODER &= (~(0x3 << 20));vir_led1->MODER |= (0x1 << 20);vir_led1->ODR &= (~(0x1 << 10));//LED2vir_led2->MODER &= (~(0x3 << 20));vir_led2->MODER |= (0x1 << 20);vir_led2->ODR &= (~(0x1 << 10));//LED3vir_led3->MODER &= (~(0x3 << 16));vir_led3->MODER |= (0x1 << 16);vir_led3->ODR &= (~(0x1 << 8));printk("寄存器初始化成功\n");return 0;
}//入口函数
static int __init mycdev_init(void)
{major = register_chrdev(0,"mychrdev",&fops);if(major < 0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功:major=%d\n",major);//寄存器映射及初始化all_led_init();//向上提交目录cls = class_create(THIS_MODULE,"mychrdev");if(IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录成功\n");//向上提交设备节点信息int i;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(dev);}}printk("向上提交设备节点信息成功\n");return 0;
}//出口函数
static void __exit mycdev_exit(void)
{//销毁设备节点信息int i;for(i=0; i<3; i++){device_destroy(cls,MKDEV(major,i));}//销毁目录信息class_destroy(cls);//取消物理内存的映射iounmap(vir_led1);iounmap(vir_led2);iounmap(vir_rcc);//字符设备驱动注销unregister_chrdev(major,"mychrdev");
}//声明
//入口函数地址
module_init(mycdev_init);
//出口函数地址
module_exit(mycdev_exit);
//遵循的GPL协议
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/mychrdev0",O_RDWR);if(fd < 0){printf("设备文件打开失败\n");exit(-1);}while(1){printf("第一个字符:1(LED1) 2(LED2) 3(LED3)\n");printf("第二个字符1(开灯)0(关灯)\n");printf("输入控制灯的两个字符>>> ");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = '\0';//像设备文件中写write(fd,buf,sizeof(buf));}close(fd);return 0;
}
4.测试
相关文章:
驱动开发,stm32mp157a开发板的led灯控制实验
1.实验目的 编写LED灯的驱动,在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制; 2.LED灯相关寄存器分析 LED1->PE10 LED1亮灭: RCC寄存器[4]->1 0X50000A28 GPIOE_MODER[21:20]->01 (输出) 0X50006000 GPIOE_ODR[10]-&g…...
黑客入侵机构,导致2万条信息被卖
近日据厦门日报报道,厦门一教育培训机构遭黑客入侵,2万条职工、学员信息被出售,教培机构被罚。 今年2月底,多名在厦门某教育培训机构学习的学员接到自称是该机构工作人员的电话,对方能准确说出学员的学科信息、缴费情…...
循环购:让消费者和商家共赢的新型电商模式
对于消费者来说,循环购可以让他们享受到优惠价格和高品质商品的同时,还能获得额外的收益和奖励。循环购可以激发消费者的积极性和忠诚度,增加他们对平台的信任和满意度。 对于商家来说,循环购可以让他们节省大量的营销成本和人力…...
分布式缓冲-Redis
个人名片: 博主:酒徒ᝰ. 个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来。 本篇励志:三人行,必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud…...
C# 流Stream详解(3)——FileStream源码
【FileStream】 构造函数 如果创建一个FileStream,常见的参数例如路径Path、操作方式FileMode、权限FileAccess。 这里说下FileShare和SafeFileHandle。 我们知道在读取文件时,通常会有两个诉求:一是如何更快的读取文件内容;二…...
C语言的文件操作(炒详解)
⭐回顾回顾文件操作的相关细节⭐ 欢迎大家指正错误 📝在之前的学习中,不管增加数据,减少数据,当程序退出时,所有的数据都会销毁,等下次运行程序时,又要重新输入相关数据,如果一直像这…...
27.基于ADS的不等分威尔金森功分器设计
27.基于ADS的不等分威尔金森功分器设计 等分的威尔金森功分器可以使用ADS非常快速的设计出来,但是不等分的功分器却没有便捷的设计方法,在此给出快速的设计方法与案例,方便大家实际设计。 等分版本的威尔金森功分器设计教程:12、…...
Linux自用命令
sudo su/sudo -i:获取root权限 cd:目录切换 cd / 切换到根目录 cd … 切换到上一级目录 cd ~ 切换到home目录 cd - 切换到上次访问的目录 ls:目录查看 ls 查看当前目录下的所有目录和文件 ls -a 查看当前目录下的所有目录和文件(…...
clickhouse union all之后数据量不一致
环境: clickhouse版本:22.8.16.32 问题:clickhouse使用union all查询结果与每一段sql查询结果只和不一致 原因:因为clickhouse版本问题,官方给出不同的解释 解决方案:将union all的每一段sql用括号括起来…...
力扣刷题19-删除链表的倒数第N个节点
题目来源 题目描述: class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {//为了删除的格式一样,引入虚拟头节点ListNode dummyNodenew ListNode(1);dummyNode.nexthead;ListNode slowdummyNode;ListNode fastdummyNode;for(int…...
Unity中的简单数据存储办法
这段代码演示了Unity中的简单数据存储办法 当涉及到不同类型的存储时,下面是一些示例代码来演示在Unity中如何使用不同的存储方法: 1. 临时存储示例代码(内存变量): csharp // 定义一个静态变量来存储临时计分 pub…...
Pytorch-MLP-CIFAR10
文章目录 model.pymain.py参数设置注意事项运行图 model.py import torch.nn as nn import torch.nn.functional as F import torch.nn.init as initclass MLP_cls(nn.Module):def __init__(self,in_dim3*32*32):super(MLP_cls,self).__init__()self.lin1 nn.Linear(in_dim,1…...
SQL2 查询多列
描述 题目:现在运营同学想要用户的设备id对应的性别、年龄和学校的数据,请你取出相应数据 示例:user_profile iddevice_idgenderageuniversityprovince12138male21北京大学Beijing23214male复旦大学Shanghai36543female20北京大学Beijing42…...
算法分享三个方面学习方法(做题经验,代码编写经验,比赛经验)
目录 0 . 前言:(遇到OI不要慌)(只要道路对了,就不怕遥远) 1. 做题经验谈 1.1 做题的目的 1.2 我对于算法比赛的题目的看法 1.2.1 类似题 1.2.2 套模型: 1.3 在训练过程中如何做题 1.4 一些建议&…...
爬虫 — 验证码反爬
目录 一、超级鹰二、图片验证模拟登录1、页面分析1.1、模拟用户正常登录流程1.2、识别图片里面的文字 2、代码实现 三、滑块模拟登录1、页面分析2、代码实现(通过对比像素获取缺口位置) 四、openCV1、简介2、代码3、案例 五、selenium 反爬六、百度智能云…...
视频图像处理算法opencv模块硬件设计图像颜色识别模块
1、Opencv简介 OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上 它轻量级而且高效——由一系列 C 函数和少量 C 类构成,同时提供了Python、Rub…...
目标检测网络之Fast-RCNN
文章目录 Fast RCNN解决的问题Fast RCNN网络结构RoI pooling layer合并损失函数及其传播统一的损失函数损失函数的反向传播过程Fast RCNN的训练方法样本选择方法SGD参数设置多尺度图像训练SVD压缩全连接层对比实验对比实验使用到的网络结构VOC2010和VOC2012数据集结果VOC2007数…...
Golang Gorm 创建HOOK
创建的时候,在插入数据之前,想要做一些事情。钩子函数比较简单,就是实现before create的一个方法。 package mainimport ("gorm.io/driver/mysql""gorm.io/gorm" )type Student struct {ID int64Name string gorm:&q…...
计算机视觉的应用15-图片旋转验证码的角度计算模型的应用,解决旋转图片矫正问题
大家好,我是微学AI,今天给大家介绍一下计算机视觉的应用15-图片旋转验证码的角度计算模型的应用,解决旋转图片矫正问题,在CV领域,图片旋转验证码的角度计算模型被广泛应用于解决旋转图片矫正问题,有效解决机…...
【Seata】分布式事务问题和理论基础
目录 1.分布式事务问题 1.1本地事务 1.2分布式事务 2.理论基础 2.1CAP定理 2.1.1一致性 2.1.2可用性 2.1.3分区容错 2.1.4矛盾 2.2BASE理论 2.3解决分布式事务的思路 1.分布式事务问题 1.1本地事务 本地事务,也就是传统的单机事务。在传统数据库事务中…...
文件打包解包的方法
在很多情况下,软件需要隐藏一些图片,防止用户对其更改,替换。例如腾讯QQ里面的资源图片,哪怕你用Everything去搜索也搜索不到,那是因为腾讯QQ对这些资源图片进行了打包,当软件运行的时候解包获取资源图片。…...
npm 清缓存(重新安装node-modules)
安装node依赖包的会出现失败的情况,如下图所示: 此时 提示有些依赖树有冲突,根据提示 “ this command with --force or --legacy-peer-deps” 执行命令即可。 具体步骤如下: 1、先删除本地node-modules包 2、删掉page-loacl…...
sqlserver查询表中所有字段信息
精简 SELECT 字段名 a.name,主键 case when exists(SELECT 1 FROM sysobjects where xtypePK and parent_obja.id and name in (SELECT name FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id a.id AND colida.colid))) then √ else …...
二叉树的概念、存储及遍历
一、二叉树的概念 1、二叉树的定义 二叉树( binary tree)是 n 个结点的有限集合,该集合或为空集(空二叉树),或由一个根结点与两棵互不相交的,称为根结点的左子树、右子树的二叉树构成。 二叉树的…...
【面试题】智力题
文章目录 腾讯1000瓶毒药里面只有1瓶是有毒的,问需要多少只老鼠才能在24小时后试出那瓶有毒。有两根不规则的绳子,两根绳子从头烧到尾均需要一个小时,现在有一个45分钟的比赛,裁判员忘记带计时器,你能否通过烧绳子的方…...
【SpringBoot集成Redis + Session持久化存储到Redis】
目录 SpringBoot集成Redis 1.添加 redis 依赖 2.配置 redis 3.手动操作 redis Session持久化存储到Redis 1.添加依赖 2.修改redis配置 3.存储和读取String类型的代码 4.存储和读取对象类型的代码 5.序列化细节 SpringBoot集成Redis 1.添加 redis 依赖 …...
day49:QT day2,信号与槽、对话框
一、完善登录框 点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容“账号密码不匹配,是否重新登录”,给定两个…...
Meta分析核心技术
Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…...
Gof23设计模式之责任链模式
1.概述 责任链模式又名职责链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止…...
数字孪生和元宇宙:打造未来的数字边界
数字孪生和元宇宙是近两年来被热议的两个概念,但由于技术的交叉两者也极易被混淆。本文希望带大家深入探讨一下这两者之间的关系,以及它们如何一起构建了数字时代的新格局。 1. 数字孪生的本质 数字孪生是一种虚拟模型,它通过数字手段对现实…...
网站上飘窗怎么做/淘宝网页版
其实很多人学习python是势头而来的,现在python这么火,感觉不学的话,是会非常吃亏,但是确实不知道从哪里下手,现在Python很火并且你也要学来找工作,未来Python很火,我具备了Python的技能会不错。…...
商丘网站设计/5118大数据平台官网
Log4j2 使用教程Log4j2 的好处就不在这里一一列举了,如果你搜了2,说明你对它一定有兴趣,并且想了解它,使用它。一、下载log4j2 ,基本上你只需要导入下面两个jar包即可: log4j-api-2.11.0.jarlog4j-cor…...
做网做网站建设/百度知道官网登录入口
文章目录1、面向过程(性能高、不易维护)2、面向对象(性能低、易维护)注:1、面向过程(性能高、不易维护) 是围绕功能进行的,为每一个功能写一个函数,需要考虑其中的每一个…...
海南建设工程股份有限公司网站/百度竞价优缺点
写在前面 本文学习内容来自《算法图解》一书及百度百科内容 算法是一组完成任务的指令。任何代码片段都可视为算法。 —— 摘自《算法图解》 选择排序 以下内容摘自百度百科 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从…...
网站建设方案书2000字/网络营销推广专家
友元函数 1、单方向 2、不具有传递性 3、不具有继承特性 1.外部函数友元 作为外部函数,本身不具有this指针,需要创建对象传参 外部函数后不能加const 主函数也可以定义成友元函数 实际上在调动主函数之前还调动了其他函数 从内核加载 Windows支持多线…...
外贸人常去的网站/长春做网站公司长春seo公司
现在是BigData大数据的时代,最近几年最火的是当然属于Hadoop平台了,但是Hadoop虽然说比较好用,但是他的延时性,比较差的实时计算能力被人们所诟病。所以一个比较强大的分布式实时计算平台应用而生,他的名字叫Storm。 要…...