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

2021-06-25 22:49:21 字數 3216 閱讀 5640

原始出處 、作者資訊和本宣告。否則將追究法律責任。

關於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

inttvp5158_devopen(

struct

inode *inode, 

struct

file *filp)  

static

inttvp5158_devrelease(

struct

inode *inode, 

struct

file *filp)  

(4)實現 ioctl 函式

這裡的ioctl 函式的實現很關鍵,是驅動層與使用者層互動的核心部分,這裡將會定義相關的i2c讀寫命令列舉,並且呼叫前面文章中封裝好的i2c讀寫**。

#define i2c_cmd_read       (0x01) 

#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;  

}

其中,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 

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;  

}

3.   總結

本文出自 「對影成三人」 部落格,請務必保留此出處

使用者空間訪問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...