Develop the Hal layer in android2.3.1. First, refer to the online Hello demo. First, check the location of the Hal layer in the Android system:
The hardware driver can be seen as in the keinel layer. Hal encapsulates the hardware driver and then encapsulates the JNI interface before calling the Java application.
The specific process of Hal interface encapsulation is as follows:
1) Add the hello. h header file in the directory ../Android-2.3.1/hardware/libhardware/include/hardware. For details, refer to overlay. h In the current directory,
/*************************************** ************
* Android_hal_hello_demo
* Hello. h
**************************************** ***********/
# Ifndef android_hello_interface_h
# Define android_hello_interface_h
# Include <Hardware/hardware. h>
_ Begin_decls
# Define hello_hardware_module_id "hello"
Struct hello_module_t {
Struct hw_module_t common;
};
Struct hello_device_t {
Struct hw_device_t common;
Int FD;
INT (* get_val) (struct hello_device_t * Dev, int Val );
INT (* set_val) (struct hello_device_t * Dev, int Val );
};
_ End_decls;
# Endif
2) In .. /Android-2.3.1/hardware/libhardware/modules: Create a hello folder and add hello to the folder. C and Android. MK file. For details, refer to the contents in the overlay folder under the modules directory.
/*************************************** ***************************************
* Android_hal_hello_demo
* Hello. c
**************************************** *************************************/
# Include <Hardware/hardware. h>
# Include <Hardware/Hello. h>
# Include <fcntl. h>
# Include <errno. h>
# Include <cutils/log. h>
# Include <cutils/Atomic. h>
# Define log_tag "hello_stub"
# Define device_name "/dev/hello"
# Define module_name "hello"
# Define module_author "pwzhgx@163.com"
Static int hello_device_open (const struct hw_module_t * module, const char * Name, struct hw_device_t ** device );
Static int hello_device_close (struct hw_device_t * Device );
Static int hello_set_val (struct hello_device_t * Dev, int Val );
Static int hello_get_val (struct hello_device_t * Dev, int * val );
Static struct hw_module_methods_t hello_module_methods = {
Open: hello_device_open
};
Struct hello_module_t hal_module_info_sym = {
Common :{
Tag: hardware_module_tag,
Version_major: 1,
Version_minor: 0,
ID: hello_hardware_module_id,
Name: module_name,
Author: module_author,
Methods: & hello_module_methods,
}
};
Static int hello_device_open (const struct hw_module_t * module, const char * Name, struct hw_device_t ** device ){
Struct hello_device_t * dev;
Dev = (struct hello_device_t *) malloc (sizeof (struct hello_device_t ));
If (! Dev ){
LogE ("Hello stub: failed to alloc space ");
Return-efault;
}
Memset (Dev, 0, sizeof (struct hello_device_t ));
Dev-> common. Tag = hardware_device_tag;
Dev-> common. Version = 0;
Dev-> common. module = (hw_module_t *) module;
Dev-> common. Close = hello_device_close;
Dev-> set_val = hello_set_val;
Dev-> get_val = hello_get_val;
If (Dev-> FD = open (device_name, o_rdwr) =-1 ){
LogE ("Hello stub: failed to open/dev/Hello -- % S.", strerror (errno); free (Dev );
Return-efault;
}
* Device = & (Dev-> common );
Logi ("Hello stub: Open/dev/Hello successfully .");
Return 0;
}
Static int hello_device_close (struct hw_device_t * Device ){
Struct hello_device_t * hello_device = (struct hello_device_t *) device;
If (hello_device ){
Close (hello_device-> FD );
Free (hello_device );
}
Return 0;
}
Static int hello_set_val (struct hello_device_t * Dev, int Val ){
Logi ("Hello stub: Set Value % d to device.", Val );
Write (Dev-> FD, & Val, sizeof (VAL ));
Return 0;
}
Static int hello_get_val (struct hello_device_t * Dev, int * val ){
If (! Val ){
LogE ("Hello stub: Error Val Pointer ");
Return-efault;
}
Read (Dev-> FD, Val, sizeof (* val ));
Logi ("Hello stub: Get value % d from device", * val );
Return 0;
}
/*************************************** ***************************************
* Android_hal_hello_demo
* Android. mk
**************************************** *************************************/
Local_path: = $ (call my-DIR)
Include $ (clear_vars)
Local_module_tags: = optional
Local_prelink_module: = false
Local_module_path: = $ (target_out_shared_libraries)/HW
Local_shared_libraries: = liblog
Local_src_files: = Hello. c
Local_module: = Hello. Default
Include $ (build_shared_library)
The code at this Hal layer has been basically completed, and the next step is to compile it into the module. So library file.
3) how to compile: this is a new module. For example, if you have made the android source code once, do not make clean; make again, you only need to compile the module, and then make Snod to compile the new module into the image. In the build directory of the source code, there is a configuration environment script envsetup. Sh, which contains the compilation tools M, mm, and mmm. You can view the specific functions directly. Compile and use Mmm here.
Run the following command in the android source code package:
[Root @ localhost Android-2.3.1] # sh build/envsetup. Sh
[Root @ localhost Android-2.3.1] # Croot
At this time, the mmm tool is already in the current environment. Of course, you can use Mmm to compile the module.
[Root @ localhost Android-2.3.1] # Mmm Hardware/libhardware/modules/Hello
However, some unexpected errors have occurred.
The liblog. So library file cannot be found. You can only compile and generate the liblog. So library file.
4) compile and generate liblog. So
[Root @ localhost Android-2.3.1] # Make liblog
5) recompile now
[Root @ localhost Android-2.3.1] # Mmm Hardware/libhardware/modules/Hello
Finally, the hello. Default. So library file is generated, and then repackage it.
6) repackage the image
[Root @ localhost Android-2.3.1] Make Snod
7) the next step is JNI encapsulation.
To be continued...