.net core+ado.net如何架构项目_新增LED设备从上层到底层理解安卓架构之JNI篇

e4fcc6425cf2c4ef9081503b931aa92d.gif

点击上方「蓝字」关注我们

d4f150a40a163993fcb6731fbd4789cd.png b4719a4f575d1b69c2a0a2def41b5c08.png 往期推荐
  • 新增LED设备--从上层到底层理解安卓架构之HAL篇

  • 新增LED设备--从上层到底层理解安卓架构之内核篇

  • 安卓系统开发之源码架构简介

      在上一篇中,我们已经完成了HAL层的开发,那么framework层要如何调用它呢?答案是JNI(Java Native Interface)。JNI简单来说就是java程序可以调用C/C++写的动态链接库。JNI的存在使得底层可以以C代码的形式实现,保持了高效率,上层又以java代码的形式实现,具备了跨平台的通用性,JNI就是二者的纽带。在这里我们要先实现一个led操作的JNI,在JNI中调用HAL层提供上来的函数接口。然后再实现一个LedService的服务,在service中调用Jni的函数接口。 c7009a23bfd4c9e877671ac187e271e2.png c304641c6dc018293cbf5a0149293433.png

JNI的实现

1.frameworks/base/services/core/jni/com_android_server_TestLedService.cpp

#define LOG_TAG "TestLedServiceJni"#include "jni.h"#include "JNIHelp.h"#include "android_runtime/AndroidRuntime.h"#include#include#include#include#includenamespace android  {      struct testled_device_t* testled_device = NULL;      static void testled_setLed1(JNIEnv* env, jobject clazz, jint value) {            int val = value;            ALOGI("TestLed JNI: set value %d to led1.", val);            if(!testled_device) {                  ALOGI("TestLed JNI: device is not open.");                  return;            }            if(val > 0){                  testled_device->control(0);//on            }else{                  testled_device->control(1);//off            }      }static void testled_setLed2(JNIEnv* env, jobject clazz, jint value) {            int val = value;            ALOGI("TestLed JNI: set value %d to led2.", val);            if(!testled_device) {                  ALOGI("TestLed JNI: device is not open.");                  return;            }            if(val > 0){                  testled_device->control(2);//on            }else{                  testled_device->control(3);//off            }      }static inline int testled_device_open(const hw_module_t* module, struct testled_device_t** device) {            return module->methods->open(module, LED_HAL_MODULE_ID, (struct hw_device_t**)device);      }static jboolean testled_init(JNIEnv* env, jclass clazz) {            testled_module_t* module;            ALOGI("TestLed JNI: initializing......");            if(hw_get_module(LED_HAL_MODULE_ID, (const struct hw_module_t**)&module) == 0) {                  ALOGI("TestLed JNI: testled Stub found.");                  if(testled_device_open(&(module->common), &testled_device) == 0) {                        ALOGI("TestLed JNI: testled device is open.");                        //testled_device->open();                        return 0;                  }                  ALOGE("TestLed JNI: failed to open testled device.");                  return -1;            }            ALOGE("TestLed JNI: failed to get testled stub module.");            return -1;      }      static const JNINativeMethod method_table[] = {            {"testledinit_native", "()Z", (void*)testled_init},            {"setled1_native", "(I)V", (void*)testled_setLed1},            {"setled2_native", "(I)V", (void*)testled_setLed2},      };      int register_android_server_TestLedService(JNIEnv *env) {            return jniRegisterNativeMethods(env, "com/android/server/TestLedService", method_table, NELEM(method_table));      }};
com_android_server_TestLedService.cpp文件实现了JNI方法testled_setLed1,testled_setLed2,还有JNI初始化的入口函数testled_init。 在testled_init内通过LED_HAL_MODULE_ID匹配到了Hal内的硬件模块,再通过testled_device_open得到了device结构体。在testled_setLed1和 testled_setLed2调用了device结构体在Hal层实现的led操作函数接口。 注意com_android_server_TestLedService文件的命令方法,com_android_server表示的是包名,表示硬件服务TestLedService在frameworks/base/services/java目录下的com/android/server目录下,此目录下的TestLedService的类是可以直接调用jni的内容的。

2.frameworks/base/services/core/jni/onload.cpp

  namespace中增加函数声明

namespace android {      ……int register_android_server_TestLedService(JNIEnv *env);};JNI_OnLoad增加register_android_server_TestLedService的函数调用extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */){      …    register_com_android_server_rkdisplay_RkDisplayModes(env);    register_android_server_TestLedService(env);return JNI_VERSION_1_4; }
这一步是Framework加载jni库,也就是在/system/lib/hw/test_led_hal.default.so被导入了。 3.frameworks/base/services/core/jni/Android.mk 在LOCAL_SRC_FILES变量中增加一行
LOCAL_SRC_FILES += \       ……    $(LOCAL_REL_DIR)/com_android_server_TestLedService.cpp \$(LOCAL_REL_DIR)/onload.cpp
4.局部编译 mmm frameworks/base/services/jni make snod 重新打包的system.img镜像文件就包含了LedTest的JNI方法了,后面我们可以通过Android系统的Framework层提供的硬件服务LedTestService来调用这些JNI方法,进而调用更低层的硬件抽象层接口去访问硬件了。Framework层的LedTestService服务在下一篇实现。 7a80b0112c2f98ab2fac840c99a4c2b2.png 05a95dcbce4776e70a8364b588faad13.png 近期,小编突然发现这里的小伙伴越来越多了,感谢大家的关注!


HAPPY

我们会继续努力把更好的嵌入式技术分享给大家。不论是在校大学生还是已经走上专业领域的技术大咖们,我们一起分享收获、共享知识、深度学习,不断攀登人工智能技术领域的高峰.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值