当前位置:文档之家› IPMI 及Serial Over Lan(Sol)的实现

IPMI 及Serial Over Lan(Sol)的实现

IPMI 及Serial Over Lan(Sol)的实现
IPMI 及Serial Over Lan(Sol)的实现

在Dell PowerEdge R410上实现IPMI及Serial Over LAN IPMI在服务器管理领域是一个非常有用的工具,不仅可以实现远程电源管理(比如开、关机)及传感器信息查询(比如CPU温度),而且可以配置Serial Over LAN(Sol)通过Console 重定向远程获取BIOS和系统的启动信息。本文以Dell PowerEdge R410为例,来讲述上述功能的实现。

第一、设置IPMI,主要包括开启IPMI功能、BMC的IP设定、BMC的用户名和密码设定,详细过程如下所示。

1、启动主机,按照提示(如图1)按Ctrl-E进入BMC设定界面。

图1、出现此界面时按Ctrl-E进入BMC设定界面

2、进入BMC设定界面后确保IPMI Over LAN为on状态,如图2所示。

图2、确保IPMI Over LAN为on

3、进入LAN Parameters设定BMC的IP,选择Static,并同时配置IP、掩码以及网关,如图3所示。需要注意的是BMC的IP最好和执行ipmitool的控制端在一个网段之内,否则容易导致命令执行失败。

图3、BMC的IP设定

4、设置好BMC的IP后按ESC退到BMC设置界面,并选择LAN User Configuration设定用户和密码,如图4所示。

图4、设定BMC的用户和密码

设定好用户名和密码后保存退出,这就完成了IPMI的设定。关机或重启电脑使配置生效,接下来对刚才的设定进行验证。

第二、验证IPMI设定生效。

选择一台安装有ipmitool的机器(以Linux系统为例),首先ping BMC的IP,保证网络是联通的。Ipmitool的安装与使用请参阅IPMI预研的文档。

执行以下命令进行验证:

ipmitool –I lan –H 192.168.1.120 –U root –P 123456 power status 查看当前机器是否开启;

ipmitool –I lan –H 192.168.1.120 –U root –P 123456 power on/off 执行远程开、关机操作。

也可采用其他命令验证,但要确保IPMI配置生效。

第三、配置Console重定向,从而实现远程对BIOS和系统启动的监控。

关于这个功能我是这样理解的,本来主机启动时BIOS和系统信息是输出到Console口的,也就是说会显示在和主机相连的显示器上,现在要在远端进行监控,那就需要将这些信息作输出重定向。这是通过如下方式实现的,将Console的信息重定向到COM2口,COM2口本身是和BMC相连的,BMC再通过Serial Over LAN技术就可以将这些信息送向远端的监视器(个人理解,欢迎指正)。

1、配置BIOS的Console重定向

重启机器,按F2进入BIOS,并选择Serial Communication,如图5所示。在Serial Communication界面中,作如下设定,如图6所示。

Serial Communication : on with Console Redirection via COM2

External Serial Connector : COM2

Failsafe Baud Rate: 115200

图5、在BIOS界面选择Serial Communication

图6、Serial Communication界面具体参数设定

2、配置Linux的Console重定向。

上一步完成了BIOS信息的重定向,但仍然无法监控系统启动的过程。因为系统启动信息输出到哪个地方,是由系统配置文件决定的,因此要在远端监控系统启动过程,还需要修改系统的配置文件,这里假设BMC的主机上装的是CentOS。

Tips:BIOS中的COM1、COM2在Linux中叫做ttyS0、ttyS1,BIOS中将Console的信息重定向到COM2,这对应Linux中的ttyS1。

修改/boot/grub/grub.conf:

增加两行

serial –unit=1 –speed=115200

terminal timeout=5 serial

在splashimage行前加#

在kernel行增加启动参数console=tty0 console=ttyS1,115200n8

最后效果如图7所示。

图7、修改后的gurb.conf

至此已经完成了启动时BIOS和系统的Console重定向,达到了在远端监控的目的,但如果还要允许远端的Console登录,请按照下面步骤进行修改。

第四、开启系统启动后的Console登录

如果要允许远端通过Console口登录,在/etc/inittab中增加一行:

co:2345:respawn:/sbin/apetty –h –L 115200 ttyS1 vt100

图8、修改后的/etc/inittab

在/etc/securetty中增加ttyS1,如图9所示。

图9、修改后的/etc/seruretty

第五、远端监控命令

在远端安装了ipmitool的Linux机器上可以用如下命令监控BIOS和系统的启动信息:ipmitool –I lanplus –H192.168.1.120 –U root –P 123456 sol activate

Tips:要使用Sol必须用lanplus接口,也可以使用-f 制定密码存放的文件或-a提示输入密码,详细内容请参阅ipmitool的man手册。

拿云时代

Email:wytdah@https://www.doczj.com/doc/c35732843.html,

Date: 2012.07

Linux下I2C驱动介绍

1、I2C概述 I2C是philips公司提供的外设总线,I2C有两条数据线,一条是串行数据线SDA、一条是时钟线SCL,使用SDA和SCL实现了数据的交换,便于布线。I2C总线方便用在EEPROM、实时钟、小型LCD等与CPU外部的接口上。 2、Linux下的驱动思路 Linux系统下编写I2c驱动主要有两种方法:一种是把I2C当做普通字符设备来使用;另一种利用Linux下驱动的体系结构来实现。 第一种方法: 优点:思路比较直接,不用花费大量时间去了解Linux系统下I2C体系结构 缺点:不仅对I2C设备操作要了解,还有了解I2C的适配器操作 不仅对I2C设备器和设备操作需要了解,编写的驱动移植性差,内核 提供的I2C设备器都没有用上。 第二种方法: 第一种的优点就是第二种的缺点,第一种的缺点就是第二种的优点。 3、I2C框架概述 Linux的I2C体系结构分为3部分: 1)I2C核心I2C核心提供了I2C总线驱动和设备驱动的注册和注销的方法,I2C 通信方法(algorithm)上层,与具体适配器无关的代码,检测设备上层的代 码等。 2)I2C总线驱动I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可以直接受CPU来控制。 3)I2C设备驱动I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备端挂在受CPU控制的适配器上,通过I2C适配器与CPU交换数据。 Linux下的I2C体系结构: 1)Linux下的I2C体系结构 4、I2C设备驱动编写方法 首先让我们明白适配器驱动的作用是让我们能够通过它发出标准的I2C时序,在linux

内核源代码中driver/I2C/buss包含一些适配器的驱动,例如s3c2410的驱动I2C-s3c2410.c,适配器被加载到内核中,接下的任务就是实现设备驱动的编写。编写设备驱动的方法主要分为两种方法: 第一种:利用设备提供的I2C-dev.c来实现I2C适配器设备文件,然后通过上层应用程序来操作I2C设备器来控制I2C设备。 第二种:为I2C设备独立编写一个设备驱动 注意:第二种方法不能用设备提供的I2C-dev.c 5、I2C系统下的文件架构 在linux下driver下面有个I2C目录,在I2C目录下包含以下文件和文件夹 1)I2C-core.c 这个文件实现I2C核心功能以及/proc/bus/I2C*接口 2)I2C-dev.c 实现I2C适配器设备文件的功能,每个I2C适配器被分配一个设备,通过 适配器访问设备的时候,主设备号是89,此设备号是0-255. I2C-dev.c并没有针对特定设备而设计,只提供了read() write()和ioctl()等接口,应用层可以通过这些接口访问挂在适配器上的I2C设备存储空间和寄存器,并控制I2C设备的工作方式。 3)Chips 这个文件下面包含特定的I2C设备驱动。 4)Busses 这个文件包含一些I2C总线驱动。 5)Algos文件夹下实现了I2C总线适配器的algorithm 6、重要结构体 1)在内核中的I2C.h这个头文件中对I2C_driver;I2C_client;I2C_adapter和I2C_algorithm 这个四个结构体进行了定义。理解这4个结构体的作用十分关键。 i2c_adapter结构体 struct i2c_adapter { struct module *owner; //所属模块 unsigned int id; //algorithm的类型,定义于i2c-id.h, unsigned int class; const struct i2c_algorithm *algo; //总线通信方法结构体指针 void *algo_data;//algorithm数据 struct rt_mutex bus_lock; //控制并发访问的自旋锁 int timeout; int retries; //重试次数 struct device dev; //适配器设备 int nr; char name[48]; //适配器名称 struct completion dev_released; //用于同步 struct list_head userspace_clients; //client链表头

Linux下I2C驱动架构全面分析概要

Linux下I2C驱动架构全面分析 I2C概述 I2C是philips提岀的外设总线. I2C只有两条线,一条串行数据线:SDA, —条是时钟线SCL,使用SCL , SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线。 因此,I2C总线被非常广泛地应用在EEPROM,实时钟,小型LCD等设备与CPU的接口中。 linux下的驱动思路 在linux系统下编写I2C驱动,目前主要有两种方法,一种是把I2C设备当作一个普通的字符设备来处理,另一种是利用linux下I2C驱动体系结构来完成。下面比较下这两种方法: 第一种方法: 优点:思路比较直接,不需要花很多时间去了解linux中复杂的I2C子系统的操作方法。 缺点: 要求工程师不仅要对I2C设备的操作熟悉,而且要熟悉I2C的适配器(I2C控制器)操作。要求工程师对I2C的设备器及I2C的设备操作方法都比较熟悉,最重要的是写岀的程序可以移植性差。 对内核的资源无法直接使用,因为内核提供的所有I2C设备器以及设备驱动都是基于I2C 子系统的格式。 第一种方法的优点就是第二种方法的缺点, 第一种方法的缺点就是第二种方法的优点。 I2C架构概述 Linux的I2C体系结构分为3个组成部分: I2C核心:I2C核心提供了I2C总线驱动和设备驱动的注册,注销方法,I2C通信方法 (” algorithm 上层的,与具体适配器无关的代码以及探测设备,检测设备地址的上层代码等。 I2C总线驱动:I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。 I2C设备驱动:I2C设备驱动(也称为客户驱动)是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。

linux下iic(i2c)读写AT24C02

https://www.doczj.com/doc/c35732843.html,/jammy_lee/ https://www.doczj.com/doc/c35732843.html, linux下iic(i2c)读写AT24C02 linux驱动2010-02-09 16:02:03 阅读955 评论3 字号:大中小订阅 linux内核上已有iic的驱动,因此只需要对该iic设备文件进行读写则能够控制外围的iic器件。这里以AT24C02为对象,编写一个简单的读写应用程序。iic设备文件在我的开发板上/dev/i2c/0 ,打开文件为可读写。AT24C02的器件地址为0x50 ,既是iic总线上从器件的地址,每次只读写一字节数据。 /************************************************************/ //文件名:app_at24c02.c //功能:测试linux下iic读写at24c02程序 //使用说明: (1) // (2) // (3) // (4) //作者:jammy-lee //日期:2010-02-08 /************************************************************/ //包含头文件 #include #include #include #include #include #include #include

#include #include #include //宏定义 #define Address 0x50 //at24c02地址 #define I2C_RETRIES 0x0701 #define I2C_TIMEOUT 0x0702 #define I2C_SLAVE 0x0703 //IIC从器件的地址设置 #define I2C_BUS_MODE 0x0780 typedef unsigned char uint8; uint8 rbuf[8] = {0x00}; //读出缓存 uint8 wbuf[8] = {0x01,0x05,0x06,0x04,0x01,0x01,0x03,0x0d}; //写入缓存int fd = -1; //函数声明 static uint8 AT24C02_Init(void); static uint8 i2c_write(int fd, uint8 reg, uint8 val); static uint8 i2c_read(int fd, uint8 reg, uint8 *val); static uint8 printarray(uint8 Array[], uint8 Num); //at24c02初始化 static uint8 AT24C02_Init(void) { fd = open("/dev/i2c/0", O_RDWR); //允许读写 if(fd < 0) { perror("Can't open /dev/nrf24l01 \n"); //打开iic设备文件失败 exit(1);

实例解析linux内核I2C体系结构(2)

实例解析linux内核I2C体系结构(2) 华清远见刘洪涛四、在内核里写i2c设备驱动的两种方式 前文介绍了利用/dev/i2c-0在应用层完成对i2c设备的操作,但很多时候我们还是习惯为i2c设备在内核层编写驱动程序。目前内核支持两种编写i2c驱动程序的方式。下面分别介绍这两种方式的实现。这里分别称这两种方式为“Adapter方式(LEGACY)”和“Probe方式(new style)”。 (1)Adapter方式(LEGACY) (下面的实例代码是在2.6.27内核的pca953x.c基础上修改的,原始代码采用的是本文将要讨论的第2种方式,即Probe方式) ●构建i2c_driver static struct i2c_driver pca953x_driver = { .driver = { .name= "pca953x", //名称 }, .id= ID_PCA9555,//id号 .attach_adapter= pca953x_attach_adapter, //调用适配器连接设备 .detach_client= pca953x_detach_client,//让设备脱离适配器 }; ●注册i2c_driver static int __init pca953x_init(void) { return i2c_add_driver(&pca953x_driver); } module_init(pca953x_init); ●attach_adapter动作 执行i2c_add_driver(&pca953x_driver)后会,如果内核中已经注册了i2c适配器,则顺序调用这些适配器来连接我们的i2c设备。此过程是通过调用i2c_driver中的attach_adapter方法完成的。具体实现形式如下: static int pca953x_attach_adapter(struct i2c_adapter *adapter) { return i2c_probe(adapter, &addr_data, pca953x_detect); /* adapter:适配器 addr_data:地址信息 pca953x_detect:探测到设备后调用的函数 */ } 地址信息addr_data是由下面代码指定的。 /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,I2C_CLIENT_END}; I2C_CLIENT_INSMOD;

Linux_I2C总线分析(主要是probe的方式)1

Linux I2C 总线浅析 ㈠ Overview 内核空间层次! i2c adapter 是一个struct, 用来抽象一个物理i2c bus ,而且还和linux 设备驱动架构柔和在一起.. 如果只说硬件的话,就是在CPU内部集成的一个I2C控制器(提供给用户的就是那几个register),硬件上并没的所谓的adapter,client这些东东,,adapter和client都是linux 驱动软件抽象出来的东西 资料帖子: i2c_algorithm { /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated

using common I2C messages */ /* master_xfer should return the number of messages successfully processed, or a negative value on error */ i nt (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); i nt (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data); /* To determine what the adapter supports */ u32 (*functionality) (struct i2c_adapter *); }; /* * i2c_adapter is the structure used to identify a physical i2c bus along * with the access algorithms necessary to access it. */ struct i2c_adapter { s truct module *owner; u nsigned int id; u nsigned int class; /* classes to allow probing for */ c onst struct i2c_algorithm *algo; /* the algorithm to access the bus */ v oid *algo_data; /* data fields that are valid for all devices */ u8 level; /* nesting level for lockdep */ s truct mutex bus_lock; i nt timeout; /* in jiffies */ i nt retries; s truct device dev; /* the adapter device */ i nt nr; c har name[48]; s truct completion dev_released; }; Linux的I2C体系结构分为3个组成部分: 1·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即“algorithm”)上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。这部分是与平台无关的。 2·I2C总线驱动: I2C总线驱动是对I2C硬件体系结构中适配器端的实现。I2C总线驱动主要包含了I2C适配

实例解析linux内核I2C体系结构

实例解析linux内核I2C体系结构 作者:刘洪涛,华清远见嵌入式学院讲师。 一、概述 谈到在linux系统下编写I2C驱动,目前主要有两种方式,一种是把I2C 设备当作一个普通的字符设备来处理,另一种是利用linux I2C驱动体系结构来完成。下面比较下这两种驱动。 第一种方法的好处(对应第二种方法的劣势)有: ●思路比较直接,不需要花时间去了解linux内核中复杂的I2C子系统的操作方法。 第一种方法问题(对应第二种方法的好处)有: ●要求工程师不仅要对I2C设备的操作熟悉,而且要熟悉I2C的适配器操作; ●要求工程师对I2C的设备器及I2C的设备操作方法都比较熟悉,最重要的是写出的程序可移植性差; ●对内核的资源无法直接使用。因为内核提供的所有I2C设备器及设备驱动都是基于I2C子系统的格式。I2C适配器的操作简单还好,如果遇到复杂的I2C适配器(如:基于PCI的I2C适配器),工作量就会大很多。 本文针对的对象是熟悉I2C协议,并且想使用linux内核子系统的开发人员。 网络和一些书籍上有介绍I2C子系统的源码结构。但发现很多开发人员看了这些文章后,还是不清楚自己究竟该做些什么。究其原因还是没弄清楚I2C子系统为我们做了些什么,以及我们怎样利用I2C子系统。本文首先要解决是如何利用现有内核支持的I2C适配器,完成对I2C设备的操作,然后再过度到适配器代码的编写。本文主要从解决问题的角度去写,不会涉及特别详细的代码跟踪。 二、I2C设备驱动程序编写 首先要明确适配器驱动的作用是让我们能够通过它发出符合I2C标准协议的时序。 在Linux内核源代码中的drivers/i2c/busses目录下包含着一些适配器的驱动。如S3C2410的驱动i2c-s3c2410.c。当适配器加载到内核后,接下来的工作就要针对具体的设备编写设备驱动了。

linux i2c驱动

linux i2c驱动 1. i2c-dev interface I2C dev-interface 通常,i2c设备由某个内核驱动控制。但是在用户空间,也可以访问某个I2C设备:你需要 加载i2c-dev模块。 每个被注册的i2c适配器(控制器)会获得一个数字号,从0开始。你可以检查/sys/class/i2c-dev,来查看适配器对应哪个数字号。你也可以通过命令 "i2cdetect -l"获 取你的当前系统的所有I2c适配器的列表。i2cdetct是i2c-tool包中的一个工具。 i2c设备文件是字符设备,主设备号是89,次设备号的分配如上所述。设备文件名通常被 规定为"i2c-%d"(i2c-0, i2c-1, ...,i2c-10, ...)i2c设备文件是字符设备, 主设备号是 89,次设备号的分配如上所述。设备文件名通常被规定为"i2c-%d"(i2c-0, i2c-1, ...,i2c-10, ...).所有256个次设备号都保留给i2c使用。 C example ========= 假定你要在你的C应用程序中访问i2c适配器。第一件事情就是包含头文件 "#include "。注意,存在两个"i2c-dev.h"文件: 一个属于Linux kernel,用于 内核驱动中;一个由i2c-tools发布,用于用户程序。显然,这里需要使用第二个 i2c-dev.h文件。 现在,你需要确定访问哪个适配器。你需要通过查看/sys/class/i2c-dev/或者运行 "i2cdetect -l"确定。适配器号时常是动态分配的,你无法预先假定某个值。因为它们甚 至会在系统重启后变为不同的值。 下一步,打开设备文件,如下: int file; int adapter_nr = 2; /*probably dynamically determined */ char filename[20];

Linux驱动之i2c用户态调用

一、概述 I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL.正因为这样,它方便了工程人员的布线. 二、用户态实现设备驱动 在Linux内核代码文件i2c-dev.c中实现了I2C适配器设备文件的功能,针对每个适配器生成一个主设备号为89的设备节点(次设备号为0-255),I2c-dev.c并没有针对特定的设备而设计,只是提供了通用的read(),write(),和ioctl()等文件操作接口,在用户空间的应用层就可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器,并控制I2C设备的工作方式。 i2c适配器的设备节点是/dev/i2c-x,其中x是数字。由于适配器编号是动态分配的(和注册次序有关),所以想了解哪一个适配器对应什么编号,可以查看/sys/class/i2c-dev/目录下的文件内容。 三、用户态调用 3.1、i2c-dev 用户空间操作i2c,需要包含以下头文件。 打开适配器对应的设备节点

i2c-dev为打开的线程建立一个i2c_client,但是这个i2c_client并不加到i2c_adapter的client链表当中。他是一个虚拟的临时client,当用户打开设备节点时,它自动产生,当用户关闭设备节点时,它自动被释放。 3.2、ioctl() 查看include/linux/i2c-dev.h文件,可以看到i2c支持的IOCTL命令1.#define I2C_RETRIES0x0701 /*设置收不到ACK时的重试次数*/ 2.#define I2C_TIMEOUT0x0702/*设置超 时时限的jiffies*/ 3.#define I2C_SLAVE0x0703/ *设置从机地址*/ 4.#define I2C_SLAVE_FORCE0x0706/*强制设置从机地 址*/ 5.#define I2C_TENBIT0x0704/* 选择地址位长:=0for7bit,!=0for10bit*/ 6.#define I2C_FUNCS0x0705/* 获取适配器支持的功能*/ 7.#define I2C_RDWR0x0707 /*Combin ed R/W transfer(one STOP only)*/ 8.#define I2C_PEC0 x0708/* !=0to use PEC with SMBus*/ 9.#define I2C_SMBUS0x0720 /*SMBus transfer*/

Android I2C精析

Android I2C精析 基于linux内核开发的arm系统,会用到很多components。要让这些components正常的工作,我们必须了解它们的接口,懂得如何去注册总线,初始化芯片,进而让芯片正常的工作。下面我会介绍在arm开发过程中使用最频繁的一些接口和总线的原理,以及如何在开发的过程中去使用它们。 1 I2C总线与接口 I2C总线具有结构简单,使用方便的特点。下面我会描述linux下I2C驱动的结构,幷给出I2C设备驱动和应用的实现。 1.1 I2C总线概述 I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。 I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据,每个器件都有一个惟一的地址识别。I2C 规程运用主/从双向通讯。器件发送数据到总线上,则定义为发送器,器件接收数据则定义为接收器。主器件和从器件都可以工作于接收和发送状态。总线必须由主器件(通常为微控制器)控制,主器件产生串行时钟(SCL)控制总线的传输方向,并产生起始和停止条件。SDA 线上的数据状态仅在SCL为低电平的期间才能改变,SCL为高电平的期间,SDA 状态的改变被用来表示起始和停止条件。 从理论上说一根I2C总线上可以挂载128个I2C设备,但是通常情况下,由于有些设备在传输数据时占用的I2C总线带宽频繁,所以我们在一根I2C总线上挂载的设备是越少越好。下面给出I2C总线的连线图:

Linux I2C设备驱动编写

Linux I2C设备驱动编写(一) 在Linux驱动中I2C系统中主要包含以下几个成员: 如果一个I2C适配器不支持I2C通道,那么就将master_xfer成员设为NULL。如果适配器支持SMBUS 协议,那么需要去实现smbus_xfer,如果smbus_xfer指针被设为NULL,那么当使用SMBUS协议的时候将会通过I2C通道进行仿真。master_xfer指向的函数的返回值应该是已经成功处理的消息数,或者返回负数表示出错了。functionality指针很简单,告诉询问着这个I2C主控器都支持什么功能。 在内核的drivers/i2c/i2c-stub.c中实现了一个i2c adapter的例子,其中实现的是更为复杂的SMBUS。 SMBus 与I2C的区别 通常情况下,I2C和SMBus是兼容的,但是还是有些微妙的区别的。

时钟速度对比: 在电气特性上他们也有所不同,SMBus要求的电压范围更低。 I2C driver 具体的I2C设备驱动,如相机、传感器、触摸屏、背光控制器常见硬件设备大多都有或都是通过I2C 协议与主机进行数据传输、控制。结构体如下:

如同普通设备的驱动能够驱动多个设备一样,一个I2C driver也可以对应多个I2C client。以重力传感器AXLL34X为例,其实现的I2C驱动为:

这里要说明一下module_i2c_driver宏定义(i2c.h): module_driver(): 理解上述宏定义后,将module_i2c_driver(adxl34x_driver)展开就可以得到:

这一句宏就解决了模块module安装卸载的复杂代码。这样驱动开发者在实现I2C驱动时只要将i2c_driver结构体填充进来就可以了,无需关心设备的注册与反注册过程。 I2C client 即I2C设备。I2C设备的注册一般在板级代码中,在解析实例前还是先熟悉几个定义: 下面还是以adxl34x为例:

Linux_I2C设备驱动文件操作接口

I2C适配器驱动被作为一个单独的模块被加载进内核,在模块的加载和卸载函数中,只需注册和注销一个platform_driver结构体,如代码清单15.25。 代码清单15.25 S3C2410 I2C总线驱动模块加载与卸载 1 static int __init i2c_adap_s3c_init(void) 2 { 3 int ret; 4 5 ret = platform_driver_register(&s3c2410_i2c_driver); 6 if (ret == 0) { 7 ret = platform_driver_register(&s3c2440_i2c_driver); 8 if (ret) 9 platform_driver_unregister(&s3c2410_i2c_driver); 10 } 11 12 return ret; 13 } 14 15 static void __exit i2c_adap_s3c_exit(void) 16 { 17 platform_driver_unregister(&s3c2410_i2c_driver); 18 platform_driver_unregister(&s3c2440_i2c_driver);

—— 19 } 20 module_init(i2c_adap_s3c_init); 21 module_exit(i2c_adap_s3c_exit); platform_driver结构体包含了具体适配器的probe()函数、remove()函数、resume()函数指针等信息,它需要被定义和赋值,如代码清单15.26。 代码清单15.26 platform_driver结构体 1 static struct platform_driver s3c2410_i2c_driver = { 2 .probe = s3c24xx_i2c_probe, 3 .remove = s3c24xx_i2c_remove, 4 .resume = s3c24xx_i2c_resume, 5 .driver = { 6 .owner = THIS_MODULE, 7 .name = "s3c2410-i2c", 8 }, 9 }; 当通过Linux内核源代码/drivers/base/platform.c文件中定义platform_driver_unregister()函数注册platform_driver结构体时,其中probe指针指向的s3c24xx_i2c_probe()函数将被调用以初始化适配器硬件,如代码清单15.27。 代码清单15.27 S3C2410 I2C总线驱动中的s3c24xx_i2c_probe函数 1 static int s3c24xx_i2c_probe(struct platform_device *pdev)

学会嵌入式Linux下I2C的接口调试

学会嵌入式Linux下I2C的接口调试 1). 简介 I2C是嵌入式设备最为常用的接口之一,常用于如下面这些应用场景,因此本文就基于嵌入式Linux演示在User Space进行I2C设备调试。 - Digital to Analog converter - EEPROM - Real Time Clock - Touch screen LCD - Audio codec 本文所演示的平台来自于Toradex Apalis iMX6Q 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). 本文演示示例则通过读写Apalis Ixora载板连接在i2c-1总线上面的2Kb EEPROM c). User Space下通过I2C tools直接操作i2c-1总线进行访问EEPROM ./ 查看Apalis iMX6Q的所有I2C总线 --------------------------------- root@apalis-imx6:~# ls -l /dev/i2c-*

基于Linux的I2C驱动组成结构

基于Linux的I2C驱动组成结构 Linux的I2C驱动架构 1. Linux的I2C驱动架构Linux中I2C总线的驱动分为两个部分,总线驱动(BUS)和设备驱动(DEVICE)。其中总线驱动的职责,是为系统中每个I2C总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯,它只是存在在那里,等待设备驱动调用其函数。 设备驱动则是与挂在I2C总线上的具体的设备通讯的驱动。通过I2C总线驱动提供的函数,设备驱动可以忽略不同总线控制器的差异,不考虑其实现细节地与硬件设备通讯。 1.1 总线驱动在系统开机时,首先装载的是I2C总线驱动。一个总线驱动用于支持一条特定的I2C总线的读写。一个总线驱动通常需要两个模块,一个struct i2c_adapter和一个struct i2c_algorithm来描述: static struct i2c_adapter pb1550_board_adapter = { name: "pb1550 adapter", id: I2C_HW_AU1550_PSC, algo: NULL, algo_data: &pb1550_i2c_info, inc_use: pb1550_inc_use, dec_use: pb1550_dec_use, client_register: pb1550_reg, client_unregister: pb1550_unreg, client_count: 0, }; 这个样例挂接了一个叫做“pb1550 adapter”的驱动。但这个模块并未提供读写函数,具体的读写方法由第二个模块,struct i2c_algorithm提供。 static struct i2c_algorithm au1550_algo = { .name = "Au1550 algorithm", .id = I2C_ALGO_AU1550,

LinuxI2C总线详解

Linux I2C 总线详解 ㈠ Overview Linux的I2C体系结构分为3个组成部分: ·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即“algorithm”)上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。这部分是与平台无关的。 ·I2C总线驱动: I2C总线驱动是对I2C硬件体系结构中适配器端的实现。I2C总线驱动主要包含了I2C适配器数据结构i2c_adapter、I2C适配器的algorithm数据结构i2c_algorithm和控制I2C适配器产生通信信号的函数。经由I2C总线驱动的代码,我们可以控制I2C适配器以主控方式产生开始位、停止位、读写周期,以及以从设备方式被读写、产生ACK等。不同的CPU平台对应着不同的I2C 总线驱动。 总线驱动的职责,是为系统中每个I2C总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯,它只是存在在那里,等待设备驱动调用其函数。 这部分在MTK 6516中是由MTK已经帮我们实现了的,不需要我们更改。 · I2C设备驱动: I2C设备驱动是对I2C硬件体系结构中设备端的实现。设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。I2C设备驱动主要包含了数据结构i2c_driver和 i2c_client,我们需要根据具体设备实现其中的成员函数。在Linux内核源代码中的drivers 目录下的i2c_dev.c文件,实现了I2C适配器设备文件的功能,应用程序通过“i2c-%d”文件名并使用文件操作接口open()、write()、read()、ioctl()和close()等来访问这个设备。应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器并控制I2C设备的工作方式。 设备驱动则是与挂在I2C总线上的具体的设备通讯的驱动。通过I2C总线驱动提供的函数,设备驱动可以忽略不同总线控制器的差异,不考虑其实现细节地与硬件设备通讯。 这部分在MTK 6516中是由具体的设备实现的。(比如camera)

linux的I2C子系统详解

Linux中I2C驱动子系统详解 Author :Aston Mail : astonqa@https://www.doczj.com/doc/c35732843.html, 写在前面 首先,本教程不来自于权威书籍或文献,完全为本人个人理解的描述。限于水平,其中若有错误及不当,敬请指正、不胜感激。 其次,本教程撰写过程中虽参考了网络上各种资料,但不同于网上大部分资料的 粗略介绍或只关注一个点。相反,本教程从全局出发,全面描述了I2C总线及设备在linux系统中的实现方法,适合于希望对linux中I2C子系统进行详细、彻底学习的人士共享与阅读。 第一部分:框架描述 第二部分:I2C总线与实际硬件介绍 第三部分:linux中I2C子系统与主要数据结构分析 一个I2C设备要在linux下使用,必须包含两个驱动:I2C总线驱动和I2C设备驱动。涉及到的主要数据结构有i2c_adapter, i2c_client, i2c_driver, i2c_algorithm(均包含在include/linux/i2c.h中),这几个数据结构是I2C驱动中主 要的数据抽象,搞清楚这几个数据结构的意义是理解I2C驱动架构的前提。 i2c_adapter用来虚拟I2C适配器,所谓的适配器即用来匹配其两端连接的设备的器件。在这里,I2C适配器是一个虚拟的器件,该器件用来匹配I2C总线上连接的设备和I2C主控制器。因此可以认为:i2c_adapter对应的物理实体就是SoC内部的I2C控制器。 i2c_algorithm是一个纯软件层面的数据抽象,没有对应的物理实体。它用来描述一个i2c_adapter(实质是一个I2C控制器)的通信时序,这其实很好理解。大家都知道,I2C总线上的通信双方要完成通信需要按照一定的时序吧,如下图即是S3C2440中I2C控制器的主发送时序(即2440作为I2C主设备向外部连接的从设备发送信息)。 i2c_algorithm中封装的方法旨在描述该种时序,I2C总线驱动中最终需要靠这里封装 的方法来操作I2C控制器硬件发送通信时序。

linux下i2c驱动源码详解

Linux i2c驱动详细分析. 首先在S3C2440平台的初始化函数中,主要是将开发平台的设备注册进了系统,也就是将device注册到了platform虚拟的总线上,并进行了一些初始化的工作,这里我们只关注I2C的部分。 static void __init smdk2440_machine_init(void) { s3c24xx_fb_set_platdata(&smdk2440_fb_info); s3c_i2c0_set_platdata(NULL); platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); smdk_machine_init(); } s3c_i2c0_set_platdata()函数将S3C2440上的I2C控制器进行了一些初始化,但是并没有写入硬件寄存器,仅仅是保存在了 s3c2410_platform_i2c结构体中。 void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) { struct s3c2410_platform_i2c *npd; if (!pd) pd = &default_i2c_data0;

npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); if (!npd) printk(KERN_ERR "%s: no memory for platform data\n", __func__); else if (!npd->cfg_gpio) npd->cfg_gpio = s3c_i2c0_cfg_gpio; /* s3c_i2c0_cfg_gpio为 配置I2C控制器GPIO函数指针 */ s3c_device_i2c0.dev.platform_data = npd; /*最后将struct device 中的platform_data指针直指向了初始化后的 s3c2410_platform_i2c结构体 */ } 函数s3c_i2c0_cfg_gpio()很简单,实际上就是配置GPIO为I2C的工作模式 void s3c_i2c0_cfg_gpio(struct platform_device *dev) { s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); } s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)函数实际上就是把初始化数据段中的default_i2c_data0结构体复制过来,然后对GPIO进行配置的函数指针进行了初始化。default_i2c_data0结构体如下:

Linux I2C驱动分析

一:前言 I2c是philips提出的外设总线.I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL.正因为这样,它方便了工程人员的布线.另外,I2C是一种多主机控制总线.它和USB总线不同,USB是基于master-slave机制,任何设备的通信必须由主机发起才可以.而I2C是基于multi master机制.一同总线上可允许多个master.关于I2C协议的知识,这里不再赘述.可自行下载spec阅读即可. 二:I2C架构概述 在linux中,I2C驱动架构如下所示: 如上图所示,每一条I2C对应一个adapter.在kernel中,每一个adapter提供了一个描述的结构(struct i2c_adapter),也定义了adapter支持的操作(struct i2c_adapter).再通过i2c core层将i2c 设备与i2c adapter关联起来.

这个图只是提供了一个大概的框架.在下面的代码分析中,从下至上的来分析这个框架图.以下的代码分析是基于linux 2.6.26.分析的代码基本位于: linux-2.6.26.3/drivers/i2c/位置. 三:adapter注册 在kernel中提供了两个adapter注册接口,分别为i2c_add_adapter()和i2c_add_numbered_adapter().由于在系统中可能存在多个adapter,因为将每一条I2C总线对应一个编号,下文中称为I2C总线号.这个总线号的PCI中的总线号不同.它和硬件无关,只是软件上便于区分而已. 对于i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,如果这个总线号非法或者是被占用,就会注册失败. 分别来看一下这两个函数的代码: int i2c_add_adapter(struct i2c_adapter *adapter) { int id, res = 0; retry: if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) return -ENOMEM; mutex_lock(&core_lock); /* "above" here means "above or equal to", sigh */ res = idr_get_new_above(&i2c_adapter_idr, adapter, __i2c_first_dynamic_bus_num, &id); mutex_unlock(&core_lock); if (res < 0) { if (res == -EAGAIN) goto retry; return res; } adapter->nr = id; return i2c_register_adapter(adapter); } 在这里涉及到一个idr结构.idr结构本来是为了配合page cache中的radix tree而设计的.在这里我们只需要知道,它是一种高效的搜索树,且这个树预先存放了一些内存.避免在内存不够的时候出现问题.所在,在往idr中插入结构的时候,首先要调用idr_pre_get()为它预留足够的空闲内存,然后再调用idr_get_new_above()将结构插入idr中,该函数以参数的形式返回一个id.以后凭这个id就可以在idr中找到相对应的结构了.对这个数据结构操作不太理解的可以查阅本站<< linux文件系统之文件的读写>>中有关radix tree的分析. 注意一下idr_get_new_above(&i2c_adapter_idr, adapter,__i2c_first_dynamic_bus_num, &id)的参数的含义,它是将adapter结构插入到i2c_adapter_idr中,存放位置的id必须要大于或者等于__i2c_first_dynamic_bus_num,

相关主题
文本预览
相关文档 最新文档