導航:首頁 > 操作系統 > linuxi2c測試

linuxi2c測試

發布時間:2022-09-27 00:07:47

⑴ 用linux 調用內核中的統一I2C驅動 i2c總是 busy,求大神支招

希望能幫到你。
沒這樣用過,以前都是直接對/sys/bus/i2c/devices/0-0050/eeprom操作。
代碼里有兩次寫,一次讀,是在哪一次出錯?

⑵ 請教i2c驅動測試 Linux交流區 ARM9之家論壇

這是IIC驅動中ioctl()的處理函數(源代碼在drivers/i2c/i2c-dev.c)

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

{
struct i2c_client *client = (struct i2c_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;
return 0;

⑶ 如何使用linux內核自帶的gpio模擬i2c驅動

單獨編譯?在不同的平台下 GPIO的驅動是不同的 不過大致是相似的 可以根據不同的平台修改下

⑷ linux下怎麼直接使用iic介面

利用Linux中IIC設備子系統移植IIC設備驅動

背景描述

IIC匯流排在嵌入式系統中應用十分廣泛,常見的有eeprom,rtc。一般的處理器會包含IIC的控制器,用來完成IIC時序的控制;另外一方面,由於IIC的時序簡單,使用GPIO口來模擬時序也是常見的做法。面對不同的IIC控制器,各種各樣的晶元以及linux源碼,如何更快做好IIC設備驅動。

問題描述

在我們的方案中,我們會用到eeprom,rtc以及tw2865。由於Hi3520的IIC控制器設計有問題,無法正常使用。而IIC控制器的SDA和SCL管腳正好是和兩個GPIO管腳復用的。Hisi將控制gpio來實現IIC的時序,從而對IIC設備進行操作。這種設計方式簡單明了,但使用IIC子系統,可以更方便的移植和維護其他的設備驅動。

問題分析

Hisi對於gpio口,rtc晶元以及tw2865的處理方式如下:將gpio口做成一個模塊化的驅動,該驅動模擬IIC時序,並向外提供一些函數介面,比如:EXPORT_SYMBOL(gpio_i2c_read_tw2815);等。對於具體的rtc晶元,將其注冊為一個misc設備,並利用gpio模塊導出的函數進行rtc晶元的配置操作。

其實對於linux-2.6.24\drivers\i2c目錄下代碼,我們可以加以利用。

Linux的IIC字結構分為三個組成部分:

IIC核心

IIC核心提供了IIC匯流排驅動和設備驅動的注冊、注銷方法,IICalgorithm上層的、與具體適配器無關的代碼以及探測設備、檢測設備地址的上層代碼。

IIC匯流排驅動

IIC匯流排驅動是對IIC硬體體系結構中適配器端的實現。

IIC設備驅動

IIC設備驅動是對IIC硬體體系總設備端的實現。

我們查看下該目錄下的makefile和kconfig:

obj-$(CONFIG_I2C_BOARDINFO) +=i2c-boardinfo.o

obj-$(CONFIG_I2C) += i2c-core.o

obj-$(CONFIG_I2C_CHARDEV) +=i2c-dev.o

obj-y +=busses/ chips/ algos/

i2c-core.c就是IIC核心,buses中的文件是主流處理器中IIC匯流排的匯流排驅動,而chips中的文件就是常用晶元的驅動,algos中的文件實現了一些匯流排適配器的algorithm,其中就包括我們要用到的i2c-algo-bit.c文件。

我們首先利用i2c-gpio.c和i2c-algo-bit.c做好匯流排驅動。

在i2c-gpio.c中,mole_initi2c_gpio_initplatform_driver_probe(&i2c_gpio_driver,i2c_gpio_probe);

將其注冊為platform虛擬匯流排的驅動。

在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,

定義了如下三個結構體:

structi2c_gpio_platform_data *pdata;//平台相關的gpio的設置

structi2c_algo_bit_data *bit_data;//包含algorithm的具體函數,setor
get SDA和SCL

structi2c_adapter *adap;//適配器

i2c_gpio_probe主要做了下面幾件事:

填充bit_data結構的各個函數指針,關聯到具體的操作SDA和SCl函數。

填充adap結構,adap->algo_data= bit_data;

pdata= pdev->dev.platform_data;

bit_data->data= pdata;

pdev->dev->driver_data= adap;

在i2c-core中注冊適配器類型。

inti2c_bit_add_numbered_bus(struct i2c_adapter *adap)

在staticint i2c_bit_prepare_bus(struct i2c_adapter *adap)中

adap->algo= &i2c_bit_algo;

將i2c_bit_algo與adap關聯上。

static const structi2c_algorithm i2c_bit_algo = {

.master_xfer = bit_xfer,

.functionality = bit_func,

};

其中,master_xfer函數指針就是IIC傳輸函數指針。

I2c-algo-bit.c還實現了IIC開始條件,結束條件的模擬,發送位元組,接收位元組以及應答位的處理。

i2c-gpio.c中的i2c_gpio_setsda_val等函數是與具體平台gpio相關的。

修改對應arch-hi3520v100目錄下的gpio.h中的各個函數,這些函數是通過操作寄存器來控制gpio的方向和值。

在對應mach-hi3520v100中的platform-devices.c中添加如下:

static structi2c_gpio_platform_data pdata = {

.sda_pin = 1<<0,

.sda_is_open_drain = 1,

.scl_pin = 1<<1,

.scl_is_open_drain = 1,

.udelay = 4, /* ~100 kHz */

};

static struct platform_devicehisilicon_i2c_gpio_device = {

.name = "i2c-gpio",

.id = -1,

.dev.platform_data = &pdata,

};

static struct platform_device*hisilicon_plat_devs[] __initdata = {

&hisilicon_i2c_gpio_device,

};

int __inithisilicon_register_platform_devices(void)

{

platform_add_devices(hisilicon_plat_devs,ARRAY_SIZE (hisilicon_plat_devs));

return 0;

}

通過platform添加devices和driver,使得pdev->dev.platform_data=pdata

綜合上面的過程,我們完成了adapter的注冊,並將用gpio口模擬的algorithm與adapter完成了關聯。

這樣,在rtc-x1205.c中,x1205_attach函數利用i2c核心完成client和adap的關聯。

在x1205_probe函數中填充i2c_client結構體,並調用i2c_attach_client通知iic核心。

接著注冊rtc驅動。

最後我們要讀取時間,就需要構造i2c_msg結構體,如下所示:

struct i2c_msg msgs[] = {

{ client->addr, 0, 2,dt_addr }, /* setup read ptr */

{ client->addr, I2C_M_RD,8, buf }, /* read date */

};

/* read date registers */

if((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {

dev_err(&client->dev,"%s: read error\n", __FUNCTION__);

return -EIO;

}

dt_addr是寄存器的地址,I2C_M_RD表示iicread。

⑸ 如何在Linux中讓I2C驅動支持Sub Address的兩種方法

【目的】
AS3527有一個模擬部分,稱作AFE,其與數字部分通過i2c通信,此處AFE部分有很多寄存器供外界操作訪問,如果想要訪問這些寄存器,就要用到Sub Address,所以,要實現讓i2c 驅動支持Sub Address的模式。
i2C本身的架構中,沒有支持sub address,所以,我們只能想辦法,讓其I2C支持(方法1)或者用smbus的架構(方法2).
【方法】
方法1:
在i2c的message中傳遞一個2個位元組的buffer,分別存放Sub Address和data
比如,對於讀操作,就可以這么實現:
int afe_read_reg(int addr, u8 *pdata)
{
u8 msgbuf[2];
struct i2c_msg msg =
{
.addr = save_client->addr | ( << 8),
.flags = I2C_M_RD ,
.len = 2,
.buf = msgbuf,
};
msgbuf[0] = addr; //存放Sub Address,此處的Addr是寄存器地址,也就是Sub Address
msgbuf[1] = 0; //初始化
if (i2c_transfer(save_client->adapter, &msg, 1) < 0) {
dev_warn(&save_client->dev,
"can't read from afe /n");
return -ENOMEM;
}
*pdata = msgbuf[1];
return 0;
}
方法2:
使用SMBUS的框架,其支持Sub Address
在i2c讀操作中,直接調用SMBUS架構中的函數i2c_smbus_read_byte_data:
int afe_read_reg(int addr, u8 *pdata)
{
int ret;
ret = i2c_smbus_read_byte_data(save_client, addr);
if (ret < 0)
return ret;
else {
*pdata = (u8)ret;
return 0;
}
}
然後函數調用順序是
i2c_smbus_read_byte_data -> i2c_smbus_xfer ->
adapter->algo->smbus_xfer 或 i2c_smbus_xfer_emulated
(1)此處如果你自己的I2C驅動中沒有實現
adapter->algo->smbus_xfer
那麼就會去調用i2c_smbus_xfer_emulated,其會把I2C的讀一個位元組的操作,
分成2個message,然後
i2c_smbus_xfer_emulated -> i2c_transfer -> adap->algo->master_xfer(adap,msgs,num)
去調用底層自己的i2c傳輸的函數master_xfer去實現兩個message的傳輸。
此處要注意的是,如果你的i2C的控制器和i2c設備,支持將此I2C的讀一個位元組操作分兩個message傳輸,
那麼此處此方法也是可以的。
而你的底層的master_xfer函數,只要負責將對應的message發送出去也就可以實現對應的功能了。
否則,就像我此處遇到的,我這里的AFE的i2c控制器,不支持讀操作分成兩次message,只支持一個I2C message的傳輸,
所以,只能是在底層特殊處理,將2個message自己整理成一個message,或者是用下面的辦法。
(2)自己實現了adapter->algo->smbus_xfer
自己仿照i2c_smbus_xfer_emulated,在具體實現的時候,對於讀和寫都只是發送一個message,然後讓底層代碼
adap->algo->master_xfer去處理這個message,實現對應的讀和寫。
【注意】
1.以上,不論是1還是2,都是在實現了自己I2C驅動底層message傳輸的基本函數之後,才可以工作的。
而對於這個基本函數,即adap->algo->master_xfer,
都是要在實現的時候,注意上層傳遞過來的buffer的第一個位元組是sub address,第二個位元組才是要用於寫入或讀取的buffer。
2.對於方法2(2),在模擬i2c_smbus_xfer_emulated實現自己的xfer函數的時候,
不能直接調用i2c_transfer,因為i2c_transfer裡面,去獲得adapter->bus_lock,而i2c_smbus_xfer中,調用adapter->algo->smbus_xfer之前,已經進行了對於adapter->bus_lock鎖定,而因此會形成死鎖的的,辦法是不要再去獲得鎖,而直接調用adapter->algo->master_xfer即可。

⑹ LinuxI2C匯流排外接設備寫入問題

"/dev/i2c/0"
在內核裡面實現了讀取的操作了?有沒模塊注冊了字元驅動。
內核列印的信息

⑺ 用linux 調用內核中的統一I2C驅動 i2c總是 busy,求大神支招,謝謝! 程序很短

最近我也遇到這個問題了,糾結了一天,在網友的支持下解決了,這個天嵌的版本中,i2c和他的攝像頭驅動(OV9650驅動)相沖突,你在編譯內核之前,將攝像頭的驅動全部去掉,這樣子重新編譯之後,i2c就可以正常測試使用了。

⑻ linux i2c驅動 什麼時候調用 detect

1、使用linux系統i2c體系,包括設備驅動,匯流排驅動,一般匯流排驅動已經寫好了,需要你寫一個設備驅動 2、使用gpio模擬i2c協議 3、望採納 4、謝謝

⑼ 如何測試IIC通訊成功

一是看數據傳輸成功沒有啊 ,還有是示波器看波形,波形正確了就證明成功了啊。

⑽ i2c 在Linux下編程,測試i2c模塊是否能正常通信

如果你用的IC自己帶I2C模塊那肯定有一個寄存器可以給你寫地址進去
然後傳輸中 會自動判斷地址是否匹配

如果你是IO口模擬I2C傳輸
那就要主機先發送地址
從機用if判斷 主機那邊發過來的地址數據 是不是 我這邊想收到的地址數據

閱讀全文

與linuxi2c測試相關的資料

熱點內容
編程誰都能學會嗎 瀏覽:407
使用國家反詐app都要開啟什麼 瀏覽:710
下載民宿APP有什麼用 瀏覽:50
續子語pdf 瀏覽:385
2021年加密貨幣最新行情 瀏覽:162
nfs怎麼加密ipsec 瀏覽:245
國二考試調用編譯器運算選擇題 瀏覽:750
同濟大學高等數學pdf 瀏覽:234
延時的宏命令怎麼設置 瀏覽:596
資料庫有哪些加密 瀏覽:209
改之理反編譯注冊教程 瀏覽:391
什麼是編譯程序和翻譯程序 瀏覽:207
python課程心得總結 瀏覽:17
派派中怎麼看對方在哪個伺服器 瀏覽:796
xp配置java環境變數配置 瀏覽:9
python中1到100怎麼算 瀏覽:767
小度我想看程序員 瀏覽:508
bs刷裝備建立後文件夾沒有 瀏覽:81
找漫畫看應該下載什麼app 瀏覽:182
如何在vps上搭建自己的代理伺服器 瀏覽:744