根據前一篇的文章介紹 at24c02的讀寫方式有很多種,
寫有兩種1.寫一字節數據到word address處2.從指定的word address處開始寫一頁數據,此word address需要頁對齊!
讀有三種1.從at24c02當前的word address讀一字節數據2.從指定的word address 讀數據3.從當前的word address地址開始讀一串數據
根據驅動中write() read()的實現方法可以發現,當msg發送完畢時才發送stop信號,而msg之間是是連續發送的不會插入stop信號。
但是,write() read()每次都固定只能發送一則msg!這對at24c02的寫以及current read、sequential read來說沒問題,可以通過write()和read()函數直接實現這四種操作。
但是at24c02的random read就不能直接通過write() read()來實現了。因為random read需要先寫word address,寫完之後不能直接發送stop信號,
而是要接著發送start信號開始發送device address。而驅動中的write() read()只能一次發送一則msg,並且發送完畢就發送stop信號,所以這種時序不符合random read的操作。
不過系統通過ioctl操作,可以一次發送多則msg,而在msg之間是不會發送stop信號的。
所以at24c02的random read操作可以通過發送兩則msg的方式來實現,第一則msg是寫的,並且寫的內容是word address,第二則msg為讀。
下面在分析下ioctl 的驅動實現函數i2cdev_ioctl_rdrw()
其中有一句比較難理解的是
1.在內核空間申請一塊buf,
2.將data_ptrs[i] (其值和目前的rdwr_pa[i].buf是一致的)指向的用戶空間的buf中的數據拷貝到剛申請的內核buf中。
3.將內核空間的buf地址返回,並且覆蓋rdwr_pa[i].buf中的數值,使其值由原來用戶空間的buf地址變為內核空間的buf地址。
然後調用函數i2c_transfer開始發送信息。發送時序可以通過
i2s_s3c_irq_nextbyte()函數中的流程來判斷,此處不具體分析了.
相關閱讀:
I2C子系統之at24c02讀寫測試 http://www.linuxidc.com/Linux/2012-08/68256.htm
I2C子系統之ioctl() http://www.linuxidc.com/Linux/2012-08/68257.htm
I2C子系統之at24c02簡介 http://www.linuxidc.com/Linux/2012-08/68258.htm
I2C子系統之總結 http://www.linuxidc.com/Linux/2012-08/68259.htm
I2C子系統之內核中I2C子系統的結構 http://www.linuxidc.com/Linux/2012-08/68260.htm
I2C子系統之I2C bus初始化——I2C_init() http://www.linuxidc.com/Linux/2012-08/68261.htm
I2C子系統之platfor_device初始化——smdk2440_machine_init() http://www.linuxidc.com/Linux/2012-08/68262.htm
I2C子系統之platform_driver初始化——I2C_adap_s3c_init() http://www.linuxidc.com/Linux/2012-08/68263.htm
I2C子系統之I2C總線時鐘頻率設置 http://www.linuxidc.com/Linux/2012-08/68264.htm
I2C子系統之adapter device和client device注冊——I2C_add_number_adapter() http://www.linuxidc.com/Linux/2012-08/68265.htm
I2C子系統之__I2C_first_dynamic_bus_num變量的相關分析 http://www.linuxidc.com/Linux/2012-08/68266.htm
I2C子系統之 adapter driver注冊——I2C_dev_init() http://www.linuxidc.com/Linux/2012-08/68267.htm
I2C子系統之write() http://www.linuxidc.com/Linux/2012-08/68268.htm