驱动day2:LED灯实现三盏灯的亮灭

news2024/11/7 1:39:05

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#define PHY_PE_MODER 0x50006000
#define PHY_PF_MODER 0x50007000
#define PHY_PE_ODR 0x50006014
#define PHY_PF_ODR 0x50007014
#define PHY_RCC 0x50000A28


#endif

应用程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.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");
        return -1;
    }
    printf("打开设备文件成功\n");
    while(1)
    {
        printf("请输入要进行的操作:0(关灯) 1 (开灯)>");
        fgets(buf,sizeof(buf),stdin);   //在终端读一个字符串
        buf[strlen(buf) - 1] = '\0';
        write(fd,buf,sizeof(buf));//将数据传递给内核
    }
/*
    fgets(buf,sizeof(buf),stdin);   //在终端读一个字符串
    buf[strlen(buf) - 1] = '\0';

   write(fd,buf,sizeof(buf));//将数据传递给内核
   memset(buf, 0, sizeof(buf));   //清空数组
    read(fd,buf,sizeof(buf));    //将内核数据传递给用户
 
    printf("buf: %s\n", buf);
*/
    close(fd);
    return 0;
}

驱动程序

#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] = {};   //内核空间buf
//定义五个指针指向映射后的虚拟内存
unsigned int *vir_pe_moder;
unsigned int *vir_pf_moder;
unsigned int *vir_pe_odr;
unsigned int *vir_pf_odr;
unsigned int *vir_rcc;
//封装操作方法
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)
{
    //mycdev_read()函数中的ubuf和size分别是指向应用程序中read()函数中的buf, 和sizeof(buf)的值
    printk("%s:%s:%d\n", __FILE__,__func__,__LINE__);
    int ret;
    ret = copy_to_user(ubuf, kbuf, size);
    if(ret)
    {
        printk("copy_to_user filed\n");
        return -EIO;
    }
    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__);
    int ret;
    ret = copy_from_user(kbuf, ubuf, size);
    if(ret)
    {
        printk("copy_from_user failed\n");
        return -EIO;
    }
    if(kbuf[0] == '0')//关灯
    {   
        //关灯逻辑
        (*vir_pe_odr) &= (~(0x1 << 10));     //默认关灯
        (*vir_pf_odr) &= (~(0x1 << 10));
        (*vir_pe_odr) &= (~(0x1 << 8));

    }
    else if(kbuf[0] == '1')
    {
        //开灯逻辑
        (*vir_pe_odr) |= (0x1 << 10); 
        (*vir_pf_odr) |= (0x1 << 10); 
        (*vir_pe_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,"mycdev",&fops);
    if(major < 0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("注册字符设备成功major=%d\n",major);

    //进行寄存器的地址映射
    vir_pe_moder = ioremap(PHY_PE_MODER, 4);
    if(vir_pe_moder == NULL)
    {
        printk("物理地址内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir_pf_moder = ioremap(PHY_PF_MODER,4);
    if(vir_pf_moder == NULL)
    {
        printk("物理地址内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir_pe_odr = ioremap(PHY_PE_ODR, 4);
    if(vir_pe_odr == NULL)
    {
        printk("物理地址内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir_pf_odr = ioremap(PHY_PF_ODR, 4);
    if(vir_pf_odr == NULL)
    {
        printk("物理地址内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir_rcc = ioremap(PHY_RCC, 4);
    if(vir_rcc == NULL)
    {
        printk("物理地址内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    printk("寄存器内存映射成功\n");

    //LED寄存器初始化
    (*vir_rcc) |= (0x3 << 4);   //GPIOE和GPIOF控制器时钟使能
    //PE10
    (*vir_pe_moder) &= (~(0x3 << 20));   //MODER[21:20]->00
    (*vir_pe_moder) |= (0x1 << 20);  //MODER[21"20]->01
    (*vir_pe_odr) &= (~(0x1 << 10));   //默认关灯
    //PF10
    (*vir_pf_moder) &= (~(0x3 << 20));
    (*vir_pf_moder) |= (0x1 << 20);
    (*vir_pf_odr) &= (~(0x1 << 10));   //默认关灯
    //PE8
     (*vir_pe_moder) &= (~(0x3 << 16));
    (*vir_pe_moder) |= (0x1 << 16); 
    (*vir_pe_odr) &= (~(0x1 << 8));   //默认关灯
    return 0;
}

static void __exit mycdev_exit(void)
{
    //取消内存映射
    iounmap(vir_pe_moder);
    iounmap(vir_pf_moder);
    iounmap(vir_pe_odr);
    iounmap(vir_pf_odr);
    iounmap(vir_rcc);
    //注销字符设备驱动
    unregister_chrdev(major,"mychrdev");
}

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

实现效果

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

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

相关文章

【C语言必知必会 | 第二篇】编译器的安装与使用

引言 C语言是一门面向过程的、抽象化的通用程序设计语言&#xff0c;广泛应用于底层开发。它在编程语言中具有举足轻重的地位。 此文为【C语言必知必会】系列第二篇&#xff0c;介绍C语言编译器的安装与使用&#xff0c;为之后的学习安装环境基础 文章目录 1️⃣ Dev-C的安装与…

【2024秋招】用友项目管理部门java后端二面2023.9.12

1 rpc框架 1.1 深入讲讲你做的这个rpc框架 答&#xff1a; 1.2 你这个注册中心有实现相关的监控吗 1.2.1 如何实现注册中心有实现相关的监控 是的&#xff0c;我可以为你提供关于RPC注册中心及其监控的相关信息。RPC注册中心是用于管理微服务之间调用关系的中心化服务&…

数学建模入门

一 数学建模简介 数学建模创办于1992年&#xff0c;每年一届&#xff0c;是首批列入“高校学科竞赛排行榜”的19项竞赛之一。2022年&#xff0c;来自全国及英国、马来西亚的1606所院校/校区、54257队(本科49424队、专科4833队)、超过16万人报名参赛。是目前奖项最具有含金量的…

基于材料生成优化的BP神经网络(分类应用) - 附代码

基于材料生成优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于材料生成优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.材料生成优化BP神经网络3.1 BP神经网络参数设置3.2 材料生成算法应用 4.测试结果…

Spring Boot + EasyUI 创建第一个项目(一)

创建一个Spring Boot和EasyUI相结合的项目。 一、构建一个Spring Boot项目 Spring Boot之创建一个Spring Boot项目&#xff08;一&#xff09;-CSDN博客 二、配置Thymeleaf Spring Boot Thymeleaf&#xff08;十一&#xff09;_thymeleaf 设置字体_人……杰的博客-CSDN博客…

轴承寿命相关细节的研究

数据集PHM2012 介绍一下IEEE PHM2012数据集_phm2012轴承数据集-CSDN博客 标签如何设置的? 剩余寿命预测的标签设置_rul 标签_兔子牙丫丫的博客-CSDN博客 参考自刘硕师兄的毕业答辩PPT 图 4.9 训练数据的切分方法 数据段的重叠切分&#xff0c;不仅可以覆盖更多的标签数据…

分布式锁之环境准备

文章目录 分布式锁1. 传统锁回顾1.1. 从减库存聊起1.2. 环境准备 分布式锁 在应用开发中&#xff0c;特别是web工程开发&#xff0c;通常都是并发编程&#xff0c;不是多进程就是多线程。这种场景下极易出现线程并发性安全问题&#xff0c;此时不得不使用锁来解决问题。在多线…

YZ系列工具:YZ11:VBA_窗体缩放

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套一部VBA手册&#xff0c;教程分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的…

京东敏捷实践指南

ISBN: 978-7-121-38257-4 编著&#xff1a;赵卫、王立杰 页数&#xff1a;211页 阅读时间&#xff1a;2023-09-02 推荐指数&#xff1a;★★★★★ 本文主要讲解的是敏捷开发&#xff0c;介绍了敏捷转型的必要性和收益。 介绍的方法有&#xff1a;Scrum、Kanban&#xff08;看板…

Android自行车在线租借租赁系统+全套手把手视频教程

【项目功能介绍】 功能列表: 本系统包含后台管理和前端app双端系统, 本系统包含三个角色: 管理员,员工,app用户。 后台管理员的功能包含: 登录, 退出, 自新车管理,添加自新车,修改自新车,禁用启用自新车; 自新车车辆管理,添加自新车车辆,修改自新车车辆,启用禁用自新车车辆; …

JVM——JVM概述以及双亲委派机制

JVM探究 请你谈谈你对JVM的理解&#xff1f;Java8虚拟机和之前的有什么变化更新&#xff1f;什么是OOM&#xff0c;什么是栈溢出StackOverFlowError&#xff1f;怎么分析&#xff1f;JVM的常用调优参数有哪些&#xff1f;内存快照如何抓取&#xff1f;怎么分析Dump文件&#x…

STM32F40X之时钟树

一、时钟树概述 目前用到的STM32的许多片上外设都需要先打开相应的时钟&#xff0c;告诉当前这个器件是以什么频率在运行&#xff0c;而每个片上外设的时钟频率其实在出厂时已经固化。 二、时钟树框架 25M / 25 * 336 / 2 168M 系统时钟计算公式&#xff1a;SYSCLKPLLCLK H…

从入门到进阶 之 ElasticSearch 配置优化篇

&#x1f339; 以上分享从入门到进阶 之 ElasticSearch 配置优化篇&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏…

【JavaEE】_Servlet API

目录 1. HttpServlet 1.1 init方法 1.2 destroy方法 1.3 service方法 1.4 Servlet的生命周期 1.5 代码示例 1.5.1 使用postman构造请求 1.5.2 使用ajax构造请求 2. HttpServletRequest 2.1 核心方法 2.2 代码示例1&#xff1a;打印请求信息 3. 前端给后端传参 3.1…

新手如何用Airtest实现在图片范围内随机点击?

1. 前言 前几天有个新手同学在Airtest官群里问了这样一个问题&#xff1a; 我是新手&#xff0c;在图片范围内随机点击 &#xff0c;用Airtest怎么实现&#xff1f;代码&#xff1f; 那我们就以这个问题为例&#xff0c;浅浅聊一下&#xff0c;怎么把需求转化成我们的Airtest代…

Linux——shell外壳程序

shell外壳程序 1. 什么是shell外壳程序 Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心 “ &#xff0c;但我们一般用户&#xff0c;不能直接使用核心。 而是通过核心的“外壳”程序&#xff0c;也就是所谓的shell。 shell是所有外壳程序的统称 平时程序员…

毅速3D打印丨哪些产品最适合应用3D打印随形水路模具

3D打印技术随形水路模具无论是从生产效率、生产成本&#xff0c;还是从产品质量出发考虑&#xff0c;在各个领域有着重要的应用&#xff0c;毅速3D打印根据统计了目前应用比较多的产品领域主要有以下几类&#xff1a; 1、医疗美妆类产品。如化妆品包装瓶、脸部按摩仪等透明产品…

行情分析——加密货币市场大盘走势(10.20)

大饼昨日迅猛上涨&#xff0c;并在今日依然上涨&#xff0c;目前处在蓝色上涨趋势线&#xff0c;上涨趋势依然在。中长线可以考虑过几天止损或者继续持有。目前MACD日线呈现绿色实心5天&#xff0c;预计明后天可能会绿色空心&#xff0c;注意后续空头的到来&#xff0c;注意多单…

UART通信——笔记

UART通信特点 异步、全双工、串行。 只使用一对线就可以实现数据的通信&#xff0c;节约成本。 数据一位一位发送&#xff0c;数据传输较慢。 只能一对一通信。 如何实现通信的&#xff1f; UART&#xff1a; 发送数据的TX接受数据的RX参考GND UART是异步通信&#xff0c;…

SpringCloud 微服务全栈体系(一)

第一章 认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 一、单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff…