linux系统之字符设备驱动——点灯

2023-11-05

linux系统之字符设备驱动——点灯

1. 原理图

在这里插入图片描述

底板 核心板
RGB-RED GPIOA28
RGB-GREEN GPIOE13
RGB-BLUE GPIOB12

2. 驱动代码

  1. 驱动代码程序 led_dev.c
/*
 * @Author: your name
 * @Date: 2021-02-06 00:06:43
 * @LastEditTime: 2021-02-23 20:06:05
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \2-led\led_dev.c
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>

#include "led.h"

#define GPIONO(m,n) (m*32+n)
#define GPIOA28 GPIONO(0,28)
#define GPIOB12 GPIONO(1,12)
#define GPIOE13 GPIONO(4,13)

#define NAME "RGB_IO"	// 设备节点名字
struct led_dev{
	unsigned int major;
    struct class *class;	// 设备节点目录
    struct device *dev; 	// 设备
}LedDevice;

int led_open (struct inode *inode, struct file *file)
{
	return 0;
}
int led_close (struct inode *inode, struct file *file)
{
	return 0;
}
long led_ioctl (struct file *file, unsigned int cmd, unsigned long agrs)
{
	switch(cmd){
		case RED_ON:
			gpio_set_value(GPIOA28, 1);
			break;
			
		case RED_OFF:
			gpio_set_value(GPIOA28, 0);
			break;

		case GREEN_ON:
			gpio_set_value(GPIOE13, 1);
			break;

		case GREEN_OFF:
			gpio_set_value(GPIOE13, 0);
			break;

		case BLUE_ON:
			gpio_set_value(GPIOB12, 1);
			break;

		case BLUE_OFF:
			gpio_set_value(GPIOB12, 0);
			break;

	}
	return 0;
}
const struct file_operations fops = 
{
	.open = led_open,
    .release = led_close,
    .unlocked_ioctl = led_ioctl,  
};
static int __init myRGB_Init(void)
{
	int ret = -1;

	// 1. 注册字符设备驱动
	LedDevice.major = register_chrdev(LedDevice.major, NAME, &fops);
	if(LedDevice.major < 0)
	{
		printk("%s, %s, register_chrdev failed\n", __FILE__, __func__);
		goto ERR1;
	}
	// 2. 创建设备驱动目录
    LedDevice.class = class_create(THIS_MODULE, "cleddev");
	if(IS_ERR(LedDevice.class)){
		printk("%s, %s, class_create failed\n", __FILE__, __func__);
		goto ERR2;
	}
    // 3. 创建设备驱动节点
    LedDevice.dev = device_create(LedDevice.class, NULL, MKDEV(LedDevice.major, 0), NULL, NAME);
	if(IS_ERR(LedDevice.dev)){
		printk("%s, %s, device_create failed\n", __FILE__, __func__);
		ret = PTR_ERR(LedDevice.dev);
		goto ERR3;
	}
	gpio_set_value(GPIOA28, 0);
	gpio_set_value(GPIOB12, 0);
	gpio_set_value(GPIOE13, 0);

	printk("%s, %s, myRGB_Init succeed \n", __FILE__, __func__);

	return 0;

ERR3:
	class_destroy(LedDevice.class);
ERR2:
	unregister_chrdev(LedDevice.major, NAME);
ERR1:
	return ret;
}

static void __exit myRGB_Exit(void)
{
	gpio_set_value(GPIOA28, 1);
	gpio_set_value(GPIOB12, 1);
	gpio_set_value(GPIOE13, 1);

	device_destroy(LedDevice.class, MKDEV(LedDevice.major, 0));
    // 3. 销毁设备驱动目录
	class_destroy(LedDevice.class);
    // 4. 注销字符设备驱动
    unregister_chrdev(LedDevice.major, NAME);

	printk("%s, %s, myRGB_Exit succeed \n", __FILE__, __func__);
}
module_init(myRGB_Init);
module_exit(myRGB_Exit);
MODULE_LICENSE("GPL");
  1. 中间文件 led.h
/*
 * @Author: your name
 * @Date: 2021-02-23 20:01:02
 * @LastEditTime: 2021-02-23 20:01:35
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \2-led\led.h
 */

#ifndef __LED_H__
#define __LED_H__

#define TYPE 'L'

#define RED_ON 		_IO(TYPE, 0)
#define RED_OFF		_IO(TYPE, 1)
#define GREEN_ON 	_IO(TYPE, 2)
#define GREEN_OFF 	_IO(TYPE, 3)
#define BLUE_ON 	_IO(TYPE, 4)
#define BLUE_OFF 	_IO(TYPE, 5)

#endif /* __LED_H__ */
  1. 应用程序 main.c
/*
 * @Author: your name
 * @Date: 2021-02-23 20:09:13
 * @LastEditTime: 2021-02-23 20:15:03
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \2-led\main.c
 */
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "led.h"

int main(int argc, char const *argv[])
{
    int fd = open("/dev/RGB_IO", O_RDWR);
    if(fd < 0)
    {
         perror("open");
         return -1;  
    }

    while(1)
    {
        ioctl(fd, RED_ON);
		sleep(1);
		ioctl(fd, RED_OFF);
		ioctl(fd, GREEN_ON);
		sleep(1);
		ioctl(fd, GREEN_OFF);
		ioctl(fd, BLUE_ON);
		sleep(1);
		ioctl(fd, BLUE_OFF);
    }
    close(fd);

    return 0;
}

3. 实验现象

红、绿、蓝三个灯交替闪烁。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux系统之字符设备驱动——点灯 的相关文章

  • 让Redis突破内存大小的限制

    Redis虽然可以实现持久化存储 也是基于数据内存模型的基础之上 单机内存大小限制着Redis存储的数据量 有没有一种替代方案呢 本文介绍一款笔者使用的采用New BSD License 许可协议的软件 SSDB 官网地址 http ssd
  • Avalonia-VS环境安装

    链接 https pan baidu com s 1T1TYf7 Q5T6hbpOyGCW2Vg 提取码 m8eu 安装SDK 没有这个 vs2019安装后Avalonia插件 无法选择netcore 生成项目 插件地址 上面为vs2019
  • ld 链接程序出错定位

    工具链相关问题 一般可 verbose 下 看看具体什么地方出问题 设置 LDFLAGS Wl verbose 例如 链接一堆 o文件 只有以下错误信息 ld final link failed Bad value 就可以加入 Wl ver
  • Linux系统:ulimit命令

    目录 一 理论 1 ulimit命令 二 实验 1 打开的最大文件描述符的数量为65535 一 理论 1 ulimit命令 1 概念 ulimit是一个计算机命令 用于shell启动进程所占用的资源 可用于修改系统资源限制 限制每个用户可使
  • TCP的半关闭状态以及tcp-keepalive

    文章目录 半关闭状态 实现方法 tcp keepalive 开启 tcp keepalive 方法1 Linux系统全局开启 方法2 setsockopt 设置 socket 半关闭状态 一次TCP四次挥手的过程如上图所示 设左侧为客户端
  • VirtualBox中Ubuntu 14.04 LTS安装GATE7.1

    开发环境 win7 VirtualBox Ubuntu 14 04 LTS 主要参考博客 1 Compilation Instructions V7 1 2 Gate7 1在Ubuntu下编译 3 Package Requirements
  • SMTP邮件格式、SMTP 协议,SMTP的MIME写法,SMTP发送HTML邮件

    转载 http blog sina com cn s blog 759444350100vx8u html MIME邮件格式 在RFC 2822文档中定义了简单的ASCII编码的Email的邮件格式 然而随着Internet的发展 Emai
  • Linux命令:lsof

    目录 一 理论 1 lsof 二 实验 1 无参数 2 p 参数 3 l 参数 4 u 参数 5 c 参数 6 d 参数 7 fileName 8 i 参数 一 理论 1 lsof 1 概念 命令 lsof list opened file
  • 07 - 日志服务器的搭建与攻击

    目录 1 项目环境 2 拓扑图 3 思路 4 配置GW CentOS 7 4 1 配置ens33 4 2 配置ens32 4 3 配置ens34 5 配置Server CentOS 7 1804 7 配置Syslog CentOS 7 18
  • 理解virt res shr之间的关系 - linux

    转自 https www orchome com 298 想必在linux上写过程序的同学都有分析进程占用多少内存的经历 或者被问到这样的问题 你的程序在运行时占用了多少内存 物理内存 通常我们可以通过top命令查看进程占用了多少内存 这里
  • Ubuntu安装java

    转自 https www cnblogs com ziyue7575 p 13898610 html java8 apt安装 参考 https www cnblogs com zzy1024 p 11406269 html 若是没有配置国内
  • CentOS8 MySQL 主主模式+keepalived高可用环境搭建非docker版

    概述 采用了MySQL KeepAlived实现MySQL高可用 旨在当主机发生宕机等异常情况时 使用备机的MySQL服务 以此保证系统服务的高可用 这套环境的搭建过程中 需要注意的事项如下 1 MySQL是否数据同步 在大批量数据写入的情
  • Centos 7安装mysql

    1 安装前清理工作 1 1 1 清理原有的mysql数据库 使用以下命令查找出安装的mysql软件包和依赖包 rpm pa grep mysql 显示结果如下 mysql80 community release el7 1 noarch m
  • linux内核对于指令异常的处理

    1 处理流程 以arm64来介绍一下流程 如果在用户层发生指令异常时 首先进入入口el0 undef arch arm64 kernel entry s el0 undef Undefined instruction enable inte
  • MAC版本Mysql数据库忘记密码解决教程

    MAC初始化安装获取密码 删除Data文件夹内容 并重新生成 rm rf usr local mysql data 初始化再次生成Data文件夹中的内容 初始化完成之后再代码最后生成随机密码需要保存 mysqld initialize us
  • Centos7.4制作简易RPM包

    准备nginx 1 10 1 tar gz 准备php 7 1 7 tar bz2 这两个源码编译tar包 1 准备制作环境 yum y install rpm build 安装rpm build软件 rpmbuild ba xx spec
  • Linux的目录切换和用户管理

    切换目录 在使用linux系统的时候 会用cd来切换目录 cd 切换到根目录 cd 切换到主目录 cd 切换到之前工作目录 cd 虽然很方便但只能保存一次目录 pushd命令使用目录堆栈可以把多个目录存放起来 配套使用pushd popd
  • docke的基础入门

    docker基础入门操作 一 如何安装docker 一 如何安装docker 安装docker命令通过一下命令顺序执行 即可进行安装 校验操作系统内核版本 要求是3 10以上的版本 1 安装一些必要的系统工具 其中yum utils包含yu
  • Linux shell中if [ $? -eq 0 ] 语句作用:判断命令是否执行成功

    shell脚本中 是指上一次命令执行的成功或者失败的状态 如果成功就是0 失败为1 语句if eq 0 是判断if语句的上一个命令执行如果成功就执行if中的语句 否则就执行else中的内容 note 使用时要注意 if后面的中括号 eq 0
  • Add/Remove software 或yum从光盘安装

    Add RemoveSoftware 好像是集成了一些类似于yum的功能 每次打开它时 它都会上网去搜索安装包的列表 要搜好一阵子 如果不想让它上网去索搜 而只是在本地添加 删除软件 那我们就要先把yum的仓库文删除 也就是把 etc yu

随机推荐

  • POJ - 3253 Fence Repair(哈夫曼树,优先队列)

    题目 Farmer John wants to repair a small length of the fence around the pasture He measures the fence and finds that he ne
  • 信号与槽的详解

    以前也写过这方面的知识 但是因为都是参照着别人的文章来写的 就是很虚 很浮夸 今天下午我又好好看了一下这方面的知识 查阅了一些资料 现在来写写我自己的发现 接下来分为四大小点 一 信号和槽的基本认识 当对象的内部状态发生改变 信号就被发射
  • 20220906工作问题学习记录

    今天 在解决一个项目中的BUG问题的时候 遇到了需要过滤接口返回字段数据中的换行符 n 这里顺便 需要对php语言中的str replace 函数进行使用 做一下学习记录 由于原字符串是使用 来进行包裹的 所以 在使用str replace
  • C#之Console输入输出实用的

    潘鹏在CSDN上原创 如其他网站转载请注意排版和写明出处 1 Console Beep 发出蜂鸣声 2 Console Title 控制台的标题 3 Console Write 输入 4 Console WriteLine 输入 遇ente
  • Linux下GDB调试程序

    1 什么是GDB GDB 全称 GNU Debugger 是GNU工程师为GNU操作系统开发的调试器 它可以用于调试C C Objective C Pascal Ada等语言编写的程序 2 GDB的使用条件 在程序编译的时候 添加响应的调试
  • Linux: ARM32各CPU模式下栈配置

    文章目录 1 前言 2 背景 3 ARM32 中断向量表 和 中断处理流程 3 1 ARM32 中断向量表 3 2 ARM32 中断处理流程 4 ARM32 各CPU模式下的栈配置 4 1 SVC模式下各CPU栈配置 内核栈配置 4 1 1
  • java中score用法,Lucene 8.x 使用 FunctionScoreQuery 实现自定义的文档评分

    在使用不管是 Lucene 或者 ElasticSearch 进行全文搜索中 检索到文档很简单 但是把搜索者最想要的结果排在最前面 这是最具挑战性的 我们举个最简单的例子 假设我们需要做一个博客搜索 当我们用 Lucene 默认的匹配度进行
  • 怎么看服务器是中毒了还是被攻击?

    服务器是企业或个人重要的信息系统设备之一 它的正常运行对于企业和个人的业务和日常生活都非常重要 然而 服务器也很容易成为黑客攻击的目标 一旦遭到攻击 会对系统的正常运行和数据安全产生严重影响 在服务器出现异常情况时 如何判断是中毒还是被攻击
  • JSTL——jstl标签简介

    文章目录 1 jstl简介以及jstl标签库导入 2 set标签 3 if标签 4 choose when标签 5 forEach标签 1 jstl简介以及jstl标签库导入 1 jstl全称Jsp Standarded Tag Libra
  • VTK安装与配置补充

    本文参考 https blog csdn net Robin Chou article details 50476007 1 CMake的安装 CMake安装是用来对VTK编译前的配置工作 此博客中使用的是CMake2 8 CMake的下载
  • 【毕业设计】基于红外热释电的房间人数计数系统 - 单片机 物联网嵌入式

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 设计原理 4 1 PIR传感器 4 2 mlx90614红外传感器 5 部分核心代码 6 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新
  • SD卡/TF卡简记

    文章目录 MicroSD卡与SD卡关系与区别 对比NM卡 XQD卡 CFexpress卡 SD规格标识 FAQ 拍摄1080p或2k视频需要什么速度的sd卡 拍摄4k视频需要什么速度的sd卡 拍摄8k视频需要什么速度的sd卡 MicroSD
  • BH1750 传感器实战教学 —— 驱动移植篇

    前言 上一篇 BH1750 的实战教学我们说明的实际应用中传感器的硬件设计 BH1750 传感器实战教学 硬件设计篇 我们提到过在本次使用的芯片为 51 内核 I2C 通讯驱动实现与 STM32 上还是有很大区别的 对于我们来说 已经掌握了
  • 【python数据分析】jupyter notebook常用快捷键

    相信不少人在学习python数据分析会用到jupyter notebook 而作为一个刚刚接触的插件 往往不会使用快捷键加快我们的学习或开发 这里就给大家分享一下jupyter notebook常用快捷键 总的来说 分为2种模式 一 命令模
  • 几个常用的匹配html标签的正则

    1 去除 a 标签 保留中间的文字 原字符串 a href www baidu com 点我跳转百度 a 正则 lt a A s gt gt 替换为 1 结果 点我跳转百度 2 去除指定标签及其里面的内容 原字符串 span style c
  • OP-TEE是如何使用RPMB来实现可信存储的

    1 目的 写这篇博客主要是为了记录这段时间的成果 方便自己和有需要的人理解可信存储 以及OP TEE是如何实现可信存储的 最近在重构公司的可信存储的实现 主要是想将Trust Storage的主要逻辑实现从user space挪到kerne
  • 互联网+SC联盟解决大学生五大难题!

    这是一个历史性的时刻 互联网 SC联盟 震撼面世 小编能想到的类似事件有宇宙大爆炸 恐龙灭绝 第一个人类诞生 中国四大发明 天呐 相信你也迫不及待地想了解了 赶紧阅读下文 来做第一个见证人吧 一 SC是什么意思 Study and Care
  • unity3D基础操作之01--unity3d窗口界面介绍

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 最常使用5种窗口 1 Scene场景编辑窗口 2 Game游戏运行窗口 需要注意的是 3 Hierarchy场景物体列表窗口 4 Project项目资源列表窗口 需
  • 【多线程操作】线程池模拟实现

    目录 一 线程池的作用 二 线程池的模拟实现 1 线程模块 Thread hpp 2 线程锁模块 LockGuard hpp 3 任务模块 Task hpp 4 线程池核心 ThreadPool hpp 一 线程池的作用 线程池是用来维护多
  • linux系统之字符设备驱动——点灯

    linux系统之字符设备驱动 点灯 1 原理图 底板 核心板 RGB RED GPIOA28 RGB GREEN GPIOE13 RGB BLUE GPIOB12 2 驱动代码 驱动代码程序 led dev c Author your na