日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 下i2c读写命令,S3C2440 Linux下的I2C驱动以及I2C体系下对EEPROM进行读写操作

發布時間:2025/3/12 linux 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 下i2c读写命令,S3C2440 Linux下的I2C驱动以及I2C体系下对EEPROM进行读写操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

成員。我們可以看到消息結構體里面有從設備地址,讀寫標志,數據長度以及存儲數據buf。這些成員我們看完之后會發現它大致符合先給設備地址,然后給寫信號以及數據的時序。其實但我們寫代碼的時候并不一定是addr非得定義在flags前面,因為內核會自動幫助我們完成這些具體的時序操作。但有一點,我們必須要填充好nmsgs以及i2c_msg中的成員。

那么我們具體的i2c下的?ioctl?函數是怎么樣的呢?我們暫且把i2c-dev.c看作一個設備驅動。里面的fops結構體顯示

我們繼續追蹤看看i2cdev_ioctl這個函數

static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

struct i2c_client *client = file->private_data;

unsigned long funcs;

dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",

cmd, arg);

switch (cmd) {

case I2C_SLAVE:

case I2C_SLAVE_FORCE:

/* NOTE: ?devices set up to work with "new style" drivers

* can't use I2C_SLAVE, even when the device node is not

* bound to a driver. ?Only I2C_SLAVE_FORCE will work.

*

* Setting the PEC flag here won't affect kernel drivers,

* which will be using the i2c_client node registered with

* the driver model core. ?Likewise, when that client has

* the PEC flag already set, the i2c-dev driver won't see

* (or use) this setting.

*/

if ((arg > 0x3ff) "|

(((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))

return -EINVAL;

if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))

return -EBUSY;

/* REVISIT: address could become busy later */

client->addr = arg; //設置addr

return 0;

case I2C_TENBIT://設置10 bit地址模式

if (arg)

client->flags |= I2C_M_TEN;

else

client->flags &= ~I2C_M_TEN;

return 0;

case I2C_PEC://設置傳輸后增加PEC標志

if (arg)

client->flags |= I2C_CLIENT_PEC;

else

client->flags &= ~I2C_CLIENT_PEC;

return 0;

case I2C_FUNCS://獲取函數支持

funcs = i2c_get_functionality(client->adapter);

return put_user(funcs, (unsigned long __user *)arg);

case I2C_RDWR://讀取和發送數據

return i2cdev_ioctl_rdrw(client, arg);

case I2C_SMBUS: //SMBUS協議數據傳輸

return i2cdev_ioctl_smbus(client, arg);

case I2C_RETRIES://設置重試次數

client->adapter->retries = arg;

break;

case I2C_TIMEOUT://設置超時時間

/* For historical reasons, user-space sets the timeout

* value in units of 10 ms.

*/

client->adapter->timeout = msecs_to_jiffies(arg * 10);

break;

default:

/* NOTE: ?returning a fault code here could cause trouble

* in buggy userspace code. ?Some old kernel bugs returned

* zero in this case, and userspace code might accidentally

* have depended on that bug.

*/

return -ENOTTY;

}

return 0;

}

對于簡單使用來說,我現在并沒有全深入整明白,所以暫且知道:

ioctl是設備驅動程序中對設備的I/O通道進行管理的函數。

在驅動程序中實現的ioctl函數體內,實際上是有一個switch{case}的結構,每一個case對應一個cmd操作命令,并有相對應的操作。

我這里cmd參數使用的是I2C_RDWR這個命令碼,根據i2c-dev.c里的源碼看i2cdev_ioctl_rdrw結構體可知

I2C 設備的寫操作經歷了如下幾個步驟。

(1) 從用戶空間到字符設備驅動寫函數接口,寫函數構造 I2C 消息數組。

(2) 寫函數把構造的 I2C 消息數組傳遞給 I2C 核心的傳輸函數 i2c_transfer()。

(3) I2C 核心的傳輸函數 i2c_transfer()找到對應適配器 algorithm 的通信方法函數 master_xfer()去最終完成 I2C 消息的處理。

PS:I2c_transfer這個函數實現了core與adapter的聯系。想更深入的探究,可以自己去看看I2C總線驅動中的I2C_algorithm結構以及其中的s3c24xx_i2c_xfer(),s3c24xx_i2c_doxfer()和s3c24xx_i2c_message_start()函數和i2c_transfer()函數。

下面我們看看代碼在開發板中運行的現象:

1.在把可執行文件放入開發板啟動之前我們先檢查下I2C控制器s3c2410-i2c節點是否配置好。

上面的i2c_dev/i2c-0是在注冊i2c-dev.c后產生的,代表一個可操作的適配器。如果不使用i2c-dev.c的方式,就沒有,也不需要這個節點。

2.確保出現I2C控制器s3c2410-i2c后即可通過交叉編譯器將編譯后可執行文件放入開發板中執行。

仔細看上面的結果。可以看到我們原本的數據test1234\n在上面的顯示中出了點問題。后來我又測試一次test123\n與test12345678

我第一次是通過at24.c的read和write以及lseek直接對eeprom讀寫,所以可以一次寫入超過8個字節,第二次通過內部i2c控制器的ioctl來間接讀寫eeprom時則遭遇了阻擊,一次時序,若超過8個字節,超過的字節數自動將前面的數據覆蓋掉。然后我想到at24c02是32個頁,一頁8個字節。通過網上查閱知:

===================================================================================================

================================================================================================================================

由于E2PROM的半導體工藝特性,對E2PROM的寫入時間要5~10ms,但AT24CXX系列串行E2PROM芯片內部設置了一個具有SRAM性質的輸入緩沖器,稱為頁寫緩沖器。CPU對該芯片寫操作時,AT24CXX系列芯片先將CPU輸入的數據暫存頁寫緩沖器內,然后,慢慢寫入E2PROM中。因此,CPU對AT24CXX系列E2PROM一次寫入的數據,受到該芯片頁寫緩沖器容量的限制。頁寫緩沖器的容量:AT24C01A/02為8B,AT24C04/08/16為16B,AT24C32/64為32B。

====================================================================================================

注意:

寫AT24CXX應用時,若CPU需寫入超過芯片頁寫緩沖器容量的字節數據,應在一頁寫完后,隔5~10ms重新啟動一次寫操作。其次,若不是從頁寫緩沖器零地址(指AT24CXX片內末位地址0或8)寫起,一次寫入不能超出頁內地址111,若超出頁寫緩沖器最大地址時,也應將超出部分,隔5~10ms重新啟動一次寫操作。

最后通我們回顧AT24C02的官方datasheet來看看本質:

Byte write:

==================================================================================================================

Byte write的操作時序如上圖所示。主機在發送device address,并且接受到確定回應Ask后再接著發送需要寫的地址(把這個數據寫到芯片的哪個地址上),然后收到確定回應ask后再發送數據。當AT24C02接受完畢這個數據時會輸出一個確認回應Ack,此時主機發送一個停止信號Stop,然后AT240C2進入寫時序,將剛才接受到的數據從緩沖器寫到存儲單元中,并在此期間不響應任何輸入,直到操作完成。

==================================================================================================================

Pagewrite:

==================================================================================================================

Page write前面幾步的操作和Bytewrite操作類似,只是在成功發送第一個數據之后,主機在收到AT24C02的確認回應Ask之后不會發送停止信號Stop而是繼續發送剩余的7個字節數據。直到一個page的8字節數據發送完畢之后才發送停止信號Stop。在頁操作的時候word address用與表示業內的低地址的低3bit會每收到一個數據就自動增長,頁地址維持不變。所以,當業內地址到頂端時,此時假如還有數據,則數據將會被放到頁的起始地址處,頁起始地址中之前存放的數據也將會被覆蓋。即AT24C02頁操作時,寫入的數據大于8byte,則大于8byte的數據將重新從此頁起始處存放,并覆蓋掉之前寫入的的數據

==================================================================================================================

另外我們再說一下隨機讀取:

==================================================================================================================

隨機讀寫的操作就是主機先用一個寫操作來騙過AT24C02器件,使AT24C02內部的data word address中的地址值修改,然后再通過current ad

[1] [2] [3] [4]

本網站轉載的所有的文章、圖片、音頻視頻文件等資料的版權歸版權所有人所有,本站采用的非本站原創文章及圖片等內容無法一一聯系確認版權者。如果本網所選內容的文章作者及編輯認為其作品不宜公開自由傳播,或不應無償使用,請及時通過電子郵件或電話通知我們,以迅速采取適當措施,避免給雙方造成不必要的經濟損失。

總結

以上是生活随笔為你收集整理的linux 下i2c读写命令,S3C2440 Linux下的I2C驱动以及I2C体系下对EEPROM进行读写操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。