系统驱动实现点灯

news2025/1/15 6:36:42

应用程序:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    /* code */
    char buf[128]={0};
    int fd=open("/dev/demo0", O_RDWR);
    if(fd<0){
        printf("打开设备文件失败\n");
        exit(-1);
    }
    printf("成功打开设备文件\n");
    while(1){
        printf("请输入要实现的逻辑》\n");
        printf("11:LED1亮\n");
        printf("10:LED1灭\n");
        printf("21:LED2亮\n");
        printf("20:LED2灭\n");
        printf("31:LED3亮\n");
        printf("30:LED3灭\n");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        write(fd,buf,sizeof(buf));
    }
    close(fd);
    return 0;
}

驱动程序:

        头文件

#ifndef __HEAD_H__
#define __HEAD_H__

typedef struct{
    volatile unsigned int MODER;
    volatile unsigned int OTYPER;
    volatile unsigned int OSPEEDR;
    volatile unsigned int PUPDR;
    volatile unsigned int IDR;
    volatile unsigned int ODR;
}gpio_t;
#define GPIOE 0x50006000
#define GPIOF 0x50007000
#define PHY_LED_RCC 0x50000A28
#endif

        驱动文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include "head.h"

// extern int add(int i,int j);

int major;
char kbuf[128]={0};
struct class *cls;
struct device *dev;
//定义指针接收映射成功的虚拟内存首地址
gpio_t *vir_gpioe;
gpio_t *vir_gpiof;
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)
{
    int ret;
    ret=copy_to_user(ubuf, kbuf, size);
    if(ret){
        printk("copy_to_user failed\n");
        return ret;
    }

    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)
{
    int ret;
    ret=copy_from_user(kbuf, ubuf, size);
    if(ret){
        printk("copy_from_user failed\n");
        return ret;
    }
    //开关灯逻辑
    //LED1
    if(kbuf[0]=='1'&&kbuf[1]=='1'){
        printk("开灯\n");
        vir_gpioe->ODR|=(0x1<<10);
    }else if(kbuf[0]=='1'&&kbuf[1]=='0'){
        printk("关灯\n");
        vir_gpioe->ODR&=(~(0x1<<10));
    }
    //LED2
    if(kbuf[0]=='2'&&kbuf[1]=='1'){
        printk("开灯\n");
        vir_gpiof->ODR|=(0x1<<10);
    }else if(kbuf[0]=='2'&&kbuf[1]=='0'){
        printk("关灯\n");
        vir_gpiof->ODR&=(~(0x1<<10));
    }
    //LED3
    if(kbuf[0]=='3'&&kbuf[1]=='1'){
        printk("开灯\n");
        vir_gpioe->ODR|=(0x1<<8);
    }else if(kbuf[0]=='3'&&kbuf[1]=='0'){
        printk("关灯\n");
        vir_gpioe->ODR&=(~(0x1<<8));
    }
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    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, "demo0", &fops);
    if (major < 0)
    {
        printk("字符设备驱动组测失败\n");
        return major;
    }
    printk("字符设备驱动注册成功major=%d\n", major);
    //物理内存映射首地址
    vir_gpioe=ioremap(GPIOE,sizeof(gpio_t));
    if(vir_gpioe==NULL){
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir_gpiof=ioremap(GPIOF,sizeof(gpio_t));
    if(vir_gpiof==NULL){
        printk("物理内存映射失败\n");
        return -EFAULT;
    }   
    vir_rcc=ioremap(PHY_LED_RCC,4);
    if(vir_rcc==NULL){
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    printk("物理内存映射成功\n");
    //硬件寄存器初始化
    //gpioe、gpiof寄存器组使能
    (*vir_rcc)|=(0x3<<4);
    //LED1设置---PE10
    vir_gpioe->MODER&=(~(0x3<<20));
    vir_gpioe->MODER|=(0x1<<20);
    vir_gpioe->ODR&=(~(0x1<<10));
    //LED2设置---PF10
    vir_gpiof->MODER&=(~(0x3<<20));
    vir_gpiof->MODER|=(0x1<<20);
    vir_gpiof->ODR&=(~(0x1<<10));
    //LED3设置---PE8
    vir_gpioe->MODER&=(~(0x3<<16));
    vir_gpioe->MODER|=(0x1<<16);
    vir_gpioe->ODR&=(~(0x1<<8));

    //创建设备节点文件
    //向上提交目录信息
    cls=class_create(THIS_MODULE,"demo0");
    if(IS_ERR(cls)){
        printk("向上提交目录信息失败\n");
        return -PTR_ERR(cls);
    }
    printk("向上提交目录信息成功");
    //向上提交设备信息
    int i;
    for(i=0;i<3;i++){
        dev=device_create(cls,NULL,MKDEV(major,i),NULL,"demo%d",i);
        if(IS_ERR(dev)){
            printk("向上提交设备信息失败\n");
            return -PTR_ERR(dev);
        }     
    }
    printk("向上提交设备信息成功\n");
    return 0;
}

static void __exit mycdev_exit(void)
{
    //取消物理内存的映射
    iounmap(vir_gpioe);
    iounmap(vir_gpiof);
    iounmap(vir_rcc);

    //销毁设备信息
    int i;
    for(i=0;i<3;i++){
        device_destroy(cls,MKDEV(major,i));
    }
    //销毁目录信息
    class_destroy(cls);

    // 字符设备驱动注销
    unregister_chrdev(major, "demo0");
}

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

 

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

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

相关文章

小游戏扫雷实现教学(详解)

目录 【前言】 一、模块化程序设计&#xff08;多文件编程&#xff09;介绍 1.概述 2.传统编程的方式 3.模块化程序设计的方法 二、扫雷代码设计思路 三、扫雷代码设计 1.创建菜单函数 2.实现9x9扫雷 3.初始化棋盘 4.打印棋盘 5.随机布置雷的位置 6.排查雷的信息 7.回…

谈谈网络协议的定义、组成和重要性

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、网络协议的定义 二、网络协议的组成 1、…

java小技能:Stream流操作【foreach、filter、map、collect】(根据分类ID穿透查询文章、返回树结构菜单列表)

文章目录 引言I 根据分类ID穿透查询文章II Java小技能:多级菜单排序并返回树结构菜单列表引言 Stream可以由数组或集合创建,对流的操作分为两种: 中间操作,每次返回一个新的流,可以有多个。(筛选filter、映射map、排序sorted、去重组合skip—limit) 终端操作,每个流只…

idea 选中代码生成方法

idea 选中代码生成方法 非常好用 这边给大家送上显示GIF windows&#xff1a; 快捷键&#xff1a; CtrlAltM mac&#xff1a; commonAltM 转载至&#xff1a;https://blog.csdn.net/qq_38377190/article/details/80619632

flutter:webview_flutter的简单使用

前言 最近在研究如何在应用程序中嵌入Web视图&#xff0c;发现有两个库不错。 一个是官方维护、一个是第三方维护。因为没说特别的需求&#xff0c;就使用了官方库&#xff0c;实现一些简单功能是完全ok的 基本使用 官方文档 https://pub-web.flutter-io.cn/packages/webv…

中文大模型 Chinese-LLaMA-Alpaca-2 开源且可以商用

“ Meta 开源 LLAMA2 后&#xff0c;国内出现了不少以此为基座模型训练的中文模型&#xff0c;这次我们来看看其中一个不错的中文模型&#xff1a;Chinese-LLaMA-Alpaca-2 。” 01 — 目前在开源大模型中&#xff0c;比较有名的是Meta的LLAMA模型系列和清华的ChatGLM模型。 特别…

Vue 框架下如何实现加载速度的提升

现在前端的框架有很多&#xff0c;甚至两只手已经数不过来&#xff0c;当然也完全没必要全部都学&#xff0c;还是应该深入的学习一两个被广泛使用的就好。其实我和大部分同学的想法一致&#xff0c;认为最值得我们深究的还是主流的 Vue 和 React。我们通过深入的学习了解这些框…

Docker、Linux网络代理设置

网络代理 linux机器通过windows主机代理访问外网 windows机器借用 CCProxy 软件&#xff0c;官网下载免费版(http://www.ccproxy.com/) CCProxy 默认使用808端口&#xff0c;如果端口冲突可以在设置处修改 在帐号处添加允许的linux机器ip&#xff0c;也可以直接允许所有ip,其…

flinksql实时统计程序背压延迟优化

问题&#xff1a; flinkcdcflinksql做实时读取sls日志和实时统计业务指标&#xff0c;今天发现程序背压了&#xff0c;业务延迟了6个小时。解决办法&#xff1a; 1、资源优化 作业并发大时&#xff1a;在作业的高级配置的资源配置中&#xff0c;增加JobManager的资源&#xf…

最低日薪2K的护网怎么才能参加?

前天&#xff0c;这张图在网络安全圈里传疯了&#xff0c;原因是黑客一年一度的盛会&#xff1a;HVV行动开始了。并且有人戏称昨天是黑客界的春运。 更有人建议把所有的交通工具都停掉&#xff0c;就没有黑客了。甚至有火车站电子大屏显示被黑客进攻&#xff0c;有可疑程序正在…

快速通过华为HCIP认证

你可以按照以下步骤进行准备和学习&#xff1a; 华为认证课程和资料--提取码:1234https://pan.baidu.com/s/1YJhD8QbocHhZ30MvrKm8hg 了解认证要求&#xff1a;查看华为官方网站上的HCIP认证要求和考试大纲&#xff0c;了解考试的内容、考试形式和考试要求。 学习相关知识&am…

Springboot 实践(5)springboot添加资源访问目录及目录测试

前文讲解了swagger测试服务控制器&#xff0c;实现了数据库数据访问&#xff0c;这些功能都是运行在后台服务器上&#xff0c;实际用户并不能直接调用接口获取数据&#xff0c;即使用户能够利用接口获取到数据&#xff0c;数据也是结构化数据&#xff0c;不能争取转化成用户使用…

【js】Array.from将类数组对象转为数组

Array.from()方法支持将类似数组的对象转为数组。所谓类似数组的对象&#xff0c;本质特征只有一点&#xff0c;即必须有length属性。因此&#xff0c;任何有length属性的对象&#xff0c;都可以通过Array.from()方法转为数组。 代码&#xff1a; var arrayObj {"0"…

行业首发!《硬件工程师进阶武器库》免费赠送!限量2000份,送完不补!

对于刚入硬件行业的3~5年工程师来说&#xff0c;如果能有一个好的师傅引路&#xff0c;那是最好不过的了&#xff0c;但是往往大神很少&#xff0c;能够愿意倾囊相授的也难遇到&#xff1b; 如果在这个阶段&#xff0c;能够找到行业中top级企业内部的学习资料&#xff0c;或者…

【正点原子STM32连载】 第七章 Geehy标准库版本MDK工程创建 摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第七…

图解 Paxos 算法

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱写博客的嗯哼&#xff0c;爱好Java的小菜鸟 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;个人博客&#xff1a;敬请期待 &#x1f4d5;系列…

Dubbo基础学习(笔记一)

目录 第一章、概念介绍1.1&#xff09;什么是RPC框架1.2&#xff09;什么是分布式系统1.3&#xff09;Dubbo概述1.3&#xff09;Dubbo基本架构 第二章、服务提供者2.1&#xff09;目录结构和依赖2.2&#xff09;model层2.3&#xff09;service层2.4&#xff09;resources配置文…

vector【2】模拟实现(超详解哦)

vector 引言&#xff08;实现概述&#xff09;接口实现详解默认成员函数构造函数析构函数赋值重载 迭代器容量size与capacityreserveresizeempty 元素访问数据修改inserterasepush_back与pop_backswap 模拟实现源码概览总结 引言&#xff08;实现概述&#xff09; 在前面&…

VMware虚拟安装Ubuntu,然后切换Ubuntu内核版本

无论你选择哪种方法&#xff0c;一旦进入 GRUB 引导菜单&#xff0c;你应该能够选择需要的内核版本并启动系统。 打开终端&#xff1a;你可以通过按下 Ctrl Alt T 快捷键来打开终端。 使用 sudo&#xff1a;切换内核需要管理员权限&#xff0c;因此你需要使用 sudo 命令。首…

QtCreator 配置 MSVC 编译工具

在官网下载的 Qt 都是配置 mingw&#xff0c;没法使用 webenginewidgets&#xff0c;只有使用 msvc 编译的 Qt&#xff0c;才带有 web 控件。原理都是下载 Visual Studio 安装&#xff0c;使用其中的 msvc 工具&#xff0c;如果只下载 msvc 而不必下载使用 VS 其它工具&#xf…