android 底层开发 ----- LED实验

本文介绍了一个具体的LED硬件抽象层(HAL)模块实现案例,详细展示了从底层设备控制到上层应用调用的整个流程,包括关键结构体定义、具体方法实现、JNI层交互及框架层调用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

halmoudle需要涉及的三个关键结构体:

structhw_module_t;

structhw_module_methods_t;

structhw_device_t;


led.h文件

//HAL不能直接使用hw_module_t结构体,需要使用一个继承

structled_module_t {

struct hw_module_t common;

};

//自定义一个针对led控制的结构体,包含hw_module_t和支持的API操作

structled_control_device_t {

structhw_device_t common;

int(*set_on) (struct led_control_device_t *dev, int32_t led);

int(*set_off)(struct led_control_device_t *dev, int32_t led);

};

structled_control_context_t {

structled_control_device_t device;

};

//定义一个MODULE_IDHAL层可以根据这个ID找到HALstub

#defineLED_HARDWARE_MODULE_ID “led”

led.c文件


int led_on(struct led_control_device_t *dev, int32_t led)

{

intfd;

charbuff[3] = “”;

intsize = 0;

if((fd= open(DEVICE_NAME,O_RDWR)) == -1)

{

LOGI(“openleds fail”);

return0;

}

memset(buff,'1',5);

buff[0]= 1;//表示led灯开

buff[1]= (char)led;//控制哪一个led

size= write(fd,buff,sizeof(buff));

LOGI(“LEDStub:set %d on”,led);

close(fd);

return0;

}


intled_off(struct led_control_device_t *dev, int32_t led)

{


intfd;

charbuff[5] = “”;

intsize = 0;

if((fd= open(DEVICE_NAME,O_RDWR)) == -1)

{

LOGI(“openleds fail”);

return0;

}

memset(buff,0,3);

buff[0]= 0;//表示led灯关

buff[1]= (char)led;

size= write(fd,buff,sizeof(buff));

LOGI(“LEDStub:set %d off”,led);

close(fd);

return0;

}


staticint led_device_open(const struct hw_module_t *module, const char*name, struct hw_device_t **device)

{

structled_control_device_t *dev;

dev =(struct led_control_device_t*)malloc(sizeof(*dev));

memset(dev,0, sizeof(*dev));

dev->common.tag= HARDWARE_DEVICE_TAG;

dev->common.version= 0;

dev->common.module= module;

dev->common.close= led_device_close;

dev->set_on= led_on;//实例化支持的操作

dev->set_off= led_off;

*device=&dev->common;//将实例化后的led_control_device_t地址返回给jni层,这样jni层就可以直接调用led_on,led_off,led_device_close方法

success:

return0;

}


//向系统注册一个IDLED_HARDWARE_MODULE_IDstub,注意这里的HAL_MODULE_INFO_SYM不能修改

conststruct led_module_t HAL_MODULE_INFO_SYM = {

common:{

tag: HARDWARE_MODULE_TAG,

version_major: 1,

version_minor: 0,

id:LED_HARDWARE_MODULE_ID,

name: “Sample LED Stub”,

author: “LED CONTROL”;

methods: &led_module_methods,

}

};


JNI层文件:(com_liumr_server_LedService.cpp)

structled_control_device_t *sLedDevice = NULL;

staticjboolean _setOn(JNIEnv *env, jobject thiz, jint led)

{

LOGI(“LedServiceJNI: _setOn() is invoked”);

if(sLedDevice== NULL)

{

LOGI(“LedServiceJNI: sLedDevice was not fetched correctly”);

return-1;

}else{

returnsLedDevice->set_on(sLedDevice,led);//调用HAL层的方法

}

}


staticjboolean _setOff(JNIEnv *env, jobject thiz, jint led)

{

LOGI(“LedServiceJNI: _setOff()is invoked”);

if(sLedDevice== NULL)

{

LOGI(“LedServiceJNI: sLedDevice was not fetched correctly”);

return-1;

}else{

returnsLedDevice->set_off(sLedDevice,led);//调用HAL层的方法

}

}


staticinline int led_control_open(const struct hw_module_t *module, structled_control_device_t **device)

{

//这个过程很重要,JNI通过LED_HARDWARE_MODULE_ID找到对应的Stub

returnmodule->methods->open(module, LED_HARDWARE_MODULE_ID, (structhw_device_t **)device);

}


staticjboolean _init(JNIEnv *env, jclass clazz)

{

led_module_t*module;

//根据LED_HARDWARE_MODULE_ID找到应对的hw_module_t

if(hw_get_module(LED_HARDWARE_MODULE_ID,(consthw_module_t **)&module) == 0) {

LOGI(“LedServiceJNI:LED Stub found”);

if(led_control_open(&module->common,&sLedDevice) == 0) {

LOGI(“LedServiceJNI: Got Stub operations”);

return0;

}

}

LOGE(“LedServiceJNI: Get Stub operations failed”);

return-1;

}


/*

*JNINativeMethodJNI层注册的方法,Framework层可以使用这些方法,

*()Z 无参数返回值的bool

*(I)Z 整型参数返回值为bool

*/


staticconst JNINativeMethod gMethods[] = {

{“_init”, “()Z”,(void*)_init},

{“_set_on”, “(I)Z”, (void *)_setOn},

{“_set_off”,“(I)Z”, (void *)setOff},

};


staticint registerMethods(JNIEnv *env)

{

staticconst char *const kClassName = “com/liumr/server/LedService”;

//必须与Framework层的service类名相同

jclassclazz;

clazz= env->FindClass(kClassName);

if(clazz= = NULL)

{

LOGE(“Can'tfind class %s\n”,kClassName);

return-1;

}

if(env->RegisterNatives(clazz,gMethods, sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)

{

LOGE(“Failedregistering methods for %s\n”,kClassName);

return-1;

}

return0;

}


//Framework层加载JNI库时调用

jintJNI_OnLoad(JavaVM *vm, void* reserved)

{

JNIEnv*env = NULL;

jintresult = -1;

if(vm->GetEnv((void**)&env,JNI_VERSION_1_4) != JNI_OK)

{

LOGE(“ERROR:GetEnvfailed \n”);

gotobail;

}

assert(env!= NULL);

if(registerMethods(env)!= 0)

{

LOGE(“ERROR:PlatformLibrary native registeration failed\n”);

gotobail;

}

result= JNI_VERSION_1_4;

bail:

returnresult;

}


framework层的service文件

publicfinal class LedService extends IledService.Stub

{

static{

System.load(“/system/lib/libmokoid_runtime.so”);//动态加载库

}

publicLedService()

{

Log.i(“LedService”,”goto get LED Stub..”);

_init();

}

publicboolean setOn(int led)

{

Log.i(“Platform”,”LEDOn”);

return_set_on(led);

}

publicboolean setOff(int led)

{

Log.i(“Platform”,”LEDOff”);

return _set_off(led);

}


privatestatic native boolean _init();

privatestatic native boolean _set_on(int led);

privatestatic native boolean _set_off(int led);


}


上层应用程序有两种调用模式:

1)、直接通过service调用.sojni

2)、通过Manager调用service

publicclass LedManager

{

privatestatic final String TAG = “LedManager”;

privateIledService mLedService;

publicLedManager()

{

//利用ServiceManager获取LedService,从而调用它提供的方法,这要求LedService必须已经增加到ServiceManager中,这个过程将在App的一个service进程中完成。

mLedService= IledService.Stub.asInterface(ServiceManager.getService(“led”));

if(mLedService!= null)

Log.i(TAG,”TheLedManager object is ready”);

}

publicboolean LedOn(int n)

{

booleanresult = false;

try{

result= mLedService.setOn(n);

}catch(RemoteExceptione){

Log.e(TAG,“RemoteExceptionin LedManager.LedOn”,e);

}

returnresult;

}


publicboolean LedOff(int n)

{

booleanresult = false;

try{

result= mLedService.setOff(n);

}catch(RemoteExceptione) {

Log.e(TAG,”RemoteExceptionin LedManager.LedOff”,e);

}

returnresult;

}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值