开干:
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时,数据会变动。并且数据大小正常。

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

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

    #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #inclu ...

  2. 【Linux高级驱动】linux设备驱动模型之平台设备驱动机制

    [1:引言: linux字符设备驱动的基本编程流程] 1.实现模块加载函数  a.申请主设备号    register_chrdev(major,name,file_operations);  b.创 ...

  3. Linux中总线设备驱动模型及平台设备驱动实例

    本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...

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

    misc设备驱动.又称混杂设备驱动. misc设备驱动共享一个设备驱动号MISC_MAJOR.它在include\linux\major.h中定义:         #define MISC_MAJO ...

  5. Linux驱动之I2C总线设备以及驱动

    [ 导读] 本文通过阅读内核代码,来梳理一下I2C子系统的整体视图.在开发I2C设备驱动程序时,往往缺乏对于系统整体的认识,导致没有一个清晰的思路.所以从高层级来分析一下I2C系统的设计思路,将有助于 ...

  6. Linux 驱动框架---cdev字符设备驱动和misc杂项设备驱动

    字符设备 Linux中设备常见分类是字符设备,块设备.网络设备,其中字符设备也是Linux驱动中最常用的设备类型.因此开发Linux设备驱动肯定是要先学习一下字符设备的抽象的.在内核中使用struct ...

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

    这里所说的复杂设备驱动涉及到PCI.USB.网络设备.块设备等(严格意义而言,这些设备在概念上并不并列,例如与块设备并列的是字符设备,而PCI.USB设备等都可能属于字符设备),这些设备的驱动中又涉及 ...

  8. Linux驱动编写(块设备驱动代码)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 按照ldd的说法,linux的设备驱动包括了char,block,net三种设备.char设备 ...

  9. Linux gadget驱动分析3------复合设备驱动

    windows上面对usb复合设备的识别需要下面条件. “ 如果设备满足下列要求,则总线驱动程序还会报告 USB\COMPOSITE 的兼容标识符: 设备描述符的设备类字段 (bDeviceClass ...

随机推荐

  1. BZOJ.4826.[AHOI/HNOI2017]影魔(树状数组/莫队 单调栈)

    BZOJ LOJ 洛谷 之前看\(mjt\)用莫队写了,以为是一种正解,码了3h结果在LOJ T了没A= = 心态爆炸(upd:发现是用C++11(NOI)交的,用C++11交就快一倍了...) 深刻 ...

  2. 2018.12.1 Test

    目录 2018.12.1 Test A 串string(思路) B 变量variable(最小割ISAP) C 取石子stone(思路 博弈) 考试代码 B C 2018.12.1 Test 题目为2 ...

  3. 洛谷 P2814 家谱(gen)

    题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系的描述,其中每一组 ...

  4. 面试题fugui

    1.什么是栈溢出,在什么情况下可能会出现 栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当数据足够大时,将会溢出缓冲区的范围. python函数调用是通过栈这 ...

  5. C++程序设计方法3:自动类型转换

    方法1:在源类中定义目标类型转换运算符 #include <iostream> using namespace std; class Dst { public: Dst() { cout ...

  6. 腾讯云CDN python SDK

    腾讯云CDN python SDK 博主在开发时偶尔要用到CDN,感觉适合学生党的应该是腾讯云的CDN了,还提供了每月10G的流量,博主平时学习使用已经足够了. 代码 #coding=utf-8 fr ...

  7. db2 执行报错收集

    1.对于执行中的报错,可以在db2命令行下运行命令 : db2=>? SQLxxx 查看对应的报错原因及解决方法. 2.错误SQL0206N SQLSTATE=42703  检测到一个未定义的列 ...

  8. 爬虫程序获取登录Cookie信息时遇到302,怎么处理

    最近要做个爬虫程序爬爬东西,先搞定登录授权这块,没得源代码,所以只能自行搞定了,按平时的直接发起HttpWebRequest(req)请求,带上用户名密码,好了,然后 HttpWebResponse ...

  9. ASCII到Unicode到UTF-8

    1.很久以前使用的是ASCII:只有一个字节,也就是2的8次方,可以表示256个不同状态,电脑最初起源于美国,够用了,刚开始只是使用了127位,后来后面的部分被他们用来表示一些横线字符之类的128-2 ...

  10. GMA Round 1 新年祝福

    传送门 新年祝福 15个人聚集在一起,新年到来,他们每个人写下了一句新年祝福.大家把祝福收集起来,然后重新分回去.如果一个人拿到了自己写的祝福,他就会觉得很没有意思,因为得不到别人的祝福.要避免这种尴 ...