驱动开发--day2(内核不同模块的相互访问、字符设备驱动、led控制实验代码及现象)

news2024/9/20 10:43:45

实现三盏灯的控制,编写应用程序测试
head.h

#ifndef __HEAD_H__
#define __HEAD_H__

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

#define LED2_MODER 0X50007000
#define LED2_ODR 0X50007014


#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"

//保存主设备号
unsigned int major;

char kbuf[128]={0};

unsigned int* vir_moder;
unsigned int* vir_odr;
unsigned int* vir_rcc;

unsigned int* vir_moder_F;
unsigned int* vir_odr_F;
//封装操作方法
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')
    {
        //开灯逻辑
        if(kbuf[1]=='1')
        {
            (*vir_odr) |= (0x1<<10);
        }
        else if(kbuf[1]=='2')
        {
            (*vir_odr_F) |= (0x1<<10);
        }
        else if(kbuf[1]=='3')
        {
            (*vir_odr) |= (0x1<<8);
        }
    }
    else if(kbuf[0]=='0')
    {
        //关灯逻辑
        if(kbuf[1]=='1')
        {
            (*vir_odr) &= (~(0x1<<10));
        }
        else if(kbuf[1]=='2')
        {
            (*vir_odr_F) &= (~(0x1<<10));
        }
        else if(kbuf[1]=='3')
        {
            (*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);

    //进行相关寄存器的内存映射
    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");

    vir_moder_F=ioremap(LED2_MODER,4);
    if(vir_moder_F==NULL)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    printk("寄存器内存映射成功\n");
    vir_odr_F=ioremap(LED2_ODR,4);
    if(vir_odr_F==NULL)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    printk("寄存器内存映射成功\n");
    //硬件寄存器的初始化
    //RCC使能
    (*vir_rcc) |= (0x1<<4);
    (*vir_rcc) |= (0x1<<5);
    //设置PE10为输出
    (*vir_moder) &= (~(0x3<<20));
    (*vir_moder) |= (0x1<<20);
    //设置PF8为输出
    (*vir_moder_F) &= (~(0x3<<20));
    (*vir_moder_F) |= (0x1<<20);
    //设置PE8为输出
    (*vir_moder) &= (~(0x3<<16));
    (*vir_moder) |= (0x1<<16);
    //默认关灯
    (*vir_odr) &= (~(0X1<<10));
    (*vir_odr_F) &= (~(0X1<<10));
    (*vir_odr) &= (~(0X1<<8));

    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消物理内存映射
    iounmap(vir_moder);
    iounmap(vir_odr);
    iounmap(vir_rcc);
    iounmap(vir_moder_F);
    iounmap(vir_odr_F);
    //字符设备驱动的注销
    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)
    {
        memset(buf,0,sizeof(buf));
        printf("请输入对LED1的控制命令11(开灯) 01(关灯)>>>");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        write(fd,buf,sizeof(buf));

        memset(buf,0,sizeof(buf));
        printf("请输入对LED2的控制命令12(开灯) 02(关灯)>>>");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        write(fd,buf,sizeof(buf));

        memset(buf,0,sizeof(buf));
        printf("请输入对LED3的控制命令13(开灯) 03(关灯)>>>");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        write(fd,buf,sizeof(buf));
    }
    
    close(fd);
}

测试过程及现象:

1.编译>>>

2.测试>>>

3.现象>>>

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

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

相关文章

关于andriod App开发---查看与导出logcat日志内容

adb rootadb remountadb logcat&#xff08;开始打印指令&#xff09;按住 CtrlC&#xff08;终止打印指令&#xff09;保存日志指令&#xff1a;adb logcat -v time >D:\log\logcat.txt日志导出完成&#xff08;如下图&#xff09; 抓包工具&#xff1a; Charles(IOS 基础…

长春泛域名证书和通配符证书有什么区别

通配符SSL证书是一种数字证书&#xff0c;只是因为数字证书保护的域名数量或者类型不一样&#xff0c;将数字证书分为了单域名SSL证书、多域名SSL证书和通配符SSL证书三种。今天就随SSL盾小编了解通配符SSL证书和泛域名SSL证书的关系。 1.根据保护的域名类型&#xff0c;通配符…

传感器融合带来多重好处

传感器融合是一个热门话题&#xff0c;正好与物联网的增长趋势相吻合&#xff0c;尤其是与自动驾驶汽车和先进的驾驶员辅助系统&#xff08;ADAS&#xff09;相连。这个概念本身并不是什么新鲜事物。在Google Scholar上进行的搜索确定了可追溯到1960年代或更早的概念。但是如今…

云服务器下如何部署Flask项目详细操作步骤

参考网上各种方案&#xff0c;再结合之前学过的Django部署方案&#xff0c;最后确定Flask总体部署是基于&#xff1a;centos7nginxuwsgipython3Flask之上做的。 本地windows开发测试好了我的OCR项目&#xff0c;现在要部署我的OCR项目到云服务器上验证下。 第一步&#xff1a…

调用API接口的一些注意技巧

在实践中我们经常发现&#xff0c;很多同学都是直接请求调用和读取接口数据&#xff0c;而没有做状态码的判断&#xff0c;这在设计角度是非常不合理的。 另外&#xff0c;对于一些实时性要求不高的接口&#xff0c;更合理的做法应该是先把数据拉到本地缓存&#xff0c;再从缓存…

sql server 设置字段自增

1.将字段设置为主键&#xff1b; 2.将“标识规范”设置为是&#xff0c;这里注意切勿将默认值设置为0&#xff0c;否则无法选择“标识规范”

mybatis初体验(细节满满)

1.创建数据表&#xff08;库名为&#xff1a;mayikt&#xff09; CREATE TABLE mayikt_user (id int NOT NULL AUTO_INCREMENT,username varchar(20) DEFAULT NULL,userpwd varchar(20) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT9 DEFAULT CHARSETutf8mb3…

QT for andriod

QT for andriod 开发 apk软件&#xff0c;因为一些特殊的原因&#xff0c;在这里简单的记录一哈自己开发apk的流程和心得。 首先说明我采用的环境有哪些&#xff1f; 1、QT的版本&#xff0c;个人建议5.15.2的版本及以上&#xff0c;我是用的5.15.2。 2、andriod studio 可以…

日期--data与String的相互转换

首先我们要明确 yyyy-MM-dd HH:mm:ss 其中y:年份 MM:月份 dd:天 HH:小时 mm&#xff1a;分 ss&#xff1a;秒 date转String // 获取当前时间LocalDateTime dateLocalDateTime.now(); // 设置日期格式DateTimeFormatter formatterDateTimeFormatter.ofPattern("yyyy-MM-dd…

步进电机选型-根据应用场景

步进电机选型-根据应用场景 在线计算传动机构与步进电机选型问题&#xff0c;这个网站挺好用的 https://www.orientalmotor.com.cn/guide/motorsizingtool/[电机选型]

【C++】C++11新特性 function

包装器function 一、包装器的引入二、包装器的介绍三、bind函数的介绍 一、包装器的引入 在C中我们的可调用对象是很多的&#xff0c;例如函数指针&#xff0c;仿函数&#xff0c;lambda表达式&#xff0c;这多的可调用对象极大的丰富了C的功能&#xff0c;但是也给我们带来了…

Python continue 语句

Python continue 语句跳出本次循环&#xff0c;而break跳出整个循环。 continue 语句用来告诉Python跳过当前循环的剩余语句&#xff0c;然后继续进行下一轮循环。 continue语句用在while和for循环中。 Python 语言 continue 语句语法格式如下&#xff1a; continue 流程图…

PaddleOCR训练部署文档

Cuda安装 wget https://developer.download.nvidia.com/compute/cuda/11.6.0/local_installers/cuda_11.6.0_510.39.01_linux.run sh cuda_11.6.0_510.39.01_linux.run#可能会报错&#xff0c;查看/var/log/nvidia-installer.log &#xff0c;kill -9 [ID]可以解决vim ~/.bash…

计算机网络 第一章:概述

目录 一.因特网概述 1.1网络、互联网(互连网)和因特网 1.2internet与Internet的区别 1.3因特网服务提供者ISP(Internet Service Provider) 1.4因特网组成 二.三种交换方式 2.1电路交换 2.2分组交换(重点) 2.3报文交换 三.计算机网络的定义和分类 四.计算机网络的性能…

前端居中截取不同形状的图片

开发的时候拿到这样一个需求: 意思就是要居中截取图片,这个功能跟微信朋友圈的九宫格显示功能差不多的效果。 方案一 用样式居中,这种方案适合紧急情况下的临时方案 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8&…

华为云云耀云服务器L实例评测|基于华为云云耀云服务器L实例搭建MySQL集群并开展性能评测

文章目录 华为云云耀云服务器L实例的使用搭建MySQL集群环境搭建安装MySQL数据库 集群搭建安装Galera Cluster配置MySQL启动集群 性能测试安装sysbench创建测试数据库运行性能测试 使用Superset从MySQL数据源中获取数据进行分析准备工作配置MySQL数据源从MySQL数据源中获取数据 …

基于Java+SpringBoot+Vue前后端分离的房屋租赁管理系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 房屋租赁管理系统是一…

029:vue项目,勾选后今天不再弹窗提示

第029个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

【校招VIP】前端算法考察之字符串

考点介绍 说到字符串算法我们最先想到的就是模式匹配问题&#xff0c;所谓模式匹配就是字符串匹配问题&#xff0c;就是在一个长的主串中寻找子串的过程&#xff0c;如果我们直接暴力匹配那就是最基本的BF算法&#xff1b;KMP算法与BF算法最大的区别区别就是主串不进行回溯。 …

PaddleOCR学习笔记1-初步尝试

尝试使用PaddleOCR方法&#xff0c;如何使用自定义的模型方法&#xff0c;参数怎么配置&#xff0c;图片识别尝试简单提高识别率方法。 目前仅仅只是初步学习下如何使用PaddleOCR的方法。 一&#xff0c;测试识别图片&#xff1a; 1.png : 正确文本内容为“哲学可以帮助辩别现…