Linux驱动【day2】

news2025/1/15 20:32:50

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_moder2;
unsigned int *vir_odr2;
unsigned int *vir_rcc2;

// 封装操作方法
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')//PE10开灯
    {
        //开灯逻辑
        (*vir_odr) |= (0X1<<10);
    }
    else if(kbuf[0]=='0')
    {
        //关灯逻辑
        (*vir_odr) &= (~(0X1<<10));
    }

    if(kbuf[1]=='1')//PF10开灯
    {
        //开灯逻辑
        (*vir_odr2) |= (0X1<<10);
    }
    else if(kbuf[0]=='0')
    {
        //关灯逻辑
        (*vir_odr2) &= (~(0X1<<10));
    }

    if(kbuf[2]=='1')//PE8开灯
    {
        //开灯逻辑
        (*vir_odr) |= (0X1<<8);
    }
    else if(kbuf[0]=='0')
    {
        //关灯逻辑
        (*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);
    //进行GPIE相关寄存器的内存映射
    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");

    //进行GPIOF相关寄存器的内存映射
    vir_odr2=ioremap(LED2_ODR,4);
    if(vir_odr2==NULL)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir_rcc2=ioremap(LED2_RCC,4);
    if(vir_rcc2==NULL)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    vir_moder2=ioremap(LED2_MODER,4);
    if(vir_moder2==NULL)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    printk("寄存器内存映射成功\n");

    //PE10硬件寄存器的初始化
    //RCC使能
    (*vir_rcc) |= (0X1<<4);
    //设置PE10为输出
    (*vir_moder) &= (~(0X3<<20));
    (*vir_moder) |= (0X1<<20);
    //默认关灯
    (*vir_odr) &= (~(0X1<<10));

    //PF10硬件寄存器的初始化
    //RCC使能
    (*vir_rcc2) |= (0X1<<5);
    //设置PF10为输出
    (*vir_moder2) &= (~(0X3<<20));
    (*vir_moder2) |= (0X1<<20);
    //默认关灯
    (*vir_odr2) &= (~(0X1<<10));

    //PE8硬件寄存器的初始化
    //设置PE10为输出
    (*vir_moder) &= (~(0X3<<16));
    (*vir_moder) |= (0X1<<16);
    //默认关灯
    (*vir_odr) &= (~(0X1<<8));
    
    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消物理内存映射
    iounmap(vir_moder);
    iounmap(vir_odr);
    iounmap(vir_rcc);

    //取消物理内存映射
    iounmap(vir_moder2);
    iounmap(vir_odr2);
    iounmap(vir_rcc2);

    // 字符设备驱动注销
    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)
    {
        printf("输入指令控制开/关灯(LED1|LED2|LED3)==>0(OFF)/1(ON)>");
        fgets(buf, sizeof(buf), stdin); // 在终端输入数据传递到buf
        buf[strlen(buf) - 1] = '\0';    // 替换末尾的'\n'
        write(fd, buf, sizeof(buf));
    }
    close(fd);
 
    return 0;
}

head.h:

#ifndef __HEAD_H__
#define __HEAD_H__

//PE10
#define LED1_RCC 0X50000A28
#define LED1_MODER 0X50006000
#define LED1_ODR  0X50006014

//PF10
#define LED2_RCC 0X50000A28
#define LED2_MODER 0X50007000
#define LED2_ODR 0X50007014

#endif

实验结果:
在这里插入图片描述

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

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

相关文章

Stable Diffusion WebUI内存不够爆CUDA Out of memory怎么办?

在我们运行SD的时候,我们经常会爆CUDA Out of memory。 我们应该怎么办呢? 这是因为我们的显存或者内存不够了。 如果你是用cpu来跑图的则表示内存不够,这个时候就需要换个大点的内存了。 如果你是用gpu来跑图的就说明你显存不够用咯,这时候咋办呢? 下面我将一一述说…

企业架构LNMP学习笔记39

MySQL读写分离案例实现&#xff1a; 搭建M-S复制 主从复制的原理&#xff1a;主服务器开启bin-log&#xff08;记录了写操作&#xff09;&#xff0c;从服务器获取到主服务器的bin-log&#xff0c;记录到relay-log中。从服务器在通过异步的线程方式&#xff0c;对于relay-log…

明星为何会偷税?我国的交税政策是?

近几年常常会看到某明星偷税漏税塌房的&#xff0c;从最开始的震惊&#xff0c;到后面的习以为常&#xff1a;很多明星都在偷税漏税啊。那么明星为什么会是偷税漏税的高发区&#xff1f; 交税标准 个人 根据我国的税务相关法律规定&#xff0c;个人收入每月超过5000&#xf…

微服务高可用容灾架构设计

导语 相对于过去单体或 SOA 架构&#xff0c;建设微服务架构所依赖的组件发生了改变&#xff0c;因此分析与设计高可用容灾架构方案的思路也随之改变&#xff0c;本文对微服务架构落地过程中的几种常见容灾高可用方案展开分析。 作者介绍 刘冠军 腾讯云中间件中心架构组负责…

windows本地验证码识别工具

windows本地验证码识别小工具 - 可以用在windows系统中&#xff0c;并可以集成在Java或python程序中 演示视频如下&#xff1a;可用于识别4-7位的字母数字组合的验证码&#xff08;识别准确率在70% - 80%&#xff09;。 验证码识别演示 本项目未开源&#xff0c;如需使用请联…

IntelliJ IDEA 远程调试 Tomcat

准备工作 明确远程服务器的 IP 地址&#xff0c;比如我是&#xff1a;192.168.92.128 关掉服务器防火墙&#xff1a;service iptables stop 本地 Remote Server 配置 添加 Remote Server&#xff0c;如下图 复制 Remote Server 自动生成的 JVM 参数&#xff0c;等下有用&…

透过优衣库秋冬新品巡展,看见服装消费新风尚

这是一个被高温笼罩的夏天&#xff0c;人们想法设法适应季节变换&#xff0c;在这种适应中&#xff0c;尽可能地保持着装之美。 一向走在穿衣风格一线的优衣库&#xff0c;并没有缺席市场更替中涌现的需求&#xff0c;其春夏系列从凉感防晒的功能性服装&#xff0c;到“辣妹T”…

腾讯云2023年云服务器优惠活动价格表

腾讯云经常推出各种云产品优惠活动&#xff0c;为了帮助大家更好地了解腾讯云服务器的价格和优惠政策&#xff0c;下面给大家分享腾讯云最新云服务器优惠活动价格表&#xff0c;助力大家轻松上云&#xff01; 一、轻量应用服务器优惠活动价格表 1、轻量应用服务器&#xff1a;…

稳定的 Glance 来了,安卓小部件有救了!

稳定的 Glance 来了&#xff0c;安卓小部件有救了&#xff01; 稳定版本的 Glance 终于发布了&#xff0c;来一起看看吧&#xff0c;看看这一路的旅程&#xff0c;看看好用么&#xff0c;再看看如何使用&#xff01; 前世今生 故事发生在两年的一天吧&#xff0c;其实夸张了…

数据结构算法刷题(29)动态规划

思路一&#xff1a;回溯&#xff1a;按照选和不选的判断方式&#xff0c;使用回溯来解决这个问题。 class Solution: def rob(self, nums: List[int]) -> int: n len(nums) #数组的长度 def dfs(i): if i<0: #到达边界条件后 return 0 #返回最大金额是0 res max(dfs(i…

医疗环境升级改造,从此温湿度监控不用慌!

在现代医疗环境中&#xff0c;为了确保患者的舒适和康复&#xff0c;温度和湿度的监控和管理变得至关重要。特别是在疗养院这样的医疗机构中&#xff0c;患者的健康与室内环境条件密切相关。温度和湿度的不适当波动可能导致不仅是不适&#xff0c;还可能加剧病情&#xff0c;影…

9月8日上课内容 第一章 rsync远程同步

主从复制总结 redis主从复制 是为了数据冗余和读写分离 在这两种模式中&#xff0c;有两种角色主节点 (master) 和从节点 (slave) &#xff0c;主节点负责处理写的操作&#xff0c;并将数据更改复制到一个或多个从节点。这样我们的主节点负载减轻&#xff0c;从节点可以提供数据…

UI设计新手指南之什么是UI设计?

最直观的&#xff0c;只要用手机&#xff0c;打开界面就会接触到 UI 设计。 UI 设计是什么&#xff1f;它是指对软件人机交互、操作逻辑、界面美观的整体设计。UI设计的目的是创造出简单、直观、易于使用的界面&#xff0c;为用户提供良好的体验。随着移动互联网的兴起&#x…

分享一下奶茶店怎么在小程序上做商城功能

随着移动互联网的普及&#xff0c;越来越多的消费者倾向于在手机上完成购物需求。对于奶茶店来说&#xff0c;在小程序上开设商城功能不仅可以扩大销售渠道&#xff0c;还能提高品牌知名度和用户体验。本文将探讨如何在小程序上为奶茶店实现商城功能。 对于奶茶店的商城功能&am…

Spring-MVC使用JSR303及拦截器,增强网络隐私安全

目录 一、JSR303 ( 1 ) 是什么 ( 2 ) 作用 ( 3 ) 常用注解 ( 4 ) 入门使用 二、拦截器 2.1 是什么 2.2 拦截器与过滤器的区别 2.3 应用场景 2.4 基础使用 2.5 用户登录权限控制 给我们带来的收获 一、JSR303 ( 1 ) 是什么 JSR 303是Java规范请求&#xff…

旅游复苏弹高OTA业绩,未来走势却有“U型曲线”与“抛物线”之变

文 | 螳螂观察 作者 | 易不二 经历了3年蛰伏&#xff0c;旅游业确实熬出头了&#xff0c;OTA也迎来了强势反弹。 自年初起就逐步恢复的旅游行业&#xff0c;经历了暑期小高潮后&#xff0c;正在逐步以强劲的复苏能力&#xff0c;为OTA们的期中财报增彩。 今年二季度&#x…

83 # 静态服务中间件 koa-static 的使用以及实现

静态服务中间件&#xff1a;koa-static 中间件可以决定是否向下执行&#xff0c;如果自己可以处理&#xff0c;那么直接处理完毕结束&#xff0c;如果自己处理不了&#xff0c;next 方法会继续向下执行 新建 public 文件夹&#xff0c;里面添加 index.html、style.css 文件 …

机器学习_个人笔记_周志华(更新中......)

第1章 绪论 1.1 引言 形成优秀的心理表征&#xff0c;自然能成为领域内的专家。 系统1 & 系统2。 机器学习&#xff1a;致力于研究如何通过计算的手段&#xff0c;利用经验来改善系统自身的性能。主要研究计算机从数据中产生model的算法&#xff0c;即“learning algori…

myCobot Pro600六轴机械臂与3D深度视觉:物体精确识别抓取堆叠

Introduction 随着时代的进步&#xff0c;各种精密的机械臂&#xff0c;人形机器人不断的问世。我们即将迎来到处都是机器人的高科技时代。为了跟上时代的脚步&#xff0c;我最近入手了一台myCobot pro 600机械臂&#xff0c;我主要是想要用它来学习机械臂相关得控制以及机器视…

【跟小嘉学 Apache Flink】二、Flink 快速上手

系列文章目录 【跟小嘉学 Apache Flink】一、Apache Flink 介绍 【跟小嘉学 Apache Flink】二、Flink 快速上手 文章目录 系列文章目录[TOC](文章目录) 一、创建工程1.1、创建 Maven 工程1.2、log4j 配置 二、批处理单词统计&#xff08;DataSet API&#xff09;2.1、创建 Bat…