最主要的莫過於是了解了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)),mediatek\source\kernel\drivers\leds
二、設想驗證
這裡關鍵就是要清楚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!\n");
-
- //__android_log_print("");
-
- //printf("call ctlbl function succ!\n");
-
- fd = open("/sys/class/leds/lcd-backlight/brightness",O_RDWR);
-
- if(fd < 0)
-
- {
-
- //fprintf(stderr,"error: open %s\n",DEV_PATH);
-
- LOGI("error: open!\n");
-
- exit(1);
-
- }
-
- #if 0
-
- err = read(fd,ctl,1);
-
- if(err != 1)
-
- {
-
- //fprintf(stderr,"error: write %d!\n",err);
-
-
-
- exit(1);
-
- }else{
-
- //printf("the data is %s\n",ctl[0]);
-
- }
-
- #endif
-
- err=write(fd,ctl,2);
-
- //printf("%s\n",ctl);
-
- if(err != 2)
-
- {
-
- //fprintf(stderr,"error: write %d!\n",err);
-
- LOGI("error: write !\n");
-
- 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!!看看高手們的實現吧!!