1.现象展示: 2
2.app源码: 3
3.JNI源码: 4
4.HAL源码: 5
5.硬件驱动源码: 6
6.编译: 8
1.现象展示:
点击按钮,关灯:
硬件现象:
点击按钮,开灯:
硬件现象:
2.app源码:
led_srv = new LedService();
btn0 = (ImageButton)this.findViewById(R.id.imageButton1);
this.btn0.setOnClickListener(new OnClickListener(){
public void onClick(View v){
String title = new String();
if (iflag) {
title = led_srv.set_on(1);
setTitle(title);
btn0.setImageResource(R.drawable.bulb_on);
iflag = false;
} else {
title = led_srv.set_off(1);
setTitle(title);
btn0.setImageResource(R.drawable.bulb_off);
iflag = true;
}
}
});
3.JNI源码:
....
static const JNINativeMethod gMethods[] = {
{"_init", "()Z",
(void*)led_init},
{ "_set_on", "(I)I",
(void*)led_setOn },
{ "_set_off", "(I)I",
(void*)led_setOff },
{ "_get_count", "()I",
(void*)get_count },
};
static int registerMethods(JNIEnv* env) {
static const char* const kClassName =
"com/farsight/service/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)
{
LOGE("Failed registering methods for %s\n", kClassName);
return -1;
}
/* fill out the rest of the ID cache */
return 0;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = -1;
LOGI("JNI_OnLoad");
 nbsp; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed\n");
goto fail;
}
assert(env != NULL);
if (registerMethods(env) != 0) {
LOGE("ERROR: PlatformLibrary native registration failed\n");
goto fail;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
fail:
return result;
}
....
4.HAL源码:
...
static int led_device_open(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
struct led_control_context_t *context;
LOGD("led_device_open");
context = (struct led_control_context_t *)malloc(sizeof(*context));
memset(context, 0, sizeof(*context));
context->device.common.tag= HARDWARE_DEVICE_TAG;
context->device.common.version = 0;
context->device.common.module= module;
context->device.common.close = led_device_close;
context->device.set_on= led_set_on;
context->device.set_off= led_set_off;
context->device.getcount_led = led_getcount;
*device= (struct hw_device_t *)&(context->device);
if((fd=open("/dev/led",O_RDWR))==-1)
{
LOGI("open error");
// exit(1);
}else
LOGI("open ok\n");
return 0;
}
static struct hw_module_methods_t led_module_methods = {
open: led_device_open
};
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,
name: "led HAL module",
author: "farsight",
methods: &led_module_methods,
},
};
...
5.硬件驱动源码:
...
static int simple_release(struct inode *node, struct file *file)
{
return 0;
}
static void simple_setup_cdev(struct cdev *dev, int minor,
struct file_operations *fops)
{
int err, devno = MKDEV(simple_major, minor);
cdev_init(dev, fops);
dev->owner = THIS_MODULE;
dev->ops = fops;
err = cdev_add (dev, devno, 1);
if (err)
printk (KERN_NOTICE "Error %d adding simple%d", err, minor);
}
static struct file_operations simple_remap_ops = {
.owner = THIS_MODULE,
.open = simple_open,
.release = simple_release,
.read = simple_read,
.write = simple_write,
.unlocked_ioctl = simple_ioctl,
};
static struct cdev SimpleDevs;
static struct class *my_class;
static int simple_init(void)
{
int result;
dev_t dev = MKDEV(simple_major, 0);
if (simple_major)
result = register_chrdev_region(dev, 1, "simple");
else {
result = alloc_chrdev_region(&dev, 0, 1, "simple");
simple_major = MAJOR(dev);
}
if (result < 0) {
printk(KERN_WARNING "simple: unable to get major %d\n", simple_major);
return result;
}
if (simple_major == 0)
simple_major = result;
simple_setup_cdev(&SimpleDevs, 0, &simple_remap_ops);
printk("Led simple simple device installed, with major %d\n", simple_major);
my_class= class_create(THIS_MODULE, "simple");
device_create(my_class, NULL, MKDEV(simple_major, 0),
NULL, "led");
return 0;
}
static void simple_cleanup(void)
{
cdev_del(&SimpleDevs);
unregister_chrdev_region(MKDEV(simple_major, 0), 1);
device_destroy(my_class,MKDEV(simple_major,0));
printk("led device uninstalled\n");
}
module_init(simple_init);
module_exit(simple_cleanup);
....
6.编译:
(1)编译驱动
工具链:lichee/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi-
注意:内核源码是“lichee/linux-3.4”.
执行make编译完成后生成led.ko
(2) 编译JNI代码
编译前的准备工作:
①source ./build/envsetup.sh
②lunch (选择15)
进入源码目录下,执行mm命令。
“install”指定出生成JNI库libled_runtime.so的位置。
(3)编译HAL源码
编译前的准备工作:
①source ./build/envsetup.sh
②lunch (选择15)
进入源码目录下,执行mm命令。
“install”指定出生成HAL库led.defaut.so的位置
(4)apk编译
通过eclipse自动生成apk即可。