Android版本:2.3.7_r1
Linux内核版本:android-goldfish-2.6.29
本文介绍如何开发Android驱动程序并进行测试。
一、Android驱动程序开发
Android是基于Linux的,所以Android驱动程序的开发方法与Linux驱动程序开发方法相同。
下面我们通过一个例子程序来熟悉一下Android驱动程序的开发,这里只是一个简单的说明,如果你对Linux驱动开发也不熟悉,可以学习《Linux Device Driver》或参考的我博客的《LDD3源码分析》系列文章。
首先我们在Android内核源码的drivers目录下创建一个新的目录example,我们的驱动程序源码就放在这个目录下:
# mkdir drivers/example
# cd drivers/example
创建example.h文件,其内容如下:
[cpp]
1#ifndef _EXAMPLE_H_
2#define _EXAMPLE_H_
3
4#include <linux/cdev.h>
5#include <linux/semaphore.h>
6
7#define EXAMPLE_DEVICE_NODE_NAME "example"
8#define EXAMPLE_DEVICE_FILE_NAME "example"
9#define EXAMPLE_DEVICE_PROC_NAME "example"
10#define EXAMPLE_DEVICE_CLASS_NAME "example"
11#define EXAMPLE_MAJOR 0
12
13struct example_dev {
14 struct semaphore sem;
15 struct cdev cdev;
16 int val;
17};
18
19#endif
该头文件中定义了驱动程序中将用到的一些宏,并定义了设备结构体example_dev,该结构体的成员sem用于保证对设备的同步访问,cdev表示该设备是Linux设备驱动中的字符设备,val则代表该设备中的一个寄存器,我们这个驱动程序的作用就是给用户层应用程序提供读写这个val寄存器的方法。
创建example.c文件,其内容如下:
[cpp]
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/types.h>
4#include <linux/fs.h>
5#include <linux/proc_fs.h>
6#include <linux/device.h>
7#include <asm/uaccess.h>
8
9#include "example.h"
10
11static int example_major = EXAMPLE_MAJOR;
12static int example_minor = 0;
13
14static struct class* example_class = NULL;
15static struct example_dev* example_dev = NULL;
16
17module_param(example_major, int, S_IRUGO);
18module_param(example_minor, int, S_IRUGO);
19
20static int example_open(struct inode* inode, struct file* filp)
21{
22 struct example_dev* dev;
23
24 /*
25 * 取得设备结构体example_dev,保存在filp私有数据区中,以方便其它函数使用。
26 */
27 dev = container_of(inode->i_cdev, struct example_dev, cdev);
28 filp->private_data = dev;
29
30 return 0;
31}
32
33static int example_release(struct inode* inode, struct file* filp)
34{
35 return 0;
36}
37
38static ssize_t example_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos)
39{
40 struct example_dev* dev = filp->private_data;
41 ssize_t retval = 0;
42
43 /*
44 * 加锁
45 */
46 if(down_interruptible(&(dev->sem)))
47 return -ERESTARTSYS;
48
49 if(count < sizeof(dev->val))
50 goto out;
51
52 /*
53 * 读寄存器的值到用户空间。
54 */
55 if(copy_to_user(buf, &(dev->val), sizeof(dev->val)))
56 {
57 retval = -EFAULT;
58 goto out;
59 }
60
61 retval = sizeof(dev->val);
62
63out:
64 /*
65 * 解锁
66 */
67 up(&(dev->sem));
68 return retval;
69}
70
71static ssize_t example_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos)
72{
73 struct example_dev* dev = filp->private_data;
74 ssize_t retval = 0;
75
76 /*
77 * 加锁
78 */
79 if(down_interruptible(&(dev->sem)))
80 return -ERESTARTSYS;
81
82 if(count != sizeof(dev->val))
83 goto out;
84
85 /*
86 * 从用户空间读取并给寄存器赋值。
87 */
88 if(copy_from_user(&(dev->val), buf, count))
89 {
90 retval = -EFAULT;
91 goto out;
92 }
93
94 retval = sizeof(dev->val);
95
96out:
97 /*
98 * 解锁
99 */
100 up(&(dev->sem));
101 return retval;
102}
103
104/*
105 * 设备操作函数集
106 */
107static struct file_operations example_fops =
108{
109 .owner = THIS_MODULE,
110 .open = example_open,
补充:移动开发 , Android ,