• TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(总结篇)


        本文是对前面驱动--HAL--JNI--APK的一个总结。

       

          上图即是整个流程的一个框架,上层APK通过JNI调用HAL层提供的接口,从而驱使硬件进行相应的操作。

          对于上图更为详细的解析:

         在APK层通过   

    static{
        	System.loadLibrary("ledunders");  
        }

    加载位于/system/lib/ 下的libledunders.so的动态共享库文件,在加载libledunders.so共享库时,首先运行JNI_OnLoad函数,主要做两件事 :

     1.((*vm)->GetEnv判断当前JVM是否支持JNI_VERSION_1_4这个版本

     2.register_native_led_method(env)注册本地函数

    jint JNI_OnLoad(JavaVM * vm, void * reserved)  //加载库时,第一个调用的函数
    {
    	JNIEnv *env=NULL;  //JNI函数的接口指针 pointer to the location where the JNI interface pointer for the current thread will be placed.
    	jint result=-1;
    	if((*vm)->GetEnv(vm,(void **)&env,JNI_VERSION_1_4)!=JNI_OK)  //判断JNI_VERSION_1_4这个版本是否支持
    		{
    			__android_log_print(ANDROID_LOG_DEBUG,"msg","JNI_VERSION_1_4 not supported.
    ");
    			return result;
    		}
    	if(register_native_led_method(env)!=0) //注册本地方法
    		{
    			__android_log_print(ANDROID_LOG_DEBUG,"msg","register native failed.
    ");
    			return result;
    		}
    	return JNI_VERSION_1_4;
    }



    接下来通过APK层的led_init()本地函数调用JNI层的led_init函数

    if(!led_init())  //led初始化 加载库 初始化led 打开led
            {
            	new AlertDialog.Builder(LedUnderActivity.this).setTitle("error").setMessage("init led fail
    ").setPositiveButton("确定", null).show();
            }


    在JNI层的led_init函数中,通过hardware/libhardware/hardware.c的hw_get_module的方法使用ID找到在/system/lib/hw/下的led_unders.tq210.so文件,通过hardware/libhardware/hardware.c里面的load方法然后找到HMI符号,返回模块给module

    int err=hw_get_module(LED_UNDERS_HARDWARE_MODULE_ID, (const  hw_module_t **) &module);

    接着在JNI层使用led_control_open方法调用module->methods->open方法即HAL层中led_init函数初始化led_control_device_t结构体,打开/dev/led_unders设备文件,并返回给JNI层中的ledunderdevice

    if(led_control_open(&(module->common),&ledundersdevice)==0) return true;
    static inline int led_control_open(struct hw_module_t *module,struct led_control_device_t **device)
    {
    //通过module的open方法找到device,并赋值给ledunderdevice
    	int err=module->methods->open(module,LED_UNDERS_HARDWARE_MODULE_ID,(struct hw_device_t **)device);
    	__android_log_print(ANDROID_LOG_DEBUG,"msg","led_control_open ,err=%d",err);
    	return err;
    }


     

    此时上层APK即可通过led_setOn/led_setOff来调用JNI层的led_setOn/led_setOff,然后调用HAL层的led_on/led_off,最终调用驱动层的gpio_led_under_ioctl来控制led灯

  • 相关阅读:
    C#调用java类、jar包方法
    利用IKVM在C#中调Java程序
    同样版本的jstl,都是jstl1.2版本,有个有问题,另一个没有问题
    Python安装及开发环境配置
    jQuery EasyUI parser 的使用场景
    关于HttpURLConnection.setFollowRedirects
    HttpUrlConnection 的 setDoOutput 与 setDoInput
    【Mybatis】向MySql数据库插入千万记录 单条插入方式,用时 1h16m30s
    [MyBatis]再次向MySql一张表插入一千万条数据 批量插入 用时5m24s
    [MyBatis]向MySql数据库插入一千万条数据 批量插入用时6分 之前时隐时现的异常不见了
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275629.html
Copyright © 2020-2023  润新知