[国嵌攻略][155][I2C用户态驱动设计]

用户态驱动模型

用户态驱动模型首先是一个应用程序,其次是在这个用户程序中通过内核调用来驱动设备。

IIC通用驱动代码

IIC通用驱动程序的代码在/drivers/i2c/i2c-dev.c中。一次读操作或者一次写操作就是一条消息。

EEPROM用户态驱动

IIC通用设备对应/dev/i2c-0设备文件。

1.打开通用设备驱动

2.构造写数据到eeprom的消息

3.使用ioctl写入数据

4.构造从eeprom读数据的消息

5.使用ioctl读出数据

6.关闭设备

配置IIC驱动

make menuconfig ARCH=arm

device drviers-><*>I2C soupport-><*>I2C device interface

device drviers-><*>I2C soupport->I2C hardware bus support-><*>s3c2410 I2C driver

i2capp.c

/********************************************************************
*头文件
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

/********************************************************************
*宏定义
*********************************************************************/
#define I2C_RDWR 0x0707   //I2C读写命令

/********************************************************************
*类型定义
*********************************************************************/
typedef struct i2c_msg{
    unsigned short addr;    //设备地址
    unsigned short flags;   //读写标志
    unsigned short len;     //消息长度
    unsigned char  *buf;    //消息内容
}IIC_MSG;

typedef struct i2c_rdwr_ioctl_data{
    struct i2c_msg *msgs;   //消息指针
    unsigned int nmsgs;     //消息数量
}IIC_DATA;

/********************************************************************
*名称:main
*参数:
*    none
*返回:
*    none
*功能:主函数
*********************************************************************/
int main(){
    //打开设备文件
    int fd;

    fd = open("/dev/i2c-0", O_RDWR);

    //构造写入消息
    IIC_DATA wrData;

    wrData.msgs = (IIC_MSG *)malloc(1*sizeof(IIC_MSG));

    wrData.msgs[0].addr  = 0x50;   //注意设备地址为0b01010000,但是芯片手册地址为0b10100000
    wrData.msgs[0].flags = 0;
    wrData.msgs[0].len   = 2;
    wrData.msgs[0].buf = (unsigned char *)malloc(2*sizeof(unsigned char));
    wrData.msgs[0].buf[0] = 0;
    wrData.msgs[0].buf[1] = 123;

    wrData.nmsgs = 1;

    //写入消息数据
    ioctl(fd, I2C_RDWR, (unsigned long)(&wrData));
    printf("wrData is %d\n", wrData.msgs[0].buf[1]);

    //释放写入消息
    free(wrData.msgs[0].buf);
    free(wrData.msgs);

    //构造读取消息
    IIC_DATA rdData;

    rdData.msgs = (IIC_MSG *)malloc(2*sizeof(IIC_MSG));

    rdData.msgs[0].addr  = 0x50;
    rdData.msgs[0].flags = 0;
    rdData.msgs[0].len   = 1;
    rdData.msgs[0].buf = (unsigned char *)malloc(1*sizeof(unsigned char));
    rdData.msgs[0].buf[0] = 0;

    rdData.msgs[1].addr  = 0x50;
    rdData.msgs[1].flags = 1;
    rdData.msgs[1].len   = 1;
    rdData.msgs[1].buf = (unsigned char *)malloc(1*sizeof(unsigned char));
    rdData.msgs[1].buf[0] = 0;

    rdData.nmsgs = 2;

    //读取消息数据
    ioctl(fd, I2C_RDWR, (unsigned long)(&rdData));
    printf("rdData is %d\n", rdData.msgs[1].buf[0]);

    //释放读取消息
    free(rdData.msgs[0].buf);
    free(rdData.msgs[1].buf);
    free(rdData.msgs);

    //关闭设备文件
    close(fd);
}
时间: 2024-10-13 19:05:33

[国嵌攻略][155][I2C用户态驱动设计]的相关文章

[国嵌攻略][147][简单块设备驱动设计]

头文件 #include <linux/blkdev.h> #include <linux/bio.h> blkdev.c /******************************************************************** *头文件 *********************************************************************/ #include <linux/init.h> #incl

[国嵌攻略][152][I2C总线介绍]

IIC电气特性 I2C(inter intergrated circuit)总线是由philps公司开发的两线式串行总线,用于连接微控制器及其外围设备. I2C总线只有两根双向信号线: SDA:serial date line   数据线 SCL:serial clock line   时钟线 总线寻址 I2C总线规定:从设备采用7位的地址.D7-D1:从设备地址.D0:数据传输方向,为0时表示主设备向从设备写入数据,为1时表示主设备从从设备读取数据.主设备发送地址时,总线上的每个从设备都将这7

[国嵌攻略][156][I2C自编设备驱动设计]

AT24C08的驱动在Linux内核中已经提供,在/drivers/misc/eeprom/at24.c文件中.在对应的probe函数中有一个创建/sys/.../eeprom文件的函数,应用程序通过调用/sys/.../eeprom设备文件来对设备进行读写操作. 移植AT24C08驱动 1.修改内核注册eeprom设备 在kernel/linux-mini2440/arch/arm/mach-s3c2440.c中的machine_init下注册IIC设备. mach-mini2440.c st

[国嵌攻略][112][使用字符设备驱动]

编译/安装驱动程序 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此编译/安装一个驱动程序,其实就是编译/安装一个内核模块. 示例: make insmod memdev.ko 创建设备文件 应用程序->设备文件->驱动程序 通过字符设备文件,应用程序可以使用相应的字符设备驱动程序来控制字符设备.创建字符设备文件的方法一般有两种: 1.使用mknod命令 mknod /dev/文件名 c 主设备号 次设备号 驱动程序通过主设备号与字符设备文件一一对应,驱动程序的主设备号可

聊聊Linux用户态驱动设计

序言 设备驱动可以运行在内核态,也可以运行在用户态,用户态驱动的利弊网上有很多的讨论,而且有些还上升到政治性上,这里不再多做讨论.不管用户态驱动还是内核态驱动,他们都有各自的缺点.内核态驱动的问题是:系统调用开销大:学习曲线陡峭:接口稳定性差:调试困难:bug致命:编程语言选择受限:而用户态驱动面临的挑战是:如何中断处理:如何DMA:如何管理设备的依赖关系:无法使用内核服务等.对此,<User-Space Device Drivers in Linux: A First Look> 一文有较详

[国嵌攻略][073][静态函数库设计]

外部函数 Linux应用程序设计中需要的外部函数主要由函数库和系统调用来提供. 两者区别 系统调用在Linux内核中位于核心态,而函数库是由工程师提供位于用户态 函数库分类 函数库按照链接方式可以分为静态函数库和动态函数库 存放位置 Linux应用程序使用的主要函数库均存放于/lib,/usr/lib目录下,其中以*.so.*方式命名的是动态函数库,而以*.a方式命名的是静态函数库. 静态链接库的特点 程序所要用到的库函数代码在链接时全部被拷贝到程序中.如果有多个进程在内存中同时运行,并且使用了

[国嵌攻略][090][linux网络编程模型]

编程模型 Socket的实质就是一个接口,利用该接口,用户在使用不同的网络协议时,操作函数得以统一.而针对不同协议的差异性操作,则交给了Socket去自行解决. TCP编程模型 UDP编程模型

[国嵌攻略][049][中断处理流程深度剖析]

中断的生命周期 1.串口控制器产生事件,送到中断控制器,如果通过中断控制器的过滤,由中断控制器把事件送到CPU核 2.中断信号产生(中断源)->中断信号过滤(中断控制器)->中断信号处理(CPU) 中断源在中断的生命周期中,中断源的作用是负责产生中断信号.2440支持60个中断源:6410支持64个中断源:210支持93个中断源 中断过滤 1.中断信号送到中断控制器来了之后,中断控制器要进行过滤 2.串口子中断TX0的过滤过程: 2.1.首先,当TX0产生中断后SUBSRCPND中相应的位会被

[国嵌攻略][116][字符设备控制技术]

设备控制理论 1.设备控制的作用 大部分驱动程序除了需要提供读写设备的能力外,还需要具备控制设备的能力.比如改变波特率. 2.设备控制的函数 在用户空间使用ioctl系统调用函数来控制设备. int ioclt(int fd, unsigned long cmd, ...) fd:要控制的设备文件描述符 cmd:发送给设备的命令 ...:第三个参数是可选的参数,存在与否是依赖于控制命令 当应用程序使用ioclt系统调用时,驱动程序将由如下函数来响应: 1. 2.6.36以前的内核 long (*