日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

I2C驱动程序框架probe道路

發(fā)布時(shí)間:2024/10/12 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 I2C驱动程序框架probe道路 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基于Linux的I2C驅(qū)動(dòng)器。采納probe道路。根據(jù)這個(gè)框架,如下面就可以寫任何支持I2C總線設(shè)備Linux驅(qū)動(dòng)器。

I2C設(shè)備連接到cpu具體i2c接口。被安裝在cpu的i2c適配器。i2c設(shè)備和cpu信息交流需要通過cpu操作適配器互動(dòng)。cpu上有1個(gè)或多個(gè)適配器。每一個(gè)適配器上能夠掛載256個(gè)設(shè)備地址不一樣的i2c器件,通過i2c驅(qū)動(dòng)就能夠讓cpu和適配器上的多個(gè)不一樣的i2c器件通信而不會(huì)產(chǎn)生沖突。

驅(qū)動(dòng)包含兩個(gè)文件,dev.c和drive.c,當(dāng)中dev.c是構(gòu)建I2C設(shè)備,即創(chuàng)建I2C_Client結(jié)構(gòu)體。而driver.c是在probe中獲取dev.c中構(gòu)建的i2c_client,然后構(gòu)建fileoperation。詳細(xì)步驟結(jié)合代碼例如以下。

1、在dev的入口函數(shù)中構(gòu)建I2C-CLient

static unsigned short addr_list[] = {0x60, 0x50, I2C_CLIENT_END //這個(gè)數(shù)組包括了設(shè)備地址,以I2C_CLIENT_END為數(shù)組結(jié)尾</span>}; static struct i2c_client *at24cxx_client; //創(chuàng)建I2C_Client結(jié)構(gòu)體 static int at24cxx_dev_init(void) {/*構(gòu)建I2C_Client*/struct i2c_adapter *adapter;struct i2c_board_info info; adapter=i2c_get_adapter(0); //獲取適配器,由于有些cpu有多個(gè)I2C適配器。參數(shù)0為適配器編號(hào)memset(&info, 0, sizeof(struct i2c_board_info));strlcpy(info.type, "at24cxx", I2C_NAME_SIZE); //這個(gè)是I2C_NAME,是和i2c_driver匹配的keywordat24cxx_client=i2c_new_probed_device(adapter, &info, addr_list);//假設(shè)數(shù)組中地址的設(shè)備存在則成功返回i2c_client結(jié)構(gòu)體//這個(gè)函數(shù)終于會(huì)調(diào)用device_create創(chuàng)建設(shè)備i2c_put_adapter(adapter);if(at24cxx_client)return 0;else return -ENODEV; }

2、在driver.c的入口函數(shù)中注冊(cè)I2C_driver結(jié)構(gòu)體

static const struct i2c_device_id = {

{ "at24cxx", 0 }, { } }; static struct i2c_driver at24cxx_driver = {.driver = {.name = "100ask",.owner = THIS_MODULE,},.probe = at24cxx_probe,.remove = __devexit_p(at24cxx_remove),.id_table = at24cxx_ids,//id_table中name是和dev創(chuàng)建i2c_client的name匹配,若匹配則會(huì)調(diào)用probe設(shè)備方法 };static int at24cxx_drv_init(void) {/*×¢2ái2c_driver*/return i2c_add_driver(&at24cxx_driver);}3、在probe設(shè)備方法中構(gòu)建file_operation注冊(cè)字符設(shè)備

static struct file_operations at24cxx_fops = {.owner = THIS_MODULE,.read = at24cxx_read,.write = at24cxx_write,};static int at24cxx_probe(struct i2c_client *client, const struct i2c_device_id *id) {printk("%s %s %d.\n",__FILE__,__FUNCTION__,__LINE__);at24cxx_client = client;//將dev中構(gòu)建的i2c_client結(jié)構(gòu)體傳遞過來,由于這個(gè)結(jié)構(gòu)體在read,write等設(shè)備方法中傳遞信息時(shí)須要用到major = register_chrdev(0,"at24cxx",&at24cxx_fops);//注冊(cè)字符設(shè)備class = class_create(THIS_MODULE,"at24cxx");device_create(class,NULL,MKDEV(major,0),NULL,"at24cxx");return 0; }

4、構(gòu)建write和read等設(shè)備方法中傳遞I2C消息

static ssize_t at24cxx_read(struct file *file, char __user *buf, size_t count, loff_t *off) {unsigned char addr,data;copy_from_user(&addr,buf,1);data = i2c_smbus_read_byte_data(at24cxx_client,addr);//這里用i2c_smbus_read_byte_data函數(shù)來和實(shí)際的I2C設(shè)備進(jìn)行信息交互</span> //這里詳細(xì)用哪個(gè)函數(shù)來傳遞消息須要結(jié)合詳細(xì)的器件的時(shí)序。不同的時(shí)序有不同的傳遞函數(shù),查看Linux源代碼中的說明文檔有關(guān)于傳遞函數(shù)的說明。

copy_to_user(buf,&data,1); return 0; } static ssize_t at24cxx_write(struct file *file, const char __user *buf, size_t count , loff_t *off) { unsigned char ker_buf[2]; unsigned char addr,data; copy_from_user(ker_buf,buf,2); addr = ker_buf[0]; data = ker_buf[1]; if(!i2c_smbus_write_byte_data(at24cxx_client,addr,data)) return 2; else return -EIO; }


假設(shè)i2c總線中掛載了實(shí)際的i2c設(shè)備,并且設(shè)備地址在以上的addr_list中,則不管是先載入dev.ko還是先載入driver.ko都會(huì)成功的運(yùn)行probe函數(shù),然后創(chuàng)建字符設(shè)備。在應(yīng)用程序中open設(shè)備,并調(diào)用read和write則會(huì)對(duì)應(yīng)的調(diào)用driver中的read和write設(shè)備方法。

測(cè)試應(yīng)用程序

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>/* i2c_test r addr* i2c_test w addr val*/void print_usage(char *file) {printf("%s r addr\n", file);printf("%s w addr val\n", file); }int main(int argc, char **argv) {int fd;unsigned char buf[2];if ((argc != 3) && (argc != 4)){print_usage(argv[0]);return -1;}fd = open("/dev/at24cxx", O_RDWR);if (fd < 0){printf("can't open /dev/at24cxx\n");return -1;}if (strcmp(argv[1], "r") == 0){buf[0] = strtoul(argv[2], NULL, 0);printf("before data: %c, %d, 0x%2x\n", buf[0], buf[0], buf[0]);read(fd, buf, 1);printf("data: %c, %d, 0x%2x\n", buf[0], buf[0], buf[0]);}else if ((strcmp(argv[1], "w") == 0) && (argc == 4)){buf[0] = strtoul(argv[2], NULL, 0);buf[1] = strtoul(argv[3], NULL, 0);if (write(fd, buf, 2) != 2)printf("write err, addr = 0x%02x, data = 0x%02x\n", buf[0], buf[1]);}else{print_usage(argv[0]);return -1;}return 0; }
2014--12--17

征途開始

興許補(bǔ)充









轉(zhuǎn)載于:https://www.cnblogs.com/mfrbuaa/p/4593267.html

總結(jié)

以上是生活随笔為你收集整理的I2C驱动程序框架probe道路的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。