原始出處 、作者資訊和本宣告。否則將追究法律責任。
關於linux下如何編寫晶元的i2c驅動,本系列第一篇文章《手把手教你寫linux i2c裝置驅動》對編寫i2c client 裝置驅動的關鍵**給出了初步的講述和示例,第二篇文章《linux下讀寫晶元的i2c暫存器》對於具體如何在驅動層封裝讀寫晶元i2c暫存器也進行了詳細的描述,這兩篇文章的**整合到一起,就構成了i2c裝置驅動的主要部分,本文則致力於將該驅動進一步封裝,為使用者空間提供訪問的介面。
如果希望在使用者空間訪問我們寫的i2c裝置驅動,最常用的做法就是為該i2c驅動編寫一套字元裝置驅動,這樣,使用者空間則可以通過對字元裝置驅動的訪問,間接地實現對i2c晶元暫存器的讀寫控制。下面,我們在前兩篇文章的**的基礎上,封裝一層字元裝置驅動,並給出在使用者空間的使用示例。
1. 編寫字元裝置驅動
關於字元裝置驅動的編寫,我依然從例項應用的角度來展開描述,關於原理性的東西,網上有許多文章,可以搜尋參考。
(1)首先,建立乙個包含有cdev物件的結構體及物件,代表著本例項的字元裝置物件。
structcdev即字元裝置物件,major為分配的字元裝置主裝置號,semaphore用於互斥,保護i2c讀寫過程。tvp5158_dev;
// global dev object
struct
tvp5158_dev g_tvp5158_dev;
(2)第二步,建立檔案操作結構體物件
struct我們把對i2c暫存器的讀寫操作放到 ioctl 命令中執行,不需要實現 read 和 write 函式,故這裡只實現檔案的開啟、釋放、以及 ioctl 操作。file_operations tvp5158_dev_fileops = ;
(3) 實現裝置開啟和關閉函式
static(4)實現 ioctl 函式inttvp5158_devopen(
struct
inode *inode,
struct
file *filp)
static
inttvp5158_devrelease(
struct
inode *inode,
struct
file *filp)
這裡的ioctl 函式的實現很關鍵,是驅動層與使用者層互動的核心部分,這裡將會定義相關的i2c讀寫命令列舉,並且呼叫前面文章中封裝好的i2c讀寫**。
#define i2c_cmd_read (0x01)其中,i2c_param是與使用者空間互動用的引數結構體,使用者空間必須定義相同的結構體以保證互動的正確性。g_tvp5158_obj 和 tvp5158_i2c_read/write 均為前面文章中定義的變數和函式。#define i2c_cmd_write (0x02)
struct
i2c_param;
static
inttvp5158_devioctl(
struct
inode *inode,
struct
file *filp, unsigned
intcmd, unsigned
long
arg)
case
i2c_cmd_read:
default
: break
; }
up(&g_tvp5158_dev.semlock);
return
0;
}
(5)在__init **中註冊本字元裝置驅動
static(6)在 __exit **中登出本字元裝置驅動int__init tvp5158_i2c_init(
void
)
g_tvp5158_dev.major = major(dev);
sema_init(&g_tvp5158_dev.semlock, 1);
cdev_init(&g_tvp5158_dev.cdev, &tvp5158_dev_fileops);
g_tvp5158_dev.cdev.owner = this_module;
g_tvp5158_dev.cdev.ops = &tvp5158_dev_fileops;
cdev_add(&g_tvp5158_dev.cdev, dev, 1);
return
i2c_add_driver(&tvp5158_i2c_driver);;
}
static注意,本初始化**和逆初始化在第一篇文章中已經出現過,這裡補充完整了,將字元裝置驅動的**新增進來了。void
__exit tvp5158_i2c_exit(
void
)
2. 使用者空間的使用方法
首先,編寫makefile將驅動編譯成模組,然後在使用者空間對生成的模組(*.ko)進行載入(insmod),然後再 /dev 目錄下建立裝置節點 /dev/tvp5158_dev ,最後,在使用者空間即可編寫測試**,開啟該裝置檔案,通過 ioctl 命令進行訪問。
上面這個過程示例如下:
// 假設生成的模組.ko名稱為 tvp5158.ko下面給出最後在使用者空間的測試**示例。第一步:insmod tvp5158.ko
// 假設上面tvp5158_i2c_init函式中 g_tvp5158_dev.major 的值為 74
第二步:mknod /dev/tvp5158_dev c 74 0
#include3. 總結intmain()
param.reg = ®
param.value = &value;
status = ioctl(fd,i2c_cmd_read,¶m);
if( status < 0)
printf(
"the 0x80 reg 's value = %d\n"
,value);
close(fd);
return
0;
}
本文出自 「對影成三人」 部落格,請務必保留此出處
使用者空間訪問I2C裝置驅動
關於linux下如何編寫晶元的i2c驅動,本系列第一篇文章 手把手教你寫linux i2c裝置驅動 見 對編寫i2c client 裝置驅動的關鍵 給出了初步的講述和示例,第二篇文章 linux下讀寫晶元的i2c暫存器 見 對於具體如何在驅動層封裝讀寫晶元i2c暫存器也進行了詳細的描述,這兩篇文章的...
使用者空間訪問I2C裝置驅動
關於linux下如何編寫晶元的i2c驅動,本系列第一篇文章 手把手教你寫linux i2c裝置驅動 對編寫i2c client 裝置驅動的關鍵 給出了初步的講述和示例,第二篇文章 linux下讀寫晶元的i2c暫存器 對於具體如何在驅動層封裝讀寫晶元i2c暫存器也進行了詳細的描述,這兩篇文章的 整合到...
i2c裝置驅動
1,i2c 裝置註冊 static struct i2c board info i2c2 devices i2c裝置一般在板級 中註冊 static void msm8916 add i2c deivces void 2,i2c驅動註冊 include static const struct i2c...