我是靠谱客的博主 缥缈航空,最近开发中收集的这篇文章主要介绍嵌入式LINUX驱动学习之15 i2c代码举例(三轴加速度传感器MMA8653)方式一一、添加板级信息(硬件信息)二、软件驱动代码三、用户空间代码举例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

嵌入式LINUX驱动学习之15 i2c代码举例(三轴加速度传感器MMA8653)方式一

  • 一、添加板级信息(硬件信息)
    • 1.1 插入到其它原文件中
    • 1.2 利用arch_initcall()函数,新建一个源文件的方式添加i2c硬件
      • 1.2.1 源文件
      • 1.2.2 Makefile文件
  • 二、软件驱动代码
  • 三、用户空间代码举例

说明:
本例使用开发板为x6818,三星S5P6818 cpu

一、添加板级信息(硬件信息)

注: 1.1和1.2是原理相同,两种不同方式,二选一即可

1.1 插入到其它原文件中

本小节以在“arch/arm/plat-s5p6818/x6818/device.c” 文档中插入内容为例

//vim arch/arm/plat-s5p6818/x6818/device.c
#include <linux/i2c.h>
/*注:添加如下信息前,应先查检原代码中是否有相关的硬件信息注册,
如果有,则可以不必添加,或注释后自行添加。
*/
static struct i2c_board_info mma8653_obj[] = {
{
I2C_BOARD_INFO("my_mma8653_test",0x1D)// "my_mma8653_test" 用于匹配,0x1D为i2c从设备地址
}
};
/*
2
: mma8653连接S5P6818芯片的I2C端口编号
mma8653_obj : struct i2c_board_info 结构体对象地址
ARRAY_SIZE(mma8653_obj) : 当 mma8653_obj为数组时,可以直接求组元素个数,即i2c从设备个数;
*/
i2c_register_board_info(2,mma8653_obj,ARRAY_SIZE(mma8653_obj));

1.2 利用arch_initcall()函数,新建一个源文件的方式添加i2c硬件

1.2.1 源文件

//vim mymma8653_dev.c
#include <linux/i2c.h>
#include <linux/init.h>
static struct i2c_board_info mma8653_obj[] = {
{
I2C_BOARD_INFO("my_mma8653_test",0x1D)
}
};
static int __init mma8653_dev(void){
i2c_register_board_info(2,mma8653_obj,1);
return 0;
}
arch_initcall(mma8653_dev);

1.2.2 Makefile文件

//vim Makefile
obj-y
:= board.o device.o x6818-lcds.o mymma8653_dev.o

二、软件驱动代码

功能:读取mma8653的x,y,z轴数值,并传递给用户空间

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
void mma8653_state(void);
void mma8653_action(void);
struct i2c_client *g_cli = NULL;
/* 定义x,y,z三轴*/
struct mma8653_state_struct {
int x;
int y;
int z;
};
struct mma8653_state_struct *mma8653_state_obj = NULL;
/*当用户采用ioctl函数读取三轴加速度传感器信息时,调用此函数*/
static long my_ioctl(struct file * file,unsigned int ucmd,unsigned long ubuf){
int copy_ret = 0;
//池软件驱动没有匹配到硬件驱动时,不参获取信息,报错
if(!g_cli){
printk("设备打开失败!n");
return -EIO;
}
mma8653_state_obj =(struct mma8653_state_struct *) kmalloc(sizeof(mma8653_state_obj),GFP_KERNEL);
mma8653_action();
mma8653_state();
copy_ret = copy_to_user((struct mma8653_state_struct *)ubuf,
mma8653_state_obj,sizeof(struct mma8653_state_struct));
kfree(mma8653_state_obj);
return 0;
}
struct file_operations f_ops={
.owner = THIS_MODULE,
.unlocked_ioctl = my_ioctl
};
struct miscdevice misc_ops = {
.minor = MISC_DYNAMIC_MINOR,
.fops
= &f_ops,
.name = "mma8653_ioctl"
};
void mma8653_state(void){
int mma8653_x,mma8653_y,mma8653_z;
mma8653_x = (i2c_smbus_read_byte_data(g_cli, 0x01) << 2 ) |
(i2c_smbus_read_byte_data(g_cli,0x2) >> 6 );
mma8653_y = (i2c_smbus_read_byte_data(g_cli, 0x03) << 2 ) |
(i2c_smbus_read_byte_data(g_cli,0x4) >> 6 );
mma8653_z = (i2c_smbus_read_byte_data(g_cli, 0x05) << 2 ) |
(i2c_smbus_read_byte_data(g_cli,0x6) >> 6 );
/*判断第10位是否为1,如果为1,说明结果是负值
0x3ff
=>
11 1111 1111
//确保有效值为低10位
*/
if(mma8653_x & (0x1 << 9))
mma8653_x = ((mma8653_x & 0x3ff) & ~(0x1 << 9)) - (0x1 << 9);
if(mma8653_y & (0x1 << 9))
mma8653_y = ((mma8653_y & 0x3ff) & ~(0x1 << 9)) - (0x1 << 9);
if(mma8653_z & (0x1 << 9))
mma8653_z = ((mma8653_z & 0x3ff) & ~(0x1 << 9)) - (0x1 << 9);
mma8653_state_obj -> x = mma8653_x;
mma8653_state_obj -> y = mma8653_y;
mma8653_state_obj -> z = mma8653_z;
}
//激活mma8653
void mma8653_action(void){
int data;
data= i2c_smbus_read_byte_data(g_cli, 0x2a);
data|= 1;
i2c_smbus_write_byte_data(g_cli,0x2a,data);
}
/*当软件驱动和硬件驱动匹配成功时执行*/
static int mma8653_probe(struct i2c_client * client,
const struct i2c_device_id *i2c_dev_id){
g_cli = client;
return 0;
}
/*当软件驱动卸载时执行*/
static int mma8653_remove(struct i2c_client *client){
g_cli = NULL;
return 0;
}
struct i2c_device_id i2c_dev_id_obj = {
.name = "my_mma8653_test",
.driver_data = 0
};
struct i2c_driver mma8653_dri_obj = {
.probe
= mma8653_probe,
.remove
= mma8653_remove,
.id_table = &i2c_dev_id_obj,
.driver
= {
.name = "my_mma8653_dri"
}
};
static int mma8653_test_init(void){
misc_register(&misc_ops);
i2c_add_driver(&mma8653_dri_obj);//向内核注册软件驱动
printk("%sn",__func__);
return 0;
}
static void mma8653_test_exit(void){
misc_deregister(&misc_ops);
i2c_del_driver(&mma8653_dri_obj);//从内核卸载软件驱动 
printk("%sn",__func__);
}
module_init(mma8653_test_init);
module_exit(mma8653_test_exit);
MODULE_LICENSE("GPL");

三、用户空间代码举例

打印mma8653驱动传递过来的三轴数值

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#define RD 0X1111
/*定义三轴结构体*/
struct mma8653_state_struct {
int x;
int y;
int z;
};
/*打印三轴的数值*/
struct mma8653_state_struct mma8653_obj;//保存三轴数值
void mma8653_print(void){
printf("x:%*d,y:%*d,z:%*dr",4,mma8653_obj.x,
4,mma8653_obj.y , 4,mma8653_obj.z);
fflush(NULL);
}
int main(int argc , char * argv[]){
int fp,ioctl_ret;
if(argc != 2)
goto comm_err;
fp = open(argv[1],O_RDWR);
if(fp < 0)
goto fp_err;
/*每隔1秒读取一次三轴的数值*/
while(1){
ioctl_ret = ioctl(fp,RD,&mma8653_obj);
if(ioctl_ret)
goto ioctl_err;
mma8653_print();
sleep(1);
}
return 0;
comm_err :
printf("命令错误!n");
printf("
comm <cdev_file>n");
fp_err :
perror("open file error :");
return -1;
ioctl_err:
perror("ioctl error :");
return -1;
}

最后

以上就是缥缈航空为你收集整理的嵌入式LINUX驱动学习之15 i2c代码举例(三轴加速度传感器MMA8653)方式一一、添加板级信息(硬件信息)二、软件驱动代码三、用户空间代码举例的全部内容,希望文章能够帮你解决嵌入式LINUX驱动学习之15 i2c代码举例(三轴加速度传感器MMA8653)方式一一、添加板级信息(硬件信息)二、软件驱动代码三、用户空间代码举例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部