drivers_day15

回顾:

1.select

目的:利用select/poll能够对多个设备进行同时的监听;

应用程序调用select/poll,对应底层驱动的接口都是同一个poll.

 

select系统调用实现过程:

1.应用程序调用select,首先调用C库的select

2.保存系统调用号,触发软中断

3.最终到达内核的sys_select

4.sys_select:

根据select指定的文件描述符,通过文件描述符获取对应的设备的file对象指针;

把被监听设备的驱动poll函数挨个调用一遍,如果设备都不可用,设备驱动的poll函数都返回0;

判断是否设备可用,是否超时,是否接收到信号;

如果都不成立,进程进入休眠状态;

一旦设备可用,必然产生中断,在中断处理函数中唤醒休眠的主进程,之前的休眠状态结束(poll_schedule_timeout函数返回);再次把设备驱动的poll函数挨个调用一遍,此时有一个设备的poll函数返回值应该不为0(设备可用);

返回用户空间;

 

5.底层驱动的poll主要完成等待队列实现进程休眠过程的一部分内容:

调用poll_wait将当前进程添加到驱动的等待队列头中

判断设备是否可用,如果不可用,返回0,如果可用返回非0

 

**********************************************************

2.混杂设备

主设备号为10;

通过次设备号分区;

字符设备;

struct miscdevice;

分配初始化混杂设备对象;

misc_register;

misc_deregster;

 

**********************************************************

3.ADC/DAC

ADC:模拟信号转数字信号的硬件;

DAC:数字信号转模拟信号的硬件;

衡量ADC、DAC的工作参数:分辨率

 

**********************************************************

I2C总线:

1.掌握I2C总线的硬件特性:

定义:两线式串行总线;

作用:用于连接CPU和外设,CPU和外设通过I2C总线进行数据的交互!

对象:CPU和外设,CPU由称master,外设由称slave;

"两线式":CPU和外设之间的通信接口需要2根信号线,一根是时钟控制信号线SCL,一根是数据传输信号线SDA;

SCL时钟控制信号只能由CPU发起,控制权交与CPU;

SDA数据信号线CPU和外设都能进行操作和控制!

 

"串行":CPU和外设之间传输数据是一个时钟周期传输一个bit位,如果CPU给外设写入0x55,需要8个时钟周期;

"一个时钟周期传输一个bit":CPU和外设之间传输一个bit位,必须要通过时钟控制信号线来实现双方的数据发和收!比如,CPU在时钟的高电平向数据线写入数据,设备在同周期的低电平从数据线上读取数据!

"总线":这两根信号线上可以挂接很多的外设,也可以挂接很多的CPU,一般总线只有一个CPU。如果有多个CPU,I2C总线具有仲裁机制来实现同步访问!

 

SCL和SDA分别会接一个上拉电阻,这两根信号线的默认状态为高电平状态!

一般如果CPU或者外设配置GPIO为输出口,就等于CPU或者外设控制了GPIO获取控制权;如果配置为输入口,就等于释放控制权!

 

MSB:高位

LSB:低位

 

问:CPU如果通过这两根线找到要访问的具体设备?

答:以上三个问题的答案在I2C总线协议中!

总线协议相关内容(看芯片手册):

1.START信号,起始信号:CPU如果要访问总线,必须CPU首先向总线上发送一个START起始信号;此信号由CPU发起;SCL为高电平,SDA由高电平向低电平跳变,产生START信号;

 

2.STOP信号,结束信号:CPU如何结束访问总线,CPU需要向总线发送一个STOP信号;此信号由CPU发起;SCL为高电平,SDA由低电平向高电平跳变,产生STOP信号;

 

3.设备地址:用于标识外设在I2C总线上的唯一性!同一个I2C总线上外设,每一个外设都有唯一的设备地址;如果CPU要访问某一个外设,CPU只需要在总线上发送这个外设的设备地址即可,发送完毕,如果外设存在于总线上,外设会给CPU一个反馈信号,就可以进行后续的数据访问;

外设的设备地址如何确定:一般有芯片厂家和原理图共同决定,

这里以三个外设为例,看看它们的设备地址分别是什么,电可擦除存储器AT24C02,温度传感器LM77,背光灯控制芯片ADP8860:

 

AT24C02,EEPROM的设备地址:

1010A2A1A0R/W:

1010:高4bit位,芯片厂家定义;

A2A1A0:原理图上A2A1A0都接GND=》A2A1A0=000

R:=1,表示CPU读取外设

W:=0,表示CPU写外设

通过以上信息,得到:

读设备地址:10100001=》0xA1

写设备地址:10100000=>0xA0

设备地址(7位,不算读写位,地址右移1位,高位补0)=》

最终设备地址=01010000=>0x50

 

LM77温度传感器设备地址:

10010A1A0:如果A1A0都接地:A1A0=00

读设备地址:10010001=>0x91

写设备地址:10010000=>0x90

设备地址:01001000=>0x48

 

ADP8860背光灯控制芯片设备地址:

0101010x:

读设备地址:01010101=>0x55

写设备地址:01010100=>0x54

设备地址:00101010=>0x2a

 

ACK信号:反馈应答信号,如果CPU发送完设备地址,并且外设进行响应,此时给CPU发送一个ACK应答信号,告诉CPU,外设存在于总线上;如果在数据读写过程中,也可以通过ACK信号指示数据的读写过程是否正常!有效的ACK信号为低电平(数据线),无效的ACK信号为高电平!

 

I2C数据传输,从高位开始发送,一次的数据传输为一字节!

I2C传输速度:100KHz,400KHz,3.4M

问:CPU如果找到了具体的某个外设,那么CPU和这个外设是如何通过这两根信号线完成数据的最终交互呢?

答:以三个芯片为例,了解掌握I2C的数据交互过程:

以温度传感器LM77为例:

1.CPU发送START信号;

2.CPU发送设备地址

3.CPU发送读写位

4.设备如果正常的存在于总线上,设备给CPU发送一个ACK信号

5.根据芯片手册进行数据的读写操作,其中会涉及到ACK信号,这个ACK信号和4步骤的ACK信号意义不太一样!

6.CPU发送STOP信号,接触此次的数据交互

 

ADP8860芯片的访问:

ADP8860芯片内部有一组寄存器,但是这些寄存器CPU不能像访问GPIO一样直接去访问寄存器地址,原因ADP8860并没有直接连接到CPU的4G地址空间中,需要间接得利用I2C总线访问芯片内部的寄存器地址;

例如现在把数据0xaa写入芯片内部寄存器0x55这个地址;

 

1.CPU发送START信号

2.CPU发送设备地址

3.CPU发送读写位,如果是写,这个bit为0

4.ADP8860如果正常存在于总线上,设备返回一个ACK信号给CPU,低电平有效

5.CPU发送访问的内部寄存器的地址0x55

6.设备获取CPU要访问的寄存器以后,设备给CPU发送一个ACK信号,告诉CPU可以继续访问;

7.CPU发送要写入的数据0xaa

8.设备将数据0xaa写入到内部寄存器0x55,然后设备给CPU一个ACK信号,告诉CPU写入成功;

9.CPU发送STOP信号,结束这次的寄存器的写入操作

 

电可擦除存储器EEPROM(at24c02)访问过程:

AT24C02的容量为256字节,地址编址:0~255

将数据0xaa写入到内部存储地址0x55地方去,CPU要访问内部地址的操作过程和ADP8860相似!

1.CPU发送START信号

2.CPU发送设备地址

3.CPU发送写:0

4.设备如果存在于总线上,那么设备给CPU发送一个ACK应答信号,告诉CPU,我在总线上!

4.CPU发送要操作的地址:0x55

5.设备接收到这个要操作的这个地址,设备给CPU发送一个ACK信号,告诉CPU,可以访问这个地址!

6.CPU发送要写入的数据0xaa

7.设备接收到这个要写入的数据,并且将数据写入到对应的地址0x55中,设备给CPU发送一个ACK信号,告诉CPU,写入成功!

8.CPU发送一个STOP信号,停止数据的此次访问!

 

随机读:就是读任何一个地址里的数据即可,例如读取0x55地址空间中的数据信息

 

问:SDA和SCL如何搭配使用?

答:

如果CPU或者设备要向数据线上写入数据,应该在SCL为低电平写入数据;如果CPU或者设备从数据线上获取数据,应该在同周期的高电平去读取数据!

 

总结:

I2C外设的具体如何操作,关键看芯片手册即可!

 

AT24C02的硬件特性:

EEPROM,电可擦除存储器;

容量:2Kbit,256字节;

传输速度:100KHz、400KHz

写周期:5ms

分页:1页为8字节,如果按页写,最多只能一次写8字节,如果写9字节,第9字节的数据会把第一字节的数据进行覆盖;

地址编址:0~255

设备地址:0x50

 

用户需求:

存储软件和硬件版本号到EEPROM中:

软件版本号:SYYMMDDXY->S14101700

硬件版本号:HYYMMDDXY->H14101700

EEPROM存储器地址规划:

软件版本号的地址范围:0x0~0x9

硬件版本号的地址范围:0x10~0x19

 

测试:

./at24c02_test w 0x55 0xaa //将数据0xaa写入地址0x55

./at24c02_test r 0x55 //读0x55地址中的数据

 

驱动设计:

1.采用GPIO模拟I2C时序来实现I2C总线硬件操作!

2.采用操作I2C控制器来实现I2C总线硬件操作!

3.采用linux内核I2C驱动框架来实现I2C硬件操作!

 

采用方法1来实现驱动:参考代码gpio_emu_i2c

GPIO模拟I2C时序的本质的就是利用软件操作GPIO的状态,来实现I2C总线的时序要求!

SDA->GPD1_0

SCL->GPD1_1

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值