当前位置: 首页 > news >正文

RK3568驱动指南|第九篇 设备模型-第95章 创建属性文件并实现读写功能实验1

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。


【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第九期_设备模型_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第95章 创建属性文件并实现读写功能实验1

本章节我们来探索如何创建具有读写功能的属性文件。属性文件通过 sysfs 文件系统提供了一种方便的方式来与内核对象进行交互。我们将深入研究一个代码示例,演示如何创建具有属性的自定义 kobject,使我们能够读取和写入值。让我们开始吧!

95.1实验程序的编写

95.1.1 驱动程序编写

本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\70_attr\module

我们编写驱动代码,该代码创建了一个自定义的 kobject,并在 sysfs 中创建了两个属性——value1和value2,允许读取和写入这些属性的值。模块的初始化函数负责创建和添加 kobject,而退出函数则负责释放相关资源。编写完成的attr.c代码如下所示:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/sysfs.h> // 自定义的kobject结构体,包含一个kobject对象和两个整型值
struct mykobj
{struct kobject kobj;int value1;int value2;
};// 定义了mykobj结构体指针变量mykobject01
struct mykobj *mykobject01;// 自定义的kobject释放函数
static void dynamic_kobj_release(struct kobject *kobj)
{struct mykobj *mykobject01 = container_of(kobj, struct mykobj, kobj);printk("kobject: (%p): %s\n", kobj, __func__);kfree(mykobject01);
}// 自定义的attribute对象value1和value2
struct attribute value1 = {.name = "value1",.mode = 0666,
};
struct attribute value2 = {.name = "value2",.mode = 0666,
};// 将attribute对象放入数组中
struct attribute *myattr[] = {&value1,&value2,NULL,
};// 自定义的show函数,用于读取属性值
ssize_t myshow(struct kobject *kobj, struct attribute *attr, char *buf)
{ssize_t count;struct mykobj *mykobject01 = container_of(kobj, struct mykobj, kobj);if (strcmp(attr->name, "value1") == 0){count = sprintf(buf, "%d\n", mykobject01->value1);}else if (strcmp(attr->name, "value2") == 0){count = sprintf(buf, "%d\n", mykobject01->value2);}else{count = 0;}return count;
}// 自定义的store函数,用于写入属性值
ssize_t mystore(struct kobject *kobj, struct attribute *attr, const char *buf, size_t size)
{struct mykobj *mykobject01 = container_of(kobj, struct mykobj, kobj);if (strcmp(attr->name, "value1") == 0){sscanf(buf, "%d\n", &mykobject01->value1);}else if (strcmp(attr->name, "value2") == 0){sscanf(buf, "%d\n", &mykobject01->value2);}return size;
}// 自定义的sysfs_ops结构体,包含show和store函数指针
struct sysfs_ops myops = {.show = myshow,.store = mystore,
};// 自定义的kobj_type结构体,包含释放函数、默认属性和sysfs_ops
static struct kobj_type mytype = {.release = dynamic_kobj_release,.default_attrs = myattr,.sysfs_ops = &myops,
};// 模块的初始化函数
static int mykobj_init(void)
{int ret;// 分配并初始化mykobject01mykobject01 = kzalloc(sizeof(struct mykobj), GFP_KERNEL);mykobject01->value1 = 1;mykobject01->value2 = 1;// 初始化并添加mykobject01到内核中,名为"mykobject01"ret = kobject_init_and_add(&mykobject01->kobj, &mytype, NULL, "%s", "mykobject01");return 0;
}// 模块的退出函数
static void mykobj_exit(void)
{// 释放mykobject01kobject_put(&mykobject01->kobj);
}module_init(mykobj_init); // 指定模块的初始化函数
module_exit(mykobj_exit); // 指定模块的退出函数MODULE_LICENSE("GPL");   // 模块使用的许可证
MODULE_AUTHOR("topeet"); // 模块的作者MODULE_LICENSE("GPL");   // 模块使用的许可证
MODULE_AUTHOR("topeet"); // 模块的作者

95.2 运行测试

95.2.1 编译驱动程序

在上一小节中的attr.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += attr.o   #此处要和你的驱动源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modules    #make操作
clean:make -C $(KDIR) M=$(PWD) clean    #make clean操作

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放attr.c和Makefile文件目录下,如下图(图95-1)所示:

图 95-1

然后使用命令“make”进行驱动的编译,编译完成如下图(图95-2)所示:

图 95-2

编译完生成attr.ko目标文件,如下图(图95-3)所示:

图 95-3

至此驱动模块就编译成功了,接下来进行测试。

95.2.2 运行测试

开发板启动之后,使用以下命令进行驱动模块的加载,如下图(图95-4)所示:

insmod attr.ko

图95-4

驱动加载之后,我们进入/sys/目录下,可以看到创建生成的myobject01,如下图所示

图95-6

我们可以使用echo和cat命令对属性值进行写入和读取,如下图所示:

图95-7

最后可以使用以下命令进行驱动的卸载,如下图(95-8)所示:

rmmod attr 

图95-8

至此,创建属性文件并实现读写功能实验就完成了。


 

相关文章:

  • 详解卡尔曼滤波(Kalman Filter)
  • vue常见面试题
  • C++:第十一讲DFS深搜
  • 后端开发——jdbc的学习(一)
  • 企业微信会话存档sdk报错:A fatal error has been detected by the Java Runtime Environment
  • 【MySQL】数据库中为什么使用B+树不用B树
  • 冒泡排序算法
  • 集群部署篇--Redis 集群动态伸缩
  • Wpf 使用 Prism 实战开发Day08
  • FTP简介及搭建计算机端口的介绍
  • 【docker】安装 Redis
  • OceanBase入选Gartner®云数据库管理系统魔力象限“荣誉提及”
  • elasticsearch系列七:聚合查询
  • Pytorch详细安装过程
  • java企业人事信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • 【刷算法】求1+2+3+...+n
  • CentOS 7 防火墙操作
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • MYSQL 的 IF 函数
  • Rancher-k8s加速安装文档
  • Sass 快速入门教程
  • session共享问题解决方案
  • Spark RDD学习: aggregate函数
  • vue-router 实现分析
  • 判断客户端类型,Android,iOS,PC
  • 浅谈web中前端模板引擎的使用
  • 微信小程序开发问题汇总
  • MPAndroidChart 教程:Y轴 YAxis
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • #if和#ifdef区别
  • #Linux(Source Insight安装及工程建立)
  • #Linux(权限管理)
  • #WEB前端(HTML属性)
  • #数学建模# 线性规划问题的Matlab求解
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (1)(1.9) MSP (version 4.2)
  • (2)nginx 安装、启停
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (三)elasticsearch 源码之启动流程分析
  • (十六)串口UART
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)库存超卖案例实战——优化redis分布式锁
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)关于pipe()的详细解析
  • (转)详解PHP处理密码的几种方式
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .form文件_一篇文章学会文件上传
  • .net refrector
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET企业级应用架构设计系列之应用服务器
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • @Documented注解的作用
  • @html.ActionLink的几种参数格式
  • []T 还是 []*T, 这是一个问题