MPU6050带字符驱动的i2c从设备驱动1

开干:

1、闲言碎语

这个驱动,越写觉的越简单,入门难,入门之后感觉还好。Linux开发还是比较友好的。

2、编写MPU6050带字符驱动的i2c从设备驱动

要实现的功能就是,将MPU6050作为字符驱动,在应用层,对其进行读数据。实现简单的功能。在前面的分析和实践中,可以看到实现字符驱动主要是实现file_operation中的方法,注册初始化cdev,让cdev和file_opration产生联系,字符驱动的初始化通过module_init来声明。实现i2c从设备驱动,主要是i2c_client和i2c_driver通过名字匹配,然后调用probe函数对设备进行初始化。那么,实现字符驱动的i2c从设备驱动,其实就是在i2c从设备驱动中添加字符驱动操作方法,从而在/dev中产生设备节点,让用户可以通过Linux
application的API对其进行操作。

本文实现了带字符驱动的i2c从设备驱动,然后编写了用户层测试程序,测试结果正确。下面对部分代码进行分析。

定义i2c_driver,file_operations,

static struct i2c_driver mpu6xxx_driver = {

.driver = {

.name = "mpu6xxx",

.owner = THIS_MODULE,

},

.class = I2C_CLASS_HWMON,

.id_table = mpu6xxx_ids,

.probe = mpu6xxx_probe,

.remove = mpu6xxx_remove,

};

主要实现其中的probe函数。

struct file_operations mpu6xxx_fops = {

owner : THIS_MODULE,

unlocked_ioctl : mpu6xxx_ioctl,

open : mpu6xxx_open,

release : mpu6xxx_release,

};

主要实现其中的ioctl函数。

probe函数实现:

static int mpu6xxx_probe(struct i2c_client *client, const struct i2c_device_id *id){

u16 version;

int result,retval = -1;

struct mpu6xxx_data *mpu6xxx;

dev_t dev;

printk(KERN_DEBUG "mpu6xxx driver probe... \n");

if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){

retval = -EINVAL;

goto failed;

} //核查i2c驱动

mpu6xxx = kzalloc(sizeof(struct mpu6xxx_data),GFP_KERNEL);

//分配用户数据

if(!mpu6xxx)

{

retval = -ENOMEM;

goto failed;

}

memset(&mpu6xxx->gyro,0,sizeof(struct sub_sensor));

memset(&mpu6xxx->accel,0,sizeof(struct sub_sensor));

mutex_init(&mpu6xxx->lock);

mpu6xxx->client = client;

i2c_set_clientdata(client,mpu6xxx); //用来在驱动中获取数据

this_client = client;

version = i2c_smbus_read_byte_data(client,MPU6050_REG_WHO_AM_I);

if(version != 0x70)

{

printk("error retval %d , version %.2x \n",retval , version);

retval = -2;

goto failed;

}

//检查version

result = alloc_chrdev_region(&dev,this_major,1,"mpu6xxx");

if(result < 0)

{

retval = result;

goto failed;

}

this_major = MAJOR(dev);

cdev_init(&mpu6xxx->cdev,&mpu6xxx_fops);

mpu6xxx->cdev.owner = THIS_MODULE;

result = cdev_add(&mpu6xxx->cdev,dev,1);

if(result)

{

retval = result;

goto failed;

}

mpu_cls = class_create(THIS_MODULE,"mpu6xxx");

if(IS_ERR(mpu_cls))

{

retval = -3;

goto failed;

}

mpu_device = device_create(mpu_cls,NULL,dev,NULL,"mpu6xxx");

if(IS_ERR(mpu_device))

{

class_destroy(mpu_cls);

}

//注册cdev,以及在/dev中产生节点

mpu6xxx_reset(mpu6xxx);

mpu6xxx_disable(mpu6xxx);

retval = 0;

printk(KERN_DEBUG "mpuxxx probe succeed...\n");

return retval;

failed:

return retval;

};

ioctl实现:

static int mpu6xxx_ioctl(struct file *file, unsigned int cmd,unsigned long arg)

{

int re = -1;

void __user *argp = (void __user *)arg;

struct mpu6xxx_data *mpu6xxx = i2c_get_clientdata(this_client);

printk("ioctl ... cmd %d mpucmd %d BUFFERSIZE %d\n",cmd,MPU_IOCTL_GETGYRO,BUFFERSIZE);

switch(cmd)

{

case MPU_IOCTL_GETGYRO:

// ioctl这个cmd码,可以参考博客http://blog.csdn.net/shanshanpt/article/details/19897897

mutex_lock(&(mpu6xxx->lock) ); //通过互斥操作来避免频繁读写

re = mpu6xxx_read_data(mpu6xxx,0);

if(re != 0) return re;

printk("x : %d \n", mpu6xxx->gyro.x.value);

if(copy_to_user(argp,&mpu6xxx->gyro,sizeof(struct sub_sensor))) //将数据拷贝到用户空间

{

printk("failed copy data .. \n");

mutex_unlock(&mpu6xxx->lock);

return -EFAULT;

}

printk("ioctl succed...\n");

mutex_unlock(&mpu6xxx->lock);

break ;

case MPU_IOCTL_GETACCEL:

mutex_lock(&(mpu6xxx->lock) );

re = mpu6xxx_read_data(mpu6xxx,1);

if(re != 0) return re;

if(copy_to_user(argp,&mpu6xxx->accel,sizeof(struct sub_sensor)))

{

mutex_unlock(&(mpu6xxx->lock) );

printk("failed copy data .. \n");

return -EFAULT;

}

mutex_unlock(&(mpu6xxx->lock) );

break;

default: break;

}

return 0;

}

驱动加载结果:

应用层代码结果:

在动6050时,数据会变动。并且数据大小正常。

时间: 2025-01-01 06:39:09

MPU6050带字符驱动的i2c从设备驱动1的相关文章

【linux驱动分析】misc设备驱动

misc设备驱动.又称混杂设备驱动. misc设备驱动共享一个设备驱动号MISC_MAJOR.它在include\linux\major.h中定义: #define MISC_MAJOR 10 miscdevice的结构体例如以下,它在include\linux\miscdevice.h中定义: struct  miscdevice { int  minor; const  char  *name; const  struct file_operations  *fops; struct  li

Linux设备驱动编程之复杂设备驱动

这里所说的复杂设备驱动涉及到PCI.USB.网络设备.块设备等(严格意义而言,这些设备在概念上并不并列,例如与块设备并列的是字符设备,而PCI.USB设备等都可能属于字符设备),这些设备的驱动中又涉及到一些与特定设备类型相关的较为复杂的数据结构和程序结构.本文将不对这些设备驱动的细节进行过多的介绍,仅仅进行轻描淡写的叙述. PCI 是The Peripheral Component Interconnect -Bus的缩写,CPU使用PCI桥chipset与PCI设备通信,PCI桥chipset

字符设备驱动、平台设备驱动、设备驱动模型、sysfs的关系

Linux驱动开发的童鞋们来膜拜吧:-)  学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关联的分析.对于开发者而言,能够熟悉某一点并分享出来已很难得,但对于专注传授技术和经验给

[kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联

转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术.对于初学者来说会非常困惑,甚至对Linux有一定基础的工程师而言,能够较好理解这些相关技术也相对不错了.要深刻理解其中的原理需要非常熟悉设备驱动相关的框架和模型代码.网络上有关这些技术的文章不少,但多是对其中的某一点进行阐述,很难找到对这些技术进行比较和关

Linux设备驱动第七篇:高级字符驱动操作之阻塞IO

我们之前介绍过简单的read,write操作,那么会有一个问题:当驱动无法立即响应请求该怎么办?比如一个进程调用read读取数据,当没有数据可读时该怎么办,是立即返回还是等到有数据的时候:另一种情况是进程调用write向设备写数据,如果缓冲区满了或者设备正忙的时候怎么办,是立即返回还是继续等待直到设备可写?这种情况下,一般的缺省做法是使进程睡眠直到请求可以满足为止.本篇就介绍遇到这类问题驱动的处理方法. 睡眠 什么是睡眠?一个进程睡眠意味着它暂时放弃了CPU的运行权,直到某个条件发生后才可再次被

Linux设备驱动第六篇:高级字符驱动操作之iotcl

在之前我们介绍了怎样实现一个简单的字符设备驱动.并介绍了简单的open,close,read,write等驱动提供的基本功能.可是一个真正的设备驱动往往提供了比简单读写更高级的功能. 这一篇我们就来介绍一些驱动动中使用的一些高级的操作的实现. 大部分驱动除了提供对设备的读写操作外,还须要提供对硬件控制的接口,比方查询一个framebuffer设备能提供多大的分辨率,读取一个RTC设备的时间,设置一个gpio的高低电平等等.而这些对硬件操作能力的实现一般都是通过ioctl方法来实现的 1. 原型介

RT-Thread 设备驱动I2C浅析及使用

由于 I2C 可以控制多从机的属性,设备驱动模型分为  I2C总线设备(类似与Linux里面的I2C适配器) + I2C从设备: 系统I2C设备驱动主要实现 I2C 总线设备驱动,而具体的I2C 从设备的实现则调用I2C总线设备ops 访问 I2C 总线设备 一般情况下 MCU 的 I2C 器件都是作为主机和从机通讯,在 RT-Thread 中将 I2C 主机虚拟为 I2C总线设备,I2C 从机通过 I2C 设备接口和 I2C 总线通讯,相关接口如下所示: 函数 描述 rt_device_fin

Linux设备驱动核心理论(三)

10.中断与时钟 10.1 中断与定时器 所谓中断是指CPU在执行程序的过程中,出现了某些突发事件急待处理,CPU必须暂停执行当前程序,转去处理突发事件,处理完毕后CPU又返回原程序被中断的位置并继续执行. 根据中断的来源,中断可分为内部中断和外部中断,内部中断的中断来源来自CPU内部(软件中断.溢出.除法错误等,例如,操作系统从用户态切换到内核态需借助CPU内部的软件中断),外部中断的中断来源来自CPU外部,由外设提出请求. 根据中断是否可以屏蔽分为可屏蔽中断与不屏蔽中断(NMI),可屏蔽中断

spi驱动框架全面分析,从master驱动到设备驱动

内核版本:linux2.6.32.2 硬件资源:s3c2440 参考:  韦东山SPI视频教程 内容概括: 1.I2C 驱动框架回顾 2.SPI 框架简单介绍 3.master 驱动框架 3.1 驱动侧 3.2 设备侧 4.SPI 设备驱动框架 4.1 设备册 4.2 驱动侧 5.设备驱动程序实例 1.I2C 驱动框架回顾 在前面学习 I2C 驱动程序的时候我们知道,I2C 驱动框架分为两层,一层是控制器驱动程序 i2c_adapter,它一般是由芯片厂商写好的,主要提供一个 algorithm