rk平台i2c学习小结

一口Linux 2025-02-19 11:50


击左上方蓝色“一口Linux”,选择“设为星标

第一时间看干货文章 

【干货】嵌入式驱动工程师学习路线
【干货】Linux嵌入式知识点-思维导图-免费获取
【就业】一个可以写到简历的基于Linux物联网综合项目
【就业】找工作简历模版


图片


作者:csdn  小虾米的Daddy

本篇我们以 RK 板的 IIC 控制器为例,先讲解 Linux 下的 IIC 驱动框架。

设备树创建 i2c 设备的节点,在设备树遍历时会创建一个 i2c 的 platform 设备出来:

     i2c@fdd40000 {         compatible = "rockchip,rk3399-i2c";         reg = <0x00 0xfdd40000 0x00 0x1000>;         clocks = <0x32 0x07 0x32 0x2d>;         clock-names = "i2c\0pclk";         interrupts = <0x00 0x2e 0x04>;         pinctrl-names = "default";         pinctrl-0 = <0x35>;         #address-cells = <0x01>;         #size-cells = <0x00>;         status = "okay";         phandle = <0x17a>;     }

备包含如下信息:

  • compatible:兼容性,用于匹配可以用于该设备的驱动;

  • reg:该设备的寄存器基地址和范围;

  • interrupts:i2c 中断控制器使用的中断配置;

这个 platform device 在被放入平台总线时,会匹配对应的 platform driver,那么先来看一下 platform bus 是什么

 struct bus_type platform_bus_type = { .name= "platform", .dev_groups= platform_dev_groups, .match= platform_match, .uevent= platform_uevent, .dma_configure= platform_dma_configure, .pm= &platform_dev_pm_ops, };

们只关注其中的 match 函数,它是当一个新的设备或者一个新的驱动被添加到该总线时会被调用的匹配函数,当一个新的设备被加入时,使用 match 来匹配对应的驱动,当一个新的驱动被添加到该总线时,也会使用这个 match 来匹配设备。

我们以 rk 板的 i2c 平台总线驱动为例,首先我们找到 rk 板的 i2c 平台总线驱动

 static struct platform_driver rk3x_i2c_driver = { .probe   = rk3x_i2c_probe, .remove  = rk3x_i2c_remove, .driver  = { .name  = "rk3x-i2c", .of_match_table = rk3x_i2c_match, .pm = &rk3x_i2c_pm_ops, }, };

使用of_match_table 来匹配对应的的设备,使用probe 来初始化设备。

整体流程如下


在深入分析 IIC 的驱动代码前,先简单看一下 IIC 的整个数据发送和接受流程,这里不会涉及底层硬件的时序,需要读者自己去学习。

IIC 主机向从机写数据:

IIC 主机向从机读数据:

然IIC的发送接收不止上述两种模式,这里只讨论常用的两种发送和接收数据的方法。

然后我们开始分析 IIC platform driver 的代码了:

我们以 RK board 为例,其总线驱动代码在:drivers\i2c\busses\i2c-rk3x.c 中,具体实现可以参考我之前的文章,这里只给出一个整体框图。最终 i2c 的控制器也会以字符设备节点暴露给用户态,我们可以通过 i2c 控制器的字符设备给相应的 i2c 外设通信。


然后看一下用户层打开一个 i2c 控制器对应的字符设备节点的整体流程图:


整个流程如下:

当应用程序打开一个设备文件时,通过系统调用 sys_open 进入内核,

在内核空间中由 do_sys_open 负责发起整个设备文件的打开操作,

首先获得该设备文件所对应的 inode,然后调用其中的 i_fop 函数,对字符设备而言,i_fop 函数就是 chrdev_open,

后者通过 inode 中的 i_rdev 成员在 cdev_map 中查找该设备所对应的设备对象 cdev,

在成功找到了该设备对象后,将 inode 的 cdev 成员指向该字符设备对象,这样下次再对该设备文件节点进行打开操作时,就可以直接通过 i_cdev 成员得到设备节点所对应的字符设备对象了。

内核在每次打开一个设备文件时,会产生一个整形的文件描述符 fd 和一个新的 struct file 对象 filp 来跟踪对该文件的这一次操作,

在打开设备文件时,内核会将 filp 和 fd 关联起来,同时会将 cdev 中的 ops 赋值给 filp->f_op,同时创建 i2c_client,关联 i2c_adapter,并将 filp 的 private_data 和 i2_client 关联起来。

最后 sys_open 系统调用将设备文件描述符 fd 返回到用户空间。

接下来用一个实际的例子去理解一下 IIC 的完成一次 Combined R/W 的流程:

用户侧示例代码如下

 
int main(void){     int fd = 0;     int ret = 0;      const char *path_name ="/dev/i2c-0";     uint8_t buf[8] = {0};     uint8_t start_reg = 0x0;      struct i2c_msg read_msg[2] = {         {             0x20,               /* slave addr */             0,                  /* operate flags */             1,                  /* data len */             &start_reg          /* data buf */         },            {             0x20,               /* slave addr */             I2C_M_RD,           /* operate flags */             8,                  /* data len */             &buf[0]   /* data buf */         },     };      struct i2c_rdwr_ioctl_data rdwr = {         .msgs = read_msg,         .nmsgs = 2     };      fd  = open(path_name, O_RDWR);     ret = ioctl(fd, I2C_SLAVE_FORCE, 0x20);     ret = ioctl(fd, I2C_RDWR, (unsigned long)&rdwr);     return 0; }

是一次 Combined 的从机数据读取操作,由两部分i2c_msg 组成,第一个 msg 向从机写设备寄存器地址,表示要读取的设备寄存器,然后再发送读数据请求,向从机请求 8 个字节的 data。

对应整个 IIC 的协议段如下:


然后我们通过 ioctl 进入内核,并最终调用 i2cdev_fops->i2cdev_ioctl。

 
static const struct file_operations i2cdev_fops = { ...     .compat_ioctl= compat_i2cdev_ioctl,     ... };  static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct i2c_client *client = file->private_data;     ... switch (cmd) {     ...  case I2C_RDWR: {         ... return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); }     ... return 0; }  static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, unsigned nmsgs, struct i2c_msg *msgs) {     ... res = i2c_transfer(client->adapter, msgs, nmsgs);     ... return res; }  int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) {     ... ret = __i2c_transfer(adap, msgs, num); return ret; }  int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) {     ... ret = adap->algo->master_xfer(adap, msgs, num);     ... return ret; }

可以看到最后就是调用了i2c_adapter 中的master_xfer。


 
static int rk3x_i2c_xfer(struct i2c_adapter *adap,  struct i2c_msg *msgs, int num) { struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;     ... for (i = 0; i < num; i += ret) { ret = rk3x_i2c_setup(i2c, msgs + i, num - i);         ... rk3x_i2c_start(i2c);         ... }     ... }

rk3x_i2c_xfer 中初始化MRXADDR 和 MRXRADDR 寄存器并初始化 i2c 的初始化状态机状态。

然后通过rk3x_i2c_start 发送 start 信号开始 i2c 的整个流程,并在rk3x_i2c_irq 中维护整个 i2c 数据发送和接受的状态机:

 
static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) {     ... switch (i2c->state) { case STATE_START: rk3x_i2c_handle_start(i2c, ipd); break; case STATE_WRITE: rk3x_i2c_handle_write(i2c, ipd); break; case STATE_READ: rk3x_i2c_handle_read(i2c, ipd); break; case STATE_STOP: rk3x_i2c_handle_stop(i2c, ipd); break; case STATE_IDLE: break;   }     ... }

在 Combined W/R 模式下的流程图和状态机如下所示:

流程图:


IIC 驱动状态机:

到这里我们简单的介绍了Linux下的IIC驱动框架和其工作流程,如果要深入理解还需自己阅读驱动代码

原文链接:https://blog.csdn.net/cxjczy1990/article/details/144853176

end



一口Linux 


关注,回复【1024】海量Linux资料赠送


精彩文章合集

文章推荐

【专辑】ARM
【专辑】粉丝问答
【专辑】所有原创
专辑linux入门
专辑计算机网络
专辑Linux驱动
【干货】嵌入式驱动工程师学习路线
【干货】Linux嵌入式所有知识点-思维导图

一口Linux 写点代码,写点人生!
评论 (0)
  •        当今社会已经步入了知识经济的时代,信息大爆炸,新鲜事物层出不穷,科技发展更是一日千里。知识经济时代以知识为核心生产要素,通过创新驱动和人力资本的高效运转推动社会经济发展。知识产权(IP)应运而生,成为了知识经济时代竞争的核心要素,知识产权(Intellectual Property,IP)是指法律赋予人们对‌智力创造成果和商业标识等无形财产‌所享有的专有权利。其核心目的是通过保护创新和创意,激励技术进步、文化繁荣和公平竞争,同时平衡公共利益与
    广州铁金刚 2025-03-24 10:46 75浏览
  • 在嵌入式语音系统的开发过程中,广州唯创电子推出的WT588系列语音芯片凭借其优异的音质表现和灵活的编程特性,广泛应用于智能终端、工业控制、消费电子等领域。作为该系列芯片的关键状态指示信号,BUSY引脚的设计处理直接影响着系统交互的可靠性和功能拓展性。本文将从电路原理、应用场景、设计策略三个维度,深入解析BUSY引脚的技术特性及其工程实践要点。一、BUSY引脚工作原理与信号特性1.1 电气参数电平标准:输出3.3V TTL电平(与VDD同源)驱动能力:典型值±8mA(可直接驱动LED)响应延迟:语
    广州唯创电子 2025-03-26 09:26 73浏览
  • 无论你是刚步入职场的新人,还是已经有几年经验的职场老手,培养领导力都是职业发展中一个至关重要的环节。拥有良好的领导能力不仅能让你从人群中脱颖而出,也能让你在团队中成为一个值得信赖、富有影响力的核心成员。什么是领导力?领导力并不仅仅意味着“当老板”或者“发号施令”。它更多地是一种能够影响他人、激发团队潜能,并带领大家实现目标的能力。一位优秀的领导者需要具备清晰的沟通能力、解决问题的能力,以及对人心的深刻理解。他们知道如何激励人心,如何在压力下保持冷静,并能在关键时刻做出正确的决策。如何培养领导力?
    优思学院 2025-03-23 12:24 94浏览
  • WT588F02B是广州唯创电子推出的一款高性能语音芯片,广泛应用于智能家电、安防设备、玩具等领域。然而,在实际开发中,用户可能会遇到烧录失败的问题,导致项目进度受阻。本文将从下载连线、文件容量、线路长度三大核心因素出发,深入分析烧录失败的原因并提供系统化的解决方案。一、检查下载器与芯片的物理连接问题表现烧录时提示"连接超时"或"设备未响应",或烧录进度条卡顿后报错。原因解析接口错位:WT588F02B采用SPI/UART双模通信,若下载器引脚定义与芯片引脚未严格对应(如TXD/RXD交叉错误)
    广州唯创电子 2025-03-26 09:05 77浏览
  • 人形机器人产业节奏预估:2024年原型机元年,2025年小规模量产元年。当宇树科技H1人形机器人以灵动的手部动作在春晚舞台上演创意融合舞蹈《秧Bot》,舞出"中国智造"时,电视机前十几亿观众第一次深刻意识到:那个需要仰望波士顿动力的时代正在落幕。*图源:宇树科技短短数周后,宇树G1机器人又用一段丝滑的街舞在网络收割亿级播放量,钢铁之躯跳出赛博朋克的浪漫。2月11日,宇树科技在其京东官方旗舰店上架了两款人形机器人产品,型号分别为Unitree H1和G1。2月12日,9.9万元的G1人形机器人首批
    艾迈斯欧司朗 2025-03-22 21:05 137浏览
  • 在智慧城市领域中,当一个智慧路灯项目因信号盲区而被迫增设数百个网关时,当一个传感器网络因入网设备数量爆增而导致系统通信失效时,当一个智慧交通系统因基站故障而导致交通瘫痪时,星型网络拓扑与蜂窝网络拓扑在构建广覆盖与高节点数物联网网络时的局限性便愈发凸显,行业内亟需一种更高效、可靠与稳定的组网技术以满足构建智慧城市海量IoT网络节点的需求。星型网络的无线信号覆盖范围高度依赖网关的部署密度,同时单一网关的承载设备数量有限,难以支撑海量IoT网络节点的城市物联系统;而蜂窝网络的无线信号覆盖范围同样高度依
    华普微HOPERF 2025-03-24 17:00 177浏览
  • 在智能终端设备快速普及的当下,语音交互已成为提升用户体验的关键功能。广州唯创电子推出的WT3000T8语音合成芯片,凭借其卓越的语音处理能力、灵活的控制模式及超低功耗设计,成为工业控制、商业终端、公共服务等领域的理想选择。本文将从技术特性、场景适配及成本优势三方面,解析其如何助力行业智能化转型。一、核心技术优势:精准、稳定、易集成1. 高品质语音输出,适配复杂环境音频性能:支持8kbps~320kbps宽范围比特率,兼容MP3/WAV格式,音质清晰自然,无机械感。大容量存储:内置Flash最大支
    广州唯创电子 2025-03-24 09:08 192浏览
  • 核心板简介创龙科技 SOM-TL3562 是一款基于瑞芯微 RK3562J/RK3562 处理器设计的四核 ARM C ortex-A53 + 单核 ARM Cortex-M0 全国产工业核心板,主频高达 2.0GHz。核心板 CPU、R OM、RAM、电源、晶振等所有元器件均采用国产工业级方案,国产化率 100%。核心板通过 LCC 邮票孔 + LGA 封装连接方式引出 MAC、GMAC、PCIe 2.1、USB3.0、 CAN、UART、SPI、MIPI CSI、MIPI
    Tronlong 2025-03-24 09:59 184浏览
  • 在人工智能与物联网技术蓬勃发展的今天,语音交互已成为智能设备的重要功能。广州唯创电子推出的WT3000T8语音合成芯片凭借其高性能、低功耗和灵活的控制方式,广泛应用于智能家居、工业设备、公共服务终端等领域。本文将从功能特点、调用方法及实际应用场景入手,深入解析这款芯片的核心技术。一、WT3000T8芯片的核心功能WT3000T8是一款基于UART通信的语音合成芯片,支持中文、英文及多语种混合文本的实时合成。其核心优势包括:高兼容性:支持GB2312/GBK/BIG5/UNICODE编码,适应不同
    广州唯创电子 2025-03-24 08:42 158浏览
  •       知识产权保护对工程师的双向影响      正向的激励,保护了工程师的创新成果与权益,给企业带来了知识产权方面的收益,企业的创新和发明大都是工程师的劳动成果,他们的职务发明应当受到奖励和保护,是企业发展的重要源泉。专利同时也成了工程师职称评定的指标之一,专利体现了工程师的创新能力,在求职、竞聘技术岗位或参与重大项目时,专利证书能显著增强个人竞争力。专利将工程师的创意转化为受法律保护的“无形资产”,避免技术成果被他人抄袭或无偿使
    广州铁金刚 2025-03-25 11:48 125浏览
  • 在智能终端设备开发中,语音芯片与功放电路的配合直接影响音质表现。广州唯创电子的WTN6、WT588F等系列芯片虽功能强大,但若硬件设计不当,可能导致输出声音模糊、杂音明显。本文将以WTN6与WT588F系列为例,解析音质劣化的常见原因及解决方法,帮助开发者实现清晰纯净的语音输出。一、声音不清晰的典型表现与核心原因当语音芯片输出的音频信号存在以下问题时,需针对性排查:背景杂音:持续的“沙沙”声或高频啸叫,通常由信号干扰或滤波不足导致。语音失真:声音断断续续或含混不清,可能与信号幅度不匹配或功放参数
    广州唯创电子 2025-03-25 09:32 66浏览
  • 文/Leon编辑/cc孙聪颖‍“无AI,不家电”的浪潮,正在席卷整个家电行业。中国家电及消费电子博览会(AWE2025)期间,几乎所有的企业,都展出了搭载最新AI大模型的产品,从电视、洗衣机、冰箱等黑白电,到扫地机器人、双足机器人,AI渗透率之高令人惊喜。此番景象,不仅让人思考:AI对于家电的真正意义是什么,具体体现在哪些方面?作为全球家电巨头,海信给出了颇有大智慧的答案:AI化繁为简,将复杂留给技术、把简单还给生活,是海信对于AI 家电的终极答案。在AWE上,海信发布了一系列世俱杯新品,发力家
    华尔街科技眼 2025-03-23 20:46 78浏览
  • 今年全国两会期间,“体重管理”和“育儿”整体配套政策引发了持久广泛关注。从“吃”到“养”,都围绕着国人最为关心的话题:健康。大家常说“病从口入”,在吃这件事上,过去大家可能更多是为了填饱肚子,如今,消费者从挑选食材到厨电都贯彻着健康的宗旨,吃得少了更要吃得好了。这也意味着在新消费趋势下,谁能抓住众人的心头好,就能带起众人的购买欲望,才能在新一轮竞争中脱颖而出。作为家电行业的风向标,在2025年中国家电及消费电子博览会(AWE)上,这两个话题也被媒体和公众频繁提及。深耕中国厨房三十余年的苏泊尔再次
    华尔街科技眼 2025-03-22 11:42 83浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦