从内核LED驱动到APK应用实例(旧HAL架构 )
来源:互联网 发布:网络歌曲你是否爱过我 编辑:程序博客网 时间:2024/06/01 07:48
一、内核驱动
myled/
├── Kconfig
├── Makefile
└── led.c
/*led.c*/#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/io.h>#include <linux/highmem.h>#include <linux/ioport.h>#include <linux/platform_device.h>#include <linux/miscdevice.h>#define GPMBASE 0x7f008000#define GPMCON (GPMBASE + 0x820)#define GPMDAT (GPMBASE + 0x824)#define LED_ON 1111#define LED_OFF 2222static void *gpio_virt;static struct resource *conf_res, *data_res;static int led_open(struct inode *inode, struct file *filp){ int ret = 0; return ret;}static long led_ioctl(struct file *filp, unsigned int cmd, unsigned long args){ int ret = 0; switch (cmd) { case LED_ON: iowrite32(ioread32(GPMCON) & ~0xffff, GPMCON); iowrite32(ioread32(GPMCON) | 0x1111, GPMCON); iowrite32(ioread32(GPMDAT) | ~0xF, GPMDAT); break; case LED_OFF: iowrite32(ioread32(GPMCON) & ~0xffff, GPMCON); iowrite32(ioread32(GPMCON) | 0x1111, GPMCON); iowrite32(ioread32(GPMDAT) | 0xf, GPMDAT); break; } return ret;}static int led_release(struct inode *inode, struct file *filp){ int ret = 0; return ret;}struct file_operations ledops = { .open = led_open, .unlocked_ioctl = led_ioctl, .release = led_release,};struct miscdevice led_misc = { .name = "led_misc", .minor= 100, .fops = &ledops,};static int led_probe(struct platform_device *dev){ int ret = -1; conf_res = request_mem_region(GPMCON, 4, "myled_conf"); if (conf_res == NULL) { goto ERR0; } data_res = request_mem_region(GPMDAT, 4, "myled_dat"); if (data_res == NULL) { goto ERR1; } gpio_virt = ioremap(GPMBASE, SZ_4K); if (gpio_virt == NULL) { goto ERR2; } ret = misc_register(&led_misc); if (ret) { goto ERR3; } return ret;ERR3: iounmap(gpio_virt);ERR2: release_resource(data_res);ERR1: release_resource(conf_res);ERR0: return ret;}static int led_remove(struct platform_device *dev){ int ret = 0; misc_deregister(&led_misc); iounmap(gpio_virt); return ret;}static void led_pdev_release(struct device *dev){}struct platform_device led_pdev = { .name = "s3c6410_led", .dev = { .release = led_pdev_release, },};struct platform_driver led_pdrv = { .probe = led_probe, .remove = led_remove, .driver = { .name = "s3c6410_led", }};static int __init led_init(void){ int ret; ret = platform_device_register(&led_pdev); if (ret) { goto ERR0; } ret = platform_driver_register(&led_pdrv); if (ret) { goto ERR1; } return ret;ERR1: platform_device_unregister(&led_pdev);ERR0: return ret;}static void __exit led_exit(void){ platform_device_unregister(&led_pdev); platform_device_unregister(&led_pdev);}module_init(led_init);module_exit(led_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Micky Liu");
/*Makefile*/obj-$(CONFIG_MY_LED_TEST) = myled.o
/*Kconfig*/config MY_LED_TEST tristate "MY_LED_TEST" ---help--- It's my led test.
myled是放在android-kernel-*.*.*/drivers/目录下面的。
在drivers目录下Makefile中加入一行:
obj-$(CONFIG_MY_LED_TEST) += myled/在drivers目录下的Kconfig中加入一行:
source "drivers/myled/Kconfig"
接着在内核根目录下make menuconfig,找到刚才的MY_LED_TEST选项,设置成*号,然后保存,make。OK,现在LED驱动已经编译进内核了。
2、编写JNI代码
jni
├── Android.mk
└── led.c
/*led.c*/#include <jni.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <errno.h>#define LOG_TAG "LED_JNI"#undef LOG#include <utils/Log.h>#define LED_ON 1111#define LED_OFF 2222static jboolean turn_led(int cmd){ int fd, ret = -1; fd = open("/dev/led_misc", O_RDWR); if (fd < 0) { goto ERR0; } ret = ioctl(fd, cmd); close(fd); if (ret) { LOGE("ioctl /dev/led_misc failed!"); goto ERR0; } return JNI_TRUE;ERR0: return JNI_FALSE;}/* * Class: com_lhw_framework_led_Led * Method: turnOn * Signature: ()Z */JNIEXPORT jboolean JNICALL com_lhw_led_Led_turnOn(JNIEnv *env, jobject thiz){ LOGD("LED ON!"); return turn_led(LED_ON);}/* * Class: com_lhw_framework_led_Led * Method: turnOff * Signature: ()Z */JNIEXPORT jboolean JNICALL com_lhw_led_Led_turnOff(JNIEnv *env, jobject thiz){ LOGE("LED OFF!"); return turn_led(LED_OFF);}static JNINativeMethod gMethods[] = { {"turnOn", "()Z", (void *)com_lhw_led_Led_turnOn}, {"turnOff", "()Z", (void *)com_lhw_led_Led_turnOff},};static int register_com_lhw_led_Led(JNIEnv *env) { jclass clazz = (*env)->FindClass(env, "com/lhw/framework/led/Led"); return (*env)->RegisterNatives(env, clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));}jint JNI_OnLoad(JavaVM *vm, void *reserved){ JNIEnv *env = NULL; jint result = -1; if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) { LOGE("ERROR: GetEnv failed!\n"); goto bail; } if (register_com_lhw_led_Led(env) < 0) { LOGE("ERROR: LED_JNI native registration failed!\n"); goto bail; } result = JNI_VERSION_1_4;bail: return result;}
/*Android.mk*/LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := led.cLOCAL_MODULE:= libled_jniLOCAL_MODULE_TAGS:= libled_jniLOCAL_PRELINK_MODULE:= falseLOCAL_C_INCLUDES:= $(JNI_H_INCLUDE)LOCAL_SHARED_LIBRARIES:= \libc \libutilsinclude $(BUILD_SHARED_LIBRARY)
接着使用在Android源码目录下使用mmm命令编译.
mmm /home/administrator/workspace/android_test/led/ljni
cp system/lib/libled_jni.so /nfsroot1/system/lib/
3、framework jar包
framework/
├── Android.mk
└── com
└── lhw
└── framework
└── led
└── Led.java
/*Led.java*/package com.lhw.framework.led;import android.util.Log;/* * Led 操作Jar库 * @author Micky Liu * @email sglazelhw@126.com */public class Led { static { System.loadLibrary("led_jni"); } public native boolean turnOn(); public native boolean turnOff(); /*开灯*/ public boolean turnLedOn() { return turnOn(); } /*关灯*/ public boolean turnLedOff() { return turnOff(); }}
/*Android.mk*/LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= $(call all-subdir-java-files)LOCAL_MODULE:= ledLOCAL_MODULE_TAGS:= ledLOCAL_JAVA_LIBRARIES:=LOCAL_STATIC_JAVA_LIBRARIES :=include $(BUILD_JAVA_LIBRARY)
接着使用在Android源码目录下使用mmm命令编译.
mmm /home/administrator/workspace/android_test/led/framework
cp system/framework/led.jar /nfsroot1/system/framework/
4、APK应用
使用如下命令创建Android应用:
android create project -t 1 -k com.lhw.led_test -a MainActivity -p ./apk
led_apk
├── AndroidManifest.xml
├── Android.mk
├── bin
├── default.properties
├── libs
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── layout
│ │ └── main.xml
│ └── values
│ └── strings.xml
└── src
└── com
└── lhw
└── led_test
└── MainActivity.java
/*MainActivity.java*/package com.lhw.led_test;import android.app.Activity;import android.os.Bundle;import android.widget.Button;import android.widget.TextView;import android.view.View;import android.view.View.OnClickListener;import com.lhw.framework.led.Led;public class MainActivity extends Activity{ private Button btnOn; private Button btnOff; private TextView tvState; private View.OnClickListener listener; private Led led; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnOn = (Button) findViewById(R.id.btn_on); btnOff = (Button) findViewById(R.id.btn_off); tvState = (TextView) findViewById(R.id.tv_state); listener = new MyListener(); btnOn.setOnClickListener(listener); btnOff.setOnClickListener(listener); led = new Led(); } class MyListener implements View.OnClickListener { public void onClick(View v) { switch(v.getId()) { case R.id.btn_on: if(led.turnLedOn()) { tvState.setText("LED ON"); } break; case R.id.btn_off: if(led.turnLedOff()) { tvState.setText("LED OFF"); } break; default: break; } } }}
<!-- main.xml --><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tv_state" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_on" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/turn_on" /> <Button android:id="@+id/btn_off" android:layout_marginLeft="10dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/turn_off" /></LinearLayout>
<!-- AndroidManifest --><?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lhw.led_test" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_name" android:icon="@drawable/icon"> <uses-library android:name="led" /> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
/*Android.mk*/LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= $(call all-subdir-java-files)LOCAL_PACKAGE_NAME:= led_testLOCAL_JAVA_LIBRARIES:= led LOCAL_STATIC_JAVA_LIBRARIES:=include $(BUILD_PACKAGE)
接着使用在Android源码目录下使用mmm命令编译.
mmm /home/administrator/workspace/android_test/led/led_apk
cp system/framework/led_apk.apk /nfsroot1/system/app/
===================================================
到这,APK-->> framework -->> JNI -->> Kernel Driver,整个过程都已完成。可以从Android应用里面控制LED等的亮和灭了。
在这个过程中,遇到很多问题,这里小记一下:
一、在超级中端里不能执行system/bin下的一些命令,解决方法:
修init.rc文件
service console /system/bin/sh
console
disabled
user sh
group log
修改后设置:
service console /system/bin/sh
console
disabled
user root
group log
二、在JNI里打开/dev/下的设备文件报没权限错误,解决办法:
方法一、进入高级终端,chmod 777 /dev/led_misc
方法二、在init.rc中加入这么一行:chmod 777 /dev/led_misc
- 从内核LED驱动到APK应用实例(旧HAL架构 )
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(HAL篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(HAL篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(驱动篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(驱动篇)
- 从 HAL层 到java应用层重写mini6410 led功能
- 从HAL层到java应用层重写mini6410 led功能
- 从HAL层到java应用层重写mini6410 led功能
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(JNI篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(应用程序篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(总结篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(JNI篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(应用程序篇)
- TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(总结篇)
- TQ210搭载Android4.0.3系统构建之BEEP从驱动到HAL到JNI到应用程序(上层应用篇)
- Android HAL实例解析LED
- Android HAL实例解析---LED
- s5p4418 android 驱动 hal 应用之led 串口 rs485 can总线应用(JNI层)
- Web系统下Office文档的处理 之OpenXml应用分类资料
- iPhone SDK新手必读
- 软件外包的形式与质量控制
- 从心里彻底告别大一
- Excel 2007 如何选中图形
- 从内核LED驱动到APK应用实例(旧HAL架构 )
- gzip 和 gunzip 的使用
- hdu 3835 概率DP
- JQuery例子
- 希尔排序
- Oracle中dual表的用途介绍
- HTTP请求
- Android ApiDemos示例解析(113):Views->Expandable Lists->2. Cursor(People)
- 正则表达式学习笔记(6)向前查找和向后查找