2014-04-05i2c设备驱动程序读写EEPROM(smbus协议)实验描述:
i2c设备驱动程序读写EEPROM
注意事项:
注意设备号起始开始的设置
内核版本:
Linux 2.6.38
开发板:
Mini 6410
实验结果截图:
驱动程序:
i2c_eeprom.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
//we can learn the code from linux-2.6.38\drivers\misc\eeprom\at24.c
#define DEVICE_NAME "i2c_eep"
struct i2c_eep{
struct i2c_client *client;
struct cdev eep_cdev;
};
static struct i2c_eep my_eep;
static dev_t devt_number;
static struct class *i2c_epp_class;
ssize_t epp_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
unsigned char address, data;
copy_from_user(&address, buf, 1);
printk(KERN_ALERT"kernel hello read!address:%d\n", address);
data = i2c_smbus_read_word_data(my_eep.client, address);
printk(KERN_ALERT"kernel hello read!data%d\n", data);
copy_to_user(buf, &data, 1);
}
ssize_t epp_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
unsigned char data[2];
copy_from_user(data, buf, 2);
printk(KERN_ALERT"kernel hello write!address:%d, data:%d\n", data[0], data[1]);
i2c_smbus_write_byte_data(my_eep.client, data[0], data[1]);
}
int epp_open (struct inode *node, struct file *file)
int epp_open (struct inode *node, struct file *file)
{
printk(KERN_ALERT"hello open!\n");
return 0;
}
struct file_operations eep_ops = {
.owner = THIS_MODULE,
.read = epp_read,
.write = epp_write,
.open = epp_open,
};
int eep_probe(struct i2c_client *client, const struct i2c_device_id *device_id_tables)
{
my_eep.client = client;
printk(KERN_ALERT"my eep register!\n");
return 0;
}
int eep_remove(struct i2c_client *client)
{
printk(KERN_ALERT"my eep remove!\n");
return 0;
}
static const struct i2c_device_id eep_id[] = {
{ "at24c08", 0 },
{ }
};
static struct i2c_driver i2c_epp_driver = {
.driver = {
.name = "my_eep",
.owner = THIS_MODULE,
},
.probe = eep_probe,
.
remove = eep_remove,
.id_table = eep_id,
};
static int eeprom_init(void)
{
if(alloc_chrdev_region(&devt_number, 2, 1, DEVICE_NAME) < 0){ //the firstnor very impotant
printk(KERN_ALERT"Sorry, Can not register this device!\n");
return -1;
}
cdev_init(&p_cdev, &eep_ops);
if(cdev_add(&p_cdev, devt_number, 1)){
printk(KERN_ALERT"Sorry, bad kmalloc!\n");
return 1;
}
i2c_epp_class = class_create(THIS_MODULE, DEVICE_NAME);
device_create(i2c_epp_class, NULL, MKDEV(MAJOR(devt_number), 2), NULL, DEVICE_NAME);
int err;
err = i2c_add_driver(&i2c_epp_driver);
if(err){
printk(KERN_ALERT"Sorry, register i2c failure!\n");
return err;
}
printk(KERN_ALERT"Success!\n");
return 0;
}
}
static int eeprom_exit(void)
{
i2c_del_driver(&i2c_epp_driver);
device_destroy(i2c_epp_class, MKDEV(MAJOR(devt_number), 2)); class_destroy(i2c_epp_class);
cdev_del(&p_cdev);
unregister_chrdev_region(MKDEV(MAJOR(devt_number), 2), 1);
printk (KERN_EMERG "cdev i2c_eep Byebye\n");
return 0;
}
module_init(eeprom_init);
module_exit(eeprom_exit);
MODULE_LICENSE("GPL");
at24cxx_dev.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/slab.h>
static struct i2c_board_info at24cxx_info = {
I2C_BOARD_INFO("at24c08", 0x50),
};
static struct i2c_client *at24cxx_client;
static int at24cxx_dev_init(void)
{
struct i2c_adapter *i2c_adap;
i2c_adap = i2c_get_adapter(0);
at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info);
i2c_put_adapter(i2c_adap);
return 0;
}
static void at24cxx_dev_exit(void)
{
i2c_unregister_device(at24cxx_client);
}
module_init(at24cxx_dev_init);
module_exit(at24cxx_dev_exit);
MODULE_LICENSE("GPL");
测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int fd;
unsigned char buf[2];
fd = open("/dev/i2c_eep", O_RDWR);
if (fd < 0)
{
printf("can't open /dev/i2c_eep\n");
return -1;
alert怎么读
}
if (strcmp(argv[1], "r") == 0)
{
buf[0] = strtoul(argv[2], NULL, 0);
read(fd, buf, 1);
printf("read data: %c, %d, 0x%2x\n", buf[0], buf[0], buf[0]); }
else if (strcmp(argv[1], "w") == 0)
{
buf[0] = strtoul(argv[2], NULL, 0);
buf[1] = strtoul(argv[3], NULL, 0);
write(fd, buf, 2);
}
return 0;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。