1編寫OV9650驅動以前的準備工做:html
1.1 使用資源:linux
開發板:S3C6410芯片框架
Linux內核: linux-2.6.38ide
CMOS攝像頭: ov9650函數
1.2 瞭解須要完成的工做:spa
1.2.1 背景知識:.net
I2C驅動:視頻
Linux I2C驅動是嵌入式Linux驅動開發人員常常須要編寫的一種驅動,由於凡是系統中使用到的I2C設備,幾乎都須要編寫相應的I2C驅動去配置和控制它,例如 RTC實時時鐘芯片、音視頻採集芯片、音視頻輸出芯片、EEROM芯片、AD/DA轉換芯片等等。htm
在本例中,ov9650就是對應的I2C設備(可是它並非用的標準I2C協議,後面會提到)。blog
1.2.1.1 Linux I2C子系統:
(參考連接:http://blog.csdn.net/jmq_0000/article/details/7473682)
在內核中已經提供I2C子系統,因此在作I2C驅動以前,就必需要熟悉該子系統。
能夠看出分爲三大組成部分
1)I2C核心(i2c-core)
I2C核心提供了I2C總線驅動和設備驅動的註冊、註銷方法,I2C通訊方法(algorithm)上層的、與具體適配器無關的代碼以及探測設備、檢測設備地址的上層代碼等。
2)I2C總線驅動(I2C adapter/Algo driver)
I2C總線驅動是I2C適配器的軟件實現,提供I2C適配器與從設備間完成數據通訊的能力。
I2C總線驅動由i2c_adapter和i2c_algorithm來描述。
3)I2C客戶驅動程序 (I2C client driver)
I2C客戶驅動是對I2C從設備的軟件實現,一個具體的I2C客戶驅動包括兩個部分:一部分是i2c_driver,用於將設備掛接於i2c總線;
另外一部分是設備自己的驅動。
I2C客戶驅動程序由i2c_driver和i2c_client來描述。
全部的I2C驅動代碼位於drivers/i2c目錄下
*I2c-core.c 實現I2C核心的功能
*I2c-dev.c 通用的從設備驅動
Chips 特定的I2C設備驅動
Busses I2C適配器的驅動
Algos 實現了一些I2C總線適配器的algorithm
1.2.1.2 I2C設備驅動編寫步驟
參考連接:http://www.it165.net/embed/html/201312/2376.html
編寫一個I2C設備驅動程序的工做可分爲三部分:
1) 定義和註冊I2C設備,即構建i2c_client;(在mach-mini6410.c中添加),參考arch/arm/mach-s3c24xx/mach-mini6410.c
咱們不用直接定義一個i2c_client結構,Linux會根據I2C設備的相關信息自動建立i2c_client。因此,咱們須要提供I2C設備的相關信息。i2c_client 信息一般在BSP的板文件中經過i2c_board_info 填充。
步驟1:用i2c_board_info結構體保存I2C設備相關信息
步驟2:調用i2c_register_board_info函數註冊i2c設備相關信息
2) 定義和註冊I2C設備驅動,即i2c_driver(利用內核提供的i2c-dev.c的框架來構建) 參考linux-2.6.38\drivers\i2c\i2c-dev.c:
步驟1:構建i2c_driver,定義i2c_driver結構體變量。(struct i2c_driver)。
步驟2:註冊i2c_driver, 調用i2c_add_driver註冊i2c_driver結構體變量。(__init函數中完成)
步驟3:註銷i2c_driver。 (__exit函數中完成)
3) 實現i2c_driver中要示實現的函數
幾個重要的結構體:
i2c_msg(設置設備地址的)
i2c_client(從機設備的地址,通常採用平臺設備的形式,用probe函數探測)
i2c_driver本身構建。
幾個重要的方法:
i2c_add_driver添加設備
i2c_transfer用於進行I2C適配器和I2C設備之間的一組消息的交互
1.2.2任務規劃
總線驅動:不須要實現,已有。
這裏由於內核中已經提供了S3C6410的I2C總線驅動(在/linux-2.6.38/drivers/i2c/busses目錄下的i2c-s3c2410.c文件就是總線驅動,雖然是S3C2410的,可是一樣支持S3C6410)。
設備驅動:
1須要完成S3C6410 CAMIF的平臺資源註冊:
在arch/arm/mach-s3c24xx/mach-mini6410.c文件中:
定義並註冊S3C6410的CAMIF(camera interface)
2 而後編寫ov9650的設備驅動:
參照 linux-2.6.38\drivers\media\video\ov9640.h, ov9640.c
2 開始編寫ov9650驅動
2.1在arch/arm/mach-s3c24xx/mach-mini6410.c:
OV9650
OV9650的從設備地址:
官方資料:
注意 因爲攝像頭自己使用的是SCCB協議(8位地址),換成I2C協議(7位地址後),地址0x60變爲0x30。
I2C與SCCB協議區別:從機地址由於I2C是7位地址,最後一位是讀寫位,而SCCB是8位地址,好比ov9650,他是SCCB協議,他的地址是0x60,那麼若是掛接到I2C總線上,他的地址就變成0x30了,這樣算的:
SCCB地址::: 0x60: 0 1 1 0_0 0 0 0 這個0仍是地址位
I2C地址:::: 0 1 1 0_0 0 0 0最後紅色的0是讀寫位,那麼地址變成了7 位 +讀寫位 即 0 1 1_ 0 0 0 0 +0( 讀寫位 ) 因此從機地址變成了0x30
參考連接: http://www.cnblogs.com/crazybingo/archive/2012/03/31/2426226.html
CAMIF :
Tiny6410-1107.pdf
編輯linux-2.6.38/arch/arm/mach-s3c64xx/ mach-mini6410.c
1 i2c對應的通道 ,是默認的,不須要修改
static struct i2c_board_info i2c_devs1[] __initdata = {
{
I2C_BOARD_INFO("ov965x", 0x30), // 能夠改成ov9650
},
};
寫ov9650設備驅動:
參照 linux-2.6.38\drivers\media\video\ov9640.h, ov9640.c
對照寄存器地址表,能夠看出9640的驅動兼容9650,又省去一大頭工做。。。。。
其實內核裏面的驅動都有了,因此咱們不須要寫驅動了。。。
只是分析一下大概的結構。
參考資料:
http://blog.csdn.net/mayaoyao11/article/details/6677141
http://www.cnblogs.com/crazybingo/archive/2012/03/31/2426226.html
http://www.cnblogs.com/liugf05/archive/2012/12/11/2812997.html