使用者空間訪問I2C裝置驅動

2021-09-03 10:59:34 字數 3159 閱讀 3122

關於linux下如何編寫晶元的i2c驅動,本系列第一篇文章《手把手教你寫linux i2c裝置驅動》對編寫i2c client 裝置驅動的關鍵**給出了初步的講述和示例,第二篇文章《linux下讀寫晶元的i2c暫存器》對於具體如何在驅動層封裝讀寫晶元i2c暫存器也進行了詳細的描述,這兩篇文章的**整合到一起,就構成了i2c裝置驅動的主要部分,本文則致力於將該驅動進一步封裝,為使用者空間提供訪問的介面。

如果希望在使用者空間訪問我們寫的i2c裝置驅動,最常用的做法就是為該i2c驅動編寫一套字元裝置驅動,這樣,使用者空間則可以通過對字元裝置驅動的訪問,間接地實現對i2c晶元暫存器的讀寫控制。下面,我們在前兩篇文章的**的基礎上,封裝一層字元裝置驅動,並給出在使用者空間的使用示例。

1.  編寫字元裝置驅動

(1)首先,建立乙個包含有cdev物件的結構體及物件,代表著本例項的字元裝置物件。

struct tvp5158_dev;  

// global dev object  

struct tvp5158_dev g_tvp5158_dev;

cdev即字元裝置物件,major為分配的字元裝置主裝置號,semaphore用於互斥,保護i2c讀寫過程。

(2)第二步,建立檔案操作結構體物件

struct file_operations tvp5158_dev_fileops = ;
我們把對i2c暫存器的讀寫操作放到 ioctl 命令中執行,不需要實現 read 和 write 函式,故這裡只實現檔案的開啟、釋放、以及 ioctl 操作。

(3) 實現裝置開啟和關閉函式

static int tvp5158_devopen(struct inode *inode, struct file *filp)     

static int tvp5158_devrelease(struct inode *inode, struct file *filp)  

(4)實現 ioctl 函式

#define i2c_cmd_read       (0x01)  

#define i2c_cmd_write      (0x02)  

struct i2c_param;  

static int tvp5158_devioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)  

case i2c_cmd_read:  

default:  

break;  

}  up(&g_tvp5158_dev.semlock);  

return 0;  

}

其中,i2c_param是與使用者空間互動用的引數結構體,使用者空間必須定義相同的結構體以保證互動的正確性。g_tvp5158_obj 和 tvp5158_i2c_read/write 均為前面文章中定義的變數和函式。

(5)在__init **中註冊本字元裝置驅動

static 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);;  

}

(6)在 __exit **中登出本字元裝置驅動

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

下面給出最後在使用者空間的測試**示例。

#include int main()  

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;  

}

3. 總結

交流。

使用者空間訪問I2C裝置驅動

關於linux下如何編寫晶元的i2c驅動,本系列第一篇文章 手把手教你寫linux i2c裝置驅動 見 對編寫i2c client 裝置驅動的關鍵 給出了初步的講述和示例,第二篇文章 linux下讀寫晶元的i2c暫存器 見 對於具體如何在驅動層封裝讀寫晶元i2c暫存器也進行了詳細的描述,這兩篇文章的...

使用者空間訪問I2C裝置驅動

原始出處 作者資訊和本宣告。否則將追究法律責任。關於linux下如何編寫晶元的i2c驅動,本系列第一篇文章 手把手教你寫linux i2c裝置驅動 對編寫i2c client 裝置驅動的關鍵 給出了初步的講述和示例,第二篇文章 linux下讀寫晶元的i2c暫存器 對於具體如何在驅動層封裝讀寫晶元i2...

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...