IIC设备驱动程序(七)————设备层驱动程序实现实例

来源:互联网 发布:淘宝上怎么买到a货翡翠 编辑:程序博客网 时间:2024/06/01 10:01

bus-drv-dev模型及写程序
设备: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/regmap.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");

驱动:at24cxx_drv.c

#include <linux/kernel.h>#include <linux/module.h>#include <linux/platform_device.h>#include <linux/i2c.h>#include <linux/err.h>#include <linux/regmap.h>#include <linux/slab.h>#include <linux/fs.h>#include <asm/uaccess.h>static int major;static struct class *class;static struct i2c_client *at24cxx_client;/* 传入: buf[0] : addr * 输出: buf[0] : data */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);    copy_to_user(buf, &data, 1);    return 1;}/* buf[0] : addr * buf[1] : data */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];    printk("addr = 0x%02x, data = 0x%02x\n", addr, data);    if (!i2c_smbus_write_byte_data(at24cxx_client, addr, data))        return 2;    else        return -EIO;    }static struct file_operations at24cxx_fops = {    .owner = THIS_MODULE,    .read  = at24cxx_read,    .write = at24cxx_write,};static int __devinit at24cxx_probe(struct i2c_client *client,                  const struct i2c_device_id *id){    at24cxx_client = client;    //printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);    major = register_chrdev(0, "at24cxx", &at24cxx_fops);    class = class_create(THIS_MODULE, "at24cxx");    device_create(class, NULL, MKDEV(major, 0), NULL, "at24cxx"); /* /dev/at24cxx */    return 0;}static int __devexit at24cxx_remove(struct i2c_client *client){    //printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);    device_destroy(class, MKDEV(major, 0));    class_destroy(class);    unregister_chrdev(major, "at24cxx");    return 0;}static const struct i2c_device_id at24cxx_id_table[] = {    { "at24c08", 0 },    {}};/* 1. 分配/设置i2c_driver */static struct i2c_driver at24cxx_driver = {    .driver = {        .name   = "100ask",        .owner  = THIS_MODULE,    },    .probe      = at24cxx_probe,    .remove     = __devexit_p(at24cxx_remove),    .id_table   = at24cxx_id_table,};static int at24cxx_drv_init(void){    /* 2. 注册i2c_driver */    i2c_add_driver(&at24cxx_driver);    return 0;}static void at24cxx_drv_exit(void){    i2c_del_driver(&at24cxx_driver);}module_init(at24cxx_drv_init);module_exit(at24cxx_drv_exit);MODULE_LICENSE("GPL");

测试:i2c_test.c

#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);        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;}
0 0