由於i2c對時序的嚴格要求,而linux是乙個多工作業系統,在應用層無法滿足嚴格的時序要求,只得在驅動層做。
1.將暫存器做相應的巨集定義,包含相應的標頭檔案,定義使用者的資料結構體
[html]
view plain
copy
#include
<
linux
/module.h
>
#include <
linux
/errno.h
>
#include <
linux
/miscdevice.h
>
#include <
linux
/fcntl.h
>
#include <
linux
/init.h
>
#include <
linux
/delay.h
>
#include <
linux
/proc_fs.h
>
#include <
linux
/workqueue.h
>
#include <
asm/uaccess.h
>
#include <
asm/system.h
>
#include <
asm/io.h
>
[html]
view plain
copy
typedef struct i2c_data_s
i2c_data_s;
[html]
view plain
copy
#define gpio_0_base 0x20180000
#define scl (1 <
<
6) /* gpio 4_6 */
#define sda (1 <
<
7) /* gpio 4_7 */
#define gpio_i2c_scl_reg io_address(gpio_0_base + 0x400)
#define gpio_i2c_sda_reg io_address(gpio_0_base + 0x200
#define gpio_i2c_sclsda_reg io_address(gpio_0_base + 0x600)<
strong
>
strong
>
2.按照linux miscdevice驅動開發的一般流程:定義相應的資料結構
[html]
view plain
copy
static struct file_operations
gpioi2c_fops
= ;
static struct miscdevice gpioi2c_dev
= ;
3.編寫模組的入口函式(init)和出口函式(exit)
[csharp]
view plain
copy
static
int__init gpio_i2c_init(
void
)
static
void
__exit gpio_i2c_exit(
void
)
[csharp]
view plain
copy
module_init(gpio_i2c_init);
//宣告入口函式,模組被insmod時會自動呼叫gpio_i2c_init
module_exit(gpio_i2c_exit); //宣告出口函式,模組被rmmod時會自動呼叫gpio_i2c_exit
4.編寫unlock_ioctl,open,close函式
[cpp]
view plain
copy
long
gpioi2c_ioctl(
struct
file *file, unsigned
intcmd, unsigned
long
arg)
return
0;
} int
gpioi2c_open(
struct
inode * inode,
struct
file * file)
intgpioi2c_close(
struct
inode * inode,
struct
file * file)
至此,大概框架就搭好了,接下來就是按照i2c的時序要求編寫相應的**,在此就不全貼了,說說遇到的問題吧。
首先遇到的第乙個問題就是驅動編寫完成載入後,scl和sda的引腳均為低電平,而我在模組入口函式處將sda和scl均拉高了,通過在其中加printk語句,確認函式確實執行到了,但是就是沒有起作用,對照datasheet檢查了各種暫存器的位址和配置都沒有問題,後來通過示波器發現兩個引腳的電平都為0,但是不是很平穩,更像是乙個未被控制的引腳,類似於三態的感覺,於是懷疑方向控制暫存器配置不對,於是在gpio_i2c_init函式中將這個暫存器的值列印出來發現是對的。排除了其他的暫存器配置後,只剩下乙個管腳復用暫存器,由於復位後這個暫存器的值為0x00,即為gpio模式,就沒有對其進行配置。如下圖所示:
結果將這個暫存器的值列印出來發現是0x01,不是預設的gpio模式,於是在入口函式中重新配置該暫存器,i2c時序正常。 hi3518e這邊的工作算是完成了,接下來就是完成stm32的i2c從機配置和兩者之間的通訊協議。
I2C裝置驅動的編寫
前面我們說了如何i2c使用者模式驅動,這種驅動基於i2c子系統,但是他對於應用程式開發人員的要求較高,需要應用程式開發人員了解硬體的一些東西,比如時序,位址等等,而多數時候應用程式開發人員是按照操作檔案的方法操作裝置,所以我們更希望用一些更簡單的介面去訪問。也就是我們今天的內容 基於i2c子系統的字...
linux下的I2C驅動記錄
現在做的是rk平台的i2c驅動,不是說linux每個外設對應乙個裝置檔案嗎?可是找了一下一直沒找到,今天特別搞了一下。i2c裝置是註冊為platform平台驅動的。下面是我用adb命令檢視的 linux的裝置檔案不一定只在dev 這個目錄下面,像sys 目錄下面也會有一些裝置檔案的 mid下面的i2...
Linux驅動 I2C匯流排
這裡以rk3288為例子,使用的是linux4.14,根據裝置樹節點i2c 與rk3x i2c driver,match之後,就會呼叫對應的probe rk3x i2c probe 這裡主要就是註冊乙個adapt i2c add adapter 也就是i2c控制器,或者說是i2c主裝置,既然是主裝置...