之前寫了這麼多,長篇大論的,可是看來都是自己弄出來的東西,一個虛擬的裝置和一些自己定義的資料結構,還說kernel裡面差不多都是這樣的架構,好像單純自爽而已吧。好吧!那我們就來看看一個"I2C"裝置的實例吧!在開始之前還事先來看看他在Linux下的架構是怎樣吧,順便也可以來跟之前我們自創的架構比較一下。
如果有google過的話,類似的圖應該有看過,不過這邊就照我自己的理解重新描述一次。這就是從user space一直到硬體層的架構了,先不看硬體層的話,有沒有跟之前的架構很像。XXX_i2c.c是我們真正要實現的部分,裡面有一個很重要的資料結構i2c_adapter,他會提供一個方法來操作跟硬體相關的暫存器,並提供給上層一個callback function,master_xfer()。在上來一層就是i2c-core.c這層,它提供了下層註冊的方法和上層存取下層的方法i2c_transfer(),當然裡面還有很多kernel給的API。接下來再往上到i2c-dev.c,它就是一個字元裝置,提供給user space一個管道,並且之後再調用下層給的方法,裡面也有一個重要的資料結構i2c_client。如果和之前我們自己建立的架構比較起來,這邊其實只增加了i2c-core.c這一層。
而有關硬體層的部分,主要就是I2C bus的線路,SCL上是clock,SDA上是data。每一個I2C裝置都掛在這個bus上,它們有各自的slave address,透過一些溝通的機制,可以知道哪些資料是要傳送給他們的,詳細的資料可以參考I2C的Spec。
看到這邊,之前的長篇大論還是有點用處的啦,不是單純自爽,之後會先從我們要自己實現的XXX_i2c.c看起,就不會說明整個bus到device和driver的所有細節,不過遇到重點部分還是會提一下。最後就先列出剛才兩個重要的資料結構結束這篇吧! 暫時看不懂沒關係,之後會慢慢講囉,其實註解已經寫的滿清楚的了。
struct i2c_adapter {
struct module *owner;
unsigned int class; /* classes to allow probing for */
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
void *algo_data;
/* data fields that are valid for all devices */
struct rt_mutex bus_lock;
int timeout; /* in jiffies */
int retries;
struct device dev; /* the adapter device */
int nr;
char name[48];
struct completion dev_released;
struct mutex userspace_clients_lock;
struct list_head userspace_clients;
struct i2c_bus_recovery_info *bus_recovery_info;
}
struct i2c_client {
unsigned short flags; /* div., see below */
unsigned short addr; /* chip address - NOTE: 7bit */
/* addresses are stored in the */
/* _LOWER_ 7 bits */
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
int irq; /* irq issued by device */
struct list_head detected;
}
沒有留言:
張貼留言