Android GPIO LED 驱动与HAL分析(2)
};
/**********************************************/
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的定义如下:
相关推荐:
- [小学教育]四年级综合实践活动课《衣物的洗涤》教
- [小学教育]2014半年工作总结怎么写
- [小学教育]20世纪外国文学专题综合试题及答案
- [小学教育]TS_1循环使用催化丙烯环氧化反应研究
- [小学教育]最实用的考勤签到表(上下班签到表)
- [小学教育]气候与生态建筑——以新疆民居为例
- [小学教育]二人以上股东有限责任公司章程参考样本
- [小学教育]2014届第一轮复习资料4.1,3美好生活的
- [小学教育]土方开挖、降水方案
- [小学教育]手绘儿童绘本《秋天的图画》(蜡笔)
- [小学教育]2002级硕士研究生卫生统计学考试试题
- [小学教育]环保装备重点发展目录
- [小学教育]金蝶K3合并报表培训教材
- [小学教育]岩浆岩试题及参考答案
- [小学教育]知之深爱之切学习心得
- [小学教育]第十二章 蛋白质的生物合成
- [小学教育]Chapter 2-3 Solid structure and basi
- [小学教育]市政道路雨季专项施工方案
- [小学教育]中国海洋大学2012-2013学年第二学期天
- [小学教育]教育心理学第3章-学习迁移
- 浅谈深化国企改革中加强党管企业
- 2006年中国病理生理学会学术活动安排
- 设计投标工作大纲
- 基于ARP的网络攻击与防御
- 2016届湖北省七市(州)教科研协作体高三
- Google_学术搜索及其检索技巧
- 2019-2020学年七年级地理下册6.3美洲教
- 城市道路可研报告
- 【名师指津】2012高考英语 写作基础技
- 6级知识点培训北京师范大学《幼儿智趣
- 注册会计师会计知识点:金融资产
- 新安装 500 kV 变压器介损分析与判断
- PS2模拟器PCSX2设置及使用教程.
- 医院药事管理与药剂科管理组织机构
- {PPT背景素材}丹巴的醉人美景,免费,一
- NAS网络存储应用解决方案
- 青海省西宁市六年级上学期数学期末考试
- 测量管理体系手册依据ISO10012:2003
- 洞子小学培养骨干教师工作计划
- 浅谈《牛津初中英语》的教材特点及教学




