我是靠谱客的博主 土豪大船,这篇文章主要介绍g-sensor驱动在linux的实现,现在分享给大家,希望可以做个参考。

g-sensor 驱动

复制代码
1
2
3
4
5
6
7
8
9
10
11
裸板: i2c 控制器驱动 g-snesor 驱动程序 linux: i2c 控制器驱动程序 在内核中已经写好了 1.总线 i2c-core.c __init i2c_init(void) bus_register(&i2c_bus_type);
复制代码
1
2
3
4
5
6
7
8
struct bus_type i2c_bus_type = { .name = "i2c", .match = i2c_device_match, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, };
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2.设备 i2c_client struct i2c_client { //从设备地址 unsigned short addr; /* chip address - NOTE: 7bit */ char name[I2C_NAME_SIZE];//设备ID struct device dev; //基类 //代表一个I2C控制器 表示i2c_client //代表的芯片挂载了哪个I2C控制器上 struct i2c_adapter *adapter; ...... }; i2c_new_device 3. 设备驱动 i2c_driver struct i2c_driver { struct device_driver driver; int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); //存储了该driver可以驱动的芯片的ID列表 const struct i2c_device_id *id_table; }; i2c_add_driver i2c_del_driver i2c_device_match(struct device *dev, struct device_driver *drv);

在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
注意: 先将内核中自带的g-sensor驱动裁剪掉 make menuconfig Device Drivers---> <*> Hardware Monitoring support ---> < > Freescale MMA865X 3-Axis Accelerometor make uImage 1) 向I2c-core添加设备 kernel/umentation/i2c/instantiating-devices How to instantiate I2C devices Method 1a: Declare the I2C devices by bus number Method 1b: Declare the I2C devices via devicetree Method 1c: Declare the I2C devices via ACPI Method 2: Instantiate the devices explicitly Method 3: Probe an I2C bus for certain devices vi arch/arm/plat-s5p6818/device.c
复制代码
1
2
3
4
5
6
7
+ #include <linux/i2c.h> + /*准备创建I2C设备必备的信息*/ + static struct i2c_board_info __initdata mma8653x = { + .type = "mma8653", //设备ID + .addr = 0x1D //从设备地址 + }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void __init nxp_board_devs_register (void) { //2, 该芯片挂载了第二个I2C控制器上, //&mma8653x,创建I2C设备时需要的ID和从设备地址 //1, 第二个参数给定的地址中只有一个I2C设备信息 + i2c_register_board_info (2, &mma8653x, 1); } make uImage 将新内核烧录到开发板 cp arch/arm/boot/uImage /tftpboot tftp 48000000 uImage mmc write 48000000 800 3000 vi mma8653_dev.c
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <linux/module.h> #include <linux/init.h> #include <linux/i2c.h> MODULE_LICENSE("GPL"); static const struct i2c_device_id mma8653x_tab[] = { {"mma8653", 0 }, { }, }; int mma865x_probe (struct i2c_client *client, const struct i2c_device_id *id) { printk ("enter %sn",__func__); return 0; } int mma8563x_remove (struct i2c_client *client) { printk ("enter %sn",__func__); return 0; } struct i2c_driver mma8653 = { .driver = { .name = "mma865x", .owner = THIS_MODULE; }, .id_table = mma865x_tab, .prob = mma865x_probe, .remove = mma865x_remove, }; int __init mma8653_drv_init (void) { i2c_add_driver (&mma8653); return 0; } void __exit mma8653_drv_exit (void) { i2c_del_driver (&mma8653); } module_init(mma8653_drv_init); module_exit(mma8653_drv_exit);
复制代码
1
2
3
添加完设备信息之后,就可以增加prob的功能 混杂设备, 将那些不容易分类的设备成为混杂设备
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
struct miscdevice { //主设备号固定为xxx,决定次设备号 //如果minor = MISC_DYNAMIC_MINOR 代表由系统分配次设备号 int minor; //设备文件的名称 const char *name; //设备对应的操作函数集合 const struct file_operations *fops; }; extern int misc_register(struct miscdevice *misc); extern void misc_deregister(struct miscdevice *misc);
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
misc_register misc_deregister i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command); client,要读哪个寄存器 command, g-sensor寄存器的地址 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value); client,要写哪个寄存器 command, g-sensor寄存器的地址 value,要写入的值 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, u8 *values); client,要写哪个寄存器 command,要读取的起始寄存器地址 length, 要读取的字节数 value,存储地址 vi test.c arm-cortex_a9-linux-gnueabi-gcc test.c -o test cp test ../rootfs
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #define GETXYZ_CMD 0x10001 struct acc_info { short x; short y; short z; }acc; int main (void) { int fd = open("/dev/mma865x", O_RDWR); if (fd < 0) { perror("open failed"); return -1; } while (1) { ioctl (fd, GETXYZ_CMD, &acc); printf ("x = %hd y = %hd z = %hdn", acc.x, acc.y, acc.z); sleep(1); } close (fd); }
复制代码
1
2
3
4
vi mma8653_drv.c insmod mma8653_drv.ko ./test
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <linux/miscdevice.h> #include <linux/module.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/uaccess.h> #include <linux/fs.h> MODULE_LICENSE("GPL"); #define GET_XYZ 0x10001 typedef struct acc { short x; short y; short z; }acc_t; static const struct i2c_device_id mma8653x_tab[] = { {"mma8653", 0 }, { }, }; void enter_active (void) { usigned char data = 0; //读取0X2A寄存器的内容 //详细时序实现I2C控制器驱动程序中 data = i2c_smbus_read_byte_data (g_client, 0x2A); data |= 1; i2c_smbus_write_byte_data (g_client, 0x2A, data); } void read_acc (acc_t *data) { unsigned char buf[6] = {0}; //轮询是否产生了加速度值 while (!(i2c_smbus_read_byte_data (g_client, 0x00) & (1<<3))); i2c_smbus_read_i2c_block_data(g_client, 0x01, 6, buf); data->x = buf[0] << 8 | buf[1]; data->x = data->x >> 6; data->y = buf[2] << 8 | buf[3]; data->y = data->y >> 6; data->z = buf[4] << 8 | buf[5]; data->z = data->z >> 6; } long mma8653_ioctl (struct file *filep, unsigned int cmd, unsigned long arg) { acc_t acc_data = {0}; int ret = 0; if (cmd == GET_XYZ) { //设置为active模式 enter_active (); //读取加速度值 read_acc (&acc_data); //加速值拷贝到用户空间 ret = copy_to_user ((void *)arg, &acc_data, sizeof(acc_t)); } else{ return -EINVAL; } return 0; } struct file_operations mma8653_fops = { .owner = THIS_MODULE; .unlocked_ioctl = mma8653_ioctl; }; struct miscdevice mma8653_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "mma8653x", .fops = &mma8653_fops, }; struct i2c_client *g_client = NULL; int mma865x_probe (struct i2c_client *client, const struct i2c_device_id *id) { //保存芯片对应数据结构地址 以备后续使用 g_client = client; /*准备设备号 cdev 操作函数集合 自动创建设备文件*/ misc_register (&mma8653_misc); return 0; } int mma8563x_remove (struct i2c_client *client) { misc_deregister (&mma8653_misc); return 0; } struct i2c_driver mma8653 = { .driver = { .name = "mma865x", .owner = THIS_MODULE; }, .id_table = mma865x_tab, .prob = mma865x_probe, .remove = mma865x_remove, }; int __init mma8653_drv_init (void) { i2c_add_driver (&mma8653); return 0; } void __exit mma8653_drv_exit (void) { i2c_del_driver (&mma8653); } module_init(mma8653_drv_init); module_exit(mma8653_drv_exit);

最后

以上就是土豪大船最近收集整理的关于g-sensor驱动在linux的实现的全部内容,更多相关g-sensor驱动在linux内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部