底层驱动day2作业

news2024/11/7 12:45:41

控制三盏灯亮灭

代码:

//head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#define PHY_RCC 0x50000A28
#define PHY_GPIOE_MODER 0x50006000
#define PHY_GPIOF_MODER 0x50007000
#define PHY_GPIOE_ODR 0x50006014
#define PHY_GPIOF_ODR 0x50007014


#endif
//demo.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include"include/head.h"
char kbuf[128] = {0};
int a = 10;
unsigned int major;

unsigned int *vir_led1_odr;
unsigned int *vir_led1_moder;
unsigned int *vir_rcc;
unsigned int *vir_led2_odr;
unsigned int *vir_led2_moder;

int mycdev_open(struct inode *inode,struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    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 = copy_from_user(kbuf,ubuf,size);
    if(ret)
    {
        printk("failed\n");
        return -EIO;
    }
    switch(kbuf[0])     //kbuf的第0位为led灯,第2位为led灯的状态
    {
        case '1':
            if(kbuf[2] == '0')
            {
                //关灯
                (*vir_led1_odr) &= (~(0x1 << 10));
            }
            else if(kbuf[2] == '1')
            {
                //开灯
                (*vir_led1_odr) |= (0x1 << 10);
            }
            break;
        case '2':
            if(kbuf[2] == '0')
            {
                //关灯
                (*vir_led2_odr) &= (~(0x1 << 10));
            }
            else if(kbuf[2] == '1')
            {
                //开灯
                (*vir_led2_odr) |= (0x1 << 10);
            }
            break;
        case '3':
            if(kbuf[2] == '0')
            {
                //关灯
                (*vir_led1_odr) &= (~(0x1 << 8));
            }
            else if(kbuf[2] == '1')
            {
                //开灯
                (*vir_led1_odr) |= (0x1 << 8);
            }
            break;
        default:
            break;
    }
    
    
    
    return 0;
}

ssize_t mycdev_read(struct file *file,char *ubuf,size_t size,loff_t *lof)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    int ret = copy_to_user(ubuf,kbuf,size);
    if(ret)
    {
        printk("failed\n");
        return -EIO;
    }
    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,
};

module_param(a,int,0664);
static int __init mycdev_init(void)
{
    printk("a = %d\n",a);
    major = register_chrdev(0,"mychrdev",&fops);
    if(major < 0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功 major = %d\n",major);
    vir_led1_moder = ioremap(PHY_GPIOE_MODER,4); 
    if(NULL == vir_led1_moder)
    {
        printk("物理内存地址映射失败\n");
        return -EFAULT;
    } 
    vir_led1_odr = ioremap(PHY_GPIOE_ODR,4);
    if(NULL == vir_led1_odr)
    {
        printk("物理内存地址映射失败\n");
        return -EFAULT;
    } 

    vir_rcc = ioremap(PHY_RCC,4);
    if(NULL == vir_rcc)
    {
        printk("物理内存地址映射失败\n");
        return -EFAULT;
    }

    vir_led2_moder = ioremap(PHY_GPIOF_MODER,4); 
    if(NULL == vir_led2_moder)
    {
        printk("物理内存地址映射失败\n");
        return -EFAULT;
    } 

    vir_led2_odr = ioremap(PHY_GPIOF_ODR,4);
    if(NULL == vir_led2_odr)
    {
        printk("物理内存地址映射失败\n");
        return -EFAULT;
    } 
    printk("寄存器内存映射成功\n");
    (*vir_rcc) |= (0x1 << 4);
    (*vir_rcc) |= (0x1 << 5);
    (*vir_led1_moder) &= (~(0x3 << 20));    //led1_moder
    (*vir_led1_moder) |= (0x1 << 20);
    (*vir_led1_moder) &= (~(0x3 << 16));    //led3_moder
    (*vir_led1_moder) |= (0x1 << 16);
    (*vir_led1_odr) &= (~(0x1 << 10));      //led1_odr
    (*vir_led1_odr) &= (~(0x1 << 8));      //led3_odr
    (*vir_led2_moder) &= (~(0x3 << 20));    //led2_moder
    (*vir_led2_moder) |= (0x1 << 20);
    (*vir_led2_odr) &= (~(0X1 << 10));      //led2_odr


    return 0;
}

static void __exit mycdev_exit(void)
{
    unregister_chrdev(major,"mychrdev");

}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
//test.c
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.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)
    {
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf) - 1] = 0;
        write(fd,buf,sizeof(buf));
    }
    
    //read(fd,buf,sizeof(buf));
    
    memset(buf,0,sizeof(buf));
    read(fd,buf,sizeof(buf));
    printf("buf:%s\n",buf);
    close(fd);
    return 0;
}

 

实验现象:

 

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

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

相关文章

JAVA毕业设计100—基于Java+Springboot+Vue的WMS仓库管理系统+移动端微信小程序(源码+数据库+部署视频)

基于JavaSpringbootVue的WMS仓库管理系统移动端(源码数据库部署视频) 一、系统介绍 本系统前后端分离带小程序 本系统分为管理员、用户角色(角色权限可自行分配) 功能列表&#xff1a; 1、 数据管理&#xff1a;物料数据管理、物料Bom管理、物料组管理、物料分类管理、供应…

口袋参谋:如何提升宝贝的点击率?这两种方法超简单!

​如何提升宝贝的点击率&#xff1f;这是99.99%商家都在疑惑的问题。今天我说的两种方法&#xff0c;超简单&#xff0c;一起来看看吧&#xff01; 1、找精准关键词 首先一定要选择适合自己店铺的关键词&#xff0c;一定要精准。 找关键词的方法如下&#xff1a; a.卖家可以…

Coreldraw2020最新64位电脑完整版本下载教程

安装之前所有的杀毒软件都要退出。无论是360&#xff0c;腾讯管家&#xff0c;或者电脑自带的安全中心&#xff0c;要不然会阻止安装。 CorelDRAW2020版win下载如下:https://wm.makeding.com/iclk/?zoneid55678 CorelDRAW2020版mac下载如下:https://wm.makeding.com/iclk/?…

2023年全球及中国溶瘤病毒治疗药物行业现状及发展趋势分析[图]

溶瘤病毒治疗肿瘤具有杀伤效率高、靶向性好、安全性高、不良反应小等特点&#xff0c;溶瘤病毒疗法已经成为肿瘤治疗研究领域的新热点。溶瘤病毒疗法经历了早期对于天然病毒的摸索&#xff0c;后期基因工程技术的进步提升OV靶向性及免疫致敏能力&#xff0c;推动其快速发展。 …

性能测试 —— 数据准备与基准场景设计!

基础性能脚本 延迟时间网络时间服务处理时间 主要使用监听器&#xff0c;通过两者的差值&#xff0c;判断响应时间消耗&#xff1a; jpgc - Connect Times Over Timejpgc - Response Times Over Time 调试脚本阶段&#xff0c;可以使用查看结果树等监听器来观察运行结果 正…

经典网络模型

Alexnet VGG VGG的启示 VGGNet采用了多次堆叠3x3的卷积核&#xff0c;这样做的目的是减少参数的数量。 例如&#xff0c;2个3x3的卷积核效果相当于1个5x5的卷积核效果&#xff0c;因为它们的感受野&#xff08;输入图像上映射区域的大小&#xff09;相同。但2个3x3卷积核的参数…

使用SpringCloudalibaba+Vue开发仿社交小程序全套视频课程

使用SpringCloudalibabaVue开发仿社交小程序全套视频课程 学习此课程你将会学到&#xff1a; 1. 熟练掌握小程序开发与部署2. 学会前后端分离开发与联调3. 从0到1学会微服务架构与落地4. 掌握主流中间件的封装与设计5. 掌握复杂数据库分库分表6. 收获一个商业级的面试作品 适…

MyBatisPlus实现连表操作、批量处理

1、实现连表查询 正常来说单靠mybatisplus无法实现连表查询&#xff0c;只能靠单表sql然后进行拼接形成连表查询&#xff0c;或者使用xml文件去编写sql语句来实现连表查询。但他又给我们提供了一个插件MyBatis-Plus-Join&#xff0c;用来弥补mybatisplus再连表上的不足&#…

中间件安全-CVE复现IISApacheTomcatNginx漏洞复现

目录 中间件安全&CVE复现&IIS&Apache&Tomcat&Nginx漏洞复现中间件-IIS安全问题中间件-Nginx安全问题漏洞复现Nginx 解析漏洞复现Nginx 文件名逻辑漏洞 中间件-Apache-RCE&目录遍历&文件解析等安全问题漏洞复现漏洞复现CVE_2021_42013 RCE代码执行&…

LeetCode-496 下一个更大元素

一、前言 今天想要分享的题目其实和之前写的股票价格那道题所用到的结构是一样的&#xff0c;就是单调栈&#xff0c;因为自己当时也对这种结构不太熟悉&#xff0c;看到评论区很多大佬说如果遇到要找下一个最大/最小这一类的题目&#xff0c;可以往单调栈这一块儿去想&#x…

CAD Exchanger SDK 3.22.0 Crack

Docker 映像、Autodesk Inventor 2022 支持以及从 CAD Exchanger 3.22.0 中的 CATIA 导入属性 使用 Docker 映像将您的软件运送到任何地方&#xff0c;独立于 Autodesk 软件读取 .ipt、.iam 文件&#xff0c;从 CATIA 探索机械、产品和自定义属性。 软件开发工具包产品更新发明…

暄桐四阶课程「自在行草」学习装备指南

在2011年&#xff0c;暄桐成立的最初&#xff0c;课程便是面向零基础的成年人设计的。在十余年的教学实践中&#xff0c;暄桐教室为同学们提供了一种系统、有趣、扎实&#xff0c;并可持续进阶的学习可能。许多同学都是在来到暄桐以后&#xff0c;才第一次拿起毛笔&#xff0c;…

138.【JUC并发编程- 03】

JUC并发编程- 03 (六)、共享模型之无锁1.问题提出(1).为什么不安全?(2).安全实现_使用锁(3).安全实现_使用CAS 2.CAS与volatile(1).CAS_原理介绍(2).CAS_Debug分析(3).volatile(4).为什么无锁效率高(5).CAS的特点 3.原子整形(1).原子整数类型_ 自增自减(2).原子整数类型_乘除模…

【建立单链表:头插法,尾插法;循环列表,带尾指针的循环链表合并(将Tb合并在Ta之后)】

文章目录 一、单链表的基本操作的实现1.建立单链表&#xff1a;头插法----元素插入在链表头部&#xff0c;也叫头插法。2.建立单链表&#xff1a;尾插法----元素插入在链表尾部&#xff0c;也叫尾插法。 二、线性表的链式表示和实现1.循环列表2.带尾指针的循环链表合并&#xf…

用自定义的QSortFilterProxyModel实现条件过滤,使qtableview中只显示满足条件的行信息

在实际开发中&#xff0c;qtableview是qt客户端页面中最常用的控件之一。运用qtableview的同时&#xff0c;也会存在着先对初始数据进行过滤&#xff0c;然后在qtableview上展示的只有满足条件的那些信息。或者在不同的条件下要展示出不同的满足条件的行信息。 第一种方法&…

电脑删除的视频怎么恢复?可尝试着3钟恢复办法!

无论是为了工作还是生活&#xff0c;我们都有可能在电脑上保存重要的视频&#xff0c;如宣传视频、回忆录视频等。这些视频通常包含了制作者的心血&#xff0c;要是被我们误删除了&#xff0c;很难重新拍摄&#xff0c;那么电脑删除的视频怎么恢复&#xff1f; 能。通常&#…

用 GPU 加速 PQC 方案:Montgomery、SHA3

参考文献&#xff1a; [DK91] Duss S R, Kaliski B S. A cryptographic library for the Motorola DSP56000[C]//Advances in Cryptology—EUROCRYPT’90: Workshop on the Theory and Application of Cryptographic Techniques Aarhus, Denmark, May 21–24, 1990 Proceeding…

Tensorboard安装及简单使用

Tensorboard 1. tensorboard 简单介绍2. 安装必备环境3. Tensorboard安装4. 可视化命令 1. tensorboard 简单介绍 TensorBoard是一个可视化的模块&#xff0c;该模块功能强大&#xff0c;可用于深度学习网络模型训练查看模型结构和训练效果&#xff08;预测结果、网络模型结构…

带头的循环双向链表的简单介绍

目录 带头的循环双向链表&#xff1a; 1、带头&#xff1a; 2、循环&#xff1a; 3、双向&#xff1a; 图例&#xff1a; 带头的双向循环链表的创建&#xff1a; 头文件部分&#xff1a; 主函数部分&#xff1a; 最终调试效果&#xff1a; 使用一级指针传参的原因&am…

异常数据检测 | Python奇异谱分析(SSA)数据缺失值插补

文章目录 文章概述模型描述源码分享参考资料文章概述 长时序栅格数据经常会出现一些缺失值,会对后续的分析造成很大的不便。这便需要利用一些插值算法对这些缺失数据进行填补,奇异谱分析(SSA)便是常用的一种插值方法。 模型描述 在时间序列分析中,「奇异谱分析」(「SS…