Android mcu专用串口控制Frameworks部分逻辑简述

Android系统进程间通讯之Binder机制(二) Android系统进程间通讯之Binder机制(二) ----实践篇 首先我们来看一张图,binder机制的层次模型: 如果想要实现Binder机制实现进程间的通讯,从理论篇中总结下来需要有一下几步: (1)第一步,需要为这个接口定义一个继承自I 阅读详情

目录

一 代码分析

第一步

  • 1 定义 class IMcuService : public IInterface 接口

    • 0 DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口
    • 1 为 McuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
    • 2 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。
    • 3 最后定义了其他接口操作函数
  • 2 定义 Binder 本地对象类 class BnMcuService: public BnInterface

  • 3 实现 class BnMcuServic :: onTransact() 方法

  • 4 使用宏 IMPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口

    • 0 使用宏 MPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
    • 1 将 McuService 类的静态成员变量 descriptor 设置为 " android.hardware.IMcuService "
    • 2 实现了 IMcuService 类的构造函数和析构函数,是空函数
    • 3 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IMcuService类的描述符,即 descriptor
    • 4 实现了 asInterface(),用来将一个 IBinder 对象装换为一个 IMcuService 接口。
  • 5 定义BInder 代理对象类 BpMcuService BpMcuService,他继承了模块类 BpInterface
    class BpMcuService: public BpInterface
    实现如下功能:

    • 1 向服务进程发出 ATTACH 请求
    • 2 向服务进程发出 GET_VERSION 请求
    • 3 向服务进程发出 GET_TIME 请求
    • 4 向服务进程发出 SET_POWER_STATE 请求
    • 5 向服务进程发出 START_UPDATE 请求
    • 6 向服务进程发出 STOP_UPDATE 请求

第二步

  • 1 构建 class McuService : public BinderService, public BnMcuService
    • 定义class McuService 服务,继承于本地对象 public BnMcuService,此服务用于操作 mcu专用串口底层
  • 2 实现 McuService::onFirstRef()方法,用于打开 mcu专用串口。当该服务被引用的时候,自动调用该方法。
  • 3 实现 McuService::instantiate()方法,将该服务注册进 Service Manager中,并将服务命名为 “media.mcu”
  • 4 实现 McuService::ModuleClient::ModuleClient()构造函数,用于获取申请该服务的客户进程。
  • 5 实现 McuService::attach() 方法,所有申请该服务的进程对于该服务本身来说,它们都是客户进程,所以 McuService::attach() 方法 用于将申请该服务的进程绑定到自身内部的客户进程类,用于绑定和记录与自己通信的客户进程信息。
  • 6 操纵 mcu专用串口 的方法

第三步

  • 0 调用 McuService::instantiate();//注册 McuService 服务
  • 1 创建一个线程池,接着调用 进程中的 ProcessState对象的成员函数 startThreadPool来启动一个Binder线程池。
  • 2 加入线程池,调用主线程的 IPCThreadstate对象的成员函数 joinThreadPool将主线程添加到进程的Binder线程中,用来处理来自Client的进程的通信请求

第四步

  • 0 定义 class Mcu : public BnMcuClient, public IBinder::DeathRecipient
    • 1 该类用于获取 服务 “media.mcu”
  • 1 实现 Mcu::getMcuService() 获取 上述注册到 Service Manage的服务 “media.mcu”
  • 2 实现 Mcu::Mcu() 初始化 mHandle、mCallback
  • 3 实现 Mcu::attach() 获取该服务接口

第五步 实现JNI,打通Android上层服务接口通道

  • 0 JNI实现本地方法 android_server_Mcu_setup() 对应 native_setup()
    • 0 该方法内部调用 Mcu::attach() 获取 服务 “media.mcu”
  • 1 实现JNI 本地方法
    • 1 JNI实现本地方法 对应 native_finalize()
    • 2 JNI实现本地方法 对应 native_get_mcu_Version()
    • 3 JNI实现本地方法 对应 native_get_mcu_Time()
    • 4 JNI实现本地方法 对应 native_setPowerState()
    • 5 JNI实现本地方法 对应 native_startUpdate()
    • 6 JNI实现本地方法 对应 native_stopUpdate()
  • 2 注册JNI

第六步 实现Android上层硬件访服务

第七步 启动服务Android上层硬件访服务

二 服务打开过程梳理

  • 1 打开 mcu串口服务McuManagerService.java
  • 2 开mcu串口服务JNI
  • 3 调用 Mcu::attach()
  • 4 调用 McuService::attach()

三 总结

四 头文件笔记


一 代码分析

第一步 :

1 定义 class IMcuService : public IInterface 接口
	0. DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口 
	1. 为 McuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。 
	2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。 
	3. 最后定义了其他接口操作函数
	
2 定义 Binder 本地对象类  class BnMcuService: public BnInterface<IMcuService>
3 实现 class BnMcuServic :: onTransact() 方法	
4 使用宏 IMPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
	0. 使用宏 MPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
	1. 将 McuService 类的静态成员变量 descriptor 设置为  " android.hardware.IMcuService " 
	2. 实现了 IMcuService 类的构造函数和析构函数,是空函数
	3. 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IMcuService类的描述符,即 descriptor 
	4. 实现了  asInterface(),用来将一个 IBinder 对象装换为一个 IMcuService 接口。 
5 定义BInder 代理对象类 BpMcuService BpMcuService,他继承了模块类 BpInterface
	class BpMcuService: public BpInterface<IMcuService>
		实现如下功能:
		向服务进程发出 ATTACH 请求
		向服务进程发出 GET_VERSION 请求
		向服务进程发出 GET_TIME 请求
		向服务进程发出 SET_POWER_STATE 请求
		向服务进程发出 START_UPDATE 请求
		向服务进程发出 STOP_UPDATE 请求

framework/av/include/mcu/IMcuService.h

class IMcu;
class IMcuClient;

/* 定义硬件服务接口 IMcuService */
class IMcuService : public IInterface
{
public:
    mcu_metadata_t *test;

	 /* DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口 
	1. 为 McuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。 
	2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。 
	3. 最后定义了其他接口操作函数
 	*/
    DECLARE_META_INTERFACE(McuService);

    virtual status_t attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu) = 0;
    virtual String8 getVersion(int type) = 0;
    virtual String8 getTime(int type) = 0;
    virtual int setPowerState(int state)= 0;
    virtual int startUpdate(int state)= 0;
    virtual int stopUpdate(int state)= 0;
};

/*
* 定义了一个 Binder 本地对象类 BnMcuService,它实现了模板类 BnInterface的成员函数 onTransact。
*/
class BnMcuService: public BnInterface<IMcuService>
{
public:
	/*
	* 成员函数 onTransact 是虚函数,它是由 BBinder 的子类,即 Binder本地对象类来实现的,他负责分发与业务相关的进程间通
	* 信请求。事实上,与业务相关的进程间通信请求是由Binder本地对象类的子类,即Service组件来负责处理的。
	*/
    virtual status_t    onTransact( uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags = 0);
};

framework/av/mcu/IMcuService.cpp

/*
 实现本地对象 onTransact()方法:对应代理对象的各个请求
*/
status_t BnMcuService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
       case ATTACH: {
            CHECK_INTERFACE(IMcuService, data, reply);
            mcu_handle_t handle = data.readInt32();
            sp<IMcuClient> client = interface_cast<IMcuClient>(data.readStrongBinder());
            ALOGV("ATTACH handle %d ", handle);
            sp<IMcu> mcu;
            status_t status = attach(handle, client,mcu);
            reply->writeInt32(status);
            if (mcu != 0) {
                reply->writeInt32(1);
                reply->writeStrongBinder(IInterface::asBinder(mcu));
                //reply->writeStrongBinder(mcu->asBinder());
            } else {
                reply->writeInt32(0);
            }
            return NO_ERROR;
        } break;
        case GET_VERSION:{
            CHECK_INTERFACE(IMcuService, data, reply);
            int type = data.readInt32();
            String8 version = getVersion(type);
            reply->writeString8(version);
            return NO_ERROR;
        }break;
        case GET_TIME:{
            CHECK_INTERFACE(IMcuService, data, reply);
            int type = data.readInt32();
            String8 time = getTime(type);
            reply->writeString8(time);
            return NO_ERROR;
        }break;
        case SET_POWER_STATE:{
            CHECK_INTERFACE(IMcuService,data,reply);
            int type = data.readInt32();
            int state = setPowerState(type);
            reply->writeInt32(state);
            return NO_ERROR;
            }
        break;
        case START_UPDATE:{
            CHECK_INTERFACE(IMcuService,data,reply);
            int type = data.readInt32();
            int state = startUpdate(type);
            reply->writeInt32(state);
            return NO_ERROR;
            }
        break;
        case STOP_UPDATE:{
            CHECK_INTERFACE(IMcuService,data,reply);
            int type = data.readInt32();
            int state = stopUpdate(type);
            reply->writeInt32(state);
            return NO_ERROR;
            }
        break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}


/*
0. 使用宏 IMPLEMENT_META_INTERFACE 来实现 IMcuService 类的元接口
1. 将 IMcuService 类的静态成员变量 descriptor 设置为  " android.hardware.IMcuService " 
2. 实现了 IMcuService 类的构造函数和析构函数,是空函数
3. 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IMcuService类的描述符,即 descriptor 
4. 实现了  asInterface(),用来将一个 IBinder 对象装换为一个 IMcuService 接口。 
*/
IMPLEMENT_META_INTERFACE(McuService, "android.hardware.IMcuService");





/*
定义BInder 代理对象类 BpMcuService BpMcuService,他继承了模块类 BpInterface

实现如下功能:
向服务进程发出 ATTACH 请求
向服务进程发出 GET_VERSION 请求
向服务进程发出 GET_TIME 请求
向服务进程发出 SET_POWER_STATE 请求
向服务进程发出 START_UPDATE 请求
向服务进程发出 STOP_UPDATE 请求
*/
class BpMcuService: public BpInterface<IMcuService>
{
public:
    BpMcuService(const sp<IBinder>& impl): BpInterface<IMcuService>(impl)
    {
    }

	/* 
	获取目标服务的接口,并向该服务发出 ATTACH 请求
	*/
    virtual status_t attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
        data.writeInt32(handle);
        data.writeStrongBinder(IInterface::asBinder(client));
        ALOGV("attach() handle %d", handle);
        status_t status = remote()->transact(ATTACH, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        status = reply.readInt32();
        if (reply.readInt32() != 0) {
            mcu = interface_cast<IMcu>(reply.readStrongBinder());
        }
        return status;
    }

	/*
	获取目标服务的接口,并向该服务发出 GET_VERSION 请求
	*/
    virtual String8 getVersion(int type)
    {
        Parcel data,reply;
        data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
        data.writeInt32(type);
        remote()->transact(GET_VERSION,data,&reply);
        return reply.readString8();
    }

	/*
	获取目标服务的接口,并向该服务发出 GET_TIME 请求
	*/
    virtual String8 getTime(int type)
    {
        Parcel data,reply;
        data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
        data.writeInt32(type);
        remote()->transact(GET_TIME,data,&reply);
        return reply.readString8();
    }

	/*
	获取目标服务的接口,并向该服务发出 SET_POWER_STATE 请求
	*/
    virtual int setPowerState(int state)
    {
        Parcel data,reply;
        data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
        data.writeInt32(state);
        remote()->transact(SET_POWER_STATE,data,&reply);
        return reply.readInt32();
    }


	/*
	获取目标服务的接口,并向该服务发出 START_UPDATE 请求
	*/
    virtual int startUpdate(int state)
    {
        Parcel data,reply;
        data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
        data.writeInt32(state);
        remote()->transact(START_UPDATE,data,&reply);
        return reply.readInt32();
    }


	/*
	获取目标服务的接口,并向该服务发出 STOP_UPDATE 请求
	*/
    virtual int stopUpdate(int state)
    {
        Parcel data,reply;
        data.writeInterfaceToken(IMcuService::getInterfaceDescriptor());
        data.writeInt32(state);
        remote()->transact(STOP_UPDATE,data,&reply);
        return reply.readInt32();
    }

};

第二步

0 定义 class McuService : public BinderService<McuService>, public BnMcuService
	定义class McuService 服务,继承于本地对象 public BnMcuService,此服务用于操作 mcu专用串口底层
1 实现 McuService::onFirstRef()方法,用于打开 mcu专用串口。当该服务被引用的时候,自动调用该方法。
2 实现 McuService::instantiate()方法,将该服务注册进 Service Manager中,并将服务命名为 "media.mcu"
3 实现 McuService::ModuleClient::ModuleClient()构造函数,用于获取申请该服务的客户进程。
4 实现 McuService::attach() 方法,所有申请该服务的进程对于该服务本身来说,它们都是客户进程,所以 McuService::attach() 方法 用于将申请该服务的进程绑定到自身内部的客户进程类,用于绑定和记录与自己通信的客户进程信息。
5 操纵 mcu专用串口 的方法
		virtual String8 getVersion(int type);
	    virtual String8 getTime(int type);
	    virtual int setPowerState(int state );
	    virtual int startUpdate(int status);
	    virtual int stopUpdate(int status);
6 其他	

frameworks/av/services/mcuservice/McuService.h

// 继承 BnMcuService ,实现BnMcuService没有实现的方法
class McuService : public BinderService<McuService>, public BnMcuService
{
    friend class BinderService<McuService>;

public:
    class ModuleClient;
    static char const* getServiceName() { return "media.mcu"; }
    static void instantiate(); //注册McuService服务到 Service Manage 中,并将服务名称命名为"media.mcu"。

    McuService();
    virtual             ~McuService();

    // IMcuService
    virtual status_t attach(mcu_handle_t handle, const sp<IMcuClient>& client,sp<IMcu>& mcu);
    virtual String8 getVersion(int type);
    virtual String8 getTime(int type);
    virtual int setPowerState(int state );
    virtual int startUpdate(int status);
    virtual int stopUpdate(int status);
    virtual status_t    dump(int fd, const Vector<String16>& args);
    void onCallbackEvent(const sp<IMemory>& event);
    void removeClient(sp<ModuleClient> client);
    int isFileExist(const char *pathFile);
    void heartBeat();

    ......

	/* 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息 */
    class ModuleClient : public BnMcu, public IBinder::DeathRecipient {
    public:
       ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle);
       virtual ~ModuleClient();
       // IMcu
       virtual void detach();
       virtual status_t dump(int fd, const Vector<String16>& args);
       sp<IMcuClient> client() const { return mClient; }//返回 mClient
       void onCallbackEvent(const sp<IMemory>& event);
       virtual void onFirstRef();//该类第一次被引用是调用  
       // IBinder::DeathRecipient implementation
       virtual void        binderDied(const wp<IBinder> &who);

    private:

	mutable Mutex               mLock;  // protects mClient, mConfig and mTuner
	 sp<McuService>          mMcuService;

	/*
	IMcuClient 类 : 硬件服务接口 class IMcuClient : public IInterface
	event callback binder interface
	 */
	sp<IMcuClient>            mClient;
	   mcu_handle_t mHandle; 
    }; 


    sp<CallbackThread> getCallbackThread() const { return mCallbackThread; }
    int handleFrameData(FrameData *frame);
    static void callback(mcu_event_t *halEvent, void *cookie);

private:
    virtual void onFirstRef();
    int sendCallbackEvent(FrameData *frame);
    int mcuEventMonitor(int fd,const Vector<String16> &args);
    void sendCMD(int cmd);
    void sendCMD(int cmd,int length,unsigned char *data);
    FrameData sendCMDWait(int cmd,int length,unsigned char *data,int second);
    FrameData sendCMDWait(int cmd);
    int setBackLightValue(int value);
    int openBackLight(void);
    int closeBackLight(void);
    int setNextFuncState(int state,int cmd);
    Mutex               mServiceLock;   // protects mModules
    Vector< sp<ModuleClient> >    mModuleClients;//动态数组,声明一个动态数组  ModuleClient mModuleClients[]
    sp<CallbackThread>          mCallbackThread; // event callback thread
    sp<ReadThread>          mReadThread; // read data thread
    sp<HeartbeatThread> mHearbeatThread;
    sp<UpdateThread>mUpdateThread;
    sp<CommunicationInterface>  mCommInterface;
    pthread_mutex_t                 mDataMutex;
    pthread_cond_t                  mDataCond;
    int mFuncState;
    FrameData mFrameData;
};

frameworks/av/services/mcuservice/McuService.cpp

McuService::McuService() : mFuncState(FUNC_CMD_NONE)
{
    ALOGI("%s", __FUNCTION__);
}

void McuService::onFirstRef()
{
    ALOGD("McuService::onFirstRef");
...
    memset(&mFrameData,0x0,sizeof(FrameData));

    mCommInterface = new UartComm2("/dev/ttyS3");//构造函数 传递取目标字符串:"/dev/ttyS3" 
    mCommInterface->openInterface();//打开目标串口"/dev/ttyS3" ,并且设置波特率

...
}
void McuService::instantiate()
{
    ALOGV("McuService::instantiate");
	/*
	首先通过defaultServiceManager()获取一个 ServiceManager类对象,利用该类的addService()方法,将 McuService服务 注册到 Service Manager中,并且命名为 "media.mcu"
	这样Client进程就可以通过名称  "media.mcu"  来获取这个McuService服务的一个代理对象了
	*/
    defaultServiceManager()->addService(String16("media.mcu"), new McuService());
}

/*工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
1 初始化 class McuService :: class ModuleClient  ::mcu_handle_t mHandle = handle
2 初始化 class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient = class IMcuClient client
3 初始化 mcu = class McuService :: class ModuleClient  moduleClient
4 初始化 class McuService :: class ModuleClient::sp<McuService>   mMcuService = this 
5 向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象
6 初始化传递进来的 IMcu类 mcu对象 为 class McuService :: class ModuleClient  moduleClient
*/
status_t McuService::attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu)
{
    ALOGV("%s handle: %d", __FUNCTION__,handle);
    size_t i;
    sp<ModuleClient> moduleClient;//ModuleClient类对象

...

	//ModuleClient类构造函数 : McuService::ModuleClient::ModuleClient() ,创建 对象 moduleClient
	/*
	初始化 McuService类 mMcuService对象为 mcuService
		class McuService :: class ModuleClient::sp<McuService>   mMcuService;

	初始化 IMcuClient类接口 mClient 对象为 client
		class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient; 

	初始化  mcu_handle_t mHandle = handle
		class McuService :: class ModuleClient  ::mcu_handle_t mHandle;
	*/

moduleClient = new ModuleClient(this, client,handle);
if(moduleClient != 0)
{
//向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象?
    mModuleClients.add(moduleClient);

//初始化传递进来的 IMcu类 mcu对象 为 moduleClient
    mcu = moduleClient;
}
else
{
    return NO_INIT;
}
return NO_ERROR;
}


	/*	//ModuleClient类构造函数 :
	初始化 McuService类 mMcuService对象为 mcuService
		class McuService :: class ModuleClient::sp<McuService>   mMcuService;
	
	初始化 IMcuClient类接口 mClient 对象为 client
		class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient; 
	
	初始化  mcu_handle_t mHandle = handle
		class McuService :: class ModuleClient  ::mcu_handle_t mHandle;
	*/
McuService::ModuleClient::ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle)
	 : mMcuService(mcuService), mClient(client), mHandle(handle)
{
}

第三步

0  调用 McuService::instantiate();//注册 McuService 服务
1  创建一个线程池,接着调用 进程中的 ProcessState对象的成员函数 startThreadPool来启动一个Binder线程池。
2  加入线程池,调用主线程的 IPCThreadstate对象的成员函数 joinThreadPool将主线程添加到进程的Binder线程中,用来处理来自Client的进程的通信请求

frameworks/av/services/mcuservice/main_mcuservice.cpp

int main(int argc, char** argv){
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    
	/*
	首先通过 defaultServiceManager()获取一个 ServiceManager类对象,利用该类的addService()方法,将 McuService 服务 注册到 Service Manager中,并且命名为 "media.mcu"
	这样Client进程就可以通过名称  "media.mcu"  来获取这个McuService服务的一个代理对象了
	*/
	McuService::instantiate();
	
	/* 创建一个线程池
	* 接着调用 进程中的 ProcessState对象的成员函数 startThreadPool来启动一个Binder线程池。
	*/
    ProcessState::self()->startThreadPool();
	
	/* 加入线程池
	调用主线程的 IPCThreadstate对象的成员函数 joinThreadPool将主线程添加到进程的Binder线程中,用来处理来自Client的进程的通信请求。
	*/
    IPCThreadState::self()->joinThreadPool();

}

第四步

0 定义 class Mcu : public BnMcuClient, public IBinder::DeathRecipient
	该类用于获取 服务 "media.mcu" 
1 实现  Mcu::getMcuService()  获取 上述注册到 Service Manage的服务 "media.mcu" 
2 实现 Mcu::Mcu() 初始化 mHandle、mCallback 
3 实现 Mcu::attach() 获取该服务接口

frameworks/av/include/mcu/Mcu.h

class Mcu : public BnMcuClient, public IBinder::DeathRecipient
{
public:
    virtual ~Mcu();
    static  sp<Mcu> attach(mcu_handle_t handle,const sp<McuCallback>& callback);
    static const sp<IMcuService>& getMcuService(); //用于获取  "media.mcu" 的服务
    void detach()
    virtual void onEvent(const sp<IMemory>& eventMemory);  // BpMcuClient
    virtual void binderDied(const wp<IBinder>& who); //IBinder::DeathRecipient

private:
    Mcu(mcu_handle_t handle,const sp<McuCallback>&);
    Mutex                   mLock;
    sp<IMcu>              mIMcu;
    const mcu_handle_t    mHandle;
    sp<McuCallback>       mCallback;
};

frameworks/av/mcu/Mcu.cpp

namespace {
    sp<IMcuService>          gMcuService;
    const int                  kMcuServicePollDelay = 500000; // 0.5s
    const char*                kMcuServiceName      = "media.mcu";
    Mutex                      gLock;

//死亡通知子类
class DeathNotifier : public IBinder::DeathRecipient
{
public:
    DeathNotifier() {
    }

    virtual void binderDied(const wp<IBinder>& who __unused) {
        ALOGV("binderDied");
        Mutex::Autolock _l(gLock);
        gMcuService.clear();
        ALOGW("Mcu service died!");
    }
};

sp<DeathNotifier>         gDeathNotifier;
}; 



/* 用于获取  "media.mcu" 的服务 */
const sp<IMcuService>& Mcu::getMcuService()
{
    Mutex::Autolock _l(gLock);
    if (gMcuService.get() == 0) {

//IServiceManager对象,即获取ServiceManager的代理对象
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder;
    do {
    //获取名为kMcuServiceName = "media.mcu" 的服务
        binder = sm->getService(String16(kMcuServiceName));
        if (binder != 0) {
            break;
        }
        ALOGW("McuService not published, waiting...");
        usleep(kMcuServicePollDelay);
    } while(true);
    if (gDeathNotifier == NULL) {
    //创建死亡通知对象 gDeathNotifier
        gDeathNotifier = new DeathNotifier();
    }

//将死亡通知连接到binder 
    binder->linkToDeath(gDeathNotifier);
    gMcuService = interface_cast<IMcuService>(binder);
}
ALOGE_IF(gMcuService == 0, "no McuService!?");
return gMcuService;
}


/*用于请求服务接口,并且发送 ATTACH 请求
0 获取  "media.mcu" 的服务
1 传递参数 mcu_handle_t handle => class Mcu :: mcu_handle_t   mHandle
2 传递参数 McuCallback callback => class Mcu :: sp<McuCallback> mCallback
3 获取目标服务的接口,并调用该接口的attach()功能。即获取 McuService.cpp中注册的"media.mcu"服务(McuService),并且调用McuService::attach()函数
	工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
	1 初始化 class McuService :: class ModuleClient  ::mcu_handle_t mHandle = handle
	2 初始化 class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient = mcu
	3 初始化  mcu->mIMcu = class McuService :: class ModuleClient  moduleClient

*/
sp<Mcu> Mcu::attach(mcu_handle_t handle,const sp<McuCallback>& callback)
{
    ALOGV("attach()");
    sp<Mcu> mcu;
    const sp<IMcuService>& service = getMcuService();//获取  "media.mcu" 的服务
    if (service == 0) {
        return mcu;
    }
    mcu = new Mcu(handle,callback);//初始化 mHandle、mCallback 成员变量

    status_t status = service->attach(handle,mcu, mcu->mIMcu);//获取目标服务的接口,并向该服务发出 ATTACH 请求

    if (status == NO_ERROR && mcu->mIMcu != 0) {
        IInterface::asBinder(mcu->mIMcu)->linkToDeath(mcu);
    } else {
        ALOGW("Error %d connecting to mcu service", status);
        mcu.clear();
    }
    return mcu;
}


/*	// Mcu  带参构造函数 目前工作只是初始化 mHandle、mCallback 成员变量
初始化 const mcu_handle_t   mHandle = handle
初始化 sp<McuCallback> mCallback = callback
*/
Mcu::Mcu(mcu_handle_t handle, const sp<McuCallback>& callback)
    : mHandle(handle), mCallback(callback)
{
}

第五步 实现JNI,打通Android上层服务接口通道

0  JNI实现本地方法 android_server_Mcu_setup()  对应  native_setup()
	0 该方法内部调用 Mcu::attach() 获取 服务 "media.mcu"
1 实现JNI 本地方法
	1 JNI实现本地方法  对应  native_finalize()
	2 JNI实现本地方法  对应  native_get_mcu_Version()
	3 JNI实现本地方法  对应 native_get_mcu_Time()
	4 JNI实现本地方法  对应 native_setPowerState()
	5 JNI实现本地方法  对应 native_startUpdate()
	6 JNI实现本地方法  对应 native_stopUpdate()
2 注册JNI

frameworks/base/services/core/jni/com_android_server_mcu_McuManagerService.cpp
…
…

// JNI实现本地方法  对应  native_setup()
static void android_server_Mcu_setup(JNIEnv *env, jobject thiz,jobject serviceObj)

{
   ......
	/*
		调用 Mcu::attach()
	*/
    sp<Mcu> mcu = Mcu::attach(handle,callback);

}
/*
1 JNI实现本地方法  对应  native_finalize()
2 JNI实现本地方法  对应  native_get_mcu_Version()
3 JNI实现本地方法  对应 native_get_mcu_Time()
4 JNI实现本地方法  对应 native_setPowerState()
5 JNI实现本地方法  对应 native_startUpdate()
6 JNI实现本地方法  对应 native_stopUpdate()
*/

//Java 本地接口方法表
static JNINativeMethod gMethods[] = {
    {"native_setup", "(Ljava/lang/Object;)V", (void *)android_server_Mcu_setup},

    {"native_finalize", "()V", (void *)android_server_Mcu_finalize},

    {"native_get_mcu_Version", "(I)Ljava/lang/String;", (void *)android_server_Mcu_getVersion},

    {"native_get_mcu_Time","(I)Ljava/lang/String;", (void *)android_server_Mcu_getTime},

    {"native_setPowerState","(I)I", (void *)android_server_Mcu_setPowerState},

    {"native_startUpdate","(I)I",(void *)android_server_Mcu_startUpdate},

    {"native_stopUpdate","(I)I",(void *)android_server_Mcu_stopUpdate},

};

//注册java本地接口方法
int register_android_server_mcu(JNIEnv *env)
{
    ......
}

第六步 Android上层硬件访服务

frameworks/base/services/core/java/com/android/server/mcu/McuManagerService.java

public final class McuManagerService extends SystemService {

	/*构造*/
    public McuManagerService(Context context) {
      	......
      	/*
      	对应于 JNI: android_server_Mcu_setup(),获取服务 "media.mcu"
      	*/
        native_setup(this);
       ......
    }
    
......

    private native void native_setup(Object manager_this);
    private native void native_finalize();
    private native String native_get_mcu_Version(int type);
    private native String native_get_mcu_Time(int type);
    private native  int native_setPowerState(int type);
    private native  int native_startUpdate(int type);
    private native  int native_stopUpdate(int type);

}

第七步 : 启动服务 McuManagerService

SystemServer.java

import com.android.server.mcu.McuManagerService;

boolean isMcuServer = SystemProperties.get("ro.mcu.server").equals("1");

if(isMcuServer)
 {
  mSystemServiceManager.startService(McuManagerService.class);
 }

二 服务打开过程梳理

1 打开 mcu串口服务McuManagerService.java

mcu串口服务
frameworks/base/services/core/java/com/android/server/mcu/McuManagerService.java

public final class McuManagerService extends SystemService {

	private static final String TAG = "McuManagerService";
	...

	/*构造*/
    public McuManagerService(Context context) {
      ...
        native_setup(this);
      ...

    }
	
	......
	
	private native void native_setup(Object manager_this);
    private native void native_finalize();
    private native String native_get_mcu_Version(int type);
    private native String native_get_mcu_Time(int type);
    private native  int native_setPowerState(int type);
    private native  int native_startUpdate(int type);
    private native  int native_stopUpdate(int type);
}

2 开mcu串口服务JNI

......
......

// JNI实现本地方法  对应  native_setup()
static void android_server_Mcu_setup(JNIEnv *env, jobject thiz,jobject serviceObj)

{
   ......
	/*
		调用 Mcu::attach()
	*/
    sp<Mcu> mcu = Mcu::attach(handle,callback);

}
/*
1 JNI实现本地方法  对应  native_finalize()
2 JNI实现本地方法  对应  native_get_mcu_Version()
3 JNI实现本地方法  对应 native_get_mcu_Time()
4 JNI实现本地方法  对应 native_setPowerState()
5 JNI实现本地方法  对应 native_startUpdate()
6 JNI实现本地方法  对应 native_stopUpdate()
*/

//Java 本地接口方法表
static JNINativeMethod gMethods[] = {
    {"native_setup", "(Ljava/lang/Object;)V", (void *)android_server_Mcu_setup},

    {"native_finalize", "()V", (void *)android_server_Mcu_finalize},

    {"native_get_mcu_Version", "(I)Ljava/lang/String;", (void *)android_server_Mcu_getVersion},

    {"native_get_mcu_Time","(I)Ljava/lang/String;", (void *)android_server_Mcu_getTime},

    {"native_setPowerState","(I)I", (void *)android_server_Mcu_setPowerState},

    {"native_startUpdate","(I)I",(void *)android_server_Mcu_startUpdate},

    {"native_stopUpdate","(I)I",(void *)android_server_Mcu_stopUpdate},

};

//注册java本地接口方法
int register_android_server_mcu(JNIEnv *env)
{
    ......
}

3 调用 Mcu::attach()

frameworks/av/mcu/Mcu.cpp
调用 Mcu::attach(),看代码可以知道,Mcu::attach()其实就是连接到 本地服务 McuService

......

/* 用于获取  "media.mcu" 的服务 */
const sp<IMcuService>& Mcu::getMcuService()
{
    Mutex::Autolock _l(gLock);
    if (gMcuService.get() == 0) {

	//IServiceManager对象,即获取ServiceManager的代理对象
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
	    //获取名为kMcuServiceName = "media.mcu" 的服务
            binder = sm->getService(String16(kMcuServiceName));
            if (binder != 0) {
                break;
            }
            ALOGW("McuService not published, waiting...");
            usleep(kMcuServicePollDelay);
        } while(true);
        if (gDeathNotifier == NULL) {
	    //创建死亡通知对象 gDeathNotifier
            gDeathNotifier = new DeathNotifier();
        }

	//将死亡通知连接到binder 
        binder->linkToDeath(gDeathNotifier);
        gMcuService = interface_cast<IMcuService>(binder);
    }
    ALOGE_IF(gMcuService == 0, "no McuService!?");
    return gMcuService;
}

/*用于请求服务接口,并且发送 ATTACH 请求
0 获取  "media.mcu" 的服务
1 传递参数 mcu_handle_t handle => class Mcu :: mcu_handle_t   mHandle
2 传递参数 McuCallback callback => class Mcu :: sp<McuCallback> mCallback
3 获取目标服务的接口,并调用该接口的attach()功能。即获取 McuService.cpp中注册的"media.mcu"服务(McuService),并且调用McuService::attach()函数
	工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
	1 初始化 class McuService :: class ModuleClient  ::mcu_handle_t mHandle = handle
	2 初始化 class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient = mcu
	3 初始化  mcu->mIMcu = class McuService :: class ModuleClient  moduleClient

*/
sp<Mcu> Mcu::attach(mcu_handle_t handle,const sp<McuCallback>& callback)
{
    ALOGV("attach()");
    sp<Mcu> mcu;
    const sp<IMcuService>& service = getMcuService();//获取  "media.mcu" 的服务
    if (service == 0) {
        return mcu;
    }
    mcu = new Mcu(handle,callback);//初始化 mHandle、mCallback 成员变量

    status_t status = service->attach(handle,mcu, mcu->mIMcu);//获取目标服务的接口,并向该服务发出 ATTACH 请求

    if (status == NO_ERROR && mcu->mIMcu != 0) {
        IInterface::asBinder(mcu->mIMcu)->linkToDeath(mcu);
    } else {
        ALOGW("Error %d connecting to mcu service", status);
        mcu.clear();
    }
    return mcu;
}

// Mcu  带参构造函数 目前工作只是初始化 mHandle、mCallback 成员变量
/*
初始化 const mcu_handle_t   mHandle = handle
初始化 sp<McuCallback> mCallback = callback
*/
Mcu::Mcu(mcu_handle_t handle, const sp<McuCallback>& callback)
    : mHandle(handle), mCallback(callback)
{
}
4 调用 McuService::attach()

mcu专用串口本地服务
frameworks/av/services/mcuservice/McuService.cpp
调用 McuService::attach(),看代码可以知道就是 绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。

/*
当McuService类被引用的时候 就会调用McuService::onFirstRef() 打开串口,具体操作在  av/services/mcuservice/UartComm2.cpp 中实现
*/
void McuService::onFirstRef()
{
    ALOGD("McuService::onFirstRef");
......
	mCommInterface = new UartComm2("/dev/ttyS3");//构造函数 传递取目标字符串:"/dev/ttyS3" 
	mCommInterface->openInterface();//打开目标串口"/dev/ttyS3" ,并且设置波特率
......
	mUpdateThread = NULL;
}


void McuService::instantiate()
{
    ALOGV("McuService::instantiate");
		/*
		首先通过 defaultServiceManager()获取一个 ServiceManager类对象,利用该类的addService()方法,将 McuService服务 注册到 Service Manager中,并且命名为 "media.mcu"
		这样Client进程就可以通过名称  "media.mcu"  来获取这个McuService服务的一个代理对象了
		*/
    defaultServiceManager()->addService(String16("media.mcu"), new McuService());
}

/*工作 :绑定 service进程(本地对象)与client进程(代理对象),初始化 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息。
1 初始化 class McuService :: class ModuleClient  ::mcu_handle_t mHandle = handle
2 初始化 class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient = class IMcuClient client
3 初始化 mcu = class McuService :: class ModuleClient  moduleClient
4 初始化 class McuService :: class ModuleClient::sp<McuService>   mMcuService = this 
5 向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象
6 初始化传递进来的 IMcu类 mcu对象 为 class McuService :: class ModuleClient  moduleClient
*/
status_t McuService::attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu)
{
    ALOGV("%s handle: %d", __FUNCTION__,handle);
    size_t i;
    sp<ModuleClient> moduleClient;//ModuleClient类对象

    AutoMutex lock(mServiceLock);
    mcu.clear();
    if (client == 0) {
        return BAD_VALUE;
    }

    for (i = 0; i < mModuleClients.size(); i++) {
	
	/* ModuleClient类对象 mModuleClients,client()方法返回 IMcuClient接口 mClient对象 */
        if (mModuleClients[i]->client() == client) {
            // client already connected: reject
            mcu = NULL;
            return ALREADY_EXISTS;
        }
    }



	//ModuleClient类构造函数 : McuService::ModuleClient::ModuleClient() ,创建 对象 moduleClient
	/*
	初始化 McuService类 mMcuService对象为 mcuService
		class McuService :: class ModuleClient::sp<McuService>   mMcuService;

	初始化 IMcuClient类接口 mClient 对象为 client
		class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient; 

	初始化  mcu_handle_t mHandle = handle
		class McuService :: class ModuleClient  ::mcu_handle_t mHandle;
	*/

    moduleClient = new ModuleClient(this, client,handle);
    if(moduleClient != 0)
    {
	//向动态数组 ModuleClient mModuleClients[] 中添加 moduleClient 对象?
        mModuleClients.add(moduleClient);

	//初始化传递进来的 IMcu类 mcu对象 为 moduleClient
        mcu = moduleClient;
    }
    else
    {
        return NO_INIT;
    }
    return NO_ERROR;
}

......

//ModuleClient类构造函数 :
/*
初始化 McuService类 mMcuService对象为 mcuService
	class McuService :: class ModuleClient::sp<McuService>   mMcuService;

初始化 IMcuClient类接口 mClient 对象为 client
	class McuService :: class ModuleClient  :: sp<IMcuClient>  mClient; 

初始化  mcu_handle_t mHandle = handle
	class McuService :: class ModuleClient  ::mcu_handle_t mHandle;
*/
McuService::ModuleClient::ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle)
	 : mMcuService(mcuService), mClient(client), mHandle(handle)
{
}

......

这样就弄清了 上层服务到frameworks本地服务的流数据。那么是什么时候注册frameworks本地服务到 service manager的呢?

frameworks/av/services/mcuservice/main_mcuservice.cpp

int main(int argc, char** argv){
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    McuService::instantiate();//注册 McuService 服务
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

三 总结

在这里插入图片描述

四 头文件笔记

class IMcuService : public IInterface
class IMcuClient : public IInterface
class IMcu : public IInterface

本地服务
class BnMcuService: public BnInterface<IMcuService>
	onTransact()

class BnMcuClient : public BnInterface<IMcuClient>
	onTransact()

class BnMcu: public BnInterface<IMcu>
	onTransact()


服务类
class McuService : public BnMcuService
	//记录与当前服务(本地对象)连接的 客户进程(代理对象)信息
	class ModuleClient : public BnMcu

class Mcu : public BnMcuClient
    sp<IMcu>              mIMcu;
    const mcu_handle_t    mHandle;
    sp<McuCallback>       mCallback;





**********************************************************************************************************

framework/av/include/mcu/IMcuService.h

class IMcu;
class IMcuClient;

/* 定义硬件服务接口 IMcuService */
class IMcuService : public IInterface
{
public:
    mcu_metadata_t *test;

	 /* DECLARE_META_INTERFACE(McuService); 声明 IMcuService 类的元接口 
	1. 为 IMcuService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。 
	2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuService接口。 
	3. 最后定义了其他接口操作函数
 	*/
    DECLARE_META_INTERFACE(McuService);

    virtual status_t attach(mcu_handle_t handle,const sp<IMcuClient>& client,sp<IMcu>& mcu) = 0;
    virtual String8 getVersion(int type) = 0;
    virtual String8 getTime(int type) = 0;
    virtual int setPowerState(int state)= 0;
    virtual int startUpdate(int state)= 0;
    virtual int stopUpdate(int state)= 0;
};


/*
* 定义了一个 Binder 本地对象类 BnMcuService,它实现了模板类 BnInterface的成员函数 onTransact。
*/
class BnMcuService: public BnInterface<IMcuService>
{
public:
	/*
	* 成员函数 onTransact 是虚函数,它是由 BBinder 的子类,即 Binder本地对象类来实现的,他负责分发与业务相关的进程间通
	* 信请求。事实上,与业务相关的进程间通信请求是由Binder本地对象类的子类,即Service组件来负责处理的。
	*/
    virtual status_t    onTransact( uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags = 0);
};


---------------------------------------------------------------------------------------------------------

framework/av/include/mcu/IMcuClient.h


/* 定义硬件服务接口 IMcuClient */
class IMcuClient : public IInterface
{
public:
	/* DECLARE_META_INTERFACE(McuClient); 声明 IMcuClient类的元接口 
	1. 为 IMcuClient 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。 
	2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IMcuClient接口。 
	3. 最后定义了其他接口操作函数
 	*/
    DECLARE_META_INTERFACE(McuClient);

    virtual void onEvent(const sp<IMemory>& eventMemory) = 0;

};


/*定义一个Binder 本地对象 BnMcuClient */
class BnMcuClient : public BnInterface<IMcuClient>
{
public:
    virtual status_t    onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};


--------------------------------------------------------------------------------------------------------------------
frameworks/av/include/mcu/Mcu.h

class Mcu : public BnMcuClient, public IBinder::DeathRecipient
{
public:
    virtual ~Mcu();
    static  sp<Mcu> attach(mcu_handle_t handle,const sp<McuCallback>& callback);
    static const sp<IMcuService>& getMcuService(); //用于获取  "media.mcu" 的服务
    void detach()
    virtual void onEvent(const sp<IMemory>& eventMemory);  // BpMcuClient
    virtual void binderDied(const wp<IBinder>& who); //IBinder::DeathRecipient

private:
    Mcu(mcu_handle_t handle,const sp<McuCallback>&);
    Mutex                   mLock;
    sp<IMcu>              mIMcu;
    const mcu_handle_t    mHandle;
    sp<McuCallback>       mCallback;
};
---------------------------------------------------------------------------------------------------------------------
frameworks/av/include/mcu/McuCallback.h


class McuCallback : public RefBase
{
public:

    McuCallback() {}
    virtual ~McuCallback() {}

    virtual void onEvent(struct mcu_event *event) = 0;

};

------------------------------------------------------------------------------------------------------------------------

frameworks/av/include/mcu/IMcu.h

//接口
	class IMcu : public IInterface
	{
	public:

	    DECLARE_META_INTERFACE(Mcu);//声明 IMcu 接口

	    virtual void detach() = 0;
	};

	//本地对象 BnMcu 负责分发与业务相关的进程间通
	class BnMcu: public BnInterface<IMcu>
	{
	public:
	    virtual status_t    onTransact( uint32_t code,const Parcel& data,Parcel* reply, uint32_t flags = 0);
	};

------------------------------------------------------------------------------------------------------------------------
frameworks/av/services/mcuservice/UartComm2.h

	public:
	    UartComm2(char *name);//构造函数 获取目标字符串:"/dev/ttyS3" 
	    virtual ~UartComm2();
	    void setName(char *name);
	    virtual void init();
	    virtual int writeData(unsigned int length,unsigned char *buffer);
	    virtual int readData(unsigned int length,unsigned char *buffer);
	    virtual int openInterface();//打开目标串口,并且设置波特率
	    virtual int closeInterface();
	    virtual int enableDebug(int enable);
	    bool setParameter(unsigned int speed, int size, int parity, int stop);
	    bool getParameter(unsigned int *speed, int *size, int *parity, int *stop);
	private:
	    int mEnableDebug;
	    int mCommFd;
	    char mName[NAME_LEN];//存放目标字符串:"/dev/ttyS3"
	};


------------------------------------------------------------------------------------------------------------------------
frameworks/av/services/mcuservice/McuService.h

	// 继承 BnMcuService ,实现BnMcuService没有实现的方法
	class McuService : public BinderService<McuService>, public BnMcuService
	{
	    friend class BinderService<McuService>;

	public:
	    class ModuleClient;
	    static char const* getServiceName() { return "media.mcu"; }
	    static void instantiate(); //注册McuService服务到 Service Manage 中,并将服务名称命名为"media.mcu"。

	    McuService();
	    virtual             ~McuService();

	    // IMcuService
	    virtual status_t attach(mcu_handle_t handle, const sp<IMcuClient>& client,sp<IMcu>& mcu);
	    virtual String8 getVersion(int type);
	    virtual String8 getTime(int type);
	    virtual int setPowerState(int state );
	    virtual int startUpdate(int status);
	    virtual int stopUpdate(int status);
	    virtual status_t    dump(int fd, const Vector<String16>& args);
	    void onCallbackEvent(const sp<IMemory>& event);
	    void removeClient(sp<ModuleClient> client);
	    int isFileExist(const char *pathFile);
	    void heartBeat();

	    ......

		/* 记录与当前服务(本地对象)连接的 客户进程(代理对象)信息 */
	    class ModuleClient : public BnMcu, public IBinder::DeathRecipient {
	    public:
	       ModuleClient(const sp<McuService>& mcuService,const sp<IMcuClient>& client,mcu_handle_t handle);
	       virtual ~ModuleClient();
	       // IMcu
	       virtual void detach();
	       virtual status_t dump(int fd, const Vector<String16>& args);
	       sp<IMcuClient> client() const { return mClient; }//返回 mClient
	       void onCallbackEvent(const sp<IMemory>& event);
	       virtual void onFirstRef();//该类第一次被引用是调用  
	       // IBinder::DeathRecipient implementation
	       virtual void        binderDied(const wp<IBinder> &who);

	    private:

		mutable Mutex               mLock;  // protects mClient, mConfig and mTuner
		 sp<McuService>          mMcuService;

		/*
		IMcuClient 类 : 硬件服务接口 class IMcuClient : public IInterface
		event callback binder interface
		 */
		sp<IMcuClient>            mClient;
		   mcu_handle_t mHandle; 
	    }; 


	    sp<CallbackThread> getCallbackThread() const { return mCallbackThread; }
	    int handleFrameData(FrameData *frame);
	    static void callback(mcu_event_t *halEvent, void *cookie);

	private:
	    virtual void onFirstRef();
	    int sendCallbackEvent(FrameData *frame);
	    int mcuEventMonitor(int fd,const Vector<String16> &args);
	    void sendCMD(int cmd);
	    void sendCMD(int cmd,int length,unsigned char *data);
	    FrameData sendCMDWait(int cmd,int length,unsigned char *data,int second);
	    FrameData sendCMDWait(int cmd);
	    int setBackLightValue(int value);
	    int openBackLight(void);
	    int closeBackLight(void);
	    int setNextFuncState(int state,int cmd);
	    Mutex               mServiceLock;   // protects mModules
	    Vector< sp<ModuleClient> >    mModuleClients;//动态数组,声明一个动态数组  ModuleClient mModuleClients[]
	    sp<CallbackThread>          mCallbackThread; // event callback thread
	    sp<ReadThread>          mReadThread; // read data thread
	    sp<HeartbeatThread> mHearbeatThread;
	    sp<UpdateThread>mUpdateThread;
	    sp<CommunicationInterface>  mCommInterface;
	    pthread_mutex_t                 mDataMutex;
	    pthread_cond_t                  mDataCond;
	    int mFuncState;
	    FrameData mFrameData;
	};

------------------------------------------------------------------------------------------------------------------------
Android & MCU之间的串口通信(收发数据) 最近一个项目是android和MCU之间的串口指令数据通信,捣鼓了很久,也找了很多网上的资料。最后将实现的总结记录下来。 使用的是GitHub中的一个项目,下载地址:https://github.com/cepr/android-serialport-api 下载解压后会出现两个文件夹,我们使用的是这个,如图: 复制整个文件夹到项目的java目录下,不要变更名字,名字是跟里面的东西相关... 阅读详情

相关推荐

mcumgr-android:适用于运行Apache Mynewt和Zephyr的设备的移动管理库(DFU,日志,统计信息,配置等)

Android McuManager McuManager协议的与传输无关的实现。 包含BLE传输的默认实现。 Gradle安装 注意:要实现更快的固件升级,请使用版本0.12.0-beta3 (此版本较不稳定,在发布到生产环境中之前应与您的应用和设备进行彻底测试) McuManager BLE(推荐) 包含使用Nordic的的内核和BLE传输实现。 implementation 'io.runtime.mcumgr:mcumgr-ble:0.11.0' McuManager核心 仅核心依赖性。 如果要提供自己的传输实现,请使用。 implementation 'io.runtime.mcumgr:mcumgr-core:0.11.0' 介绍 McuManager是一种应用程序层协议,用于管理和监视运行Apache Mynewt和Zephyr的微控制器。 更具体地说,McuMana

DECLARE_META_INTERFACE宏展开及讲解

audiopolicy详解DECLARE_META_INTERFACEDECLARE_META_INTERFACE(AudioPolicyService)IMPLEMENT_META_INTERFACEIMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService") 此文章主要对DECLARE_MET...

wildbook 1990

泰克示波器TDS210改装便携示波器

泰克示波器TDS210改装编写示波器

超级网吧的博客 3079

DECLARE_META_INTERFACE(INTERFACE)和IMPLEMENT_META_INTERFACE(INTERFACE, NAME)宏定义分析

这里讲的两个宏定义是IPC中鼎鼎大名的 DECLARE_META_INTERFACE(INTERFACE) IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 定义 frameworks\base\include\utils\IInterface.h #define DECLARE_META_INTERFACE(

Android系统攻城狮 6244

别再死记硬背了!用Python+Matlab/Simulink手把手带你理解PID控制器的‘稳、快、准’

本文通过Python编程和Matlab/Simulink仿真,深入解析PID控制器的‘稳、快、准’三大核心指标,帮助读者直观理解PID控制的实现原理与参数整定技巧。内容涵盖经典控制理论和自动控制原理,提供实战案例和高级调参技巧,适合工业自动化领域的学习者和工程师。

weixin_42551227的博客 369

嵌入式开发之瑞芯微RK356x--基本环境搭建

嵌入式环境搭建

NexyHO的博客 617

interface宏:DECLARE_META_INTERFACE/IMPLEMENT_META_INTERFACE

frameworks/native/include/binder #define DECLARE_META_INTERFACE(INTERFACE) \ static const android::String16 descriptor; \ static andro

CCJHDOPC的专栏: 2617

复现基于混频因子模型的GDP即时预测方法

基于混频因子模型的GDP即时预测方法复现 本文复现了混频因子模型(MIDAS)在GDP即时预测中的应用。该方法整合7个月度宏观经济变量(工业增加值、CPI、PMI等)与季度GDP数据,通过状态空间模型实现高频预测。技术实现包括:1)使用PCA提取潜在共同因子;2)构建状态空间模型处理混频数据;3)通过卡尔曼滤波进行参数估计。实证结果显示模型预测效果良好(测试集R²=0.82),其中工业增加值对因子1贡献最大(0.82),CPI对因子2贡献显著(0.78)。该方法为决策者提供了更及时的季度GDP估算。

huanghm88的专栏 601

Android10.0 Binder通信原理(四)-Native-C\C++实例分析

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析 [Android取经之路] 系列文章: 《系统启动篇》 Android系统架构 Android是怎么启动的 Android 10.0系统启动之init进程 Android10.0系统启动之Zygote进程 Android 10.0 系统启动之SystemServer进程 Android 10.0 系统服务之ActivityMnagerService Android10.0系统启动之Launcher(桌面)启动流程 And

纸上得来终觉浅,绝知此事要躬行 2216

微信支付接口「系统繁忙 SYSTEM_ERROR」/「文件不存在」报错分析与解决方案 接口开发实现SDK

微信支付的“平台证书模式”只有5年的有效期,过期后微信支付将不再签发新的平台证书,转而要求开发者使用“微信支付公钥”来处理敏感信息加密及回调签名验证。然而,由于以下几点原因,许多开发者在调用 获取平台证书。尽管微信支付在技术迭代上有其必要性,但报错设计过于不友好。诸如“系统繁忙”这样的提示很难直接关联到平台证书失效或公钥切换问题。这样的信息表达,开发者不仅看不懂,还需要花费大量时间分析排查,非常影响效率。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 779

2025年最新雷电模拟器9.22安装Magisk面具和LSPosed框架完整图文教程 文章末尾附所需软件下载

操作环境:雷电模拟器9.0.22 虚拟系统版本android 91、设置-其他设置-Root权限-开启2、设置-性能设置-System.vmdk可写入3、安装Magisk-18a0b94a-delta(25205).apk,运行并给予root权限4、选择右上角安装弹出“允许“magisk Delta”访问您设备上的照片、媒体内容和文件吗?“选择允许,然后结束magisk进程。5、从新运行magisk选择右上角安装-选择修补boot镜像中的vbmeta和安装到Recovery。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 7094

Binder进程间通信系统第五篇-----Binder进程间通信实例

本文将基于应用程序框架层提供的 Binder库来开发一个Binder进程间通信应用实例,它包含一个Server进程和一个Client进程。其中Server进程实现了一个Service组件,负责管理我前面写的虚拟硬件设备 freg的寄存器 val,并且向Client进程提供访问服务。 我们将该应用实例划分为:common、server和client三个模块。其中,模块common实现了硬件访问服务接...

奶牛养殖场小马 755

如何在 UniApp 中接入讯飞语音听写功能 文末附vue3+vue2完整代码

在开发过程中,我遇到了讯飞接口返回空数据的问题。通过仔细检查传送的每一帧数据,我发现问题出在第一帧的配置信息以及 Base64 数据的切片。确保每一帧的数据正确且符合接口要求,问题就能够得到解决。希望这个过程能帮助你在项目中顺利对接讯飞语音识别。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 996

Android Binder机制 - interface_cast和asBinder源码分析

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕。

lb377463323的博客 9106

微信公众号 - 超详细 H5 网页接入微信支付功能,开发网站微信支付最详细的教程示例代码(微信公众号前端支付 JS-SDK / JSAPI 微信H5授权登录支付,唤起微信支付)最新超级详细教程

H5页面接入微信支付功能,前端网页端怎么做微信JSAPI支付,vue网站接入微信JSSDK支付,vueH5项目如何做使用微信支付,端h5调用微信支付jsapi方法,前端vue开发的H5网站怎么微信支付最详细的教程示例代码,vue怎么调取微信支付流程,将H5接入微信支付退款,vue网站怎么搞微信支付,H5前端开发网站在微信环境内H5调起微信支付,react项目h5如何调用微信支付的方法,nuxt.js项目vueH5集成微信JS支付,网站怎么做出H5微信公众号支付,请问vue.js这个框

🏆 前端领域优质创作者 8126

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

[深入理解Android卷一全文-第六章]深入理解Binder

由于《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在优快云博客中全文转发这两本书的全部内容。第6章 深入理解Binder本章主要内容·  以MediaServer为切入点,对Binder的工作机制进行分析。·  剖析ServiceManager的原理。 ·  以MediaPlayerService为切入点对Clien

Innost的专栏 2万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

android多媒体框架学习 详解 最新版本

一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了!也体现了media 在整个android系统中的重要性!framework/av下都是些C/C++代码(libmedia,libmediaplayerservice,libstagefri...

weixin_33971205的博客 3438

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

红茶一杯话Binder(初始篇)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34261415的博客 466

Android 8.1 从零开始写 HAL – (3) 实现 Bp、Bn 端

Android 8.1 从零开始写 HAL – (3) 实现 Bp、Bn 端 注意:本文基于 Android 8.1 进行分析Qidi 2020.07.18 (Markdown & Haroopad) 【前言】 既然 Binder 化的 HAL 依赖于 Binder 机制进行实现,那么我们自然必须按照 Binder 框架,相应编写 demoComponent HAL 的 Bp 端和 Bn 端。只有这样,才能打通客户端进程调用到服务端进程 —— 我们的 demoService —— 的通路。

u010783226的专栏 595

深入解析Android 5.0系统笔记第4章 进程间通信Android的Binder

4.1.4 Binder 的层次从代码实现上划分, Binder设计的类可以分成4个层次,如图4.4所示。最上层是位于Framework中的各种Binder服务类和它们的接口类。这一层的类非常多,例如常见的ActivityMangerService. WindowManagerService. PackageMangerService等,它们为应用程序提供了各种各样的服务。最底层的当然是Binder驱动。中间则分成两层,上层是用于服务类和接口类开发的基础,如Ibinder, Bbinder, BpBinde

青岛海珊瑚IT学习中心 651

Binder使用示例

BInder方面的资料虽然感觉看的比较多,但是真正用的时候才发现有很多地方模棱两棵的,所以,打算用一个实例再来巩固一下binder的使用方法 首先看下目录结构: leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$ ls T* TestBinderClient: Android.mk

new_abc的专栏 1万+

android Binder详解 (1)

做android的同学们都应该知道有个叫做binder的东西,它是android的ipc机制,是一个核心的组成部分。 一直以来,我对于binder只有一个概念,对细节不清楚,特别是核心的binder device。最近有空,完整的学习下android binder,这篇文章,基本上是整个学习过程的一个记录,如有错误的问题,请大家指正。

sky的专栏 2203

Android深入浅出之Binder机制【总结】

Android深入浅出之Binder机制 Android深入浅出之Binder机制 一说明  Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。 我们这里将以MediaService的例子来分析Binder的使用: l       

Norton的专栏 2817

Android Binder机制理解

Android Binder机制理解 一、说明 Android系统中应用很广泛的但也是最难理解的就是Binder机制了,从APP组被调到系统平台组后感觉需要学的东西更多了,思考的方式也有所改变,从是什么转变到为什么(背后的设计思想和实现细节),初次接触Framework感觉就是在于各种服务打交道,例如ActivityManagerService、WindowManagerService、Pow

Android学习之旅 3159
上一篇: 59课 类模板深度剖析
下一篇: hrtimer简单使用
Ma浩然
博客等级 码龄9年 1万+粉丝 462原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ma浩然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值