频道栏目
首页 > 程序开发 > 移动开发 > Android > 正文
第一个Android驱动添加
2017-09-12 10:38:45      个评论    来源:chenxiaoping1993的博客  
收藏   我要投稿

第一个Android驱动添加

做一下总结:

我将从从下往上的步骤进行描述:

硬件驱动层程序:

kernel/driver/hello hello.h hello. c 真正与硬件交互的代码 Kconfig Makefile 显示到内核编译选项中(只是显示) driver/Makefile 在这儿添加我们的Makefile 之后,编译时才会编译我们的硬件驱动程序 本层程序成功的标志,在hello目录下生成 hello.o

硬件抽象层 :

hardware/libhardware/include/hardware hello.h hardware/libhardware/modules/hello hello.c Android.mk 成功的标志 在 out/target/product/generic/system/lib/hw 目录下看到 hello.default.so

jni 层:

framework/base/services/jni com_android_server_HelloService.cpp (c++ 文件) onload.cpp Android.mk framework/base/services/java/com/android/server/hello hello.c frameworks/base/core/java/android/os目录,新增IHelloService.aidl接口定义文件。 frameworks/base 目录,修改 Android.mk 添加 新加的 aidl ,使其被编译。 frameworks/base/services/java/com/Android/server 添加 HelloService.java 在SystemServer.java 中添加 HelloService 以便于开机就可以把该服务运行起来。 成功的标志: 编译并烧写成功之后在 adb 中执行 adb shell service list ,查看自己的服务是否启动起来。如果有启动起来,那恭喜,成功了。

一、驱动的加载

在 driver 下边创建一个自己的目录 创建 .h 和 .c 文件 创建 Makeconfig 和 Kconfig 文件

作用: 在 menuconfig 中添加我们自己的选项(选项中的名字是我们在 Kconfig 中指定的)

但此时我们还无法把我们自己的驱动编译进去 在 drivers/Makefile 文件中添加 obj-$(注意不是s)……

此时,我们再执行编译内核的命令就可以把自己的代码编译进去了

(当然,编译的方式有多种,具体怎样视硬件而定,查对应的文档就可以了) 烧写完成之后,文档中说会在 adb shell /dev 下边看到对应的文件夹,我没有,但是后来又有了。晕。。。

我们也可以用另外一种方式,在 log 中看打的log,判断 驱动是否有加载

(附上 看log 方法)

adb shell

su

dmesg | grep “你打印的内容”

在这儿,我搜索的是 init 中的 “Initializing hello device.”

重点:在编译过程中遇到了好几个问题,导致编译不过。具体问题和解决方法如下:

1> implicit declaration of function ‘create_proc_entry’

解决方法:

1. 把 create_proc_entry 方法 换为 proc_create 。

2. 然后将下边的if 语句注释掉

3. 给proc_create 最后添加一个参数 &hello_fops。

修改后的样子:(注意下边的if 语句要使用图中方式注释掉)

bug1

2> error: implicit declaration of function ‘init_MUTEX’

解决方法:

1. 将 init_MUTEX 换为 sema_init

2. 给 sema_init 添加一个参数

修改后的样子:

bug2

3> error: implicit declaration of function ‘kmalloc’

error: implicit declaration of function ‘kfree’

解决方法:

1. 添加头文件

修改后的样子:

这里写图片描述

到这儿,恭喜大家,驱动已经加载成功了!!!!!!!!

二、在Android 系统中增加C 可执行程序来访问硬件驱动程序

这一步只是用可执行程序来验证硬件驱动程序是否可用,用命令行就可以实现,这一步不是必须的。

三、在Ubuntu 上为Android 增加硬件抽象层(HAL)模块访问Linux内核

这一部分,文档中写的很详细,也没有遇到什么问题。但需要注意的就是,Android.mk 文件中的每一行的末尾尽量不要出现空格,不然也许会编译不过。所以直接复制过去的童鞋们需要注意一下。

四、为Android 硬件抽象层(HAL)模块编写JNI 方法提供Java 访问硬件服务接口

如果以前使用过 aidl (进程间通信)的话,会好理解一些,如果没有的话,建议先去看一下aidl 的相关知识。

在这一层遇到过一个问题,解了好久。

Native registration unable to find class ‘com/android/server/HelloService’, aborting

现象:无法开机,看log, HelloService 找不到。

解决步骤:

首先看一下 com_android_server_HelloService.cpp 中的register_android_server_HelloService 方法

int register_android_server_HelloService(JNIEnv *env) {  
    return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, 
NELEM(method_table)); 

这个路径是 我们 HelloService 的路径,必须一丝不差。

2、该文档中有很多处把 android 写成 Android 地方,编译时会出现很多找不到类,方法等的错误,需要注意一下。

3、如果以上都没有错误,但还是无法开机,建议把 out 目录删掉,重新进行编译。

五、上层 App 进行访问测试

在这一块可能出现的问题:

1. 因为权限问题,无法读取也无法修改值。这个问题再文档中有提到。

DEVICE_NAME 定义为”/dev/hello”。由于设备文件是在内核驱动里面通过 device_create 创建的,而device_create 创建的设备文件默认只有root 用户可读写,而hello_device_open 一般是由上层APP 来调用的,这些APP 一般不具有root 权限,这时候就导致打开设备文件失败:

Hello Stub: failed to open /dev/hello – Permission denied.

解决办法是类似于Linux 的udev 规则,打开Android 源代码工程目录下,进入到system/core/rootdir 目录,里面有一个名为uevent.rc

文件,往里面添加一行:/dev/hello 0666 root root

在这儿,需要说的就是,修改完之后不要去编译 system/core ,我在本地一直无法编译通过。并且报出和很多问题,导致无法开机。所以,直接去全部编译就好了。

2. App无法 获取到 module

I/SystemServer( 461): Hello Service

I/HelloService( 461): Hello JNI: initializing……

E/HelloService( 461): Hello JNI: failed to get hello stub module.

最后报错,出现这样一个问题,是因为在全编的时候没有编译生成 hello.default.so ,所以无法找到。

解决方法:

自己编译 mmm hardware/libhardware/modules/hello/

然后 打包烧写,就可以解决这个问题了。

至于在全编的时候编译到自己添加的东西,后续再研究。

在整个流程中,遇到了许多问题,在这儿无法完全叙述出来,如果有童鞋遇到了不同的问题,可以在评论区留言,一起交流。

点击复制链接 与好友分享!回本站首页
上一篇:Android面试——AsyncTask
下一篇:Android发展史(Android各版本特性-知识篇)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站