IIC子系统之控制器(Adapter)驱动开发实例
创建一条虚拟的 I2C 总线定义总线怎么收发数据写i2cset -f -y 3 0x50 0 0x55 ( 往第三条I2C总线的0x50地址写入0x55)读i2cget -f -y 3 0x50 0#include linux/completion.h #include linux/debugfs.h #include linux/delay.h #include linux/gpio/consumer.h #include linux/i2c-algo-bit.h #include linux/i2c.h #include linux/init.h #include linux/interrupt.h #include linux/module.h #include linux/of.h #include linux/platform_data/i2c-gpio.h #include linux/platform_device.h #include linux/slab.h // 先定义一个i2c_adapter的全局变量后面在probe函数中分配和注册这个i2c_adapter static struct i2c_adapter *g_adapter; // 模拟一个eeprom设备地址为0x50容量为512字节 static unsigned char eeprom_buffer[512]; static int eeprom_cur_addr 0; static void eeprom_emulate_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int i; if (msg-flags I2C_M_RD) { // 读操作从eeprom_buffer中读取数据到msg-buf中 for (i 0; i msg-len; i) { msg-buf[i] eeprom_buffer[eeprom_cur_addr]; if (eeprom_cur_addr 512) eeprom_cur_addr 0; } } else { // 写操作从msg-buf中写数据到eeprom_buffer中 if (msg-len 1) { eeprom_cur_addr msg-buf[0]; for (i 1; i msg-len; i) { eeprom_buffer[eeprom_cur_addr] msg-buf[i]; if (eeprom_cur_addr 512) eeprom_cur_addr 0; } } } } static int i2c_bus_virtual_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { int i; // emulate eeprom , addr 0x50 for (i 0; i num; i) { if (msgs[i].addr 0x50) // 对输入的指令解析若有0x50则进行EEPROM的读写模拟 { eeprom_emulate_xfer(i2c_adap, msgs[i]); } else { i -EIO; break; } } return i; } static u32 i2c_bus_virtual_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_PROTOCOL_MANGLING; } // I2C虚拟总线算法 const struct i2c_algorithm i2c_bus_virtual_algo { .master_xfer i2c_bus_virtual_master_xfer, .functionality i2c_bus_virtual_func, }; // 3. probe函数 static int i2c_bus_virtual_probe(struct platform_device *pdev) { /* get info from device tree, to set i2c_adapter/hardware */ /* alloc, set, register i2c_adapter */ /* 分配设置注册一个 i2c_adapter*/ g_adapter kzalloc(sizeof(*g_adapter), GFP_KERNEL); g_adapter-owner THIS_MODULE; g_adapter-class I2C_CLASS_HWMON | I2C_CLASS_SPD; g_adapter-nr -1; // -1表示让系统自动分配 snprintf(g_adapter-name, sizeof(g_adapter-name), i2c-bus-virtual); g_adapter-algo i2c_bus_virtual_algo; // 编写这个algorithm // 注册这个i2c_adapter到i2c核心注册成功后这个i2c_adapter就可以被用户空间访问 i2c_add_adapter(g_adapter); // i2c_add_numbered_adapter(g_adapter); return 0; } // remove函数 static int i2c_bus_virtual_remove(struct platform_device *pdev) { // 清除 adapter i2c_del_adapter(g_adapter); return 0; } // 和设备树中的 compatible 匹配即compatible 100ask,i2c-bus-virtual一旦匹配成功就调用platform_driver中的probe函数 static const struct of_device_id i2c_bus_virtual_dt_ids[] { { .compatible 100ask,i2c-bus-virtual, }, { /* sentinel */ } }; // 2. platform_driver结构体 static struct platform_driver i2c_bus_virtual_driver { .driver { .name i2c-gpio, .of_match_table of_match_ptr(i2c_bus_virtual_dt_ids), }, .probe i2c_bus_virtual_probe, .remove i2c_bus_virtual_remove, }; // 入口函数-和出口函数对应 static int __init i2c_bus_virtual_init(void) { int ret; ret platform_driver_register(i2c_bus_virtual_driver); // 注册一个platform_driver if (ret) printk(KERN_ERR i2c-gpio: probe failed: %d\n, ret); return ret; } module_init(i2c_bus_virtual_init); // 出口函数 static void __exit i2c_bus_virtual_exit(void) { platform_driver_unregister(i2c_bus_virtual_driver); } module_exit(i2c_bus_virtual_exit); MODULE_AUTHOR(www.100ask.net); MODULE_LICENSE(GPL);

相关新闻

5分钟从零开始:小熊猫Dev-C++让C++编程学习变得如此简单

5分钟从零开始:小熊猫Dev-C++让C++编程学习变得如此简单

5分钟从零开始:小熊猫Dev-C让C编程学习变得如此简单 【免费下载链接】Dev-CPP A greatly improved Dev-Cpp 项目地址: https://gitcode.com/gh_mirrors/dev/Dev-CPP 你是否曾因为复杂的开发环境配置而放弃学习C编程?是否在安装编译器、配置环境变…

2026/10/17 15:52:34 阅读更多 →
关于图论【最短路径之Floyd 算法|卡码网97.小明逛公园的思考】

关于图论【最短路径之Floyd 算法|卡码网97.小明逛公园的思考】

目录 一、本题题目 二、本题代码 三、关键思路 四、注意事项 一、本题题目 二、本题代码 // 展示完整代码 三、关键思路 1、Floyd和动态规划结合 2、三维数组,dp[i][j][k] 3、遍历顺序,先遍历k 四、注意事项 1、用邻接矩阵存无向图的时候要注意s…

2026/10/18 9:24:05 阅读更多 →
C++ std::function 解读

C++ std::function 解读

前言:std::function大家用过吗?它是C11引入的一个新特性。今天,我们从原理、应用实例等方面对std::fucntion进行深度剖析。 目录 一、基本定义与使用 二、底层机制 三、典型应用场景 一、基本定义与使用 std::function是一种多态函数包装…

2026/10/18 9:24:38 阅读更多 →

最新新闻

open-code-review:可审计、可干预的开源代码审查框架

open-code-review:可审计、可干预的开源代码审查框架

1. 这不是又一个“AI代码审查工具”,而是开发者自己掌控审查权的起点“open-code-review”这个项目名乍看平平无奇,甚至有点像某个被遗忘在GitHub角落的冷门仓库——没有炫酷的UI,不提“秒级修复”,也不承诺“零Bug交付”。但如果…

2026/10/19 0:31:03 阅读更多 →
Hermes Agent 中 Skills 与 Tools 的关系分析:从 TaoToken 统一 Key 通道看能力编排

Hermes Agent 中 Skills 与 Tools 的关系分析:从 TaoToken 统一 Key 通道看能力编排

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:31:03 阅读更多 →
【AI】codex 使用教程:从 AGENTS.md 到 skills 的完整配置指南

【AI】codex 使用教程:从 AGENTS.md 到 skills 的完整配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:29:02 阅读更多 →
DeepThink V1.1.0 开源发布:用 TaoToken 统一 Key 打造个人 AI 操作系统,全自主托管跑通超复杂长程任务

DeepThink V1.1.0 开源发布:用 TaoToken 统一 Key 打造个人 AI 操作系统,全自主托管跑通超复杂长程任务

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:28:02 阅读更多 →
优秀的大模型API网关系统Veloera:Docker部署与TaoToken统一Key接入实践

优秀的大模型API网关系统Veloera:Docker部署与TaoToken统一Key接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:28:02 阅读更多 →
Java批量重命名命令行工具:正则匹配与安全校验实战

Java批量重命名命令行工具:正则匹配与安全校验实战

简介:针对Java文件批量重命名的源码包,面向日常开发中需要整理大量文件的Java程序员,提供一套简单直接的解决方案;整个资源为一个压缩包,体积仅1KB,内含1个Java源文件,代码结构紧凑,…

2026/10/19 0:28:02 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →