i2c
I2C VFS驅(qū)動(dòng)子系統(tǒng)文檔。
概述
I2C VFS驅(qū)動(dòng)子系統(tǒng),該驅(qū)動(dòng)的目的是給應(yīng)用或組件提供通過VFS形式(open/close/ioctl)訪問I2C控制器驅(qū)動(dòng)對(duì)上層提供服務(wù)的接口。 該組件初始化過程中,會(huì)根據(jù)hardware/chip/<chip_name>/package.yaml中定義的CONFIG_I2C_NUM來依此創(chuàng)建如下名稱的設(shè)備節(jié)點(diǎn):
/dev/i2c0
/dev/i2c1
...
/dev/i2c[CONFIG_I2C_NUM - 1]
I2C VFS驅(qū)動(dòng)子系統(tǒng)內(nèi)部會(huì)將open/close/ioctl請(qǐng)求轉(zhuǎn)換成對(duì)應(yīng)硬件的HAL層接口調(diào)用,通過HAL層接口控制主控芯片對(duì)I2C控制器的參數(shù)(從設(shè)備地址、CLK等)的設(shè)定或發(fā)起I2C 讀或?qū)懖僮髡?qǐng)求。
版權(quán)信息
Apache license v2.0
目錄結(jié)構(gòu)
│── src
│ └── i2c_dev.c # I2C VFS驅(qū)動(dòng)程序源代碼
├── example # I2C VFS驅(qū)動(dòng)程序使用案例
│ └── i2c_example.c # 通過I2C VFS接口進(jìn)行I2C通信的案例文件
├── include # I2C驅(qū)動(dòng)子系統(tǒng)對(duì)外提供頭文件目錄
│ ├── aos
│ │ └── hal
│ │ └── i2c.h # AOS HAL API頭文件聲明,本文件中的API是給廠商對(duì)接HAL API的原型聲明
│ └── vfsdev
│ └── i2c_dev.h # I2C VFS驅(qū)動(dòng)子系統(tǒng)對(duì)應(yīng)用/組件提供的接口聲明文件
└── package.yaml # I2C VFS驅(qū)動(dòng)子系統(tǒng)的組件配置文件
依賴組件
base # 最底層核心驅(qū)動(dòng)模型、驅(qū)動(dòng)自動(dòng)加載機(jī)制以及Device VFS core
vfs # VFS API抽象庫
epoll # 增強(qiáng)型多路復(fù)用IO接口 - epoll機(jī)制所在庫
常用配置
本組件可以通過CONFIG_I2C_NUM配置對(duì)上層提供設(shè)備節(jié)點(diǎn)的數(shù)量,CONFIG_I2C_NUM代表芯片內(nèi)部的I2C控制器的數(shù)量。 CONFIG_I2C_NUM默認(rèn)是在hardware/chip/<chip_name>/package.yaml中的define節(jié)點(diǎn)進(jìn)行配置。 如果沒有定義CONFIG_I2C_NUM,則代碼中會(huì)定義默認(rèn)對(duì)外輸出的設(shè)備節(jié)點(diǎn)數(shù)量。 設(shè)備節(jié)點(diǎn)數(shù)量:默認(rèn)4個(gè), 如需修改,在hardware/chip/<chip_name>/package.yaml中修改CONFIG_I2C_NUM配置。
define:
CONFIG_I2C_NUM: 2
API說明
打開設(shè)備節(jié)點(diǎn)
int open(const char *pathname, int flags);
args | description |
pathname | I2C控制器外設(shè)VFS路徑 |
flags | 目前固定為0值 |
兼容POSIX標(biāo)準(zhǔn)的open接口。其中參數(shù)pathname為/dev/i2c加i2c控制器序號(hào),例如/dev/i2c0。
關(guān)閉設(shè)備節(jié)點(diǎn)
int close(int fd);
兼容POSIX標(biāo)準(zhǔn)的close接口。
I2C 參數(shù)設(shè)置
I2C 數(shù)據(jù)傳輸頻率
arg為指向io_i2c_control_u的指針。
int ioctl(int fd, IOC_I2C_SET_FREQ, unsigned long arg);
// 假如和從設(shè)備通信clock頻率為100k, 則用如下代碼對(duì)其進(jìn)行設(shè)置
io_i2c_control_u c;
c.freq = 100000; // set i2c clock frequence to 100k
ioctl (fd, IOC_I2C_SET_FREQ, &c);
I2C 地址模式、角色及從設(shè)備地址設(shè)置
arg為指向io_i2c_control_u的指針。
int ioctl(int fd, IOC_I2C_SET_CONFIG, unsigned long arg);
// 假如從設(shè)備地址為0x40, 地址寬度為7-bit, 則使用如下代碼對(duì)其進(jìn)行設(shè)置
io_i2c_control_u c;
c.c.addr = 0x40; // I2C從設(shè)備地址設(shè)置為0x40
c.c.addr_width = 0; // I2C從設(shè)備地址寬度為7-bit
c.c.role = 1; // i2c master模式
ioctl (fd, IOC_I2C_SET_CONFIG, &c);
I2C 數(shù)據(jù)收發(fā)
arg為指向io_i2c_data_t的指針。
int ioctl(int fd, int cmd, unsigned long arg);
其中cmd取值及其意義說明如下:
cmd | 功能 |
IOC_I2C_MASTER_RX | 控制I2C控制器從外部I2C從設(shè)備讀取數(shù)據(jù) |
IOC_I2C_MASTER_TX | 控制I2C控制器向外部I2C從設(shè)備發(fā)送數(shù)據(jù) |
IOC_I2C_MEM_RX | 控制I2C控制器從外部I2C存儲(chǔ)類型的從設(shè)備讀取數(shù)據(jù) |
IOC_I2C_MEM_TX | 控制I2C控制器向外部I2C存儲(chǔ)類型從設(shè)備發(fā)送數(shù)據(jù) |
io_i2c_data_t 結(jié)構(gòu)體變量說明如下:
變量 | 說明 |
addr | 此次讀寫操作對(duì)應(yīng)的i2c送設(shè)備地址 |
length | 此次讀寫操作要讀寫數(shù)據(jù)的長度 |
data | 寫操作:指向要發(fā)送數(shù)據(jù)的首地址;讀操作:指向接收數(shù)據(jù)存放內(nèi)存塊首地址 |
maddr | 此次內(nèi)存操作要讀寫的memory地址,只有在ioctl cmd id為IOC_I2C_MEM_TX/IOC_I2C_MEM_RX時(shí)有效 |
mlength | 此次內(nèi)存操作要讀寫的memory的長度,只有在ioctl cmd id為IOC_I2C_MEM_TX/IOC_I2C_MEM_RX時(shí)有效 |
timeout | 此次操作的超時(shí)時(shí)間,單位:ms |
使用示例
組件使用示例相關(guān)的代碼下載、編譯和固件燒錄均依賴AliOS Things配套的開發(fā)工具,所以首先需要參考《AliOS Things集成開發(fā)環(huán)境使用說明之搭建開發(fā)環(huán)境》,下載安裝。 待開發(fā)環(huán)境搭建完成后,可以按照以下步驟進(jìn)行示例的測試。
步驟1 創(chuàng)建或打開工程
打開已有工程
如果用于測試的案例工程已存在,可參考《AliOS Things集成開發(fā)環(huán)境使用說明之打開工程》打開已有工程。
創(chuàng)建新的工程
組件的示例代碼可以通過編譯鏈接到AliOS Things的任意案例(solution)來運(yùn)行,這里選擇helloworld_demo案例。helloworld_demo案例相關(guān)的源代碼下載可參考《AliOS Things集成開發(fā)環(huán)境使用說明之創(chuàng)建工程》。
步驟2 添加組件
如果芯片內(nèi)部含有I2C控制器,則芯片廠在操作系統(tǒng)對(duì)接的時(shí)候已經(jīng)將I2C組件添加在了芯片級(jí)別配置文件“hardware/chip/<chip_name>/package.yaml”中,此配置主要包含“設(shè)置組件依賴關(guān)系”及“設(shè)置芯片內(nèi)部所含I2C控制器數(shù)量”兩個(gè)配置。
# 設(shè)置組件依賴關(guān)系
depends:
- i2c: dev_aos
# 設(shè)置芯片內(nèi)部所含I2C控制器數(shù)量
define:
CONFIG_I2C_NUM: 2
步驟3 下載組件
在已安裝了的開發(fā)環(huán)境工具欄中,選擇Terminal -> New Terminal啟動(dòng)終端,并且默認(rèn)工作路徑為當(dāng)前工程的workspace,此時(shí)在終端命令行中輸入:
aos install i2c
上述命令執(zhí)行成功后,組件源碼則被下載到了./components/drivers/peripheral/i2c路徑中。
步驟4 添加示例
在i2c組件的package.yaml中添加example示例代碼:
source_file:
I2C device driver
#i2c VFS driver
- src/i2c_dev.c ? <CONFIG_U_I2C_DEV>
#i2c VFS driver example
- example/i2c_example.c ? <CONFIG_U_I2C_DEV>
步驟5 編譯固件
在示例代碼已經(jīng)添加至組件的配置文件,并且helloworld_demo已添加了對(duì)該組件的依賴后,就可以編譯helloworld_demo案例來生成固件了,具體編譯方法可參考《AliOS Things集成開發(fā)環(huán)境使用說明之編譯固件》。
步驟6 燒錄固件
helloworld_demo案例的固件生成后,可參考《AliOS Things集成開發(fā)環(huán)境使用說明之燒錄固件》來燒錄固件。
步驟7 打開串口
固件燒錄完成后,可以通過串口查看示例的運(yùn)行結(jié)果,打開串口的具體方法可參考《AliOS Things集成開發(fā)環(huán)境使用說明之查看日志》。
當(dāng)串口終端打開成功后,可在串口中輸入help來查看已添加的測試命令。
help
步驟8 測試示例
CLI命令行輸入:
# 向掛載在I2C通道1上面的SI7006溫濕度傳感器(從設(shè)備地址)發(fā)送一個(gè)0xF5的指令,控制其量測溫度
i2c_write 1 64 245 1
關(guān)鍵日志
i2c comp write test success!
CLI命令行輸入:
# 向掛載在I2C通道1上面的SI7006溫濕度傳感器(從設(shè)備地址)發(fā)送讀2個(gè)字節(jié)數(shù)據(jù)的指令
i2c_read 1 64 2
關(guān)鍵日志
i2c comp read test success!
注意事項(xiàng)
I2C是總線類型的bus,進(jìn)行i2c組件讀寫測試,必須確保i2c總線上面有外掛i2c 從設(shè)備,并且i2c控制器id、i2c從設(shè)備地址、寫入數(shù)據(jù)及長度信息都正確才能得到正確的執(zhí)行結(jié)果;以上任一信息出錯(cuò),執(zhí)行i2c_read/i2c_write 都可能得到錯(cuò)誤的執(zhí)行結(jié)果。
FAQ
I2C總線協(xié)議的介紹可參考視頻學(xué)習(xí):https://www.bilibili.com/video/BV1zb4y197h6/。