教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 文库大全 > 小学教育 >

Android GPIO LED 驱动与HAL分析(2)

来源:网络收集 时间:2026-08-24
导读: }; /**********************************************/ struct led_control_context_t {//定义一个继承自device结构的上下文结构 struct led_control_device_t device; }; #define LED_HARDWARE_MODULE_ID led//定

};

/**********************************************/

struct led_control_context_t {//定义一个继承自device结构的上下文结构 struct led_control_device_t device;

};

#define LED_HARDWARE_MODULE_ID "led"//定义HAL 的模块ID

4.1.2 C文件

4.1.2.1 入口定义

//定一个hw_module_methods_t结构体,关联入口函数

static struct hw_module_methods_t led_module_methods = {

open: led_device_open

};

//定义Stub入口

//注意必须使用:

//1。hw_module_t继承类

//2。必须使用HAL_MODULE_INFO_SYM这个名字

const struct led_module_t HAL_MODULE_INFO_SYM = {

common: {

tag: HARDWARE_MODULE_TAG,

version_major: 1,

version_minor: 0,

id: LED_HARDWARE_MODULE_ID,//模块ID,上层的

Service通过这个ID应用当前Stub

name: "Sample LED Stub",

author: "The Mokoid Open Source Project",

methods: &led_module_methods,//入口函数管理结构体

}

/* supporting APIs go here */

};

4.1.2.2 Open & Close函数定义

static int led_device_open(const struct hw_module_t* module, const

char* name, struct hw_device_t** device)

{

struct led_control_device_t *dev;

//建立hw_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;//common是hw_device_t结构体 if((fd=open("/dev/led",O_RDWR))==-1)//将fd初始化为设备文件 { LOGE("LED open error"); }

else//这里没有失败后的处理,只是记录Log,这是Bug

LOGI("open ok");

success:

return 0;

}

int led_device_close(struct hw_device_t* device)

{

struct led_control_device_t* ctx = (struct

led_control_device_t*)device;//强制转化,得到设备指针

if (ctx) {

free(ctx);//释放

}

close(fd);

return 0;

}

4.1.2.3 操作接口定义

#define GPG3DAT2_ON 0x4800

#define GPG3DAT2_OFF 0x4801

int led_on(struct led_control_device_t *dev, int32_t led)

{

//led参数可以用来控制打开哪个LED,但是没用到

LOGI("LED Stub: set %d on.", led);

ioctl(fd,GPG3DAT2_ON,NULL);//向设备驱动发送请求

return 0;

}

int led_off(struct led_control_device_t *dev, int32_t led)

{

//led参数可以用来控制打开哪个LED,但是没用到 LOGI("LED Stub: set %d off.", led); ioctl(fd,GPG3DAT2_OFF,NULL); //向设备驱动发送请求 return 0;

}

4.2 Framework

本层共包括两个java包,一个是com.mokoid.server.LedService,另一个是mokiod.hardware.LedManager。这两个包编译在同一个jar文件中:mokoid.jar 另外还有一个/system/lib/libmokoid_runtime.so文件供JNI接口使用。详见下面jni一节。

这样上层的应用程序就可以通过调用LedServer或者LedManager来实现调用HAL的Stub了。

注意:这个jar文件需要通过xml描述文件注册到Android系统中。否则上层的应用程序会找不到需要的服务。

即:拷贝frameworks\base\service\com.mokoid.server.xml到目标系统的system/etc/permissions/目录下

4.2.1 Make file (frameworks\base\Android.mk)

……

LOCAL_SRC_FILES := \

$(call all-subdir-java-files) #编译子目录下的所有Java文件

LOCAL_MODULE_TAGS := eng

LOCAL_MODULE := mokoid #编译结果为mokoid.jar

# AIDL

LOCAL_SRC_FILES += \

core/java/mokoid/hardware/ILedService.aidl #接口定义文件

……

4.2.2 Service

本层负责通过JNI接口将C层的接口映射到Java层。其中C部分的内容以libmokoid_runtime.so文件存在,java部分以com.mokoid.server.LedServer的形式存在(编译在mokiod.jar文件中,见本章开始处Makefile的说明)

4.2.2.1 jni (com_mokoid_server_LedService.cpp)

4.2.2.1.1 JNI_OnLoad 入口函数

在Android中,JNI部分采用JNI_OnLoad作为入口的方式实现,

即:所有的C实现的so文件以JNI_OnLoad为入口。

/*

*

* This is called by the VM when the shared library is first

loaded.

*/

jint JNI_OnLoad(JavaVM* vm, void* reserved) {

JNIEnv* env = NULL;

jint result = -1;

LOGI("JNI_OnLoad LED");

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

JNI_OK) {//获取当前的VM的环境,保存在env变量中,稍候通

过这个变量

LOGE("ERROR: GetEnv failed\n");

goto fail;

}

assert(env != NULL);

if (registerMethods(env) != 0) {//自己写的函数,向

当前JAVA环境中注册接口

LOGE("ERROR: PlatformLibrary native

registration failed\n");

goto fail;

}

/* success -- return valid version number */

result = JNI_VERSION_1_4;

fail:

return result;

}

4.2.2.1.2 registerMethods 注册函数

static int registerMethods(JNIEnv* env) {

static const char* const kClassName =

"com/mokoid/server/LedService";

jclass clazz;

/* look up the class */

clazz = env->FindClass(kClassName);//查找被注册的类

if (clazz == NULL) {

LOGE("Can't find class %s\n",

kClassName);

return -1;

}

/* register all the methods */

if (env->RegisterNatives(clazz, gMethods,

sizeof(gMethods) /

sizeof(gMethods[0])) != JNI_OK)//向类中注册本SO中Native的接口,接口定义在gMethods数组中

{

LOGE("Failed registering methods for %s\n",

kClassName);

return -1;

}

/* fill out the rest of the ID cache */

return 0;

}

gMethods的定义如下:

/*< …… 此处隐藏:3794字,全部文档内容请下载后查看。喜欢就下载吧 ……

Android GPIO LED 驱动与HAL分析(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wenku/42162.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)