android2.3系统驱动模块由内核模块,硬件抽象模块,用户调用模块(jni)组成,内核模块和linux一致,硬件抽象模块主要需要定义两个结构:hw_module_t和hw_device_t。
hw_module_t包含模块id,版本号,署名和一个函数指针:
int open (struct hw_module_t* module, const char* id, struct hw_device_t** device);
hw_device_t包含版本,hw_module_t的引用和一个函数指针:
int close (struct hw_device_t* device);
必须导出一个HAL_MODULE_SYM符号引用hw_module_t结构。可以对这两个结构自定义,通过把这两个结构定义在自定义结构的开头(C惯用伎俩)。
用户调用模块通过hw_get_module函数加载硬件抽象模块。
int hw_get_module (const char* id, const struct hw_module_t** module);
第二个参数module接收硬件抽象模块导出的符号HAL_MODULE_SYM指向的结构体。
用户调用模块通过其提供的open方法打开指定id的设备,第二个参数device接收一个hw_device_t结构。open函数根据不同设备可以返回不同的hw_device_t结构,其中的close函数也可能不同。
然后用户调用模块就可以通过hw_device_t或自定义的结构调用close或自定义函数进行关闭或其他操作了。由于是在用户层,所以需要修改ueventd.rc修改内核模块提供的设备文件的访问权限。
然后需要编写硬件访问服务,用AIDL定义一个接口和服务类,通过jni调用用户调用模块访问设备。
通过ServiceManager.addService(String serviceName, Stub service)注册服务,Android会在System进程启动时在ServerThread线程中加载服务,然后应用就可以通过Binder机制调用服务模块的方法了。
(第二章完)