嵌入式Linux下I2C接口调试

供稿:韬睿(上海)计算机科技有限公司

  • 关键词:ARM,Linux,I2C,嵌入式
  • 摘要:I2C是嵌入式设备最为常用的接口之一,常用于如下面这些应用场景,因此本文就基于嵌入式Linux演示在User Space进行I2C设备调试。

1). 简介

I2C是嵌入式设备最为常用的接口之一,常用于如下面这些应用场景,因此本文就基于嵌入式Linux演示在User Space进行I2C设备调试。

- Digital to Analog converter

- EEPROM

- Real Time Clock

- Touch screen LCD

- Audio codec


本文所演示的平台来自于Toradex ApalisiMX6Q ARM嵌入式平台,这是一个基于NXP iMX6Q ARM处理器,支持四核心Cortex-A9。


2. 准备

a).Apalis iMX6Q ARM核心版配合Apalis Ixora载板,连接调试串口UART1到开发主机方便调试,同时配置好Ubuntu开发主机开发环境,具体操作方法可以参考这里。

b).Apalis iMX6Q系统使用Toradex Linux Release V2.6.1,下载和更新方法请参考这里。


3). I2C总线user space操作命令测试

a). Apalis iMX6Q核心版默认定义提供了三个I2C总线可供外部使用(i2c-2为核心板内部电源管理使用),如下所示,其中i2c-1为通用I2C接口;i2c-0为DDC接口,用于连接HDMI DDC/EDID接口,不能用做通用I2C接口;而i2c-3通常用于连接camera接口使用,不过也可以用做通用I2C接口。


b). 本文演示示例则通过读写ApalisIxora载板连接在i2c-1总线上面的2Kb EEPROM


c). User Space下通过I2C tools直接操作i2c-1总线进行访问EEPROM

./ 查看Apalis iMX6Q的所有I2C总线

---------------------------------

root@apalis-imx6:~# ls -l /dev/i2c-*

crw------- 1 root root 89, 0 4??月  26 06:52 /dev/i2c-0

crw------- 1 root root 89, 1 4??月  26 06:52 /dev/i2c-1

crw------- 1 root root 89, 2 4??月  26 06:52 /dev/i2c-2

crw------- 1 root root 89, 3 4??月  26 06:52 /dev/i2c-3

--------------------------------

./ 查看i2c-1总线上面的设备

可以看到在0x50和0x68两个地址上面挂有设备,0x68显示为UU意味着这个设备被kernel driver占用,通常不能从user space探查,这里结合Apalis iMX6Q手册可以得知挂载的为外部RTC设备;而0x50则为我们所需要测试的EEPROM设备

--------------------------------


--------------------------------


./ dump 0x50 EEPROM全部寄存器地址0-0xff,初始状态下每个寄存器地址保存的数值都是0xff

--------------------------------


--------------------------------


./使用i2cset和i2cget来写和读EEPROM特定寄存器地址

--------------------------------

// 向EEPROM 0x00寄存器地址写入0x01

root@apalis-imx6:/home# i2cset 1 0x50 0x000x01 b                              

WARNING! This program can confuse your I2Cbus, cause data loss and worse!    

DANGEROUS! Writing to a serial EEPROM on amemory DIMM                        

may render your memory USELESS and makeyour system UNBOOTABLE!                

I will write to device file /dev/i2c-1,chip address 0x50, data address        

0x00, data 0x01, mode byte.                                                    

Continue? [y/N] y                                                              

// 读取EEPROM 0x00寄存器地址

root@apalis-imx6:/home# i2cget 1 0x50 0x00b                                  

……                                                            

0x01

--------------------------------


d). User Space下通过I2C tools读取i2c-1总线进行访问RTC芯片

./Apalis Ixora载板外部RTC芯片使用ST m41t00 芯片,其内部集成8 byte寄存器用于存储时间相关信息,格式如下:

--------------------------------

1st byte: seconds register

2nd byte: minutes register

3rd byte: century/hours register

4th byte: day register

5th byte: date register

6th byte: month register

7th byte: years register

8th byte: control register

--------------------------------


./ Linux下查看当前时间

--------------------------------

root@apalis-imx6:~# date                                                      

2017??年 04??月 26??日 ??星??期??三 08:57:23 UTC

--------------------------------


./ Linux下手动修改当前时间,默认当设备联网时候自动联网校准时间是打开的

--------------------------------

// 关闭网络时间同步

timedatectl set-ntp 0


//手动设置时间并重启

timedatectl set-time 22:50:11

reboot

--------------------------------


./ 利用i2cget –f命令查看RTC寄存器数值示例

--------------------------------

// 查看当前系统时间设置

root@apalis-imx6:~# date

2017??年 04??月 26??日 ??星??期??三 09:02:17 UTC

// 读取时数值

root@apalis-imx6:~# i2cget -f 1 0x68 0x02 b

……

0x09

// 读取分数值

root@apalis-imx6:~# i2cget -f 1 0x68 0x01 b

……

0x02

// 读取秒数值

root@apalis-imx6:~# i2cget -f 1 0x68 0x00 b

……

0x41

--------------------------------


4). I2C总线C程序操作示例

使用C程序打开I2C设备并进行读写,这里编写例程以访问i2c-1总线上的EEPROM设备进行读写操作。

a). 首先以C程序访问i2C设备,需要include “i2c-dev.h”这个头文件,请注意在Linux中有两个同样名字的头文件,系统自带的通常是来自Linux kernel的i2c总线驱动对应的,这个并不是我们所需要的,而我们所需的是i2c-tools里面提供的这个“i2c-dev.h”头文件,这个文件请见这里:


b). 示例C程序代码请参考这里,说明如下:

./ 首先程序含有输入变量,i2c总线号码,设备地址以及变量X,用于设置需要读写的寄存器地址:0xX0 – 0xXf

./ 使用open函数打开i2c总线

./ 使用ioctl函数设置设备地址

./ 利用 SMBus 命令或者write函数向寄存器地址 0xX0 – 0xXf写入数据,数值就是对应的寄存器地址

./ 利用SMBus命令或者read函数读取寄存器地址 0xX0 – 0xXf数据并打印出来

./ 关闭i2c总线设备并退出程序


c). 程序运行结果

--------------------------------

// 写入并读出寄存器0x00 – 0x0f

root@apalis-imx6:~# ./i2ctest 1 80 0                                          

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x070x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x070x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f

// 写入并读出寄存器0x10 – 0x1f

root@apalis-imx6:~# ./i2ctest 1 80 1                                          

0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x170x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f

0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x170x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f

--------------------------------

这时dump EEPROM所有寄存器结果如下

--------------------------------


--------------------------------


d). 更多关于利用C程序使用I2C的说明请参考这里的内核文档说明。


发布时间:2017年4月27日 10:51  人气:   审核编辑(王静 )
相关链接

我有需求