Linux開發十二
i2c驅動
象棋小子 1048272975
i2c總線是嵌入式領域廣泛採用的一種通信標準,其具有接口線少、控制方式簡單、通信速率較高等優點。Linux內核已經支持s3c2416的i2c驅動。
1. i2c設備
i2c設備包含了名字、獨有的資源等等一些驅動程序的硬件或自定義信息。通過platform_add_devices(platform_device_register)函數將定義的平臺設備註冊到內核中,用於匹配設備驅動。
內核在drivers\i2c\i2c-s3c2410.c目錄中實現了s3c2416 i2c驅動,在mach-home2416.c中實現i2c設備。
static struct resources3c_i2c0_resource[] = {
[0]= DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),
[1]= DEFINE_RES_IRQ(IRQ_IIC),
};
struct platform_device s3c_device_i2c0 ={
.name = "s3c2410-i2c",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_i2c0_resource),
.resource = s3c_i2c0_resource,
};
struct s3c2410_platform_i2cdefault_i2c_data __initdata = {
.flags = 0,
.slave_addr = 0x10,
.frequency = 100*1000,
.sda_delay = 100,
};
void __init s3c_i2c0_set_platdata(structs3c2410_platform_i2c *pd)
{
structs3c2410_platform_i2c *npd;
if(!pd) {
pd= &default_i2c_data;
pd->bus_num= 0;
}
npd= s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
&s3c_device_i2c0);
if(!npd->cfg_gpio)
npd->cfg_gpio= s3c_i2c0_cfg_gpio;
}
在板級初始化函數home2416_machine_init ()中加入i2c平臺數據,s3c_i2c0_set_platdata(NULL),在static struct platform_device *home2416_devices[]板級平臺設備列表中加入&s3c_device_i2c0,使i2c設備能夠註冊到內核中。
2. 內核配置
Linux內核配置支持i2c設備驅動,選中Device Drivers->I2C support->I2CHardware Bus support->S3C2410 I2C Driver。
3. 應用編程
cat/proc/devices可以知道i2c的主設備號爲89,次設備號爲0,在/dev目錄中創建i2c設備文件。
mknod /dev/i2c-0 c 89 0
應用程序可以通過設備文件訪問i2c,i2c應用測試代碼i2c_test.c實現對eeprom at24cxx的讀寫。
#include "fcntl.h"
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
int main(void)
{
unsignedchar addr;
intret;
intfd;
inti;
unsignedchar buf[9];
fd= open("/dev/i2c-0", O_RDWR);
if(fd == -1) {
printf("Openi2c-0 failed\n");
exit(1);
}
ret= ioctl(fd, I2C_TENBIT, 0); // 7 bit address
if(ret == -1) {
printf("IO1failed\n");
close(fd);
exit(1);
}
ioctl(fd,I2C_SLAVE_FORCE, 0x50); // at24c08 slave address 0x50(7 bit)
ioctl(fd,I2C_TIMEOUT, 1);
ioctl(fd,I2C_RETRIES, 2);
buf[0]= 0x20; // write address
buf[1]= 0x12; // write 8 bytes
buf[2]= 0x34;
buf[3]= 0x56;
buf[4]= 0x78;
buf[5]= 0x98;
buf[6]= 0x76;
buf[7]= 0x54;
buf[8]= 0x32;
ret= write(fd, buf, 9);
if(ret == -1) {
printf("Writefailed\n");
close(fd);
exit(1);
}
printf("write:");
for(i=1; i<9; i++) {
printf("%02x", buf[i]);
}
sleep(1);// wait done
//read test
ret= write(fd, buf, 1); // read address
if(ret == -1) {
printf("Writefailed\n");
close(fd);
exit(1);
}
ret= read(fd, buf, 8); // read 8 bytes
if(ret == -1) {
printf("Readfailed\n");
close(fd);
exit(1);
}
close(fd);
printf("read:");
for(i=0; i<8; i++) {
printf("%02x", buf[i]);
}
return0;
}
用arm-linux-gcc靜態編譯,使之生成arm cpu可執行的指令,並且可脫離任何庫獨立運行,arm-linux-gcc -static -o i2c_test i2c_test.c,生成i2c_test可執行文件。複製可執行文件到根文件系統,目標板啓動後在目錄輸入./i2c_test即可執行。
4. 附錄
https://pan.baidu.com/s/1slczwhJ
bootloader源碼以及使用說明
https://pan.baidu.com/s/1eRDJtNs
Qt5.8官網源碼
https://pan.baidu.com/s/1nuGmSqt
本系列例程的根文件系統
https://pan.baidu.com/s/1i5btLGT
opev3.2.0官網源碼
https://pan.baidu.com/s/1pLpuHw3
yaffs官網源碼
https://pan.baidu.com/s/1bpkZynt
busybox-1.26.2官網源碼
https://pan.baidu.com/s/1i4EtjfR
tslib官網源碼
https://pan.baidu.com/s/1i5MGRhb
mplayer-1.3.0官網源碼
https://pan.baidu.com/s/1sl0fXlr
基於S3C2416修改的linux-4.10.10源碼