微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 手机设计讨论 > MTK手机平台交流 > Android从驱动层到应用程序层的通信

Android从驱动层到应用程序层的通信

时间:10-02 整理:3721RD 点击:

研究一下android从驱动层到应用层的通信机制是很有必要的,如新增加一个硬件并在应用层去控制硬件都需要用到,目的是知道需要增加哪些东西删改哪些东西而让系统依然工作正常。

总共需要增改的有四个东西,驱动、服务(jni、java)、应用apk

采用的方式是在驱动层写个字符型设备驱动其中内含一个定时器,每隔2秒发送一个uevent事件并改变sys下相关文件的内容,然后建立一个服务去读取文件并通过intent向上层广播,最后在应用程序层接收此事件并在TextView中显示出来


一、驱动层

kernel/drivers/char/uevent_test/test.c

Kconfig

Makefile

驱动层与服务层之间用到的通信机制是sys文件系统的uevent机制,涉及的函数有以下几个


在sys文件系统下建立一个类

class_create(THIS_MODULE, "uevent_timer");

在类里建立一个设备

device_create(uevent_timer_class, NULL, UEVENT_TIMER_MAJOR, NULL, "uevent_timer_status");

在设备目录下建立一个文件

device_create(uevent_timer_class, NULL, UEVENT_TIMER_MAJOR, NULL, "uevent_timer_status");

在本项目中建立的目录文件是/sys/class/uevent_timer/uevent_timer_status/status


注意思在使用kobject_uevent函数发送uevent事件时需要建立一个工作队列来发送,否则会在发送过程中内核死掉。

INIT_WORK(&uevent_timer_dev->changed_work, timer_change_work);

通过schedule_work(&uevent_timer_dev->changed_work);来调用timer_change_work函数,在此函数中利用

kobject_uevent(&uevent_timer_dev->clsdev->kobj, KOBJ_CHANGE);

来发送uevent事件.

当上层读取file时会调用uevent_timer_show_attrs函数来更新及显示文件内容

当上层写入file时会调用 uevent_timer_store_attrs函数来更新及写入文件内容


二、服务层

新建以下两个文件

php?mod=tag&id=6090" target="_blank" class="relatedlink">Frameworks/base/services/jni/com_android_server_UeventTimerService.cpp frameworks/base/services/jni/onload.cpp

frameworks/base/services/java/com/android/server/UeventTimerService.java

frameworks/base/services/java/com/android/server/SystEMServer.java

         (1)JNI层

                  JNI是java调用本地的接口,JNI主要工作是打开驱动所创建的file并将其值读出来,

         在static int readFROMFile(const char* path, char* buf, size_t size)函数中读取值



使用

static JNINativeMethod sMethods[] = {

            /* name, signature, funcPtr */

             {"native_update", "()V", (void*)android_server_UeventTimerService_update},   

};注册一个函数native_update以供服务的java层调用

修改onload.cpp,在其中加入

int register_android_server_UeventTimerService(JNIEnv* env);在JNI_OnLoad中加入

register_android_server_UeventTimerService(JNIEnv* env);在加载时启动此服务


(2)java层

建立一个类

Class UeventTimerService extends Binder{

         Private int mUeventTimerStatus;

         Public UeventTimerService(){/

mUEventObserver.startObserving("SUBSYSTEM=uevent_timer");

};//此函数中调用开始服务

private UEventObserver mUEventObserver = new UEventObserver() {

          @Override

          public void onUEvent(UEventObserver.UEvent event) {

             update();

              sendIntent();

          }

};建立一个服务并重写onUEvent函数

private native void native_update();

private synchronized final void update() {

         native_update();//调用jni中注册的native_update()函数

}

private final void sendIntent() {

         Intent intent = new Intent("uevent_timer_status");//启动广播

         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);//建立一个发送

         intent.putExtra("status", mUeventTimerStatus);//发送变量

         ActivityManagerNative.broADCastStickyIntent(intent, null);//向上层广播

}

在SystemServer.java中加入

UeventTimerService ueventtimer = null;

在try catch块中加入

ueventtimer = new UeventTimerService();

ServiceManager.addService("ueventtimer", ueventtimer);

三、应用层apk

         onResume(){

                   super.onResume();

                   IntentFiLTEr filter = new IntentFilter();


        filter.adDACtion("uevent_timer_status");

        registerReceiver(mBroadcastReceiver, filter);

}

onPause(){

         super.onPause();

         unregisterReceiver(mBroadcastReceiver);

}

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){

        @Override

        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            if (action.equals("uevent_timer_status")) {

                int status = intent.getIntExtra("status", 0);

                String statusString = "";

                switch (status) {

                    case 0:

                        statusString = "counting";

                        break;

                    case 1:

                        statusString = "stop";

                        break;

                    default:

                        statusString = "unknown";

                }

                Log.i("=====My_application========",statusString);

                tv.setText(statusString);//改变textView的显示值

            }

        }

    };

在AndroiDMAnifest.xml中加入

<action android:name="uevent_timer_status" />

打开监听

多好的东西啊!自己很想总结,都还没来得及开始弄!

没怎么看懂啊 。

好东西,感谢分享。

牛人就是不一样

驱动和本地函数(.cpp)通过sysfs沟通,本地函数和java通过jni沟通.

非常好的东西

虽说只有短短一页,但是要想完全理解透彻估计要半年之后了

这个例子感觉有点复杂呀.其实很简单,驱动+jni+apk就行了.比如一个LED,驱动负责底层控制IOCTRL,并且产生设备节点,JNI负责打开操作这个设备,APK直接调用JNI控制就OK了.

呵呵,纯技术坛子感觉比杂乱的52RD好

不错,知道学习!

悲剧,上层JAVA这块不怎么懂,还得加快学习中,向群主和各位大佬们学习

不错,说白了就这样。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top