最主要的莫过于是了解了Android中jni编程,游荡整个Android源码,可以看到很多直接操作底层驱动接口,封装成so库,供Java调用的例子哦。这次学习,也正是出于这样的想法,没想到这个设想高手们早就实现了哦,菜鸟现在也只能算是验证了。诶,菜鸟就是菜鸟,有虫子吃,就兴奋的不得了。驱动架构略,这里只讨论jni接口的实现。
一、我的设想 其实设想很简单,找到背光驱动提供给上层的API接口,人家Android还不是一样需要一层一层的抽象(HAL、Framework),高手们考虑的东东很多,所以才一层层抽象封装,既然这样,咱菜鸟不就一根筋,有虫吃就是王道啊,我为什么不能直接将这个驱动接口封装成jni提供给Java呢?其实这想法很早就有了,只是到现在才验证,确实可以啊。其实Android中还是有N多这样的例子的。 背光驱动提供的接口是:/sys/class/leds/lcd-backlight/brightness。至于这个接口是怎么来的??那就要去看驱动结构了。驱动注册此接口的源码位于:Kernel/driver/leds/led-class.c中。这个文件只是实现了提供上层的接口,至于真正操作硬件的驱动程序,可以给出其源码路径为:(硬件操作其实就是脉宽调制(PWM)),mediateksourcekerneldriversleds
二、设想验证 这里关键就是要清楚jni的接口实现规则咯,不过环境搭建也比较麻烦(ndk编译环境)。环境搭建另外给出日志。Jni接口的源码如下:
- #include <unistd.h>
-
- #include <stdio.h>
-
- #include <stdlib.h>
-
- #include <fcntl.h>
-
- #include <sys/types.h>
-
- #include <sys/stat.h>
-
- //#include <dirent.h>
-
- //#include <jni.h>
-
- #include <string.h>
-
- #include <android/log.h>
-
-
-
- #include "com_yecon_CtlBL_CtlBLActivity.h"
-
-
-
- #define LOG_TAG "ctlbl.c"
-
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-
- //#define DEV_PATH "/sys/class/leds/lcd-backlight/brightness"
-
- //#define DEV_PATH "/sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness"
-
-
-
- /**
-
- * native method
-
- */
-
- //JNIEXPORT jobjectArray JNICALL Java_com_yecon_CtlBL_CtlBLActivity_ctlbl(JNIEnv * env, jobject obj)
-
- JNIEXPORT jint JNICALL Java_com_yecon_CtlBL_CtlBLActivity_ctlbl(JNIEnv * env, jobject obj)
-
- {
-
-
-
-
-
- int fd;
-
- int err;
-
- char *p;
-
- char ctl[10]={"20"};
-
- LOGI("HELLO!
");
-
- //__android_log_print("");
-
- //printf("call ctlbl function succ!
");
-
- fd = open("/sys/class/leds/lcd-backlight/brightness",O_RDWR);
-
- if(fd < 0)
-
- {
-
- //fprintf(stderr,"error: open %s
",DEV_PATH);
-
- LOGI("error: open!
");
-
- exit(1);
-
- }
-
- #if 0
-
- err = read(fd,ctl,1);
-
- if(err != 1)
-
- {
-
- //fprintf(stderr,"error: write %d!
",err);
-
-
-
- exit(1);
-
- }else{
-
- //printf("the data is %s
",ctl[0]);
-
- }
-
- #endif
-
- err=write(fd,ctl,2);
-
- //printf("%s
",ctl);
-
- if(err != 2)
-
- {
-
- //fprintf(stderr,"error: write %d!
",err);
-
- LOGI("error: write !
");
-
- exit(1);
-
- }
-
-
-
- close(fd);
-
-
-
- return 0;
-
-
-
- //return (*env)->NewStringUTF(env, "Hello ww JNI !");
-
-
-
- }
上层Java调用的源码如下:(只是实现了一个Button,点击,有一个消息响应,将背光调到20)
- package com.yecon.CtlBL;
-
-
-
- import android.app.Activity;
-
- import android.os.Bundle;
-
- import android.view.View;
-
- import android.view.View.OnClickListener;
-
- import android.widget.Button;
-
- import android.widget.TextView;
-
-
-
- //import com.yecon.CtlBL.ctlbljni;
-
-
-
- public class CtlBLActivity extends Activity {
-
- Button b = null;
-
-
-
- // ctl = new ctlbljni();
-
- private OnClickListener clickListener = new OnClickListener(){
-
-
-
- @Override
-
- public void onClick(View v) {
-
- // TODO Auto-generated method stub
-
- // ctl.ctlbl();
-
- ctlbl();
-
- }
-
- };
-
-
-
- /** Called when the activity is first created. */
-
- @Override
-
- public void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.main);
-
- b = (Button) this.findViewById(R.id.BtnCancel);
-
- b.setOnClickListener(clickListener);
-
- // TextView tv = new TextView(this);
-
- // tv.setText( ctlbl() );
-
- // setContentView(tv);
-
- }
-
-
-
- public native int ctlbl();//本地方法
-
-
-
- static {
-
- System.loadLibrary("ctlbl");//载入so库
-
- }
-
- }
看上去,没几行代码,so easy!!看看高手们的实现吧!!