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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一)

發布時間:2023/11/27 生活经验 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近工作中又使用到了I2C,所以借S3C2440開發板GT2440為硬件平臺溫習一遍I2C驅動體系。

linux內核中IIC驅動的體系框架

linux內核中IIC部分驅動代碼位于:/drivers/i2c下,代碼大致分為幾個小目錄及i2c目錄下的的i2c核心代碼:

核心代碼:/drivers/i2c/i2c-core.c?/drivers/i2c/i2c-core.h

busses目錄:各種IIC控制器相關的驅動代碼(也稱為IIC總線驅動代碼),如果S3C2440A內部集成了IIC控制器,它在busses目錄下對應的控制器驅動代碼為i2c-s3c2410.c

algos目錄:定義的是一些通信方法,對于S3C2440A的IIC控制器的通信方法沒在里面

muxes目錄:各種外接在IIC控制器上的IIC從設備相關的驅動代碼

從以上的目錄我們可以看出,linux內IIC驅動體系分為3部分:IIC核心、IIC總線驅動、IIC設備驅動。

IIC核心:

IIC核心定義了各種數據結構及抽象出通用接口函數:

如注冊(銷)IIC適配器:

i2c_add_adapter(struct?i2c_adapter?*adapter);

i2c_del_adapter(struct?i2c_adapter?*adapter);

注冊(銷)IIC設備驅動:

i2c_register_drive(struct?module?*owner?,struct?i2c_driver?*driver);

i2c_del_driver(struct?i2c_driver?*driver);

IIC抽象的傳輸、發送和接收函數:

i2c_transfe(struct?i2c_adapter?*adapter,struct?i2c_msg?*msg,int?num);

i2c_master_send(struct?i2c_client?*client,const?char?*buf,int?count);

i2c_master_recv(struct?i2c_client?*client?,?char?*?buf?,?int?count);

IIC總線驅動:

IIC總線驅動及IIC控制器驅動,為此linux內核中定義一個i2c_adapter數據結構來描述一個IIC適配器,而在不同架構上有不同實現方法:如S3C2440A上就使用i2c-s3c2410.c來實現了S3C2440A上的IIC控制器驅動

IIC設備驅動:

IIC設備在linux內核中用struct?i2c_client結構來描述,而使用i2c_driver結構來描述掛載在IIC控制器上的IIC從設備如何與主機進行通信。

問:像IIC裸機驅動那樣一個文件就能搞定的IIC驅動在linux中的結構卻相當的復雜?

原因在于linux內核,IIC驅動是一類驅動,如果像裸機驅動那樣,那么這個驅動只能用于特定的IIC控制器及IIC設備,這樣一來如果有很多不同類型的IIC控制器或IIC設備,那么所有的代碼都必須重寫。這顯然是不明智的,一個簡單的方法是將不同類型的IIC控制器及IIC設備之間進行通信的共同點給抽象出來,而這部分的代碼不管是任何IIC控制器或IIC設備都是一樣的,這樣移植不同的IIC總線驅動和IIC設備驅動時就能大大的減小代碼量。就像內核中將IIC驅動分成了IIC總線驅動和IIC設備驅動一樣,在裸機驅動中我們根本看不出那部分是總線驅動,哪部分是設備驅動?二者已經融為了一體。這樣的缺陷也很明顯,當我們的IIC總線上掛載了不同的IIC設備時,那么我們不得不重新寫IIC控制器相關的驅動代碼,而如果把它抽象出來,IIC總線驅動主要負責IIC總線的數據傳輸,如時鐘控制、發出S/P信號、中斷處理等等,而IIC設備驅動從負責解析出傳輸的這些數據的含義,因為對于不同的IIC設備,其總線上傳輸的這些數據的含義不同。個人認為linux的驅動的體系也是基于這種思想產生的。當我們明白了IIC驅動框架中如此負責的構造的良苦用心自然會更加深刻將整個驅動框架銘記于心。

Linux內核為IIC構造的幾個重要的數據結構:

struct i2c_adapter {

struct module *owner;

unsigned int id __deprecated;

unsigned int

class;?適配器所屬的類?const struct i2c_algorithm *algo;

該總線上的通信方法?void

*algo_data;?通信方法的附加數據

struct rt_mutex

bus_lock;?對所有設備的鎖結構

int

timeout;?超時時間,在搞總線上發送信號多久沒回的超時時間?int

retries;?重復的次數?struct device

dev;?適配器設備

int

nr;?總線的編號?char

name[48];?名字?struct completion dev_released;

struct mutex

userspace_clients_lock;

struct list_head userspace_clients;

};

其中重要的成員有algo?:該成員所指向的i2c_algorithm實際上就是具體的IIC控制器的通信方法,如發出S/P信號、傳輸數據等最底層的控制器操作。

struct i2c_algorithm {

int (*master_xfer)(struct i2c_adapter *adap,

struct i2c_msg *msgs,

int num);?消息發送函數指針?int (*smbus_xfer) (struct i2c_adapter *adap, u16

addr,

unsigned short flags, char read_write,

u8 command, int size, union i2c_smbus_data *data);

u32 (*functionality) (struct i2c_adapter

*);?適配器所支持的功能

};

由于每種適配器所支持的功能不同、傳輸數據的方法也不同,所以講這個抽象出來,在不同的適配器中再去具體的實現它。

struct i2c_driver {

unsigned int class;

int (*attach_adapter)(struct i2c_adapter

*);

int (*detach_adapter)(struct i2c_adapter

*);

標準的驅動模型?int (*probe)(struct i2c_client *, const struct

i2c_device_id *);

int (*remove)(struct i2c_client *);

void (*shutdown)(struct i2c_client *);

int (*suspend)(struct i2c_client *, pm_message_t

mesg);

int (*resume)(struct i2c_client

*);

void (*alert)(struct i2c_client *, unsigned int

data);

類似ioctl?int (*command)(struct i2c_client *client,

unsigned int cmd, void *arg);

用于設備驅動模型?struct device_driver driver;

列出該設備驅動所支持的設備?const struct i2c_device_id

*id_table;

設備探測的回調函數?int (*detect)(struct i2c_client *, struct

i2c_board_info *);

用于探測的i2c設備地址?const unsigned short *address_list;

鏈接所有探測出的i2c設備?struct list_head clients;

};

struct i2c_client

{?i2c_client 代表i2c從設備

unsigned short flags;?I2C_CLIENT_TEN表示設備使用的是10位的地址,I2C_CLIENT_PEC表示使用SMBus包用在錯誤檢查

unsigned short

addr;?I2C設備在總線上的的地址?char name[I2C_NAME_SIZE]; 設備名

struct i2c_adapter

*adapter;?指向該I2C設備掛載的I2C適配器

struct i2c_driver

*driver;?指向支持該I2C設備的驅?

struct device

dev;?用于總線設備驅動模型

int

irq;?該設備能產生的中斷號

struct list_head detected;

};

struct i2c_msg

{?I2C總線上傳輸信息的最小單位

__u16 addr;?i2c設備地址,可以是10位的地址,如果是10位的地址flags標志中需設置I2C_M_TEN

__u16 flags; I2C_M_RD

讀標志,所有的適配器都必須支持,其他的標志見I2C_FUNC_*

#define

I2C_M_TEN?0x0010?10位的從設備的地址

#define

I2C_M_RD?0x0001?從I2C設備中讀數據

#define

I2C_M_NOSTART?0x4000?#define

I2C_M_REV_DIR_ADDR?0x2000?#define

I2C_M_IGNORE_NAK?0x1000?#define

I2C_M_NO_RD_ACK?0x0800?#define

I2C_M_RECV_LEN?0x0400?__u16

len;?消息的長度(字節數)

__u8

*buf;?指向消息數據的緩沖區

};

struct

i2c_board_info

{?創建I2C設備的模版

char?type[I2C_NAME_SIZE];?設備類型,用于填充i2c_client.name

unsigned

short?flags;?用于填充i2c_client.flags

unsigned

short?addr;?用于填充i2c_client.addr

void?*platform_data;?存儲i2c_client.dev.platform_data

struct dev_archdata?*archdata;

拷貝到i2c_client.dev.archdata

#ifdef

CONFIG_OF?指向打開固件的設備節點

struct device_node *of_node;

#endif

int?irq;?存儲到i2c_client.irq

};

i2c_board_info

被用來創建當前系統中I2C設備的列表,這些信息用來驅動模型樹,對于主板會使用i2c_register_board_info來注冊這些設備

接下來我們就著手分析linux提供的這些重要數據結構及IIC核心提供的這些核心函數是如何構造出整個IIC驅動框架的,耐心看下去你將對IIC體系驅動框架了如指掌!!!

總結

以上是生活随笔為你收集整理的linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

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