﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-luofuchong</title><link>http://www.cnitblog.com/luofuchong/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 02 Dec 2008 01:24:24 GMT</lastBuildDate><pubDate>Tue, 02 Dec 2008 01:24:24 GMT</pubDate><ttl>60</ttl><item><title>【转】终端驱动原理篇</title><link>http://www.cnitblog.com/luofuchong/archive/2008/10/07/49936.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Tue, 07 Oct 2008 03:50:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/10/07/49936.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/49936.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/10/07/49936.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/49936.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/49936.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 第十四章&nbsp; Linux终端设备驱动本章导读在Linux系统中，终端设备非常重要，没有终端设备，系统将无法向用户反馈信息，Linux中包含控制台、串口和伪终端3类终端设备。 14.1节阐述了终端设备的概念及分类，14.2节给出了Linux终端设备驱动的框架结构，重点描述tty_driver结构体及其成员。14.3~14.5节在14.2节的基础上，分别给出了Linux终端设备驱动模块...&nbsp;&nbsp;<a href='http://www.cnitblog.com/luofuchong/archive/2008/10/07/49936.html'>阅读全文</a><img src ="http://www.cnitblog.com/luofuchong/aggbug/49936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-10-07 11:50 <a href="http://www.cnitblog.com/luofuchong/archive/2008/10/07/49936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>i2c总线使用</title><link>http://www.cnitblog.com/luofuchong/archive/2008/10/05/49882.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sun, 05 Oct 2008 15:44:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/10/05/49882.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/49882.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/10/05/49882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/49882.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/49882.html</trackback:ping><description><![CDATA[了解了i2c总线的主要结构成员及适配器、设备驱动的注册后，现在我们从上而下的来研究一下i2c总线的使用(仍然以i2c-dev.c为例)：<br><br>1、这是面向用户的虚拟字符设备所提供的所有i2c总线操作接口函数：<br>static const struct file_operations i2cdev_fops = {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = THIS_MODULE,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .llseek&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = no_llseek,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = i2cdev_read,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = i2cdev_write,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ioctl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = i2cdev_ioctl,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .open&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = i2cdev_open,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .release&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = i2cdev_release,<br>};<br><br>1)drivers/i2c/i2c-dev.c<br>static int i2cdev_open(struct inode *inode, struct file *file)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int minor = iminor(inode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_client *client;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_adapter *adap;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_dev *i2c_dev;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i2c_dev = i2c_dev_get_by_minor(minor);&nbsp;&nbsp;&nbsp; //通过设备文件的从设备号查找对应的i2c_dev<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!i2c_dev)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENODEV;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adap = i2c_get_adapter(i2c_dev-&gt;adap-&gt;nr);&nbsp;&nbsp;&nbsp; //查找对于的adap<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!adap)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENODEV;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client = kzalloc(sizeof(*client), GFP_KERNEL);&nbsp;&nbsp;&nbsp; //i2c从设备描述结构体<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!client) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i2c_put_adapter(adap);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snprintf(client-&gt;name, I2C_NAME_SIZE, "i2c-dev %d", adap-&gt;nr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client-&gt;driver = &amp;i2cdev_driver;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* registered with adapter, passed as client to user */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client-&gt;adapter = adap;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file-&gt;private_data = client;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br>注：<br>&nbsp;&nbsp;&nbsp; i2cdev_open的主要作用是构建并初始化用于描述i2c从设备的结构体struct i2c_client。<br><br>2)drivers/i2c/i2c-dev.c<br>i2cdev_read<br>&nbsp;&nbsp;&nbsp; -&gt; i2c_master_recv<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; i2c_transfer <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; adap-&gt;algo-&gt;master_xfer(s3c24xx_i2c_xfer)<br><br>3)drivers/i2c/i2c-dev.c<br>i2cdev_write <br>&nbsp;&nbsp;&nbsp; -&gt; i2c_master_send<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; i2c_transfer<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; adap-&gt;algo-&gt;master_xfer(s3c24xx_i2c_xfer)<br><br><br><br>7)drivers/i2c/busses/i2c-s3c2410.c <br>s3c24xx_i2c_xfer <br>&nbsp;&nbsp;&nbsp; -&gt; s3c24xx_i2c_doxfer(wait_event_timeout(i2c-&gt;wait, i2c-&gt;msg_num == 0, HZ * 5)) &lt;----|<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; s3c24xx_i2c_irq&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; i2s_s3c_irq_nextbyte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; s3c24xx_i2c_stop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -&gt; s3c24xx_i2c_master_complete(wake_up(&amp;i2c-&gt;wait))------------------|<br><br><br>    <img src ="http://www.cnitblog.com/luofuchong/aggbug/49882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-10-05 23:44 <a href="http://www.cnitblog.com/luofuchong/archive/2008/10/05/49882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>i2c总线上，适配器、设备驱动注册</title><link>http://www.cnitblog.com/luofuchong/archive/2008/10/05/49881.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sun, 05 Oct 2008 15:43:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/10/05/49881.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/49881.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/10/05/49881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/49881.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/49881.html</trackback:ping><description><![CDATA[1、总线适配器注册：<br>1)drivers/i2c/i2c-core.c<br>int i2c_add_adapter(struct i2c_adapter *adapter)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; id, res = 0;<br><br>retry:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (idr_pre_get(&amp;i2c_adapter_idr, GFP_KERNEL) == 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_lock(&amp;core_lists);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* "above" here means "above or equal to", sigh */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = idr_get_new_above(&amp;i2c_adapter_idr, adapter,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __i2c_first_dynamic_bus_num, &amp;id);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_unlock(&amp;core_lists);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (res &lt; 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (res == -EAGAIN)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto retry;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return res;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter-&gt;nr = id;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //使用动态的总线号来标识总线适配器。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i2c_register_adapter(adapter);<br>}<br>EXPORT_SYMBOL(i2c_add_adapter);<br><br>2)drivers/i2c/i2c-core.c<br>static int i2c_register_adapter(struct i2c_adapter *adap)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int res = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct list_head&nbsp;&nbsp; *item;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_driver&nbsp; *driver;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_init(&amp;adap-&gt;bus_lock);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //初始化总线访问控制变量(总线上数据传输时使用)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_init(&amp;adap-&gt;clist_lock);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //初始化客户端访问控制变量(操作客户端结构时使用)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INIT_LIST_HEAD(&amp;adap-&gt;clients);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //初始化客户端链表头<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_lock(&amp;core_lists);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_add_tail(&amp;adap-&gt;list, &amp;adapters);&nbsp;&nbsp;&nbsp; //添加到总线适配器链表中<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Add the adapter to the driver core.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * If the parent pointer is not set up,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * we add this adapter to the host bus.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (adap-&gt;dev.parent == NULL) {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adap-&gt;dev.parent = &amp;platform_bus;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pr_debug("I2C adapter driver [%s] forgot to specify "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "physical device\n", adap-&gt;name);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(adap-&gt;dev.bus_id, "i2c-%d", adap-&gt;nr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adap-&gt;dev.release = &amp;i2c_adapter_dev_release;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adap-&gt;dev.class = &amp;i2c_adapter_class;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = device_register(&amp;adap-&gt;dev);&nbsp;&nbsp;&nbsp; //注册设备<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (res)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto out_list;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(&amp;adap-&gt;dev, "adapter [%s] registered\n", adap-&gt;name);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* create pre-declared device nodes for new-style drivers */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (adap-&gt;nr &lt; __i2c_first_dynamic_bus_num)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i2c_scan_static_board_info(adap);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* let legacy drivers scan this bus for matching devices */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_for_each(item,&amp;drivers) {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //搜索总线上的所有设备驱动，通过调用其attach_adapter接口函数，查找匹配的设备。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver = list_entry(item, struct i2c_driver, list);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (driver-&gt;attach_adapter)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We ignore the return code; if it fails, too bad */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver-&gt;attach_adapter(adap);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>out_unlock:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_unlock(&amp;core_lists);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return res;<br><br>out_list:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_del(&amp;adap-&gt;list);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idr_remove(&amp;i2c_adapter_idr, adap-&gt;nr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto out_unlock;<br>}<br><br>2、设备驱动注册(以i2c-dev.c为例)：<br>1)include/linux/i2c.h<br>static inline int i2c_add_driver(struct i2c_driver *driver)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i2c_register_driver(THIS_MODULE, driver);<br>}<br><br>2)drivers/i2c/i2c-core.c<br>int i2c_register_driver(struct module *owner, struct i2c_driver *driver)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int res;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* new style driver methods can't mix with legacy ones */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (is_newstyle_driver(driver)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (driver-&gt;attach_adapter || driver-&gt;detach_adapter<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || driver-&gt;detach_client) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_WARNING<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "i2c-core: driver [%s] is confused\n",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver-&gt;driver.name);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* add the driver to the list of i2c drivers in the driver core */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver-&gt;driver.owner = owner;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver-&gt;driver.bus = &amp;i2c_bus_type;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for new style drivers, when registration returns the driver core<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * will have called probe() for all matching-but-unbound devices.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = driver_register(&amp;driver-&gt;driver);&nbsp;&nbsp;&nbsp; //注册驱动<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (res)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return res;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_lock(&amp;core_lists);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_add_tail(&amp;driver-&gt;list,&amp;drivers);&nbsp;&nbsp;&nbsp; //添加到设备驱动链表中<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pr_debug("i2c-core: driver [%s] registered\n", driver-&gt;driver.name);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* legacy drivers scan i2c busses directly */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (driver-&gt;attach_adapter) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_adapter *adapter;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_for_each_entry(adapter, &amp;adapters, list) {&nbsp;&nbsp;&nbsp; //让设备驱动搜索匹配的适配器(通过调用其attach_adapter接口)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver-&gt;attach_adapter(adapter);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_unlock(&amp;core_lists);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br>EXPORT_SYMBOL(i2c_register_driver);<br><br>3)drivers/i2c/i2c-dev.c<br>static int i2cdev_attach_adapter(struct i2c_adapter *adap)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_dev *i2c_dev;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int res;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i2c_dev = get_free_i2c_dev(adap);&nbsp;&nbsp;&nbsp; //创建并初始化i2c_dev结构<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (IS_ERR(i2c_dev))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return PTR_ERR(i2c_dev);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* register this i2c device with the driver core */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i2c_dev-&gt;dev = device_create(i2c_dev_class, &amp;adap-&gt;dev,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //注意，这里使用的次设备号为adap-&gt;nr，便于以后获取adap结构。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MKDEV(I2C_MAJOR, adap-&gt;nr),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "i2c-%d", adap-&gt;nr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (IS_ERR(i2c_dev-&gt;dev)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = PTR_ERR(i2c_dev-&gt;dev);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = device_create_file(i2c_dev-&gt;dev, &amp;dev_attr_name);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //创建设备文件<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (res)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error_destroy;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adap-&gt;name, adap-&gt;nr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>error_destroy:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap-&gt;nr));<br>error:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return_i2c_dev(i2c_dev);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return res;<br>}<br><br>总结：<br>&nbsp;&nbsp;&nbsp; 一个适配器对应一个i2c控制器。<br><br><br><img src ="http://www.cnitblog.com/luofuchong/aggbug/49881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-10-05 23:43 <a href="http://www.cnitblog.com/luofuchong/archive/2008/10/05/49881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>i2c关键结构体分析</title><link>http://www.cnitblog.com/luofuchong/archive/2008/09/15/49114.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Mon, 15 Sep 2008 15:38:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/09/15/49114.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/49114.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/09/15/49114.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/49114.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/49114.html</trackback:ping><description><![CDATA[1、总线配置结构体：<br>struct s3c2410_platform_i2c {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp; flags;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp; slave_addr;&nbsp;&nbsp;&nbsp;&nbsp; /* slave address for controller */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long&nbsp;&nbsp; bus_freq;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* standard bus frequency */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long&nbsp;&nbsp; max_freq;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* max frequency for the bus */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long&nbsp;&nbsp; min_freq;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* min frequency for the bus */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp; sda_delay;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pclks (s3c2440 only) */<br>};<br><br>2、总线描述结构体：<br>struct s3c24xx_i2c {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinlock_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lock;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//自选锁(防止总线资源被并发访问)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait_queue_head_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//等待队列(当有数据需要收/发时启动总线，然后守候在等待队列，直到数据收/发结束后被唤醒返回)<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_msg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *msg;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//i2c信息指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg_num;&nbsp;&nbsp; &nbsp;//需要传输的i2c msg数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg_idx;&nbsp;&nbsp; &nbsp;//成功传输的i2c msg数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg_ptr;&nbsp;&nbsp; &nbsp;//当前i2c msg内指针<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tx_setup;&nbsp;&nbsp; &nbsp;//延时值(保证总线启动时数据已经传输到总线上)<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum s3c24xx_i2c_state&nbsp; state;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//i2c总线状态<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __iomem&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *regs;：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct clk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *clk;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct device&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dev;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct resource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *irq;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct resource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ioarea;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct i2c_adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adap;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//总线适配器(个人觉得它更像设备驱动中的设备而非驱动)<br>};<br><br>3、总线适配器：<br>struct i2c_adapter {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct module *owner;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int id;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int class;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct i2c_algorithm *algo; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//i2c总线访问算法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *algo_data;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//用来保存struct s3c24xx_i2c结构指针<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* --- administration stuff. */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*client_register)(struct i2c_client *);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*client_unregister)(struct i2c_client *);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* data fields that are valid for all devices&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 level;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//nesting level for lockdep<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mutex bus_lock;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mutex clist_lock;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int timeout;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int retries;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct device dev;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//the adapter device<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nr;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct list_head clients;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct list_head list;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char name[48];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct completion dev_released;<br>};<br><br>4、总线访问算法：<br>struct i2c_algorithm {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If an adapter algorithm can't do I2C-level access, set master_xfer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to NULL. If an adapter algorithm can do SMBus access, set<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; smbus_xfer. If set to NULL, the SMBus protocol is simulated<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using common I2C messages */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* master_xfer should return the number of messages successfully<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processed, or a negative value on error */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,&nbsp;&nbsp; &nbsp;//i2c msg发送函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int num);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned short flags, char read_write,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 command, int size, union i2c_smbus_data * data);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* --- ioctl like call to set div. parameters. */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* To determine what the adapter supports */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 (*functionality) (struct i2c_adapter *);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//标志i2c适配器所支持的功能<br>};<br><br>struct i2c_msg {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __u16 addr;&nbsp;&nbsp;&nbsp;&nbsp; /* slave address&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __u16 flags;<br>#define I2C_M_TEN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10&nbsp;&nbsp;&nbsp; /* we have a ten bit chip address&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>#define I2C_M_RD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x01<br>#define I2C_M_NOSTART&nbsp;&nbsp; 0x4000<br>#define I2C_M_REV_DIR_ADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x2000<br>#define I2C_M_IGNORE_NAK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1000<br>#define I2C_M_NO_RD_ACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0800<br>#define I2C_M_RECV_LEN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0400 /* length will be first received byte */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __u16 len;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* msg length&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __u8 *buf;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pointer to msg data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>};<br><br>这里有我画的简单i2c重要结构体分析图：<br>http://www.cnitblog.com/Files/luofuchong/i2c%E9%87%8D%E8%A6%81%E7%BB%93%E6%9E%84%E4%BD%93.rar<br> <img src ="http://www.cnitblog.com/luofuchong/aggbug/49114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-09-15 23:38 <a href="http://www.cnitblog.com/luofuchong/archive/2008/09/15/49114.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：Linux I2C 驱动分析</title><link>http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sat, 23 Aug 2008 03:01:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/48280.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/48280.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/48280.html</trackback:ping><description><![CDATA[最近在看Linux 2.6.21内核的I2C驱动，也在网上查了一下资料，有错也有对，有些心得，记录下来吧。里面认识或许多有不当之处，还恳请指正。
<div>&nbsp;</div>
<div>1. I2C 协议</div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><span></span></span></v:shapetype></span>&nbsp;</div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><v:shapetype coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><span>&nbsp;</span>1.1&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">总线工作原理</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;"> </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;" lang="EN-US"><o:p></o:p></span></v:shapetype></span></div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">总线是由数据线</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">SDA</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">和时钟</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">构成的串行总线，各种被控制器件均并联在这条总线上，每个器件都有一个唯一的地址识别，可以作为总线上的一个发送器件或接收器件</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">(</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">具体由器件的功能决定</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">)</span></div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">1.2&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">总线的几种信号状态</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></span></div>
<div>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">空闲状态：</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">和</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">都为高电平。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">开始条件</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">(S)</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">：</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">为高电平时，</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">由高电平向低电平跳变，开始传送数据。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">结束条件</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">(P)</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">：</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">为低电平时，</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">由低电平向高电平跳变，结束传送数据。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">数据有效：在</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">的高电平期间，</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"> SDA</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">保持稳定，数据有效。</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">的改变只能发生在</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">的底电平期间。</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;">&nbsp;</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">5.&nbsp; ACK</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">信号</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">: </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">数据传输的过程中，接收器件每接收一个字节数据要产生一个</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">ACK</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">信号，向发送器件发出特定的低电平脉冲，表示已经收到数据。</font></span></p>
<span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">1.3&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">总线基本操作</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;"> <span lang="EN-US"><o:p></o:p></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">总线必须由主器件（通常为微控制器）控制，主器件产生串行时钟（</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">），同时控制总线的传输方向，并产生开始和停止条件。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">数据传输中，首先主器件产生开始条件，随后是器件的控制字节（前七位是从器件的地址，最后一位为读写位</span><span style="font-size: 9pt; color: #3b3b3b; font-family: Verdana;"> </span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">）。接下来是读写操作的数据，以及</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"> ACK</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">响应信号。数据传输结束时，主器件产生停止条件</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"></span>&nbsp;</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><strong>2. Linux I2C 结构分析</strong></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">2.1 层次分析</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">1. I2C Core</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">&nbsp;I2C Core<font size="2">用于维护Linux的I2C核心部分，<span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">其中维护了两个静态的</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">List</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">，分别记录系统中的</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> driver</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">结构和</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> adapter</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">结构。</span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"></span></font></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">static LIST_HEAD(adapters);</span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;">static LIST_HEAD(drivers);</font></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> core</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">提供接口函数，允许一个</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> adatper</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">，</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> driver</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">和</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> client</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">初始化时在</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> core</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">中进行注册，以及退出时进行注销。具体可以参见i2c_core.c代码。</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">同时还提供了</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">总线读写访问的一般接口（具体的实现在与</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">控制器相关的</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> adapter</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">中实现），主要应用在</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">设备驱动中。</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">常用的主要是</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">i2c_master_send()</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">i2c_master_recv()</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">i2c_transfer()</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"></span></span></font></span>&nbsp;</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">2. I2C&nbsp;bus driver</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;">总线驱动的职责，是为系统中每个</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯，它只是存在在那里，等待设备驱动调用其函数。</span></span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"></span></span></span></font></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">在系统开机时，首先装载的是</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">总线驱动。一个总线驱动用于支持一条特定的</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">总线的读写。一个总线驱动通常需要两个模块，一个</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_adapter</font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">和一个</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_algorithm</font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">来描述：</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman"> </font></span></span></span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">在
buses目录下的i2c-pxa.c中实现了PXA的I2C总线适配器，I2C adapter 构造一个对I2C
core层接口的数据结构，并通过接口函数向I2C core注册一个控制器。I2C
adapter主要实现对I2C总线访问的算法，iic_xfer() 函数就是I2C adapter底层对I2C总线读写方法的实现。同时I2C
adpter 中还实现了对I2C控制器中断的处理函数。 <br></font></span></span></span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">1) i2c-pxa.c定义了i2c_algorithm，并且实现了master的发送函数i2c_pxa_xfer()，以及设备查询总线的模式的函数i2c_pxa_functionality()</font></span></span></span></span></font></span></p>
</span>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 24pt; line-height: 150%; text-align: left;" align="left"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font size="2"><font face="Times New Roman"><o:p>
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>static const struct i2c_algorithm i2c_pxa_algorithm = {<br>&nbsp;.master_xfer&nbsp;= i2c_pxa_xfer,<br>&nbsp;.functionality&nbsp;= i2c_pxa_functionality,<br>};</td>
        </tr>
    </tbody>
</table>
</o:p></font></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2">2) i2c-pxa.c中，实现了i2c_adapter，主要是在定义pxa-i2c时进行初始化，并且i2c_pxa_probe()中进行填充parent指针，并且调用</font></span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2">ret = i2c_add_adapter(&amp;i2c-&gt;adap);</font></span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2">进行添加。 </font></span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>static struct pxa_i2c i2c_pxa = {<br>&nbsp;.lock&nbsp;= SPIN_LOCK_UNLOCKED,<br>&nbsp;.adap&nbsp;= {<br>&nbsp;&nbsp;.owner&nbsp;&nbsp;= THIS_MODULE,<br>&nbsp;&nbsp;.algo&nbsp;&nbsp;= &amp;i2c_pxa_algorithm,<br>&nbsp;&nbsp;.name&nbsp;&nbsp;= "pxa2xx-i2c.0",<br>&nbsp;&nbsp;.retries&nbsp;= 5,<br>&nbsp;},<br>};</td>
        </tr>
    </tbody>
</table>
</span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">总的来说，在i2c-pxa中，使用platform驱动模型，完成了i2c的总线两种模块<span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_adapter</font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">和</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_algorithm</font></span></span></font></span></p>
<span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"></span></span></font></span></div>
<span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"></span>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">&nbsp;</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">3. I2C device driver</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">I2C只有总线驱动是不够的，必须有设备才能工作。这就是I2C device driver的必要性。I2C的device是有<span style="font-size: 9pt; color: black; font-family: 宋体;">两个模块来描述的，</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_driver</font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">和</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_client</font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">。</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">在介绍chips目录下的device driver前有必要介绍一下i2c-dev.c文件。</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font>i2c-dev.c中提供了一个通用的I2C设备的驱动程序，实现了字符类
型设备的访问接口，对设备的具体访问是通过I2C adapter来实现的。构造一个对I2C core层接口的数据结构，通过接口函数向 I2C
Core注册一个I2C设备驱动。同时构造一个对用户层接口的数据结构，并通过接口函数向内核注册为一个主设备号为89的字符类型设备。</p>
<p>
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>
            <p>static struct i2c_driver i2cdev_driver = {<br>&nbsp;.driver = {<br>&nbsp;&nbsp;.name&nbsp;= "dev_driver",<br>&nbsp;},<br>&nbsp;.id&nbsp;&nbsp;= I2C_DRIVERID_I2CDEV,<br>&nbsp;.attach_adapter&nbsp;= i2cdev_attach_adapter,<br>&nbsp;.detach_adapter&nbsp;= i2cdev_detach_adapter,<br>&nbsp;.detach_client&nbsp;= i2cdev_detach_client,<br>};</p>
            <p>struct i2c_dev {<br>&nbsp;struct list_head list;<br>&nbsp;struct i2c_adapter *adap;<br>&nbsp;struct device *dev;<br>};</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">该
文件提供了用户层对I2C设备的访问，包括open，read，write，ioctl，release等常规文件操作，我们可以通过open函数打开
I2C的设备文件，通过ioctl函数设定要访问从设备的地址，然后就可以通过 read和write函数完成对I2C设备的读写操作。</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>static const struct file_operations i2cdev_fops = {<br>&nbsp;.owner&nbsp;&nbsp;= THIS_MODULE,<br>&nbsp;.llseek&nbsp;&nbsp;= no_llseek,<br>&nbsp;.read&nbsp;&nbsp;= i2cdev_read,<br>&nbsp;.write&nbsp;&nbsp;= i2cdev_write,<br>&nbsp;.ioctl&nbsp;&nbsp;= i2cdev_ioctl,<br>&nbsp;.open&nbsp;&nbsp;= i2cdev_open,<br>&nbsp;.release&nbsp;= i2cdev_release,<br>};</td>
        </tr>
    </tbody>
</table>
</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注：</font>通过I2C
driver提供的通用方法可以访问任何一个I2C的设备，但是其中实现的read，write及ioctl等功能完全是基于一般设备的实现，所有的操作
数据都是基于字节流，没有明确的格式和意义。为了更方便和有效地使用I2C设备，我们可以为一个具体的I2C设备开发特定的I2C设备驱动程序，在驱动中
完成对特定的数据格式的解释以及实现一些专用的功能。</p>
<p>在chips目录下包含着各种device 的driver，完成各种从设备的注册。作为一般的I2C设备，使用i2c-dev.c里的操作足够完成操作了。</p>
<p>当然如果不能完成，则需要独立完成该驱动，这就是chips目录下的代码。
因为i2c-dev.c已经实现了I2C设备的文件操作接口，所以只要实现struct
i2c_driver就可以了。对于某些特殊的操作，可以使用command接口进行控制。 当然，对于i2接口的fm芯片，则将struct
i2c_driver放在i2c的chips目录下，而将另外fm操作相关的代码放在了/media/radio目录下了。在这个目录下需要完成读写接口
的完成，这个大部分使用V4L2架构。</p>
<p>继续分析中&#8230;&#8230;</p>
</span></font></span></span></span><img src ="http://www.cnitblog.com/luofuchong/aggbug/48280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-08-23 11:01 <a href="http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一点想法</title><link>http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sun, 17 Aug 2008 02:48:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/48081.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/48081.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/48081.html</trackback:ping><description><![CDATA[kernel：linux-2.6.22<br><br>发现linux下字符驱动用的越来越少了，感觉就剩key、led、rtc还在用了(内核下都有现成的~_~)，而且都是因为ioctl的缘故而保留的。<br>记得曾经在一本书上看到介绍说ioctl机制不好，在以后的内核中会被逐渐摒弃之类的。<br>如果真是这样的话，那需要用到字符驱动的机会就越来越少了(个人意见，有误的话欢迎指正^_^)<br><br>ioctl机制虽然不好，可是发现新版本的内核下字符驱动有了新的应用，重新焕发出生气来：<br>象spi、i2c这些总线驱动，都会提供一些api接口函数，供设备驱动程序调用以操作总线。<br>按照这种思路，如果要操作spi、i2c总线的话，有且只能通过驱动来实现。<br>也就是说：需要编写相应的设备驱动程序来实现。<br>然而，一些基于spi、i2c的设备驱动具有相当的共通性，所以内核下提供了这么一个通用的spi、i2c字符设备驱动供用户直接调用以操作总线，达到操作设备的目的。<br><br>   <img src ="http://www.cnitblog.com/luofuchong/aggbug/48081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-08-17 10:48 <a href="http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【引】Using the initial RAM disk (initrd)</title><link>http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Wed, 28 May 2008 03:40:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/44458.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/44458.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/44458.html</trackback:ping><description><![CDATA[Using the initial RAM disk (initrd)<br>===================================<br><br>Written 1996,2000 by Werner Almesberger &lt;werner.almesberger@epfl.ch&gt; and<br>                     Hans Lermen &lt;lermen@fgan.de&gt;<br><br><br>initrd provides the capability to load a RAM disk by the boot loader.<br>This RAM disk can then be mounted as the root file system and programs<br>can be run from it. Afterwards, a new root file system can be mounted<br>from a different device. The previous root (from initrd) is then moved<br>to a directory and can be subsequently unmounted.<br><br>initrd is mainly designed to allow system startup to occur in two phases,<br>where the kernel comes up with a minimum set of compiled-in drivers, and<br>where additional modules are loaded from initrd.<br><br>This document gives a brief overview of the use of initrd. A more detailed<br>discussion of the boot process can be found in [1].<br><br><br>Operation<br>---------<br><br>When using initrd, the system typically boots as follows:<br><br>  1) the boot loader loads the kernel and the initial RAM disk<br>  2) the kernel converts initrd into a "normal" RAM disk and<br>     frees the memory used by initrd<br>  3) if the root device is not /dev/ram0, the old (deprecated)<br>     change_root procedure is followed. see the "Obsolete root change<br>     mechanism" section below.<br>  4) root device is mounted. if it is /dev/ram0, the initrd image is<br>     then mounted as root<br>  5) /sbin/init is executed (this can be any valid executable, including<br>     shell scripts; it is run with uid 0 and can do basically everything<br>     init can do).<br>  6) init mounts the "real" root file system<br>  7) init places the root file system at the root directory using the<br>     pivot_root system call<br>  8) init execs the /sbin/init on the new root filesystem, performing<br>     the usual boot sequence<br>  9) the initrd file system is removed<br><br>Note that changing the root directory does not involve unmounting it.<br>It is therefore possible to leave processes running on initrd during that<br>procedure. Also note that file systems mounted under initrd continue to<br>be accessible.<br><br><br>Boot command-line options<br>-------------------------<br><br>initrd adds the following new options:<br><br>  initrd=&lt;path&gt;    (e.g. LOADLIN)<br><br>    Loads the specified file as the initial RAM disk. When using LILO, you<br>    have to specify the RAM disk image file in /etc/lilo.conf, using the<br>    INITRD configuration variable.<br><br>  noinitrd<br><br>    initrd data is preserved but it is not converted to a RAM disk and<br>    the "normal" root file system is mounted. initrd data can be read<br>    from /dev/initrd. Note that the data in initrd can have any structure<br>    in this case and doesn't necessarily have to be a file system image.<br>    This option is used mainly for debugging.<br><br>    Note: /dev/initrd is read-only and it can only be used once. As soon<br>    as the last process has closed it, all data is freed and /dev/initrd<br>    can't be opened anymore.<br><br>  root=/dev/ram0<br><br>    initrd is mounted as root, and the normal boot procedure is followed,<br>    with the RAM disk mounted as root.<br><br>Compressed cpio images<br>----------------------<br><br>Recent kernels have support for populating a ramdisk from a compressed cpio<br>archive. On such systems, the creation of a ramdisk image doesn't need to<br>involve special block devices or loopbacks; you merely create a directory on<br>disk with the desired initrd content, cd to that directory, and run (as an<br>example):<br><br>find . | cpio --quiet -H newc -o | gzip -9 -n &gt; /boot/imagefile.img<br><br>Examining the contents of an existing image file is just as simple:<br><br>mkdir /tmp/imagefile<br>cd /tmp/imagefile<br>gzip -cd /boot/imagefile.img | cpio -imd --quiet<br><br>Installation<br>------------<br><br>First, a directory for the initrd file system has to be created on the<br>"normal" root file system, e.g.<br><br># mkdir /initrd<br><br>The name is not relevant. More details can be found on the pivot_root(2)<br>man page.<br><br>If the root file system is created during the boot procedure (i.e. if<br>you're building an install floppy), the root file system creation<br>procedure should create the /initrd directory.<br><br>If initrd will not be mounted in some cases, its content is still<br>accessible if the following device has been created:<br><br># mknod /dev/initrd b 1 250 <br># chmod 400 /dev/initrd<br><br>Second, the kernel has to be compiled with RAM disk support and with<br>support for the initial RAM disk enabled. Also, at least all components<br>needed to execute programs from initrd (e.g. executable format and file<br>system) must be compiled into the kernel.<br><br>Third, you have to create the RAM disk image. This is done by creating a<br>file system on a block device, copying files to it as needed, and then<br>copying the content of the block device to the initrd file. With recent<br>kernels, at least three types of devices are suitable for that:<br><br> - a floppy disk (works everywhere but it's painfully slow)<br> - a RAM disk (fast, but allocates physical memory)<br> - a loopback device (the most elegant solution)<br><br>We'll describe the loopback device method:<br><br> 1) make sure loopback block devices are configured into the kernel<br> 2) create an empty file system of the appropriate size, e.g.<br>    # dd if=/dev/zero of=initrd bs=300k count=1<br>    # mke2fs -F -m0 initrd<br>    (if space is critical, you may want to use the Minix FS instead of Ext2)<br> 3) mount the file system, e.g.<br>    # mount -t ext2 -o loop initrd /mnt<br> 4) create the console device:<br>    # mkdir /mnt/dev<br>    # mknod /mnt/dev/console c 5 1<br> 5) copy all the files that are needed to properly use the initrd<br>    environment. Don't forget the most important file, /sbin/init<br>    Note that /sbin/init's permissions must include "x" (execute).<br> 6) correct operation the initrd environment can frequently be tested<br>    even without rebooting with the command<br>    # chroot /mnt /sbin/init<br>    This is of course limited to initrds that do not interfere with the<br>    general system state (e.g. by reconfiguring network interfaces,<br>    overwriting mounted devices, trying to start already running demons,<br>    etc. Note however that it is usually possible to use pivot_root in<br>    such a chroot'ed initrd environment.)<br> 7) unmount the file system<br>    # umount /mnt<br> 8) the initrd is now in the file "initrd". Optionally, it can now be<br>    compressed<br>    # gzip -9 initrd<br><br>For experimenting with initrd, you may want to take a rescue floppy and<br>only add a symbolic link from /sbin/init to /bin/sh. Alternatively, you<br>can try the experimental newlib environment [2] to create a small<br>initrd.<br><br>Finally, you have to boot the kernel and load initrd. Almost all Linux<br>boot loaders support initrd. Since the boot process is still compatible<br>with an older mechanism, the following boot command line parameters<br>have to be given:<br><br>  root=/dev/ram0 rw<br><br>(rw is only necessary if writing to the initrd file system.)<br><br>With LOADLIN, you simply execute<br><br>     LOADLIN &lt;kernel&gt; initrd=&lt;disk_image&gt;<br>e.g. LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 rw<br><br>With LILO, you add the option INITRD=&lt;path&gt; to either the global section<br>or to the section of the respective kernel in /etc/lilo.conf, and pass<br>the options using APPEND, e.g.<br><br>  image = /bzImage<br>    initrd = /boot/initrd.gz<br>    append = "root=/dev/ram0 rw"<br><br>and run /sbin/lilo<br><br>For other boot loaders, please refer to the respective documentation.<br><br>Now you can boot and enjoy using initrd.<br><br><br>Changing the root device<br>------------------------<br><br>When finished with its duties, init typically changes the root device<br>and proceeds with starting the Linux system on the "real" root device.<br><br>The procedure involves the following steps:<br> - mounting the new root file system<br> - turning it into the root file system<br> - removing all accesses to the old (initrd) root file system<br> - unmounting the initrd file system and de-allocating the RAM disk<br><br>Mounting the new root file system is easy: it just needs to be mounted on<br>a directory under the current root. Example:<br><br># mkdir /new-root<br># mount -o ro /dev/hda1 /new-root<br><br>The root change is accomplished with the pivot_root system call, which<br>is also available via the pivot_root utility (see pivot_root(8) man<br>page; pivot_root is distributed with util-linux version 2.10h or higher<br>[3]). pivot_root moves the current root to a directory under the new<br>root, and puts the new root at its place. The directory for the old root<br>must exist before calling pivot_root. Example:<br><br># cd /new-root<br># mkdir initrd<br># pivot_root . initrd<br><br>Now, the init process may still access the old root via its<br>executable, shared libraries, standard input/output/error, and its<br>current root directory. All these references are dropped by the<br>following command:<br><br># exec chroot . what-follows &lt;dev/console &gt;dev/console 2&gt;&amp;1<br><br>Where what-follows is a program under the new root, e.g. /sbin/init<br>If the new root file system will be used with udev and has no valid<br>/dev directory, udev must be initialized before invoking chroot in order<br>to provide /dev/console.<br><br>Note: implementation details of pivot_root may change with time. In order<br>to ensure compatibility, the following points should be observed:<br><br> - before calling pivot_root, the current directory of the invoking<br>   process should point to the new root directory<br> - use . as the first argument, and the _relative_ path of the directory<br>   for the old root as the second argument<br> - a chroot program must be available under the old and the new root<br> - chroot to the new root afterwards<br> - use relative paths for dev/console in the exec command<br><br>Now, the initrd can be unmounted and the memory allocated by the RAM<br>disk can be freed:<br><br># umount /initrd<br># blockdev --flushbufs /dev/ram0<br><br>It is also possible to use initrd with an NFS-mounted root, see the<br>pivot_root(8) man page for details.<br><br><br>Usage scenarios<br>---------------<br><br>The main motivation for implementing initrd was to allow for modular<br>kernel configuration at system installation. The procedure would work<br>as follows:<br><br>  1) system boots from floppy or other media with a minimal kernel<br>     (e.g. support for RAM disks, initrd, a.out, and the Ext2 FS) and<br>     loads initrd<br>  2) /sbin/init determines what is needed to (1) mount the "real" root FS<br>     (i.e. device type, device drivers, file system) and (2) the<br>     distribution media (e.g. CD-ROM, network, tape, ...). This can be<br>     done by asking the user, by auto-probing, or by using a hybrid<br>     approach.<br>  3) /sbin/init loads the necessary kernel modules<br>  4) /sbin/init creates and populates the root file system (this doesn't<br>     have to be a very usable system yet)<br>  5) /sbin/init invokes pivot_root to change the root file system and<br>     execs - via chroot - a program that continues the installation<br>  6) the boot loader is installed<br>  7) the boot loader is configured to load an initrd with the set of<br>     modules that was used to bring up the system (e.g. /initrd can be<br>     modified, then unmounted, and finally, the image is written from<br>     /dev/ram0 or /dev/rd/0 to a file)<br>  8) now the system is bootable and additional installation tasks can be<br>     performed<br><br>The key role of initrd here is to re-use the configuration data during<br>normal system operation without requiring the use of a bloated "generic"<br>kernel or re-compiling or re-linking the kernel.<br><br>A second scenario is for installations where Linux runs on systems with<br>different hardware configurations in a single administrative domain. In<br>such cases, it is desirable to generate only a small set of kernels<br>(ideally only one) and to keep the system-specific part of configuration<br>information as small as possible. In this case, a common initrd could be<br>generated with all the necessary modules. Then, only /sbin/init or a file<br>read by it would have to be different.<br><br>A third scenario is more convenient recovery disks, because information<br>like the location of the root FS partition doesn't have to be provided at<br>boot time, but the system loaded from initrd can invoke a user-friendly<br>dialog and it can also perform some sanity checks (or even some form of<br>auto-detection).<br><br>Last not least, CD-ROM distributors may use it for better installation<br>from CD, e.g. by using a boot floppy and bootstrapping a bigger RAM disk<br>via initrd from CD; or by booting via a loader like LOADLIN or directly<br>from the CD-ROM, and loading the RAM disk from CD without need of<br>floppies. <br><br><br>Obsolete root change mechanism<br>------------------------------<br><br>The following mechanism was used before the introduction of pivot_root.<br>Current kernels still support it, but you should _not_ rely on its<br>continued availability.<br><br>It works by mounting the "real" root device (i.e. the one set with rdev<br>in the kernel image or with root=... at the boot command line) as the<br>root file system when linuxrc exits. The initrd file system is then<br>unmounted, or, if it is still busy, moved to a directory /initrd, if<br>such a directory exists on the new root file system.<br><br>In order to use this mechanism, you do not have to specify the boot<br>command options root, init, or rw. (If specified, they will affect<br>the real root file system, not the initrd environment.)<br>  <br>If /proc is mounted, the "real" root device can be changed from within<br>linuxrc by writing the number of the new root FS device to the special<br>file /proc/sys/kernel/real-root-dev, e.g.<br><br>  # echo 0x301 &gt;/proc/sys/kernel/real-root-dev<br><br>Note that the mechanism is incompatible with NFS and similar file<br>systems.<br><br>This old, deprecated mechanism is commonly called "change_root", while<br>the new, supported mechanism is called "pivot_root".<br><br><br>Mixed change_root and pivot_root mechanism<br>------------------------------------------<br><br>In case you did not want to use root=/dev/ram0 to trigger the pivot_root<br>mechanism, you may create both /linuxrc and /sbin/init in your initrd image.<br><br>/linuxrc would contain only the following:<br><br>#! /bin/sh<br>mount -n -t proc proc /proc<br>echo 0x0100 &gt;/proc/sys/kernel/real-root-dev<br>umount -n /proc<br><br>Once linuxrc exited, the kernel would mount again your initrd as root,<br>this time executing /sbin/init. Again, it would be the duty of this init<br>to build the right environment (maybe using the root= device passed on<br>the cmdline) before the final execution of the real /sbin/init.<br><br><br>Resources<br>---------<br><br>[1] Almesberger, Werner; "Booting Linux: The History and the Future"<br>    <a href="http://www.almesberger.net/cv/papers/ols2k-9.ps.gz" target="_blank">http://www.almesberger.net/cv/papers/ols2k-9.ps.gz</a><br>[2] newlib package (experimental), with initrd example<br>    <a href="http://sources.redhat.com/newlib/" target="_blank">http://sources.redhat.com/newlib/</a><br>[3] Brouwer, Andries; "util-linux: Miscellaneous utilities for Linux"<br>    <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux/" target="_blank">ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux/</a> <img src ="http://www.cnitblog.com/luofuchong/aggbug/44458.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-05-28 11:40 <a href="http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>资料收集</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sat, 26 Apr 2008 18:12:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42805.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42805.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42805.html</trackback:ping><description><![CDATA[【引】prayaya：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 一个非常有意思的可移动linux发行版，很多地方值得去研究：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <a href="http://www.inlsd.org/">http://www.inlsd.org/</a><br><br>【转】shell十三问：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <a href="http://www.cnitblog.com/Files/luofuchong/shell%E5%8D%81%E4%B8%89%E9%97%AE.rar">http://www.cnitblog.com/Files/luofuchong/shell%E5%8D%81%E4%B8%89%E9%97%AE.rar</a><br><br>【转】shell经典教程：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <a href="http://www.cnitblog.com/Files/luofuchong/shell%E6%95%99%E7%A8%8B.rar">http://www.cnitblog.com/Files/luofuchong/shell%E6%95%99%E7%A8%8B.rar</a>
<br><br>【转】yaffs2源代码情景分析:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <a href="http://www.cnitblog.com/luofuchong/articles/43334.html">http://www.cnitblog.com/luofuchong/articles/43334.html</a><br><br>【转】基于Video4Linux的USB摄像头图像采集实现：<span style="color: #020000;"></span><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.cnitblog.com/Files/luofuchong/%E5%9F%BA%E4%BA%8EVideo4Linux%E7%9A%84USB%E6%91%84%E5%83%8F%E5%A4%B4%E5%9B%BE%E5%83%8F%E9%87%87%E9%9B%86%E5%AE%9E%E7%8E%B0.rar">http://www.cnitblog.com/Files/luofuchong/%E5%9F%BA%E4%BA%8EVideo4Linux%E7%9A%84USB%E6%91%84%E5%83%8F%E5%A4%B4%E5%9B%BE%E5%83%8F%E9%87%87%E9%9B%86%E5%AE%9E%E7%8E%B0.rar</a><br><br>注：<br>&nbsp;&nbsp;&nbsp; 之前忘记添加转帖注明，引起不必要的误会，不好意思哦^_^<br><span style="text-decoration: underline;"></span>&nbsp;&nbsp; <br>        <img src ="http://www.cnitblog.com/luofuchong/aggbug/42805.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-27 02:12 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】ping www.baidu.com 及主机名的方法　</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Thu, 24 Apr 2008 09:01:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42694.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42694.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42694.html</trackback:ping><description><![CDATA[注：<br>&nbsp;&nbsp;&nbsp; 今天发现这东西不好找了，还是转一下吧^_^<br><br><font color="#555555">1：文件系统中/lib有</font>
<p><font color="#555555">[root@hjembed /]# ls lib<br>ld-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libm.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libresolv.so<br>ld-linux.so.2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libm.so.6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libresolv.so.2<br>libc-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_dns-2.3.2.so &nbsp; &nbsp;librt-2.3.2.so<br>libc.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_dns.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;librt.so<br>libc.so.6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_dns.so.2 &nbsp; &nbsp; &nbsp; &nbsp;librt.so.1<br>libcrypt-2.3.2.so &nbsp; &nbsp; &nbsp;libnss_files-2.3.2.so &nbsp;libstdc++.so<br>libcrypt.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_files.so &nbsp; &nbsp; &nbsp; &nbsp;libstdc++.so.6<br>libcrypt.so.1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_files.so.2 &nbsp; &nbsp; &nbsp;libstdc++.so.6.0.1<br>libdl-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; libpng.a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libutil-2.3.2.so<br>libdl.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libpng.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libutil.so<br>libdl.so.2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libpng.so.3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libutil.so.1<br>libgcc_s.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libpng.so.3.1.2.15 &nbsp; &nbsp; libuuid.so.1<br>libgcc_s.so.1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libpthread-0.10.so &nbsp; &nbsp; libuuid.so.1.2<br>libjpeg.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libpthread.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libz.so<br>libjpeg.so.62 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libpthread.so.0 &nbsp; &nbsp; &nbsp; &nbsp;libz.so.1<br>libjpeg.so.62.0.0 &nbsp; &nbsp; &nbsp;libpthread.so_orig &nbsp; &nbsp; libz.so.1.2.3<br>libm-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libresolv-2.3.2.so &nbsp; &nbsp;<br>上面与此相关的是libnss* &nbsp;libresolv*</font></p>
<p><font color="#555555">2: 四个文件<br>[root@hjembed /]# cat /etc/hosts<br>127.0.0.1 &nbsp;localhost<br>59.69.74.87 hujunlinux &nbsp; &nbsp; #为我开发的host 机器</font></p>
<p><font color="#555555"> [root@hjembed /]# cat /etc/resolve.conf<br>nameserver &nbsp;XXXXXX &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#设置DNS服务器 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>[root@hjembed /]# cat /etc/host.conf<br>order hosts,bind</font></p>
<p><font color="#555555">还有一个nsswitch.conf , 我是直接从host machine: FC2 &nbsp;下考出来的</font></p>
<p><font color="#555555">[root@hjembed /]# &nbsp;cat /etc/nsswitch.conf<br>#<br># /etc/nsswitch.conf<br>#<br># An example Name Service Switch config file. This file should be<br># sorted with the most-used services at the beginning.<br>#<br># The entry '[NOTFOUND=return]' means that the search for an<br># entry should stop if the search in the previous entry turned<br># up nothing. Note that if the search failed due to some other reason<br># (like no NIS server responding) then the search continues with the<br># next entry.<br>#<br># Legal entries are:<br>#<br># &nbsp; &nbsp; &nbsp; nisplus or nis+ &nbsp; &nbsp; &nbsp; &nbsp; Use NIS+ (NIS version 3)<br># &nbsp; &nbsp; &nbsp; nis or yp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Use NIS (NIS version 2), also called YP<br># &nbsp; &nbsp; &nbsp; dns &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Use DNS (Domain Name Service)<br># &nbsp; &nbsp; &nbsp; files &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Use the local files<br># &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Use the local database (.db) files<br># &nbsp; &nbsp; &nbsp; compat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Use NIS on compat mode<br># &nbsp; &nbsp; &nbsp; hesiod &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Use Hesiod for user lookups<br># &nbsp; &nbsp; &nbsp; [NOTFOUND=return] &nbsp; &nbsp; &nbsp; Stop searching if not found so far<br>#<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br># To use db, put the "db" in front of "files" for entries you want to be<br># looked up first in the databases<br>#<br># Example:<br>#passwd: &nbsp; &nbsp;db files nisplus nis<br>#shadow: &nbsp; &nbsp;db files nisplus nis<br>#group: &nbsp; &nbsp; db files nisplus nis<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>passwd: &nbsp; &nbsp; files<br>shadow: &nbsp; &nbsp; files<br>group: &nbsp; &nbsp; &nbsp;files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>#hosts: &nbsp; &nbsp; db files nisplus nis dns<br>hosts: &nbsp; &nbsp; &nbsp;files dns<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br># Example - obey only what nisplus tells us...<br>#services: &nbsp; nisplus [NOTFOUND=return] files<br>#networks: &nbsp; nisplus [NOTFOUND=return] files<br>#protocols: &nbsp;nisplus [NOTFOUND=return] files<br>#rpc: &nbsp; &nbsp; &nbsp; &nbsp;nisplus [NOTFOUND=return] files<br>#ethers: &nbsp; &nbsp; nisplus [NOTFOUND=return] files<br>#netmasks: &nbsp; nisplus [NOTFOUND=return] files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>bootparams: nisplus [NOTFOUND=return] files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>ethers: &nbsp; &nbsp; files<br>netmasks: &nbsp; files<br>networks: &nbsp; files<br>protocols: &nbsp;files<br>rpc: &nbsp; &nbsp; &nbsp; &nbsp;files<br>services: &nbsp; files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>netgroup: &nbsp; files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>publickey: &nbsp;nisplus<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>automount: &nbsp;files<br>aliases: &nbsp; &nbsp;files nisplus<br> &nbsp; <br>3:试验： &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </font></p>
<p><font color="#555555">[root@hjembed /]# ping <a  href="http://www.baidu.com/" target="_blank">www.baidu.com</a><br>PING <a  href="http://www.a.shifen.com/" target="_blank">www.a.shifen.com</a> (211.94.144.100): 56 data bytes<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>--- <a  href="http://www.a.shifen.com/" target="_blank">www.a.shifen.com</a> ping statistics ---<br>3 packets transmitted, 0 packets received, 100% packet loss</font></p>
<p><font color="#555555">[root@hjembed /]# ping hujunlinux &nbsp; &nbsp; &nbsp; （主机名）<br>PING hujunlinux (59.69.74.87): 56 data bytes<br>64 bytes from 59.69.74.87: icmp_seq=0 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=1 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=2 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=3 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=4 ttl=64 time=0.5 ms<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>--- hujunlinux ping statistics ---<br>5 packets transmitted, 5 packets received, 0% packet loss<br>round-trip min/avg/max = 0.5/0.5/0.5 ms</font></p>
<p><font color="#555555"><br>ok!</font></p>
<br><br><img src ="http://www.cnitblog.com/luofuchong/aggbug/42694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-24 17:01 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：《IT人离开IT还能干什么？》</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Wed, 23 Apr 2008 09:24:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42659.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42659.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42659.html</trackback:ping><description><![CDATA[<div class="content">为什么IT人一定要离开IT呢？ <br>
<br>
今天一位同事（已三十多了），被老板叫到他的办公室去。老总对他说，由于效益不好，公司不再和他续订到期的合同！我看到他很落寞地离去。他前年才结婚，还
供着房子，老婆孩子要养，这一下子就失业了，而且又是快过年的时候！我跑去和他道别，他没有说什么，只让我好好干，公司还是大有前途的。 <br>
<br>
他是一个好人，在技术上决不保密。记得三年前我刚进公司的时候，他正是公司的主力，他对我这个应届毕业生十分关照，只要我不懂的，他一定尽力相告。那时公
司的老板也很器重他，可能是正当壮年的时候（还有很多剥削价值）。但自去年开始，公司转向了。NET平台，我们都去研发新技术了，原有的PB老版本程序基
本上都由一些老程序员来维护（可能老板想他们年龄不小了，学新技术有些障碍）。公司产品的升级工作进展很快，PB版本的程序越来越少了，我们晚上经常加
班，而他由于年龄和家庭的缘故，并不经常加班了。我渐渐地从老板对他的态度的变化——从最早的极为欣赏到一般到渐渐地嫌弃。今年公司的效益不太好，也许正
是到了鸟尽弓藏、兔死狗烹的时候了？
上世纪末那会儿，曾有"做IT，35岁就可以退休"的说法，历经沧海这么多年，35岁退休成了童话，35岁的职业坎儿却无法让众多IT人回避。有人说，可
以转为管理，然而管理的一条线就像窄窄的独木桥，又有多少人可以通过呢（据统计平均大约一百个程序员也就只有一两个做管理的机会）？转向传统行业？已经
30多了，能再重新来过？绝大多数平凡IT人的出路又在哪儿呢？ <br>
<br>
35岁对于IT人是个坎儿，过了这个年纪基本技术生涯即告终结，这是IT界多数人认可的。所以，也让IT人着实为35岁后的自己生了不少忧虑：IT人离开IT后能干什么？ <br>
<br>
印象中的IT人都因为职业的缘故而木讷寡言。他们与机器沟通的能力显然优于与人沟通的能力。从机器到人，IT人必须跨过来。 IT业的技术语言过于狭窄。社会却是复杂的。IT人的知识面不够广泛。社会上不需要人人都懂如何设计程序，但IT人却必须要懂社会。 <br>
<br>
IT内的项目，有些人也有些经验，但这些经验性的东西多数是专业性的，个别种类项目的经验能否转化为普遍的社会经验，也确实需要时间。 <br>
<br>
这些劣势，可以说，凡是地球上的IT人大概都知道。除了IT，要重新换个活法一时还真的玩不转。 但IT人毕竟是IT人。IT是高薪行业，IT人从业几年十几年，一般都有了一定的物质基础。这是IT人比其他行业的人具有的优势。 <br>
<br>
有了这样的物质基础，我认为，后IT人的关键是要实现思维方式的转变：从技术性思维到社会性思维，从而开创人生事业的第二高峰。<br>
技术性思维是面向机器的、僵硬的、封闭的、单向性的；社会性思维要求是面向常识和社会的、灵活的、开放的、多向综合的。后IT的人士最需要的是这种思维方式的转变。 <br>
<br>
思维一转天地宽。后IT人会发现社会比IT里面其实更精彩。
后IT人可以走出来干销售。这个工作富于挑战，而且收入与工作业绩直接挂钩。IT人有很强的技术背景，更擅长发掘产品性能的优缺点，对于IT产品的介绍具
有权威性，容易被客户相信。
后IT人可以走出程序迷宫来做培训。IT人在运用某一技术语言上相当精深，另外他们在技术研发中的实战经验，对于学员来说也是相当宝贵的教学资源。
后IT人也可以由直面数字转为面向众人做咨询。成功的咨询师决不会因为年龄而贬值。有过实际项目经验的IT人，解决实际问题的能力非常强，出身IT的人作
为咨询师是其他行业人士无法取代的。还可以做老板，做IT活动策划等等。 <br>
<br>
需要提醒的是，思维方式的转变不是一朝一夕的事。一旦离开IT，IT人所要做的是不断调整自我，保持对社会的参与激情。阅读一些人际沟通技巧之类的书籍是
必要的，还可以参加社会活动，给自己洗洗脑，从以数字中心、个人中心的思维方式转换到以人为中心、社会为中心的模式中。要注意多与人沟通。同时，个人应该
尽早明确自己的发展方向，并根据新的事业来重新积累，不断升级完善自身的"软硬件"。 </div><img src ="http://www.cnitblog.com/luofuchong/aggbug/42659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-23 17:24 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>