zoukankan      html  css  js  c++  java
  • 代码示例_i2c读写e2prom驱动_2

    i2c_eeprom.c


      1 #include <linux/init.h>
      2 #include <linux/module.h>
      3 #include <linux/fs.h>
      4 #include <linux/device.h>
      5 #include <linux/slab.h>
      6 #include <linux/gpio.h>
      7 #include <linux/i2c.h>
      8 #include <linux/mod_devicetable.h>
      9 
     10 
     11 #include <asm/io.h>
     12 #include <asm/uaccess.h>
     13 
     14 
     15 //设计一个全局的设备类型
     16 struct i2c_e2prom{
     17     int dev_major;
     18     struct class *cls;
     19     struct device *dev;
     20     struct i2c_client *client;  //记录当前匹配的client
     21 };
     22 struct i2c_e2prom *at24_dev;
     23 
     24 int at24_e2prom_drv_open(struct inode *inode , struct file * filp)
     25 {
     26     printk("---------^_^ %s-----------
    ",__FUNCTION__);
     27     return 0;
     28 }
     29 
     30 //编写一个封装了i2c_transfer的类似于i2c_master_recv的函数
     31 int at24_i2c_read(const struct i2c_client *client, const char *buf,int size)
     32 {
     33     int ret;
     34     struct i2c_adapter *adapter;
     35     struct i2c_msg msg;
     36     printk("---------^_^ %s-----------
    ",__FUNCTION__);
     37 
     38     adapter = at24_dev->client->adapter;
     39 
     40     msg.addr = at24_dev->client->addr;
     41     msg.flags |= I2C_M_RD;
     42     msg.len = size;
     43     msg.buf = buf;
     44 
     45     //参数1 ---- 适配器
     46     //参数2 ---- 数据包
     47     //参数3 ---- 数据的个数
     48     ret = i2c_transfer(adapter, &msg, 1);
     49 
     50     return ret == 1?size:ret;
     51     
     52 }
     53 //编写一个封装了i2c_transfer的类似于i2c_master_send的函数
     54 int at24_i2c_write(const struct i2c_client *client, const char *buf,int size)
     55 {
     56     int ret;
     57     struct i2c_adapter *adapter;
     58     struct i2c_msg msg;
     59     printk("---------^_^ %s-----------
    ",__FUNCTION__);
     60 
     61     adapter = at24_dev->client->adapter;
     62 
     63     msg.addr = at24_dev->client->addr;
     64     msg.flags = 0;
     65     msg.len = size;
     66     msg.buf = buf;
     67 
     68     //参数1 ---- 适配器
     69     //参数2 ---- 数据包
     70     //参数3 ---- 数据的个数
     71     ret = i2c_transfer(adapter, &msg, 1);
     72 
     73     return ret == 1?size:ret;
     74     
     75 }
     76 
     77 
     78 ssize_t at24_e2prom_drv_read (struct file *filp , char __user *buf , size_t count, loff_t * flags)
     79 {
     80     int ret;
     81     char *tmp;
     82     printk("---------^_^ %s-----------
    ",__FUNCTION__);
     83 //    if(count < 0 || count > 256)
     84     //    return -EINVAL;        
     85 
     86     tmp = kzalloc(count, GFP_KERNEL);
     87     
     88     // 1, 从硬件中获取数据
     89     ret = at24_i2c_read(at24_dev->client, tmp, count);
     90     if(ret < 0){
     91         printk("at24_i2c_read error
    ");
     92         goto err_kfree;
     93     }
     94 
     95     // 2, 将数据给由用户
     96     ret = copy_to_user(buf, tmp, count);
     97     if(ret > 0){
     98         printk("copy_to_user error
    ");
     99         goto err_kfree;
    100     }
    101 
    102     kfree(tmp);
    103     return count;
    104 err_kfree:
    105     kfree(tmp);
    106     return ret;
    107         
    108 }
    109 ssize_t at24_e2prom_drv_write(struct file *filp, const char __user *buf, size_t count , loff_t * flags)
    110 {
    111     int ret;
    112     char *tmp;
    113     printk("---------^_^ %s-----------
    ",__FUNCTION__);
    114 //    if(size < 0 || size > 256)
    115 //        return -EINVAL;        
    116 
    117     tmp = kzalloc(count, GFP_KERNEL);
    118     
    119     // 1, 获取用户空间的数据
    120     ret = copy_from_user(tmp, buf, count);
    121     if(ret > 0){
    122         printk("copy_from_user error
    ");
    123         goto err_kfree;
    124     }
    125     
    126     // 2,将数据写入到硬件(从设备)中
    127     ret = at24_i2c_write(at24_dev->client, tmp, count);
    128     if(ret < 0){
    129         printk("at24_i2c_write error
    ");
    130         goto err_kfree;
    131     }
    132 
    133     kfree(tmp);
    134     return count;
    135 err_kfree:
    136     kfree(tmp);
    137     return ret;
    138     
    139 }
    140 int at24_e2prom_drv_close(struct inode *inode , struct file *filp)
    141 {
    142     printk("---------^_^ %s-----------
    ",__FUNCTION__);
    143     return 0;
    144 }
    145 
    146 const struct file_operations at24_fops = {
    147     .open = at24_e2prom_drv_open,
    148     .read = at24_e2prom_drv_read,
    149     .write = at24_e2prom_drv_write,
    150     .release = at24_e2prom_drv_close,
    151 };
    152 
    153 int at24_drv_probe(struct i2c_client * client, const struct i2c_device_id * id)
    154 {
    155     printk("-------id->name = %s, id->driver_data = 0x%x-----------
    ",id->name,id->driver_data);
    156     //0,实例化设备对象
    157     at24_dev = kzalloc(sizeof(struct i2c_e2prom), GFP_KERNEL);
    158     
    159     //1, 申请设备号
    160     at24_dev->dev_major = register_chrdev(0, "at24_drv", &at24_fops);
    161     
    162     //2,创建设备节点
    163     at24_dev->cls = class_create(THIS_MODULE, "at24_cls");
    164     at24_dev->dev = device_create(at24_dev->cls, NULL, MKDEV(at24_dev->dev_major, 0), NULL, "at24_e2prom");
    165 
    166     //保存当前client
    167     at24_dev->client = client;
    168 
    169     
    170     //3,硬件初始化 ----- e2prom只要上电就可以工作
    171     //4,实现fops
    172 
    173     return 0;
    174 }
    175 int at24_drv_remove(struct i2c_client * client)
    176 {
    177     device_destroy(at24_dev->cls, MKDEV(at24_dev->dev_major, 0));
    178     class_destroy(at24_dev->cls);
    179     unregister_chrdev(at24_dev->dev_major, "at24_drv");
    180     kfree(at24_dev);
    181 
    182     return 0;
    183 }
    184 
    185 const struct i2c_device_id at24_id_table[] = {
    186     {"at24c02a", 0x2222},
    187     {"at24c04a", 0x2222},
    188     {"at24c08a", 0x2222},
    189 };
    190 
    191 
    192 struct i2c_driver at24_drv = {
    193     .probe =    at24_drv_probe,
    194     .remove =     at24_drv_remove,
    195     .driver = {
    196             .name = "at24_e2prom_drv",        //不会用于比对
    197                 //   /sys/i2c/driver/at24_e2prom_drv
    198     },
    199     .id_table = at24_id_table,
    200 };
    201 
    202 
    203 static int __init at24_drv_init(void)
    204 {
    205     //注册一个i2c_driver
    206     return i2c_add_driver(&at24_drv);
    207 }
    208 
    209 
    210 static void __exit at24_drv_exit(void)
    211 {
    212     i2c_del_driver(&at24_drv);
    213 }
    214 
    215 
    216 module_init(at24_drv_init);
    217 module_exit(at24_drv_exit);
    218 MODULE_LICENSE("GPL");

    app.c


     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <unistd.h>
     5 #include <sys/types.h>
     6 #include <sys/stat.h>
     7 #include <sys/ioctl.h>
     8 #include <fcntl.h>
     9 #include <linux/i2c-dev.h>
    10 
    11 
    12 int main(int argc,char **argv)
    13 {
    14     int fd;
    15     unsigned char val;  //8bit变量
    16     char register_addr = 0x08;     //片内地址
    17     int res;
    18     char wbuf[10];
    19     char rbuf[10];
    20 
    21     if(argc < 2){
    22     printf("%s r :read at24c02 address 0
    ",argv[0]);
    23     printf("%s w  val:write at24c02 address 0
    ",argv[0]);
    24     exit(1);
    25     }
    26 
    27     //打开设备
    28     fd = open("/dev/at24_e2prom",O_RDWR);
    29     if(fd < 0){
    30     perror("open");
    31     exit(1);
    32     }
    33 
    34     if(!strncmp(argv[1],"r",1)){  //从硬件中读数据  
    35 
    36     //先将片内地址写给控制器
    37     if(write(fd,&register_addr,1) != 1){
    38         perror("write");
    39         exit(1);
    40     }
    41     //再去读取硬件中的数据
    42     if(read(fd,rbuf,1) != 1){
    43         perror("read");
    44         exit(1);
    45     }else{
    46         printf("rbuf = 0x%x
    ",rbuf[0]);
    47     }
    48 
    49     }else if((argc == 3) && !strncmp(argv[1],"w",1)){  //向硬件中写数据:argv[2]
    50     // ./at24_e2prom_app  w 0x99
    51 
    52     val = strtoul(argv[2],NULL,0);
    53     wbuf[0] = register_addr; //片内地址0x08
    54     wbuf[1] = val;
    55 
    56     if(write(fd,wbuf,2) != 2){
    57         perror("write");
    58         exit(1);
    59     }
    60     printf("write data ok!
    ");
    61     }
    62 
    63     close(fd);
    64     return 0;
    65 }

    makefile


     1 CRAOSS_COMPILE = arm-none-linux-gnueabi-
     2 CC = $(CRAOSS_COMPILE)gcc
     3 
     4 MODULE_NAME1 = at24_i2c_e2prom
     5 #MODULE_NAME2 = plat_input_dev
     6 MYAPP =  at24_i2c_app
     7 
     8 #指定内核源码的路径
     9 KERNEL_DIR = /home/lpf/s5pv210/kernel/linux-3.0.8
    10 CUR_DIR = ${shell pwd}
    11 
    12 all:
    13     #make进入内核源码目录,并告诉内核将当前路径下的源码编译为内核的模块
    14     make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
    15     $(CC) -o $(MYAPP) $(MYAPP).c
    16 clean:
    17     #删除编译过程中生成的文件
    18     make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
    19     $(RM) $(MYAPP) .*.sw?
    20 install:
    21     cp *.ko $(MYAPP) /opt/rootfs/drv_module
    22 
    23 #指定将哪个源文件编程为内核模块
    24 obj-m := $(MODULE_NAME1).o
    25 #obj-m += $(MODULE_NAME2).o
    26     

    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    oracle 函数
    Oracle 语句
    递归算法算出某个目录下所有目录和文件
    static
    递归算法
    JVM/JDK/JRE
    java跨平台原理
    .NET 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”
    JS 判断对象是否为空
    html网页打印A4样式
  • 原文地址:https://www.cnblogs.com/panda-w/p/11118591.html
Copyright © 2011-2022 走看看