linux mpu open,linux驱动之i2c子系统mpu6050设备驱动(示例代码)

以下是mpu6050简单的驱动实现,mpu6050是I2C接口的6轴传感器,可以作为字符设备注册到内核,本代码运行环境是3.4.2内核,4.3.2版本的编译链,12.04版本的Ubuntu,硬件环境是jz2440开发板;

按照之前分析的I2C驱动框架,mpu6050驱动主要是实现外设端的驱动,主要是注册外设到I2C总线,而外设端注册到I2C总线包括device及driver两个部分注册到I2C总线,采用分离的设计思想,详情见代码:

device注册到I2C总线:

#include #include#include#include#include#include#include

static const unsigned short addr_list[] = { 0x50,0x68, I2C_CLIENT_END };static struct i2c_board_info mpu6050_info ={

.type= "mpu6050",

};static struct i2c_client *mpu6050_client;static int mpu6050dev_init ( void)

{struct i2c_adapter *i2c_adap;

i2c_adap= i2c_get_adapter ( 0);

mpu6050_client= i2c_new_probed_device ( i2c_adap, &mpu6050_info, addr_list, NULL );

i2c_put_adapter ( i2c_adap );if( mpu6050_client )return 0;else

return -ENODEV;

}static void mpu6050dev_exit ( void)

{

i2c_unregister_device ( mpu6050_client );

}

module_init ( mpu6050dev_init );

module_exit ( mpu6050dev_exit );

MODULE_LICENSE ("GPL" );

注:为实现动态加载驱动模块,使用了 i2c_new_probed_device  函数,该函数的关键作用是在把设备注册到总线之前,会判断该设备的地址是否真实有效,或者也可以说是该设备是否真实存在;另外也可以使用i2c_new_device函数来加载一个设备到总线,但是该函数类似I2C总线总force属性,会强制认为加载的设备地址真实有效,或者是强制认为当前的设备真实存在,  另外在把mpu6050关联到I2C适配器上时,调用了 i2c_get_adapter ( 0 ) 函数,由于S3C2440只有一个I2C适配器,所以该函数的参数直接写0,即第一个适配器;

接下来是设备驱动加载到I2C总线:

#include #include#include#include#include#include#include#include#include#include

static int mpu6050_open ( struct inode *inode, struct file *file );static ssize_t mpu6050_write ( struct file *file, const char __user *buf, size_t, loff_t *offset );static ssize_t mpu6050_read ( struct file *file, char __user *buf, size_t size, loff_t *offset );static int mpu6050drv_probe ( struct i2c_client *i2c_client, const struct i2c_device_id *i2c_device_id );static int mpu6050drv_remove ( struct i2c_client *i2c_client );static struct i2c_device_id mpu6050drv_id ={

.name= "mpu6050",

.driver_data= 0x68,

};static struct i2c_driver mpu6050drv ={

.driver={

.name= "mympu6050",

.owner=THIS_MODULE,

},

.probe=mpu6050drv_probe,

.remove=mpu6050drv_remove,

.id_table= &mpu6050drv_id,

};/*字符设备相关*/

int major = 0;static structcdev mpu6050_cdev;static struct file_operations mpu6050ops ={

.owner=THIS_MODULE,

.read=mpu6050_read,

.write=mpu6050_write,

.open=mpu6050_open,

};static struct class *cls;static ssize_t mpu6050_read ( struct file *file, char __user *buf, size_t size, loff_t *offset )

{return 0;

}static ssize_t mpu6050_write ( struct file *file, const char __user *buf, size_t size, loff_t *offset )

{return 0;

}static int mpu6050_open ( struct inode *inode, struct file *file )

{/*可以做低功耗开关,调用open的时候,才使能mpu6050模块,电路无这样的功能,故不需要初始化这个函数*/

return 0;

}static int mpu6050drv_probe ( struct i2c_client *i2c_client, const struct i2c_device_id *i2c_device_id )

{

dev_t dev= 0;

printk ("mpu6050drv_probe\r\n");#if 0

/*把mpu6050当做字符设备注册到内核*/major= register_chrdev ( 0, "mpu6050", &mpu6050ops );#elsealloc_chrdev_region (&dev, 0, 2, "mpu6050_region" ); //占用2个次设备号

cdev_init ( &mpu6050_cdev, &mpu6050ops );

mpu6050_cdev.owner=THIS_MODULE;

cdev_add (&mpu6050_cdev, dev, 2 ); //占用2个次设备号

#endifcls= class_create ( THIS_MODULE, "mpu6050cls");

major=MAJOR ( dev );

device_create ( cls, NULL, MKDEV ( major,0 ), NULL, "mpu6050");//device_create ( cls, NULL, MKDEV ( major, 1 ), NULL, "mpu6050_2" );

return 0;

}static int mpu6050drv_remove ( struct i2c_client *i2c_client )

{

printk ("mpu6050drv_remove\r\n");

unregister_chrdev_region (0, 1);

cdev_del (&mpu6050_cdev );

device_destroy ( cls, MKDEV ( major,0) );//device_destroy ( cls, MKDEV ( major, 1 ) );

class_destroy ( cls );return 0;

}static int mpu6050_init ( void)

{

i2c_add_driver (&mpu6050drv );return 0;

}static void mpu6050_exit ( void)

{

i2c_del_driver (&mpu6050drv );

}

module_init ( mpu6050_init );

module_exit ( mpu6050_exit );

MODULE_LICENSE ("GPL" );

当设备加载到I2C总线,外设驱动也加载到总线后,I2Ccore会调用match函数,匹配 mpu6050drv 结构体总 id_table  成员里的name是否和加载的外设名一致,如果一致就会进行绑定,然后调用外设驱动的probe函数,这样I2C驱动就基本上完成了,接下来就是根据外设的具体情况去处理了,比如如果外设是mpu6050、则当做字符设备注册到内核,然后编写读写函数,这些就已经不是I2C驱动框架之内的工作了,而是字符设备驱动的范畴了;

本驱动没有具体去实现mpu6050的读写过程,具体的代码完全可以借用裸机版的代码,本实例仅供I2C驱动框架参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值