Linux下 /sys/class 一些操作

Linux下,/dev、/sys/class的区别

/dev下面有很多节点,每一个节点代表一个设备,/dev目录下面是按物理器件进行分类;而/sys/class下面的更多是按功能抽象出来的。
参考1

demo

在正点原子的基础上进行演示

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>/***************************************************************
Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
文件名		: newchrled.c
作者	  	: 左忠凯
版本	   	: V1.0
描述	   	: LED驱动文件。
其他	   	: 无
论坛 	   	: www.openedv.com
日志	   	: 初版V1.0 2019/6/27 左忠凯创建
***************************************************************/
#define NEWCHRLED_CNT			1		  	/* 设备号个数 */
#define NEWCHRLED_NAME			"newchrled"	/* 名字 */
#define LEDOFF 					0			/* 关灯 */
#define LEDON 					1			/* 开灯 *//* 寄存器物理地址 */
#define CCM_CCGR1_BASE				(0X020C406C)	
#define SW_MUX_GPIO1_IO03_BASE		(0X020E0068)
#define SW_PAD_GPIO1_IO03_BASE		(0X020E02F4)
#define GPIO1_DR_BASE				(0X0209C000)
#define GPIO1_GDIR_BASE				(0X0209C004)/* 映射后的寄存器虚拟地址指针 */
static void __iomem *IMX6U_CCM_CCGR1;
static void __iomem *SW_MUX_GPIO1_IO03;
static void __iomem *SW_PAD_GPIO1_IO03;
static void __iomem *GPIO1_DR;
static void __iomem *GPIO1_GDIR;/* newchrled设备结构体 */
struct newchrled_dev{dev_t devid;			/* 设备号 	 */struct cdev cdev;		/* cdev 	*/struct class *class;		/* 类 		*/struct device *device;	/* 设备 	 */int major;				/* 主设备号	  */int minor;				/* 次设备号   */
};struct newchrled_dev newchrled;	/* led设备 *///对应应用层的write
static ssize_t my_att_store(struct device *dev,   struct device_attribute *attr,   const char *buf, size_t count)   
{  printk("value:%s\n", buf);return count;  
}  
//对应应用层的read
static ssize_t my_att_show(struct device *dev,  struct device_attribute *attr,  char *buf)  
{  printk(buf, "my_attr show enter");buf = "hello world";return 0;     
}  static DEVICE_ATTR(my_att,0660,my_att_show,my_att_store); /** @description		: LED打开/关闭* @param - sta 	: LEDON(0) 打开LED,LEDOFF(1) 关闭LED* @return 			: 无*/
void led_switch(u8 sta)
{u32 val = 0;if(sta == LEDON) {val = readl(GPIO1_DR);val &= ~(1 << 3);	writel(val, GPIO1_DR);}else if(sta == LEDOFF) {val = readl(GPIO1_DR);val|= (1 << 3);	writel(val, GPIO1_DR);}	
}/** @description		: 打开设备* @param - inode 	: 传递给驱动的inode* @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量* 					  一般在open的时候将private_data指向设备结构体。* @return 			: 0 成功;其他 失败*/
static int led_open(struct inode *inode, struct file *filp)
{filp->private_data = &newchrled; /* 设置私有数据 */return 0;
}/** @description		: 从设备读取数据 * @param - filp 	: 要打开的设备文件(文件描述符)* @param - buf 	: 返回给用户空间的数据缓冲区* @param - cnt 	: 要读取的数据长度* @param - offt 	: 相对于文件首地址的偏移* @return 			: 读取的字节数,如果为负值,表示读取失败*/
static ssize_t led_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{return 0;
}/** @description		: 向设备写数据 * @param - filp 	: 设备文件,表示打开的文件描述符* @param - buf 	: 要写给设备写入的数据* @param - cnt 	: 要写入的数据长度* @param - offt 	: 相对于文件首地址的偏移* @return 			: 写入的字节数,如果为负值,表示写入失败*/
static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{int retvalue;unsigned char databuf[1];unsigned char ledstat;retvalue = copy_from_user(databuf, buf, cnt);if(retvalue < 0) {printk("kernel write failed!\r\n");return -EFAULT;}ledstat = databuf[0];		/* 获取状态值 */if(ledstat == LEDON) {	led_switch(LEDON);		/* 打开LED灯 */} else if(ledstat == LEDOFF) {led_switch(LEDOFF);	/* 关闭LED灯 */}return 0;
}/** @description		: 关闭/释放设备* @param - filp 	: 要关闭的设备文件(文件描述符)* @return 			: 0 成功;其他 失败*/
static int led_release(struct inode *inode, struct file *filp)
{return 0;
}/* 设备操作函数 */
static struct file_operations newchrled_fops = {.owner = THIS_MODULE,.open = led_open,.read = led_read,.write = led_write,.release = 	led_release,
};/** @description	: 驱动出口函数* @param 		: 无* @return 		: 无*/
static int __init led_init(void)
{u32 val = 0;/* 初始化LED *//* 1、寄存器地址映射 */IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE, 4);SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE, 4);SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE, 4);GPIO1_DR = ioremap(GPIO1_DR_BASE, 4);GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE, 4);/* 2、使能GPIO1时钟 */val = readl(IMX6U_CCM_CCGR1);val &= ~(3 << 26);	/* 清楚以前的设置 */val |= (3 << 26);	/* 设置新值 */writel(val, IMX6U_CCM_CCGR1);/* 3、设置GPIO1_IO03的复用功能,将其复用为*    GPIO1_IO03,最后设置IO属性。*/writel(5, SW_MUX_GPIO1_IO03);/*寄存器SW_PAD_GPIO1_IO03设置IO属性*bit 16:0 HYS关闭*bit [15:14]: 00 默认下拉*bit [13]: 0 kepper功能*bit [12]: 1 pull/keeper使能*bit [11]: 0 关闭开路输出*bit [7:6]: 10 速度100Mhz*bit [5:3]: 110 R0/6驱动能力*bit [0]: 0 低转换率*/writel(0x10B0, SW_PAD_GPIO1_IO03);/* 4、设置GPIO1_IO03为输出功能 */val = readl(GPIO1_GDIR);val &= ~(1 << 3);	/* 清除以前的设置 */val |= (1 << 3);	/* 设置为输出 */writel(val, GPIO1_GDIR);/* 5、默认关闭LED */val = readl(GPIO1_DR);val |= (1 << 3);	writel(val, GPIO1_DR);/* 注册字符设备驱动 *//* 1、创建设备号 */if (newchrled.major) {		/*  定义了设备号 */newchrled.devid = MKDEV(newchrled.major, 0);register_chrdev_region(newchrled.devid, NEWCHRLED_CNT, NEWCHRLED_NAME);} else {						/* 没有定义设备号 */alloc_chrdev_region(&newchrled.devid, 0, NEWCHRLED_CNT, NEWCHRLED_NAME);	/* 申请设备号 */newchrled.major = MAJOR(newchrled.devid);	/* 获取分配号的主设备号 */newchrled.minor = MINOR(newchrled.devid);	/* 获取分配号的次设备号 */}printk("newcheled major=%d,minor=%d\r\n",newchrled.major, newchrled.minor);	/* 2、初始化cdev */newchrled.cdev.owner = THIS_MODULE;cdev_init(&newchrled.cdev, &newchrled_fops);/* 3、添加一个cdev */cdev_add(&newchrled.cdev, newchrled.devid, NEWCHRLED_CNT);/* 4、创建类 */newchrled.class = class_create(THIS_MODULE, NEWCHRLED_NAME);if (IS_ERR(newchrled.class)) {return PTR_ERR(newchrled.class);}/* 5、创建设备 */newchrled.device = device_create(newchrled.class, NULL, newchrled.devid, NULL, NEWCHRLED_NAME);if (IS_ERR(newchrled.device)) {return PTR_ERR(newchrled.device);}/* 创建自己的节点 */device_create_file(newchrled.device, &dev_attr_my_att);return 0;
}/** @description	: 驱动出口函数* @param 		: 无* @return 		: 无*/
static void __exit led_exit(void)
{/* 取消映射 */iounmap(IMX6U_CCM_CCGR1);iounmap(SW_MUX_GPIO1_IO03);iounmap(SW_PAD_GPIO1_IO03);iounmap(GPIO1_DR);iounmap(GPIO1_GDIR);/* 注销字符设备驱动 */cdev_del(&newchrled.cdev);/*  删除cdev */unregister_chrdev_region(newchrled.devid, NEWCHRLED_CNT); /* 注销设备号 */device_destroy(newchrled.class, newchrled.devid);class_destroy(newchrled.class);
}module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zuozhongkai");

class_create

函数说明
class_create执行后,sys/class下面会生成一个NEWCHRLED_NAME的路径,但此时,该路径下为空。
在这里插入图片描述

device_create

函数说明
将dev设备与class相关联,该函数执行后,NEWCHRLED_NAME路径下出现
在这里插入图片描述

device_create_file

创建一个自己的属性
函数说明
在删除设备的时候自动删除该节点,无需在exit函数中特意删除。
my_att_store和my_att_show分别对应应用层对属性文件的读写。
一个demo
在这里插入图片描述

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

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

相关文章

基于Matlab实现多个图像压缩案例(附上源码+数据集)

图像压缩是一种将图像数据量减少的技术&#xff0c;以减少存储空间和传输带宽的需求。在本文中&#xff0c;我们将介绍如何使用Matlab实现图像压缩。 文章目录 简单案例源码数据集下载 简单案例 首先&#xff0c;我们需要了解图像压缩的两种主要方法&#xff1a;有损压缩和无…

防火墙日志分析工具

防火墙提供对进入组织网络的网络流量的来源和类型的可见性&#xff0c;这使得防火墙日志成为重要的信息源&#xff0c;包括所有连接的源地址、目标地址、协议和端口号等详细信息&#xff0c;此信息可以提供对未知安全威胁的见解&#xff0c;是威胁管理中的重要工具。 防火墙日…

bat批处理——统计当前文件夹下的所有文件名

一、在当前文件夹下建立XX.txt文件&#xff0c;将指令dir *.* /b/s>test.txt写到XX.txt文件中 测试文件夹目录及文件结构图&#xff1a; 指令说明&#xff1a; dir *.* /b/s>test.txt /*** 此部分为注释内容* dir 获取当前目录下的目录及文件* *.* 对文件进行筛选&…

手写Mybatis:第17章-Plugin插件功能实现

文章目录 一、目标&#xff1a;Plugin插件二、设计&#xff1a;Plugin插件三、实现&#xff1a;Plugin插件3.1 工程结构3.2 Plugin插件代理模式类图3.3 自定义拦截注解3.3.1 方法签名3.3.2 拦截注解 3.4 拦截器接口定义3.4.1 调用信息3.4.2 拦截器接口 3.5 类代理包装操作3.5.1…

冯诺依曼体系结构/什么是OS?

一、体系结构图 示意图 控制器可以控制其它4个硬件&#xff0c;四个硬件直接可以进行数据传输。 5大硬件 但是这些个体需要用“线”连接。 为什么要有存储器&#xff1f; 如果没有&#xff0c;实际速度则为输入、输出设备的速度。 加上后&#xff0c;变为内存的速度。&#…

大厂面试 | 百度一面,顶不住

题目来源&#xff1a;https://www.nowcoder.com/feed/main/detail/d39aabc0debd4dba810b4b9671d54348 前文 本期是【捞捞面经】系列文章的第 2 期&#xff0c;持续更新中…。&#xff08;更多与往期下方仓库直达&#xff09; 《捞捞面经》系列正式开始连载啦&#xff0c;据说看…

Kubernetes(k8s) 架构原理一文详解

目录 一、k8s 概述 1.什么是k8s&#xff1f; 2.特性 3.主要功能 三、集群架构与组件 1.Master 组件 &#xff08;1&#xff09;Kube-apiserver &#xff08;2&#xff09;Kube-controller-manager &#xff08;3&#xff09;Kube-scheduler 2.配置存储中心 3.Node 组…

【Sentinel】ProcessorSlotChain处理器插槽链与Node

文章目录 1、Sentinel的基本概念2、ProcessorSlotChain3、Node 1、Sentinel的基本概念 Sentinel实现限流、隔离、降级、熔断等功能&#xff0c;本质要做的就是两件事情&#xff1a; 统计数据&#xff1a;统计某个资源的访问数据&#xff08;QPS、RT等信息&#xff09;规则判断…

一文读懂GPU显卡的10个重要参数

在当今的高性能计算机世界中&#xff0c;GPU显卡的性能至关重要。这一领域的快速发展&#xff0c;使得图形渲染、游戏体验、视频编辑等高性能计算任务变得更加高效和流畅。正因如此&#xff0c;选择一款合适的GPU显卡变得越来越重要。在挑选GPU显卡时&#xff0c;了解其关键参数…

【真题解析】系统集成项目管理工程师 2023 年上半年真题卷(综合知识)

本文为系统集成项目管理工程师考试(软考) 2023 年上半年真题(全国卷),包含答案与详细解析。考试共分为两科,成绩均 ≥45 即可通过考试: 综合知识(选择题 75 道,75分)案例分析(问答题 4 道,75分)综合知识(选择题*75)1-10 题11-20 题21-30 题31-40 题41-50 题51-60 …

进程、线程与构造方法

进程、线程与构造方法 目录 一&#xff0e; 进程与线程1. 通俗解释2. 代码实现3. 线程生命周期&#xff08;图解&#xff09; 二&#xff0e; 构造方法 一&#xff0e; 进程与线程 1. 通俗解释 进程&#xff1a;就像电脑上运行的软件&#xff0c;例如QQ等。 线程&#xff1a;…

接口测试与功能测试的区别~

今天为大家分享的是我们在日常测试工作中, 一定会接触并且目前在企业中是主要测试内容的 功能测试与接口测试 一.功能测试与接口测试的基本概念。 1.1 什么是功能测试呢? 功能测试: 是黑盒测试的一方面, 检查实际软件的功能是否符合用户的需求 功能测试测试的内容包括以下…

改变金融贷款市场营销方式 ---- 运营商大数据精准获客

与传统的企业网络营销相比&#xff0c;最常见的是网络推广和硬广告推广。一些企业无法找到可靠准确的数据来源&#xff0c;也无法找到一些未知的总数据。这些数据大多存在持续时间长、准确性差的缺点&#xff0c;企业在将这些数据信息应用于商品在线营销时往往会遇到不足。 在…

SpringCloudAlibaba之Sentinel介绍

文章目录 1 Sentinel1.1 Sentinel简介1.2 核心概念1.2.1 资源1.2.2 规则 1.3 入门Demo1.3.1 引入依赖1.3.2 集成Spring1.3.3 Spring中资源规则 1.4 Sentinel控制台1.5 核心原理1.5.1 NodeSelectorSlot1.5.2 ClusterBuilderSlot1.5.3 LogSlot1.5.4 StatisticSlot1.5.5 Authority…

Nacos 开源版的使用测评

文章目录 一、Nacos的使用二、Nacos和Eureka在性能、功能、控制台体验、上下游生态和社区体验的对比&#xff1a;三、记使使用Nacos中容易犯的错误四、对Nacos开源提出的一些需求 一、Nacos的使用 这里配置mysql的连接方式&#xff0c;spring.datasource.platformmysql是老版本…

软件架构设计(三) B/S架构风格-层次架构(一)

层次架构风格从之前的两层C/S到三层C/S,然后演化为三层B/S架构,三层B/S架构之后仍然在往后面演化,我们来看一下层次架构演化过程中都有了哪些演化的架构风格呢? 而我们先简单了解一下之前的层次架构风格中分层的各个层次的作用。 表现层:由于用户进行交互,比如MVC,MVP,…

大数据平台数据安全具体措施有哪些?有推荐的吗?

大数据平台是企业处理和分析数据的重要工具之一&#xff0c;也是企业数据存储的重要载体&#xff0c;因此保障大数据平台安全至关重要。那你知道大数据平台数据安全具体措施有哪些&#xff1f;有推荐的吗&#xff1f; 大数据平台数据安全具体措施有哪些&#xff1f; 1、数据…

伦敦金投资中挂单的优势

在伦敦金交易中&#xff0c;其实挂单具有无可比拟的优势&#xff1f;首先&#xff0c;如果我们不是全职的投资者&#xff0c;我们在交易时间内可能有其他的工作&#xff0c;那么挂单就可以帮助我们捕捉到市场的机会&#xff0c;即便我们不一定会坐在电脑面前&#xff0c;也可以…

Flutter 完美的验证码输入框 转载

刚开始看到这个功能的时候一定觉得so easy&#xff0c;开始的时候我也是这么觉得的&#xff0c;这还不简单&#xff0c;然而真正写的时候才发现并没有想象的那么简单。 先上图&#xff0c;不上图你们都不想看&#xff0c;我难啊&#xff0c;到Github&#xff1a; https://gith…

C语言:选择+编程(每日一练Day15)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;寻找奇数 思路一&#xff1a; 题二&#xff1a;寻找峰值 思路一&#xff1a; 本人实力有限可能对一些地方解…