• 代码示例_i2c读写e2prom驱动



      1 #include <linux/init.h>
      2 #include <linux/module.h>
      3 #include <linux/i2c.h>
      4 #include <linux/miscdevice.h>
      5 #include <linux/delay.h>
      6 #include <linux/fs.h>
      7 #include <linux/device.h>
      8 
      9 
     10 //声明一个i2c client指针--保存probe中的i2c client
     11 static struct i2c_client *at24_client;
     12 static struct miscdevice  e2prom_misc;
     13 
     14 
     15 //重写类似于i2c_master_send()/i2c_master_recv()
     16 int at24_i2c_send(struct i2c_client *client, char *buf, int count)
     17 {
     18     int ret;
     19     
     20     struct i2c_adapter *adapter = client->adapter;
     21     struct i2c_msg msg;
     22     
     23     msg.addr = client->addr;
     24     msg.flags = 0; //读1还是写0
     25     msg.len = count; 
     26     msg.buf = buf;
     27     //参数1---适配器--来自于i2c client 
     28     //参数2--数据包
     29     //参数3--数据包的个数
     30     //返回值--正确返回消息的个数,错误返回负数
     31     ret = i2c_transfer(adapter, &msg, 1);
     32 
     33     return ret==1?count:ret;
     34     
     35 }
     36 
     37 int at24_i2c_recv(struct i2c_client *client, char *buf, int count)
     38 {
     39     int ret;
     40     
     41     struct i2c_adapter *adapter = client->adapter;
     42     struct i2c_msg msg;
     43     
     44     msg.addr = client->addr;
     45     msg.flags = 1; //读1还是写0
     46     msg.len = count; 
     47     msg.buf = buf;
     48     //参数1---适配器--来自于i2c client 
     49     //参数2--数据包
     50     //参数3--数据包的个数
     51     //返回值--正确返回消息的个数,错误返回负数
     52     ret = i2c_transfer(adapter, &msg, 1);
     53 
     54     return ret==1?count:ret;
     55 
     56 }
     57 
     58 
     59 const struct file_operations at24_fops = {
     60 
     61 
     62 };
     63 
     64 
     65 int at24_drv_probe(struct i2c_client *client, const struct i2c_device_id *id)
     66 {
     67 
     68     printk("id->name = %s, id->driver_data = 0x%x
    ", id->name, id->driver_data);
     69 
     70     // 0- 保存i2c_client 
     71     at24_client = client;
     72 
     73     // 1, 与用户交互
     74     e2prom_misc.name = "at24_dev";
     75     e2prom_misc.minor = MISC_DYNAMIC_MINOR,
     76     e2prom_misc.fops = &at24_fops,
     77     misc_register(&e2prom_misc);
     78 
     79     // 2, 与硬件交互(初始化硬件)--最终委托i2c adpater层与硬件打交道
     80     // e2prom上电就能工作,并不需要特定一些初始化
     81     //以下代码主要演示如何操作从设备
     82 
     83 
     84     int ret;
     85     
     86     char sendbuf[10] = {0x8/*写的地址*/, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b, 0x8b, 0x9b};
     87 
     88     ret = at24_i2c_send(client, sendbuf, 10);
     89     if(ret < 0)
     90     {
     91         printk("at24_i2c_send error
    ");
     92         misc_deregister(&e2prom_misc);
     93         return ret;
     94     }
     95 
     96     mdelay(3);
     97     //验证是否写入正确
     98     //先写地址
     99     char addr  = 0x8;
    100     ret = at24_i2c_send(client, &addr, 1);
    101     if(ret < 0)
    102     {
    103         printk("at24_i2c_send error
    ");
    104         misc_deregister(&e2prom_misc);
    105         return ret;
    106     }
    107     char recvbuf[8];
    108     ret = at24_i2c_recv(client, recvbuf, 8);
    109     if(ret < 0)
    110     {
    111         printk("at24_i2c_recv error
    ");
    112         misc_deregister(&e2prom_misc);
    113         return ret;
    114     }
    115     int i;
    116     for(i=0; i<8; i++)
    117         printk("recvbuf[%d] = 0x%x
    ", i, recvbuf[i]);
    118     
    119     
    120     return 0;
    121 
    122     
    123 }
    124 
    125 
    126 
    127 int at24_drv_remove(struct i2c_client *client)
    128 {
    129     misc_deregister(&e2prom_misc);
    130     
    131     return 0;
    132 }
    133 
    134 
    135 
    136 const struct i2c_device_id at24_id_table[] = {
    137         {"at24c02", 0x2},
    138         {"at24c04", 0x4},
    139         {"at24c08", 0x5},
    140         {"at24c16", 0x6},
    141         {},
    142 };
    143 
    144 
    145 struct i2c_driver at24_i2c_drv = {
    146     .probe = at24_drv_probe,
    147     .remove = at24_drv_remove,
    148     .driver = {
    149         .name = "at24_drv", //一定要有--/sys/bus/i2c/drivers/at24_drv
    150     },
    151     .id_table = at24_id_table,
    152 
    153 };
    154 
    155 
    156 static int __init at24_i2c_drv_init(void)
    157 {
    158 
    159     //注册一个i2c driver 
    160     return i2c_add_driver(&at24_i2c_drv);
    161     
    162 
    163 }
    164 
    165 static void __exit at24_i2c_drv_exit(void)
    166 {
    167     i2c_del_driver(&at24_i2c_drv);
    168 }
    169 
    170 
    171 late_initcall(at24_i2c_drv_init);
    172 module_exit(at24_i2c_drv_exit);
    173 MODULE_LICENSE("GPL");

    CROSS_COMPILE = arm-none-linux-gnueabi-
    CC = $(CROSS_COMPILE)gcc
    
    #指定内核源码路径
    KERNEL_DIR = /home/kernel/linux-3.0.8
    CUR_DIR = $(shell pwd)
    
    #MYAPP = plat_led_app
    
    MODULE = at24_i2c_drv
    
    all:
        #让make进入内核源码编译,同时将当前目录中的c程序作为内核模块一起编译
        make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
    ifneq ($(MYAPP), )    
        $(CC)  -o $(MYAPP) $(MYAPP).c
    endif
    
    clean:
        #删除上面编译生成的文件
        make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
        rm -rf $(MYAPP)
    
    install:
        cp *.ko $(MYAPP) /opt/rootfs/drv_module
    
    #指定当前目录下哪个文件作为内核模块编
    obj-m += $(MODULE).o

    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    Hadoop 源码编译
    Hadoop之HDFS介绍
    CentOS 7 导入epel库
    CentOS7安装 VirtualBox虚拟机
    ios开发在导入环信SDK后运行出现 Reason: image not found 的解决方案
    centos安装PHP
    centOS安装apache服务器
    centOS最小化安装后网络连接问题
    django orm
    yield, async
  • 原文地址:https://www.cnblogs.com/panda-w/p/10950008.html
Copyright © 2020-2023  润新知