RK3568驱动指南|第十五篇 I2C-第172章 I2C 驱动框架编写

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


【公众号】迅为电子

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

【视频观看】嵌入式学习之Linux驱动(第十五篇 I2C_全新升级)_基于RK3568

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


第172章I2C 驱动框架编写

在上一个章节中,讲解了I2C Client设备树的编写,在I2C控制器节点中添加了FT5X06触摸芯片对应的节点,接下来将开始一步步完善I2C驱动程序,首先在本章节中将会完善I2C驱动框架,注册一个最简单的I2C驱动设备,并匹配上一章节中编写的设备树,在后面的章节中将会逐步对该驱动程序进行内容的填充。

171.1 注册I2C设备

I2C设备的注册使用的函数为i2c_add_driver,被定义在内核源码的“include/linux/i2c.h”目录下,具体内容如下所示:

#define i2c_add_driver(driver) \
	i2c_register_driver(THIS_MODULE, driver)

可以看到i2c_add_driver是一个宏定义,这个宏定义的作用是为了简化注册 I2C 设备驱动程序的过程,实际注册I2C设备的函数为i2c_register_driver,该函数定义在“drivers/i2c/i2c-core-base.c”文件中,具体内容如下所示:

int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
    int res;

    /* 在驱动模型初始化完成之前,无法注册驱动程序 */
    if (WARN_ON(!is_registered))
        return -EAGAIN;

    /* 将驱动程序添加到驱动核心的 i2c 驱动列表中 */
    driver->driver.owner = owner;
    driver->driver.bus = &i2c_bus_type;
    INIT_LIST_HEAD(&driver->clients);

    /* 当注册返回时,驱动核心会为所有匹配但尚未绑定的设备调用 probe() 函数 */
    res = driver_register(&driver->driver);
    if (res)
        return res;

    pr_debug("driver [%s] registered\n", driver->driver.name);

    /* 遍历所有已经存在的适配器 */
    i2c_for_each_dev(driver, __process_new_driver);

    return 0;
}

该函数的主要作用是将 I2C 设备驱动程序注册到驱动核心中,并初始化相关数据结构,这里传入的数据结构类型为i2c_driver,需要我们在驱动程序编写的时候进行填充,该结构体定义在“include/linux/i2c.h”头文件中,具体内容如下所示:

struct i2c_driver {
    unsigned int class;  // 驱动程序所属的设备类型

   int (*probe)(struct i2c_client *, const struct i2c_device_id *); // 探测并绑定设备的回调函数
    int (*remove)(struct i2c_client *); // 从设备上解绑驱动程序的回调函数
    int (*probe_new)(struct i2c_client *); // 新的探测设备并绑定的回调函数
    void (*shutdown)(struct i2c_client *); // 设备关闭时调用的回调函数
    void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol,
               unsigned int data); // 设备报警时调用的回调函数,格式和含义取决于所使用的协议
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); // 用于执行设备特定功能的命令回调函数
    struct device_driver driver; // 设备驱动程序基础结构
    const struct i2c_device_id *id_table; // 与该驱动程序匹配的设备 ID 表
    int (*detect)(struct i2c_client *, struct i2c_board_info *); // 用于自动创建设备的探测回调函数
    const unsigned short *address_list; // 与该驱动程序匹配的设备地址列表
    struct list_head clients; // 与该驱动程序绑定的 I2C 设备列表
    bool disable_i2c_core_irq_mapping; // 禁用 I2C 核心中断映射的标志
};

在调用i2c_add_driver函数注册I2C设备之前,需要先填充i2c_driver结构体,然后实现的各种回调函数,跟前面讲解的平台总线内容相同。

171.2驱动程序的编写

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

本实验旨在搭建最简单的I2C驱动程序框架,申请注册一个I2C设备,所以只填充了最简单的probe初始化函数和remove移除函数,在后面的章节中会对该驱动程序进行填充。

编写完成的ft5x06_driver.c代码如下所示:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of_device.h>

// ft5x06设备的初始化函数
int ft5x06_probe(struct i2c_client *client, const struct i2c_device_id *id) {
    printk("This is ft5x06 probe\n");
    return 0;
}

// ft5x06设备的移除函数
int ft5x06_remove(struct i2c_client *client) {
    return 0;
}

// 设备树匹配表
static const struct of_device_id ft5x06_id[] = {
    { .compatible = "my-ft5x06" },
    { }, 
};

// ft5x06设备驱动结构体
static struct i2c_driver ft5x06_driver = {
    .driver = {
        .owner = THIS_MODULE,
        .name = "my-ft5x06",
        .of_match_table = ft5x06_id, // 添加设备树匹配表
    },    
    .probe = ft5x06_probe,
    .remove = ft5x06_remove,    
};

// 驱动初始化函数
static int __init ft5x06_driver_init(void) {
    int ret;
    // 注册I2C设备驱动
    ret = i2c_add_driver(&ft5x06_driver);
    if (ret < 0) {
        printk("i2c_add_driver is error\n");
        return ret;
    }
    return 0;
}

// 驱动退出函数
static void __exit ft5x06_driver_exit(void) {
    // 注销I2C设备驱动
    i2c_del_driver(&ft5x06_driver);
}

module_init(ft5x06_driver_init);
module_exit(ft5x06_driver_exit);
MODULE_LICENSE("GPL");

171.3 运行测试

171.3.1 编译驱动程序

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

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += ft5x06_driver.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的内容注释已在上图添加,保存退出之后,来到存放platform_driver.c和Makefile文件目录下,如下图所示:

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

编译完生成ft5x06_driver.ko目标文件,如下图所示:

至此驱动模块就编译成功了。

171.3.2 运行测试

在进行实验之前,首先要确保开发板烧写的是我们在170.3小节中编译出来的boot.img。开发板启动之后,首先进入到“/proc/device-tree/i2c@fe5a0000/”目录下确保存在 my-ft5x06@38目录,如下图所示:

只有在设备树节点编写正确的前提下,这里才会生成my-ft5x06@38目录,如果没有出现my-ft5x06@38目录就要回头检查看看了。

然后使用以下命令进行驱动模块的加载,如下图所示:

insmod ft5x06_driver.ko

可以看到成功打印了在probe函数中的打印,证明我们添加的设备树节点和ft5x06_driver驱动匹配成功了。

然后使用以下命令进行驱动模块的卸载,如下图所示:

rmmod ft5x06_driver.ko

由于没有在remove卸载函数中添加打印相关内容,所以使用rmmod命令卸载驱动之后,没有任何打印,至此,最简单的I2C驱动实验就完成了。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

吃瓜Llama3-V之余,看多模态大模型架构演变!

今天最大的瓜莫过于&#xff1a;斯坦福 Llama3-V PK 清华 MiniCPM-Llama3-V-2.5&#xff0c;详细证据&#xff1a; https://github.com/OpenBMB/MiniCPM-V/issues/196吃瓜之余&#xff0c;来看一下多模态大模型架构演变&#xff01; 一篇优秀的论文综述了多模态AI架构——包含…

无线领夹麦克风哪个牌子好,口碑最好的麦克风品牌推荐!

自媒体的兴起极大地推动了音频设备技术的发展&#xff0c;尤其是麦克风&#xff0c;它已成为自媒体创作中不可或缺的工具。从早期的新闻采访到当下流行的网络直播和Vlog&#xff0c;麦克风的应用场景不断扩展。一个视频的音频质量直接影响观众的观看体验&#xff0c;因此&#…

使用Netty框架实现WebSocket服务端与客户端通信(附ssl)

仓库地址&#xff1a; https://gitee.com/lfw1024/netty-websocket 导入后可直接运行 预览页面 自签证书&#xff1a; #换成自己的本地ip keytool -genkey -alias server -keyalg RSA -validity 3650 -keystore D:\mystore.jks -ext sanip:192.168.3.7,ip:127.0.0.1,dns:lo…

【存储】相关内容

【存储】相关内容 1. 存储类型1. 块存储2. 文件存储3. 对象存储4. 三种存储类型对比 2. 常见的存储分类1. DAS2. SAN3. NAS4. 存储分类分析比较 3. 一些存储的概念1. LUN2. volume3. HBA4. iSCSI 1. 存储类型 块存储和文件存储是我们比较熟悉的两种主流的存储类型&#xff0c;…

《昇思25天学习打卡营第21天 | 昇思MindSporePix2Pix实现图像转换》

21天 本节学习了通过Pix2Pix实现图像转换。 Pix2Pix是基于条件生成对抗网络&#xff08;cGAN&#xff09;实现的一种深度学习图像转换模型。可以实现语义/标签到真实图片、灰度图到彩色图、航空图到地图、白天到黑夜、线稿图到实物图的转换。Pix2Pix是将cGAN应用于有监督的图…

JavaSE--基础语法--类和对象(第二期)

&#xff08;一&#xff09;.面向对象的初步认知 1.1什么是面向对象&#xff1f; Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象…

新手使用超市收银系统应该注意哪些问题?

大部分小型超市都没怎么使用过智能收银系统&#xff0c;都是采用的传统手工收银方式&#xff0c;盘点、进货、库存也都是靠手工记录&#xff0c;完全没有接触过智能收银系统带来的优势和便利。超市收银软件特别是小区里面的超市&#xff0c;就跟传统的夫妻便利店的营销模式差不…

教育心理学期末考试重点

人本主义学习理论 人本主义主张&#xff0c;心理学应当把人作为一个整体来研究&#xff0c;而不是将人的心理肢解为不完整的几个部分&#xff0c;应该研究正常的人&#xff0c;而且更应该关注人的高级心理活动&#xff0c;如热情、信念、生命、尊严等内容。人本主义的学习理论…

【C++】使用C++在线程中动态记录数据到外部文件

在现代软件开发中&#xff0c;多线程编程已成为处理并发任务、提高程序性能的重要手段。而在多线程环境下&#xff0c;如何有效地管理和记录数据&#xff0c;尤其是将动态生成的数据安全地写入外部文件&#xff0c;是许多应用程序必须面对的问题。本文将深入探讨如何在C中使用多…

【运维】Windows server 2022 开启 telnet 功能

控制面板》启动或关闭Windows 功能 仪表盘》添加角色和功能》功能》telnet客户端

python-糖果俱乐部(赛氪OJ)

[题目描述] 为了庆祝“华为杯”的举办&#xff0c;校园中开展了许多有趣的热身小活动。小理听到这个消息非常激动&#xff0c;他赶忙去参加了糖果俱乐部的活动。 该活动的规则是这样的&#xff1a;摊位上有 n 堆糖果&#xff0c;第 i 堆糖果有 ai​ 个&#xff0c;参与的同学可…

全平台7合一自定义小程序源码系统功能强大 前后端分离 带完整的安装代码包以及搭建教程

系统概述 这款全平台 7 合一自定义小程序源码系统是专为满足各种业务需求而设计的。它整合了多种功能&#xff0c;能够在不同平台上运行&#xff0c;为用户提供了全方位的体验。无论你是企业主、开发者还是创业者&#xff0c;这款系统都能为你提供强大的支持。 代码示例 系统…

MATLAB code 生成C代码样式

Matlab code 生成C代码需要以下产品&#xff1a; MATLABMATLAB CoderC 编译器 MATLAB Coder 将查找并使用支持的已安装编译器。 可以使用 mex -setup 更改默认编译器。 在本地工作文件夹中创建文件 创建一个本地工作文件夹&#xff0c;例如 c:\ecoder\work。创建包含以下代…

【Python】Python的安装与环境搭建

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言Python下载环境配置测试环境变量是否配置成功配置环境变量 运行Python交互式解释器&#xff1a;命令行脚本集成开发环境&#xff08;IDE&#xff1a;Integrated Development E…

电脑IP地址自动获取:操作指南与优势分析

在数字化时代&#xff0c;网络连接已成为我们日常生活和工作中的重要组成部分。而在建立网络连接的过程中&#xff0c;IP地址的设置无疑是至关重要的一环。IP地址&#xff0c;作为网络设备的唯一标识&#xff0c;其设置方式直接影响到网络的稳定性和安全性。本文将详细介绍如何…

大数据、人工智能、云计算、物联网、区块链序言【大数据导论】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 本篇序言前 必看 【大数据导论】—大数据序言 这是…

山东益康,聚焦绿葆医院场景媒体,用爱服务人类健康

山东益康集团创建于1983年&#xff0c;发展成为集药品研发生产、销售、特医功能食品、精细化工、医疗防护产品等多产业经营为一体的省级企业集团。益康集团紧跟国家发展战略&#xff0c;满足民众日益增长的健康需求&#xff0c;将食品生产向特医保健功能食品转型升级&#xff0…

校园兼职小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商家管理&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;兼职管理&#xff0c;论坛管理&#xff0c;公告管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告&#xff0c;兼职&…

【TS】TypeScript 入门指南:强大的JavaScript超集

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 TypeScript 入门指南&#xff1a;强大的JavaScript超集一、TypeScript 简介1.1 …

【Python】已解决:ValueError: If using all scalar values, you must pass an index

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ValueError: If using all scalar values, you must pass an index 一、分析问题背景 在Python编程中&#xff0c;尤其是当使用pandas库进行数据分析和处理时&a…