LINUX下I2C框架.doc_第1页
LINUX下I2C框架.doc_第2页
LINUX下I2C框架.doc_第3页
LINUX下I2C框架.doc_第4页
LINUX下I2C框架.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于2440板子,linux内核下的I2C,操作E2PROM分析篇:AT24C02 LINUX I2C架构分析:简化:设备驱动层:提供策略(我们90%的任务)。(E2PROM驱动 /触摸屏驱动 /传感器驱动)总线驱动层:提供一个硬件操作能力。I2C控制驱动(总线驱动)在芯片(S3C2410)生产出来的时候生产厂商就已经写好了,且永远不变(1类芯片对应1种控制器驱动,控制器驱动就是去操作各种寄存器的值,实现标准I2C时序)I2C核心层:的作用在这就体现出来了,得用它来承上启下,连接设备驱动和总线驱动。open 最主要就是第5步(前面绕来绕去的不用管),1,打开open时,将获取到的adap (2440就一个)放到临时变量client结构中;2,将client挂到到file-private_data中。供以后读写使用。这样适配器adap就和file建立了某种联系。第二步的三个结构体都是临时变量。I2c_transfer() :只负责将Msg 给 adap。这个函数非常通用。不管读写,最终都会调用使用篇:每一个read, write 都会构建一个msg结构体(已包含从器件地址)并自动地先发送从器件地址,再发送后面的段内地址和数据。注意:赋值的地址应该右移1位因为底层处理的时候,会将传下去的数据左移1位取其最低7位。所以实际器件地址是0xa0 (1010 0000),应用程序中应该是0x50 (0101 0000),当从控制I2C到另一个器件时,需要改的是从机地址(当然,也有片内地址)当增加适配器时,还需注意器件时挂在哪个适配器上。去掉此项为去掉通用接口,需自己写I2C驱动.此项为控制器驱动.附件/*利用通用驱动程序,在应用层使用 I2C*/#include#include#include#include#include#define I2C_SLAVE 0X0703int main (int argc,char *argv)/1,open device file int fd; int adapter_nr = 0; /* probably dynamically determined */ char filename20; char buf10;char rbuf10;unsigned char addr_data = 0x00; snprintf(filename, 19, /dev/i2c-%d, adapter_nr); fd = open(filename, O_RDWR); if (file 0) printf(open device file fail!n); return -1;/2,set slave addrint addr = 0x50; /* The I2C address ,0xa0 wrong, should be 0x50*/ ioctl(fd, I2C_SLAVE, addr);/3,send slave addr, register_addr(addr_data) and data buf0 = addr_data; buf1 = 0x92;/datawrite(fd, buf, 2);/*the write cmd will build a struct msg which contain the slave_addr, and send slave_addr first.*/4,read addr/4.1 send register addrwrite(fd,&addr_data,1);/4.2 read dataread(fd,&rbuf,1);printf(rbuf0 = 0x%xn,rbuf0);E2PROM驱动:(有误,可以参考大概思路)/*参照i2c-dev.c通用接口驱动,ds1682.c*/*参照i2c-dev.c通用接口驱动,ds1682.c*/#include#include#include#include#include#include#includeunsigned int gec_e2prom_major =0;struct class *gec_dev_class =NULL;/*不必深究,注意改动从器件地址0x50和 gec_e2prom_address_data*/static unsigned short ignore=I2C_CLIENT_END;static unsigned short normal_addr=0x50,I2C_CLIENT_END;static struct i2c_client_address_data gec_e2prom_address_data=.normal_i2c = normal_addr,.probe = ignore,.ignore = ignore,;/*不必深究,注意改动从器件地址0x50和 gec_e2prom_address_data*/struct i2c_client *gec_e2prom_client;static char wbut10;static char rbut10;static int gec_i2cdev_attach_adapter(struct i2c_adapter *adap)static int gec_i2cdev_attach_adapter(struct i2c_adapter *adap)static ssize_t gec_i2cdev_write(struct file *file, const char _user *buf, size_t count, loff_t *opps)/*1,构建1个消息结构体*/struct i2c_msg e2prom_msg1;/*2,设置片内地址*/wbut0 = 0x0;/*3要发的数据*/copy_from_user(&wbut1,buf,count);/*设置此结构体*/e2prom_mes0.addr = gec_e2prom_client-addr;e2prom_mes0.flags = 0;e2prom_mes0.len = count +1; /+1是加上片内地址e2prom_mes0.buf = wbut;/*发送数据到底层*/i2c_transfer(gec_e2prom_client-adapter,e2prom_msg,1);return static ssize_t gec_i2cdev_read(struct file *file, const char _user *buf, size_t count, loff_t *opps)int ret;/*1.构建两个msg结构体*/struct i2c_msg e2prom_msg2;wbuf0=0x0;/*2先发片内地址*/e2prom_mes0.addr = gec_e2prom_client-addr;e2prom_mes0.flags = 0;e2prom_mes0.len = 1;e2prom_mes0.buf = &wbuf0;/*3 读数据 msg*/e2prom_mes1.addr = gec_e2prom_client-addr;e2prom_mes1.flags = I2C_M_RD;/1e2prom_mes1.len = count;e2prom_mes1.buf = rbut;/*发送MSG数据到底层*/i2c_transfer(gec_e2prom_client-adapter,e2prom_msg,2);ret = copy_to_user(buf,rbut,count);return 0;static const struct file_operations gec_i2cdev_fops = .owner= THIS_MODULE,.read= gec_i2cdev_read,.write= gec_i2cdev_write,;/*调用此函数,说明设备存在, *设备存在就应该构建一个结构体来描述 */static int gec_e2prom_detect(struct i2c_adapter *adap,int address,int kind)/*1,构建一个i2c_client来描述此设备*/*放到全局变量去了*/gec_e2prom_client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL);/*2,设置此结构体*/gec_e2prom_client-addr =0x50;gec_e2prom_client-adapter = adap;gec_e2prom_client-driver = &gec_i2cdev_driver;/*3,加载此结构体*/i2c_attach_client(gec_e2prom_client);return 0;static struct i2c_driver gec_i2cdev_driver = .driver = .name= gec_e2prom_driver,.attach_adapter= gec_i2cdev_attach_adapter,.detach_adapter= gec_i2cdev_detach_adapter,;/*检测设备是否存在,利用adpa发地址数据,如果有响应,则设备存在,* 设备存在则调用gec_e2prom_detect函数*/static int gec_i2cdev_attach_adapter (struct i2c_adapter *adap)/*调用probe函数实现上述功能*/i2c_probe(adap,&gec_e2prom_address_data,gec_e2prom_detect);return 0;static int gec_i2cdev_detach_adapter (struct i2c_adapter *adap)/kfree(gec_e2prom_client);return 0;static int gec_e2prom_init(void)/*1,向上层提供接口*/gec_e2prom_major = register_chrdev(0,gec_i2c_e2prom,gec_i2cdev_fops);/*2,创建设备文件*/gec_dev_class = class_create(THIS_MODULE,gec_dev_class);device_create(gec_dev_class,NULL,MKDEV(gec_e2prom_major,0),NULL,gec_e2prom);/*加载一个I2C驱动*/i2_add_driver(&gec_i2cdev_driver);return 0;static void gec_e2prom_exit(void)unregister_chrdev(gec_e2prom_major,gec_i2c_e2prom);device_destroy(gec_dev_class,MKDEV(gec_e2prom_major,0);class_destroy(gec_dev_class);i2c_del_driver(&gec_i2cdev_driver);module_init(gec_e2prom_init);module_exit(gec_e2prom_exit);MODULE_LICENSE(GPL);/*/应用程序/* * ./xx s val

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论