迅为iTOP-i.MX6ULL开发板I2C驱动程序实现 I2C通信

news2024/11/25 4:22:20

在第 67.1 章节学习 i2c 的时候,我们是在应用层操作设备节点对 i2c 设备进行读写的,那么如果我们在

驱动里面对 i2c 设备进行读写要怎么办呢?本章节我们将来学习。

我们复制第 67.3 章节的代码,在此基础上进行修改。我们在应用里面对 i2c 进行读写,最重要的是对

我们数据包的封包的操作,封装了一个 i2c_rdwr_ioctl_data 数据包,才对 i2c 进行读写,同样在驱动里面,

我们也可以使用这种方法。

本章内容对应视频讲解链接(在线观看):

驱动程序实现 I2C 通信 → https://www.bilibili.com/video/BV1Vy4y1B7ta?p=47

我们对某个可读可写的寄存器进行读写操作,我们打开触摸芯片 ft5x06 的数据手册,打开 2.1 章节,如

下图所示:

完整的代码如下所示:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/i2c.h>

static struct i2c_client *ft5x06_client;

static void ft5x06_write_reg(u8 reg_addr, u8 data, u8 len);

static int ft5x06_read_reg(u8 reg_addr);

//读寄存器函数

static int ft5x06_read_reg(u8 reg_addr)

{

u8 data;

struct i2c_msg msgs[] = {

[0] = {

.addr = ft5x06_client->addr,

.flags = 0,

.len = sizeof(reg_addr),

.buf = &reg_addr,

},

[1] = {

.addr = ft5x06_client->addr,

.flags = 1,

.len = sizeof(data),

.buf = &data,

},

};

i2c_transfer(ft5x06_client->adapter, msgs, 2);

return data;

}

//写寄存器函数

static void ft5x06_write_reg(u8 reg_addr, u8 data, u8 len)

{

u8 buff[256];

struct i2c_msg msgs[] = {

[0] = {

.addr = ft5x06_client->addr,

.flags = 0,

.len = len + 1,

.buf = buff,

},

};

buff[0] = reg_addr;

memcpy(&buff[1], &data, len);

i2c_transfer(ft5x06_client->adapter, msgs, 1);

}

//与设备树的 compatible 匹配

static const struct of_device_id ft5x06_id[] = {

{.compatible = "edt,edt-ft5306", 0},

{.compatible = "edt,edt-ft5x06", 0},

{.compatible = "edt,edt-ft5406", 0},

{}};

// 无设备树的时候匹配 ID 表

static const struct i2c_device_id ft5x06_id_ts[] = {

{"xxxxx", 0},

{}};

/* i2c 驱动的 remove 函数 */

int ft5x06_remove(struct i2c_client *i2c_client)

{

return 0;

}

/* i2c 驱动的 probe 函数 */

int ft5x06_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id)

{

int ret;

printk("This is ft5x06_probe\n");

//因为我们要在别的函数里面使用 client,所以我们要把他复制出来

ft5x06_client = i2c_client;

//往地址为 0x80 的寄存器里面写入数据 0x4b

ft5x06_write_reg(0x80, 0x4b, 1);

//读出 0x80 寄存器的值

ret = ft5x06_read_reg(0x80);

//打印 0x80 寄存器的值

printk("ret is %#x\n", ret);

return 0;

}

//定义一个 i2c_driver 的结构体

static struct i2c_driver ft5x06_driver = {

.driver = {

.owner = THIS_MODULE,

.name = "ft5x06_test",

// 采用设备树的时候驱动使用的匹配表

.of_match_table = ft5x06_id,

},

.probe = ft5x06_probe,

.remove = ft5x06_remove,

.id_table = ft5x06_id_ts};

/* 驱动入口函数 */

static int ft5x06_driver_init(void)

{

int ret;

//注册 i2c_driver

ret = i2c_add_driver(&ft5x06_driver);

if (ret < 0)

{

printk(" i2c_add_driver is error \n");

return ret;

}

printk("This is ft5x06_driver_init\n");

return 0;

}

/* 驱动出口函数 */

static void ft5x06_driver_exit(void)

{

i2c_del_driver(&ft5x06_driver);

printk("This is ft5x06_driver_exit\n");

}

module_init(ft5x06_driver_init);

module_exit(ft5x06_driver_exit);

MODULE_LICENSE("GPL");

我们参考第三十九章 Linux 内核模块将刚刚编写的驱动代码编译为驱动模块,编译完如下图所示:

我们进入共享目录并且加载驱动模块,共享目录的搭建参考第三十七章 37.2.3 搭建 nfs 共享目录,

如下图所示:

如上图所示,我们可以看到读写函数是没问题的,可以对寄存器进行正常的读写操作。

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

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

相关文章

gis几种常用插值介绍

反距离权重法&#xff08;距离加权法&#xff09;简称IDW&#xff1a; 这个方法的原理简单来说就是插值点距离已知点的距离越远受影响的程度越低&#xff0c;下图中的黄点为已知点&#xff0c;红点为插值点&#xff0c;那这个距离是如何控制的&#xff1f; 反距离权重法主要依…

基于SGM431的电路设计问题分析

本案例中,采用SGM431芯片设计了一个过压保护电路。 这个电路初次设计,有很多的问题,下面逐一分析 1.当输入24V,测得Vref=1.59V。Vout为1.15V;,mos管关断 2。经过多次测量发现,临界值在10V到10.5之间; 当输入10.5V时,测量Vref=1.69V。vout=1.15V;mos管关断 当输入1…

存储过程批量修改数据库中部分表中的ip信息

一、背景 项目中涉及到环境迁移&#xff0c;迁移过程中&#xff0c;原来的数据库&#xff08;oracle&#xff09;中应用ip和数据库ip地址均未变更&#xff0c;每次都是手动修改&#xff0c;想通过存储过程快捷执行 二、修改目标&#xff1a; 把相关几个表格的ip地址变更为其…

flink日志实时采集写入Kafka/ElasticSearch

目录 背景注意点自定义Appenderlog4j配置文件启动脚本实现效果 背景 由于公司想要基于flink的日志做实时预警功能&#xff0c;故需要实时接入&#xff0c;并刷入es进行分析。 注意点 日志接入必须异步&#xff0c;不能影响服务性能 kafka集群宕机&#xff0c;依旧能够提交f…

我们公司的面试,有点不一样!

我们公司的面试&#xff0c;有点不一样&#xff01; 朋友们周末愉快&#xff0c;我是鱼皮。因为我很屑&#xff0c;所以大家也可以叫我屑老板。 自从我发了自己创业的文章和视频后&#xff0c;收到了很多小伙伴们的祝福&#xff0c;真心非常感谢&#xff01; 不得不说&#…

如何写出CPU友好的代码,百倍提升性能?

作者&#xff1a;王再军 不管是什么样的数据&#xff0c;投其所好&#xff0c;才能够优化代码性能。本文将用一个实际用例为大家分享如何通过用心组织的代码来提升性能。 一、出现性能差别的代码 CPU友好的代码与我们平时的那些CRUD操作可能没什么关系。但是用心组织的代码其实…

开源模型ModelScope的初探使用

泛AI开发者的一站式模型服务产品平台 阿里继续沿用它的平台思维&#xff0c;搞了这个ModelScope训练模型平台&#xff0c;一边开源一部分模型&#xff0c;一边在阿里云上卖自己的付费版&#xff0c;套路依旧没变&#xff0c;不过对AI相关模型感兴趣的同学&#xff0c;想做业务…

202303最新各大厂大数据核心面试题

1、 字节、阿里、拼多多、中移杭研、海亮等:Hive做过哪些实际优化?必须结合实际项目来谈,结合我实际离线数仓里做的优化? 本人回答: 1.小文件的优化(解决方法是combineHiveinput、merge、jvm重用等) 2.数据倾斜的优化:

Flutter 小技巧之横竖列表的自适应大小布局支持

今天这个主题看着是不是有点抽象&#xff1f;又是列表嵌套&#xff1f;之前不是分享过《 ListView 和 PageView 的各种花式嵌套》了么&#xff1f;那这次的自适应大小布局支持有什么不同&#xff1f; 算是某些奇特的场景下才会需要。 首先我们看下面这段代码&#xff0c;基本逻…

android studio EditText用法

1.自定义文本框 选中状态&#xff1a; <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android"><!--指定形状内部颜色--><solid android:color"#ffffff"&g…

机器学习在生态、环境经济学中的实践技术应用及论文写作

近年来&#xff0c;人工智能领域已经取得突破性进展&#xff0c;对经济社会各个领域都产生了重大影响&#xff0c;结合了统计学、数据科学和计算机科学的机器学习是人工智能的主流方向之一&#xff0c;目前也在飞快的融入计量经济学研究。表面上机器学习通常使用大数据&#xf…

点了下链接信息就泄露了,ta们是怎么做到的?

随着互联网的普及以及一系列可供上网设备的快速发展&#xff0c;截止2022年12月&#xff0c;中国网民规模达10.37亿&#xff0c;较之2021年12月增长3549万&#xff0c;互联网普及率达75.6%&#xff1b;在这么庞大的数据背后又有多少用户的个人信息被泄露呢? 一、信息泄露常见场…

2023 年最全面的 DevOps 工具列表,你用过几个?

在软件开发领域&#xff0c;DevOps已经成为越来越重要的概念。它强调了开发、测试、运维等各个环节之间的协作和自动化&#xff0c;以提高软件交付的速度和质量。随着时间的推移&#xff0c;DevOps所涉及的工具也不断更新和演进。本文将介绍一个预计在 2023 年最全面的 DevOps …

elementui中使用响应式布局实现五个盒子一行的适配

一、使用elementui中的自定义标签 自定义标签之后&#xff0c;浏览器中的css样式会出现这个类名 <el-row :gutter"30" class"row-bg"><el-col:xs"8":sm"6":md"4":lg"{ span: 24-5 }"class"headerC…

开发框架Furion之Winform+SqlSugar

目录 1.开发环境 2.项目搭建 2.1 创建WinFrom主项目 2.2 创建子项目 2.3 实体类库基础类信息配置 2.3.1 Nuget包及项目引用 2.3.2 实体基类创建 2.4 仓储业务类库基础配置 2.4.1 Nuget包及项目引用 2.4.2 Dtos实体 2.4.3 仓储基类 2.5 service注册类库基础配置 2…

【图形数据库】Neo4j简介及应用场景

文章目录 1.什么是Neo4j?2.图形数据结构3.Neo4j应用场景3.1我们可以将图领域划分成以下两部分&#xff1a;3.2目前&#xff0c;业内已经有了相对比较成熟的基于图数据库的解决方案&#xff0c;大致可以分为以下几类。3.2.1金融行业应用3.2.2社交网络图谱3.2.3企业关系图谱 总结…

Linux进程通信:存储映射mmap

1. 存储映射是什么&#xff1f; 如上图&#xff0c;存储映射是将块设备的文件映射到进程的虚拟地址空间。之后&#xff0c;进程可以直接使用指针操作其地址空间中映射的文件&#xff0c;对这块映射区操作就相当于操作文件。 2. 存储映射函数mmap的简单使用 &#xff08;1&…

网络安全岗位面试题大全:解析各个分支岗位的面试题目,帮助你上岸大厂

网络安全是一个广泛的领域&#xff0c;涵盖了许多不同的岗位和分支。我整理了网络安全各个岗位分支的面试题目&#xff1a; 安全工程师/系统管理员 您如何确保网络系统的安全性和保密性&#xff1f;您采用了哪些技术和工具&#xff1f;请描述一下您在过去工作中遇到的最具挑战…

C++ -5- 内存管理

文章目录 C语言和C内存管理的区别示例1. C/C 中程序内存区域划分2. C中动态内存管理3.operator new 与 operator delete 函数4.new 和 delete 的实现原理5.定位new表达式 C语言和C内存管理的区别示例 //C语言&#xff1a; struct SListNode {int data;struct SListNode* next; …

什么是内存?什么是内存逃逸?怎么做内存逃逸分析

内存 平时我们在电脑上听歌&#xff0c;聊天&#xff0c;或者启动某个程序&#xff0c;那么这个启动过程&#xff0c;其实就是把程序从硬盘读入到内存中去。就像安卓手机&#xff0c;内存不够了很卡&#xff0c;杀掉几个软件&#xff0c;内存就升上来了。但也不是所有的程序都…