I2C设备驱动
来源:互联网 发布:完美root软件 编辑:程序博客网 时间:2024/06/08 14:01
以前我们的probe只打印,现在我们做一些有用的事情 同样也是在我们以前的驱动程序里面去改
我们来看看我们芯片的时序图,当我想写的时候,
先发设备地址,然后发存储地址,最后发出数据
我们有两套函数可以用,第一套是smbus,另外一套是i2c_trasfer,这个SMBUS意思是system manager 就是系统管理总线的意思
这个smbus是I2C里面的一小部分,内核推荐我们用smbus
因为什么,因为有一些适配器只支持smbus,这篇文档上也告诉你了用哪些函数,比如
看我们这个写函数
看这里我们可以看到他发出了什么,S信号,地址,WR表示写,A表示回应,然后数据,然后回应,然后停止,我们不能用这个函数,因为我驱动里面还要发地址啊
我们接着往下看
write_byte_data,我们可以用这个函数,S表示开始信号,然后地址,然后写,然后回应,然后写要写入的地址,然后回应,然后数据,然后回应,然后停止位
这下面的S Addr Wr [A] Comm [A] Data [A] P 其实就是我们的时序图,跟我们上面的完全一样
读操作,我们看看有什么函数可以提供给我们读
这个函数刚好符合我们的时序图
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include<linux/cdev.h>
#include<linux/init.h>
#include<linux/device.h>
#include<linux/fs.h>
#include<linux/io.h>
struct cdev cdev;
dev_t devno;
#define DRIVER_NAME "at24clxx_i2c"
struct class *my_class;
static struct i2c_client *at24xx_client;
/*假设应用程序传进来两个数据,BUF[0],BUF[1]
BUF[0]是地址,你要访问芯片的那个地址
BUF[1]是date
*/
static ssize_t at24clxx_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
unsigned char ker_buf[2];
unsigned char addr,data;
copy_from_user(ker_buf,buf,2);
addr=ker_buf[0];
data=ker_buf[1];
//但是我怎么把这两个数据写进去呢
//第一个参数是设备,第二个参数是addr,第三个参数是我们的date;
if(!i2c_smbus_write_byte_data(at24xx_client,addr,data))
{
return 2;
}
else
return -EIO;
}
/*读我们也这么来,
传入BUF[0],addr
输出的数据BUF[1] data
*/
static ssize_t at24clxx_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned char addr,data;
copy_from_user(&addr,buf,1);
data =i2c_smbus_read_byte_data(at24xx_client,addr);
copy_to_user(buf,&data,1);
return 1;
}
static struct file_operations at24clxx_fops={
.owner = THIS_MODULE,
.read =at24clxx_read,
.write =at24clxx_write,
};
static int at24cl04_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
at24xx_client=client;
cdev_init(&cdev,&at24clxx_fops);
alloc_chrdev_region(&devno,0,1,DRIVER_NAME);
cdev_add(&cdev,devno,1);
my_class=class_create(THIS_MODULE,"at24clxx_class");
if(IS_ERR(my_class))
{
printk("Err: failed in creating class.\n");
return -1;
}
device_create(my_class, NULL, devno,NULL,DRIVER_NAME);
printk("24cl04_probe\n");
return 0;
}
static int at24cl04_remove(struct i2c_client *client)
{
printk("24cl04_remove\n");
device_destroy(my_class,devno);
class_destroy(my_class);
cdev_del(&cdev);
unregister_chrdev_region(devno,1);
return 0;
}
static const struct i2c_device_id at24cl04_id_table[] = {
{"gh24cl04",0x50},
{}
};
static struct i2c_driver at24cl04_driver = {
.driver = {
.name = "24cl04",
.owner = THIS_MODULE,
},
.probe = at24cl04_probe,
.remove = at24cl04_remove,
.id_table = at24cl04_id_table,
};
/*1. 分配/设置 i2c_driver*/
static int at24cl04_driver_init(void)
{
//printk("init\n");
int ret;
printk("init\n");
ret = i2c_add_driver(&at24cl04_driver);
if (ret != 0)
pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
return ret;
}
static void at24cl04_driver_exit(void)
{
i2c_del_driver(&at24cl04_driver);
}
module_init(at24cl04_driver_init);
module_exit(at24cl04_driver_exit);
MODULE_LICENSE("GPL");
测试程序如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
void print_usage(char *file)
{
printf("%s r addr\n",file);
printf("%s w addr val \n",file);
}
int main(int argc,char **argv)
{
unsigned char buf[2];
int fd;
fd=open("/dev/at24clxx_i2c",0x666);
if(fd<0)
{
printf("can't open /dev/at24clxx\n");
return -1;
}
printf("1\n");
if(strcmp(argv[1],"r")==0)
{
printf("3\n");
buf[0]=strtoul(argv[2],NULL,0);
read(fd,buf,1);
printf("data : %c,%d,0x%x\n",buf[0],buf[0],buf[0]);
}
else if (strcmp(argv[1],"w")==0)
{
printf("4");
buf[0]=strtoul(argv[2],NULL,0);
buf[1]=strtoul(argv[3],NULL,0);
if(write(fd,buf,2)!=2)
{
printf("write error\n");
}
}
else
{
printf("2\n");
print_usage(argv[0]);
}
return 0;
}
运行结果如下
- I2C设备驱动流程
- I2C设备驱动流程
- i2c 具体设备驱动
- I2C设备驱动流程
- S5PV210 I2C设备驱动
- 移植i2c设备驱动
- linux i2c设备驱动
- Linux I2C 设备驱动
- S5PV210 I2C设备驱动
- linux i2c设备驱动 .
- I2C设备驱动编写
- I2C设备驱动流程
- linux I2C设备驱动
- I2C设备驱动详述
- Linux 设备驱动 - I2C
- linux i2c设备驱动
- I2C设备驱动流程
- I2C设备驱动流程
- 求1+2+...+n的前n项和,但不用乘除法、for、while、if、else、switch、case等关键字及条件判断语句
- 简述DTFT(序列的傅里叶变换)
- js 函数调用其他函数和方法 call,apply关键字
- git 操作笔记
- (二)用 svm 识别手写体数字图片
- I2C设备驱动
- Android Studio Gradle
- JZOJ 5378. 【NOIP2017提高A组模拟9.19】闷声刷大题(60分)
- 前端~腾讯课堂选项卡部分代码
- maven(ssm)
- 算法学习之动态规划--最长公共子序列
- hdu 1251 统计难题
- AndroidStudio的文件的结构,so文件配置
- opencv3.1.0+contrib模块编译总结