對於註冊的i2c介面卡,使用者空間也可以使用它們。在linux核心**檔案/include/linux/i2c-dev.c中針對每個介面卡生成乙個主裝置號為89的裝置節點,實現了檔案操作介面,使用者空間可以通過i2c裝置節點訪問i2c介面卡。介面卡的編號從0開始,和介面卡的裝置節點的次裝置號相同。
為了在使用者空間的程式當中操作i2c介面卡,必須在程式中包含以下兩句:
#include
#include
這兩個標頭檔案中定義了之後需要用到的結構體和巨集。
然後就可以開啟裝置節點了。但是開啟哪乙個呢?因為介面卡的編號並不固定。為此我們在中端中執行以下命令:
[root@zlg /]# cat /sys/class/i2c-dev/i2c-0/name
pnx4008-i2c0
[root@zlg /]# cat /sys/class/i2c-dev/i2c-1/name
pnx4008-i2c1
[root@zlg /]# cat /sys/class/i2c-dev/i2c-2/name
usb-i2c
如果我們想開啟第二個介面卡,剛好它的編號是1,對應的裝置節點是/dev/i2c-1。那麼可以用下面的方法開啟它:
int fd;
if ((fd = open("/dev/i2c-1",o_rdwr))< 0) */
#define i2c_func_smbus_pec 0x00000008
#define i2c_func_smbus_block_proc_call 0x00008000 /* smbus 2.0 */
#define i2c_func_smbus_quick 0x00010000
#define i2c_func_smbus_read_byte 0x00020000
#define i2c_func_smbus_write_byte 0x00040000
#define i2c_func_smbus_read_byte_data 0x00080000
#define i2c_func_smbus_write_byte_data 0x00100000
#define i2c_func_smbus_read_word_data 0x00200000
#define i2c_func_smbus_write_word_data 0x00400000
#define i2c_func_smbus_proc_call 0x00800000
#define i2c_func_smbus_read_block_data 0x01000000
#define i2c_func_smbus_write_block_data 0x02000000
#define i2c_func_smbus_read_i2c_block 0x04000000/* i2c-like block xfer */
#define i2c_func_smbus_write_i2c_block 0x08000000 /* w/ 1-byte reg. addr. */
#define i2c_func_smbus_read_i2c_block_2 0x10000000 /* i2c-like block xfer */
#define i2c_func_smbus_write_i2c_block_2 0x20000000 /* w/ 2-byte reg. addr. */
6. i2c層通訊
ioctl(file,i2c_rdwr,(structi2c_rdwr_ioctl_data *)msgset);
這一行**可以使用i2c協議和裝置進行通訊。它進行連續的讀寫,中間沒有間歇。只有當介面卡支援i2c_func_i2c此命令才有效。引數是乙個指標,指向乙個結構體,它的定義如程式清單 3.3所示。其中i2c_msg的定義參考程式清單 1.7。
程式清單
3.3 i2c_rdwr_ioctl_data
struct i2c_rdwr_ioctl_data ; /* 將要讀取的資料在晶元中的偏移量 */
unsignedchar wrbuf[3] = ; /* 要寫的資料,頭兩位元組為偏移量 */
printf("inputa char you want to write to e2prom/n");
wrbuf[2]= getchar();
printf("writereturn:%d, write data:%x/n", write(fd, wrbuf, 3), wrbuf[2]);
sleep(1);
printf("writeaddress return: %d/n",write(fd, rdaddr, 2)); /* 讀取之前首先設定讀取的偏移量 */
printf("readdata return:%d/n", read(fd, &rddata, 1));
printf("rddata:%c/n", rddata);
close:
close(fd);
exit:
return0;
還可以使用i2c_rdwr實現同樣的功能,如程式清單 3.6所示。此時ioctl返回的值為執行成功的訊息數。
程式清單
3.6 使用i2c_rdwr與i2c裝置通訊
#include
#include
#include
#include
#include
#define chip "/dev/i2c-0"
#define chip_addr 0x50
int main()
printf("hello,this is i2c tester/n");
int fd =open(chip, o_rdwr);
if (fd< 0) ;
unsignedchar wrbuf[3] = ;
printf("inputa char you want to write to e2prom/n");
wrbuf[2]= getchar();
structi2c_rdwr_ioctl_data ioctl_data;
structi2c_msg msgs[2];
msgs[0].addr= chip_addr;
msgs[0].len= 3;
msgs[0].buf= wrbuf;
ioctl_data.nmsgs= 1;
ioctl_data.msgs= &msgs[0];
printf("ioctlwrite,return :%d/n", ioctl(fd, i2c_rdwr, &ioctl_data));
sleep(1);
msgs[0].addr= chip_addr;
msgs[0].len= 2;
msgs[0].buf= rdaddr;
msgs[1].addr= chip_addr;
msgs[1].flags|= i2c_m_rd;
msgs[1].len= 1;
msgs[1].buf= &rddata;
ioctl_data.nmsgs= 1;
ioctl_data.msgs= msgs;
printf("ioctlwrite address, return :%d/n", ioctl(fd, i2c_rdwr, &ioctl_data));
ioctl_data.msgs= &msgs[1];
printf("ioctlread, return :%d/n", ioctl(fd, i2c_rdwr, &ioctl_data));
printf("rddata:%c/n", rddata);
close:
close(fd);
exit:
return0;
i2c dev公用介面
注意 需開啟裝置 dev i2c 1許可權,否則會碰到pemission denied錯誤。從原始碼根目錄下,進入system core rootdir目錄,開啟ueventd.rc 新增一行 dev i2c x x為對應的匯流排編號 fd open dev i2c 0 o rdwr 讀寫方式開啟裝...
在FreeBSD 使用者空間與核心空間使用記憶體共享
kernel建立一裝置分配記憶體,並將記憶體位址通過d mmap 對映,userland使用mmap 參考 sys dev mem memdev.c.freebsd 7.1 kernel include include include include include include include ...
使用者和kernel空間使用mmap共享記憶體
原來的程式 檔案操作 static struct file operations fops static int x mmap struct file file,struct vm area struct vma ldd3中講到,對於常規記憶體,不能用remap pfn range,這個限制用來保證...