控制三盏灯

news2024/11/17 23:37:22

驱动代码

#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 *vir1_moder;
unsigned int *vir1_odr;
unsigned int *vir1_rcc;
unsigned int *vir2_moder;
unsigned int *vir2_odr;
unsigned int *vir2_rcc;
unsigned int *vir3_moder;
unsigned int *vir3_odr;
unsigned int *vir3_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)
{
    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 = 0;
    ret = copy_from_user(kbuf,ubuf,size);
    if (ret)
    {
        printk("copy_from_user err\n");
        return -EIO;
    }
    switch(kbuf[0])
    {
    case '1':
        (*vir1_odr) |= (0x1 << 10);
        break;
    case '2':   
        (*vir1_odr) &= (~(0x1 << 10));
        break;
    case '3':
        (*vir2_odr) |= (0x1 << 10);
        break;
    case '4':   
        (*vir2_odr) &= (~(0x1 << 10));
        break;
    case '5':
        (*vir3_odr) |= (0x1 << 8);
        break;
    case '6':   
        (*vir3_odr) &= (~(0x1 << 8));
        break;
        default:
        printk("输入错误\n");
        break;
     }
    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");
    }
    printk("字符设备驱动注册成功 major = %d\n",major);
    //相关寄存器内存映射
    vir1_odr = ioremap(LED1_ODR,4);
    if (vir1_odr == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir1_rcc = ioremap(LED1_RCC,4);
    if (vir1_rcc == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir1_moder = ioremap(LED1_MODER,4);
    if (vir1_moder == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
     vir2_odr = ioremap(LED2_ODR,4);
    if (vir2_odr == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir2_rcc = ioremap(LED2_RCC,4);
    if (vir2_rcc == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir2_moder = ioremap(LED2_MODER,4);
    if (vir2_moder == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
     vir3_odr = ioremap(LED3_ODR,4);
    if (vir3_odr == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir3_rcc = ioremap(LED3_RCC,4);
    if (vir3_rcc == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir3_moder = ioremap(LED3_MODER,4);
    if (vir3_moder == NULL)  
    {   
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    printk("寄存器内存映射成功\n");
    //硬件寄存器的初始化
    //RCC使能
    (*vir1_rcc) |= (0x1 << 4);
    //设置PE10为输出
    (*vir1_moder) &= (~(0x3 << 20));
    (*vir1_moder) |= (0x1 << 20);
    //默认关灯
    (*vir1_odr) &= (~(0x1 << 10));
     //RCC使能
    (*vir2_rcc) |= (0x1 << 5);
    //设置PE10为输出
    (*vir2_moder) &= (~(0x3 << 20));
    (*vir2_moder) |= (0x1 << 20);
    //默认关灯
    (*vir1_odr) &= (~(0x1 << 10));
     //RCC使能
    (*vir1_rcc) |= (0x1 << 4);
    //设置PE10为输出
    (*vir1_moder) &= (~(0x3 << 16));
    (*vir1_moder) |= (0x1 << 16);
    //默认关灯
    (*vir1_odr) &= (~(0x1 << 8));
    
    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消物理内存映射
    iounmap(vir1_moder);
    iounmap(vir1_rcc);
    iounmap(vir1_odr);
    iounmap(vir2_moder);
    iounmap(vir2_rcc);
    iounmap(vir2_odr);
    iounmap(vir3_moder);
    iounmap(vir3_rcc);
    iounmap(vir3_odr);
    //字符设备驱动注销
    unregister_chrdev(major,"mychrdev");

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

应用层代码

#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,const char * argv[])
{
    char buf[128] = {0};
    int fd = open("/dev/mychrdev",O_RDWR);
    if(fd < 0)
    {
        printf("设备文件打开失败\n");
        exit(-1);
    }  
    while(1)
    {
        printf("请输入对LED的控制命令1(LED1开灯)2(LED1关灯)3(LED2开灯)4(LED2关灯)5(LED3开灯)6(LED3关灯)>");
        fgets(buf,sizeof(buf),stdin);//在终端输入数据到buf
        buf[strlen(buf)-1] = '\0';
        write(fd,buf,sizeof(buf));
        memset(buf,0,sizeof(buf));
    }
    close(fd);
    return 0;
}

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

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

相关文章

C# Emgu.CV+Tesseract实现识别图像验证码

效果图&#xff0c;简单的还行&#xff0c;复杂的。。。拉跨 懒得写讲解了&#xff0c;全部源码直接上吧 /// <summary>/// 验证码识别/// </summary>public partial class FrmCodeIdentify : FrmBase{private string _filePath;// 原图像Image<Bgr, byte> …

基于Python开发的DIY字符画程序(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的DIY字符画程序&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&…

Kafka3.0.0版本——消费者(消费者组初始化流程图解)

一、消费者组初始化流程图解 每个consumer都发送JoinGroup请求&#xff0c;如下图所示&#xff1a; 选出一个consumer作为leader&#xff0c;如下图所示&#xff1a; 把要消费的topic情况发送给leader 消费者&#xff0c;如下图所示&#xff1a; leader会负责制定消费方案…

MFC:自绘CListBox,GetText返回一个乱码

问题描述 自绘CListBox&#xff0c;GetText返回一个乱码&#xff0c;并且还会伴随以下断言 解决方案 ListBox Control 属性【Has Strings】改为True即可

【线程池处理任务】Runnable任务和Callable任务

线程池处理任务 ExecutorService的常用方法 方法名称说明void execute(Runnable command)执行 Runnable 任务Future< T > submit(Callable< T > task)执行 Callable 任务&#xff0c;返回未来任务对象&#xff0c;用于获取线程返回的结果void shutdown()等全部任…

前端,关于一个骚气的页面阅读定位图(菜单)

之前在网上看到一个特别骚气的页面阅读定位菜单&#xff0c;今天给大家分享一下原理&#xff0c;先看效果图&#xff1a; 这是我之前浏览联想官网上看到的一个效果图&#xff0c;觉得相当骚气。然后我把他的背景图扣下来&#xff0c;也做了一个&#xff0c;看看效果。 他的实现…

接口自动化测试总结

一、什么项目适合做自动化测试&#xff1f; 软件需求变动不频繁 测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁&#xff0c;测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本&#xff0c;而脚本的维护本身就是一个代码开发的过程&#x…

【SpringCloudAlibaba】Seata分布式事务使用

文章目录 分布式事务问题示例Seata概述、官网一个典型的分布式事务过程处理过程全局GlobalTransactional分布式交易解决方案流程图 Seata安装下载修改conf目录下的application.yml配置文件dashboard demo 分布式事务问题示例 单体应用被拆分成微服务应用&#xff0c;原来的三个…

详解Transformer中的Encoder

一.Transformer架构 左半边是Encoder&#xff0c;右半边是Decoder。 二.Vision Transformer Vision Transformer取了Transformer的左半边。包含 Input EmbeddingPositional Encoding多头注意力机制 Add & Norm(前馈网络)Feed Forward Add & Norm 2.1 Input Embe…

C51智能小车(循迹、跟随、避障、测速、蓝牙、wifie、4g、语音识别)总结

目录 1.电机模块开发 1.1 让小车动起来 1.2 串口控制小车方向 1.3 如何进行小车PWM调速 1.4 PWM方式实现小车转向 2.循迹小车 2.1 循迹模块使用 2.2 循迹小车原理 2.3 循迹小车核心代码 3.跟随/避障小车 3.1 红外壁障模块分析​编辑 3.2 跟随小车的原理 3.3 跟随小…

世界级黑客丨电脑犯罪界的汉尼拔

被美国FBI称为电脑界的汉尼拔的人&#xff0c;有什么样的故事&#xff1f; 这个人就是世界级黑客凯文李波尔森&#xff0c;他在早期是正儿八经的黑客&#xff0c;他在17岁的时候就使用TRS-80电脑攻入美国国防部的高等研究计划署网络&#xff0c;但是当时他进去啥也没干&#x…

lambda nodejs 函数降低冷启动时间的最佳实践

lambda nodejs 函数降低冷启动时间的最佳实践 lambda nodejs 函数降低冷启动时间的最佳实践 前言什么是冷启动时间打包服务端 js什么是 inline进一步封装的打包工具存在的弊端以及解决方案Next Chapter完整示例及文章仓库地址 前言 本文章的思路&#xff0c;继承发展自这两篇…

vite vue项目 运行时 \esbuild\esbuild.exe 缺失 错误码 errno: -4058, code: ‘ENOENT‘,

vite vue项目运行 npm run dev 报错某个模块启动文件丢失信息 D:\PengYe_code\2\vite-vue3-admin>npm run dev> vite-vue3-admin1.0.2 dev > vitenode:events:504throw er; // Unhandled error event^Error: spawn D:\PengYe_code\2\vite-vue3-admin\node_modules\vi…

jupyter 添加中文选项

文章目录 jupyter 添加中文选项1. 下载中文包2. 选择中文重新加载一下&#xff0c;页面就变成中文了 jupyter 添加中文选项 1. 下载中文包 pip install jupyterlab-language-pack-zh-CN2. 选择中文 重新加载一下&#xff0c;页面就变成中文了 这才是设置中文的正解&#xff…

出现Browse information of one xxxx解决方法

不良现象如下&#xff1a; Browse information of one or more files is not available: Doing a project rebuild might fix this. 解决的方法&#xff1a;将C文件里面的内容全部注释掉&#xff0c;再编译正常。 然后再将注释掉的代码打开&#xff0c;再次编译就正常了。

【笔试强训选择题】Day35.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01; 文章目录 前言 一、Da…

什么是互联网打工人都需要知道的API?

我们生活在一个科技主导的世界。在这里&#xff0c;数据无处不在。作为许多不同产品的用户&#xff0c;我们所追寻的不再是某一个能将工作完成的最佳产品&#xff0c;而是一个不仅能有效完成工作&#xff0c;同时也与我们所使用的其他工具完美兼容的产品。因此&#xff0c;了解…

08-JVM垃圾收集器详解

上一篇&#xff1a;07-垃圾收集算法详解 如果说收集算法是内存回收的方法论&#xff0c;那么垃圾收集器就是内存回收的具体实现。 虽然我们对各个收集器进行比较&#xff0c;但并非为了挑选出一个最好的收集器。因为直到现在为止还没有最好的垃圾收集器出现&#xff0c;更加没…

Web安全研究(四)

No Honor Among Thieves: A Large-Scale Analysis of Malicious Web Shells Stony Brook University Ruhr-University Bochum 数据集地址&#xff1a;https://github.com/HACHp1/CWSOGG_dataset Web shell作为恶意脚本&#xff0c;攻击者将其上传到被攻陷的Web服务器&#xff…

iTunes备份文件在哪?苹果手机怎么恢复iTunes备份?

iTunes是苹果手机的一个常见应用&#xff0c;很多小伙伴都使用它来备份手机上的重要数据。通过iTunes备份数据到电脑后还可以进行随时管理和查看。itunes备份文件在哪&#xff1f;手机数据丢失怎么恢复iTunes备份&#xff1f;接下来&#xff0c;本文将给大家介绍一下&#xff0…