linux驱动-i2c子系统框架学习(2)
linux驱动-i2c子系统框架学习(1) 在这篇博客里面已经交代了i2c设备驱动层,主要的功能就是编写具体i2c的外设驱动,和创建设备接点给上层使用 ,按之前学习的字符设备,有了设备节点,就可以对硬件操作了,在i2c子系统框架中,i2c设备驱动层并没有和硬件直接连接。是通过i2c核心层和i2c适配层才和硬件打交道。 为什么呢?
了解之前,想看这里,看图,同一个i2c总线,是可以挂多个i2c外设,具体是 I2C使用7位地址空间,最多可寻址127个从设备。
在处理器中,可以运行多个app应用程序,就好比如我们的手机,可以同时运行微信和qq,假设,外设是一个摄像头,微信和qq都想在同时使用摄像头,想操作这些外设,就必须先个给外设发一个起始信号,但是微信和qq都想用,都要发起起始信号,发信号就要通过SDA和SCL这两根线,这是后就有冲突了,怎么办?总不能微信跟qq说,你等一下我先用,协商一下,可能吗?并不能。
那linux是怎么解决这个问题的?linux通过框架完美解决这个问题。
假设应用层有三个app,同时访问一个硬件,他们就把数据交给核心层来安排,先处理谁,谁等待?完全是核心层说了算,就相当于一个大管家,不管是多少个应用想调用外设,都得听核心层安排,这个访问程序就不用应用程序去关心了,核心层就解决了冲突的问题。具体是怎么解决的,进行学习才行。
i2c核心层拿到了这些数据,是不是要把它们发送出去,那么使用i2c进行通信,就要使用到SCL和SDA产生具体的时序,我的rk3568是有硬件产生的,就要用到i2c控制器,但是想要i2c能工作起来就要使用到了i2c适配层,因为i2c适配层的工作就是编写i2c控制器的驱动让i2c控制器工作起来。
起始这个框架图可以分成三份。
i2c设备驱动层:
在i2c设备驱动层,编写具体的i2c的驱动程序的时候,就不用相关时序相关的代码,比如产生一个起始信号的代码或者终止信号的代码。因为在linux框架中,是被放到了i2c适配器中。而框架中又把时序的代码拿了出去了,在不同的平台里面移植i2c外设驱动就简单了应该,因为不一样的已经被拿走了,通用性就高了。
i2c适配层:
i2c适配器是和硬件打交道的,让i2c控制器能正常工作,这就意味着,不同的平台硬件不一样比如NXP和RK的平台就不一样。这样的话i2c的适配层的代码不一样了,所以这一块东西就是原厂来编写的,但是未必能进原厂,但是时序这些东西还是需要懂的。
i2c核心层:
在编写具体的i2c驱动程序的时候我们要怎么弄i2c总线时序通信?时序相关的拿走了,那怎么通信?我在编写i2c具体程序的是对调用i2c核心层提供的函数就可以了