package com.quantum.qfnu; import android 主activity.app.Activity; import android 主activity.app.AlertDialog; import androi

Hi,这是的腾讯微博,立即登录并收听,别错过TA的精彩内容!
在他的广播中搜索
已为您隐藏部分来自游戏、活动、第三方应用等的营销和广告微博,您可查看
Copyright & 1998 - 2016 Tencent. All Rights ReservedAndroid通过JNI调用驱动程序(完全解析实例)
android LED
Android通过JNI调用驱动程序(完全解析实例)
android LED
版权声明:本文为博主原创文章,未经博主允许不得转载。
要达到的目的:android系统中,用JAVA写界面程序,调用jni中间库提供的接口,去操作某个驱动节点,实现read,writer ioctl等操作!这对底层驱动开发人员是很重要的一个调试通道,也是android 系统下提供一些特殊功能接口的方法!
本文前提:我们假设已经写了一个驱动程序,它是控制LED的亮灭的,并且创建了一个节点:/dev/vib,也就是通过open这个vib节点,可以read/write/ioctl 操作驱动程序实现LED灯的亮灭控制,具体可以看我另一篇博文《》
开发环境 1、ubuntu下的NDK编译环境,2、Esclips开发环境
一、编写JNI模块
当安装好NDK编译环境后,会在它的目录下找到sample目录,它里面有一些例子,可以参考这些例子来写我们自已的模块。
1、 source文件夹下,新建“LEDSJNI”文件夹。
2、 Source/LEDSJNI/jni/目录下,新建“vib-jni.c”
vib-jni.c文件
#include &string.h&#include &jni.h&#include &fcntl.h& /*包括文件操作,如open() read() close() write()等*///----for output the debug log message#include &android/log.h&#define
"vib-jni"#define
__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define
__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)#define
DEVICE_NAME
"/dev/vib"
//device point#define
VIB_ON 0x11#define
VIB_OFF 0x22intjstringJava_com_auly_control_vibClass_stringFromJNI( JNIEnv* env,
jobject thiz ){
return (*env)-&NewStringUTF(env, "Hello from JNI--Peter for vib!");//打印字符串} jint
Java_com_auly_control_vibClass_Init( JNIEnv*
LOGE("vibClass_Init() /n");
fd = open(DEVICE_NAME,O_RDWR);//打开设备
LOGE("vibClass_Init()-& fd = %d
if(fd == -1)
LOGE("open device %s error /n ",DEVICE_NAME);//打印调试信息
}} jint Java_com_auly_control_vibClass_IOCTLVIB( JNIEnv*
env, jobject
thiz, jint controlcode ){
int CTLCODE =
LOGE("IOCTLVIB() = %x --vibClass_IOCTLVIB /n",CTLCODE);
switch(CTLCODE)
case VIB_ON:
ioctl(fd,VIB_ON);//调用驱动程序中的ioctrl接口,把命令VIB_ON传下去,实现硬件操作
case VIB_OFF:
ioctl(fd,VIB_OFF);//调用驱动程序中的ioctrl接口,把命令VIB_OFF传下去,实现硬件操作
default:break;
return 1; }
3、相同目录下的新建Android.mk如下
Android.mk文件
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE
:= vib-jniLOCAL_SRC_FILES := vib-jni.cLOCAL_CFLAGS
:= -WerrorLOCAL_LDLIBS
:= -llog -lGLESv2 //__android_log_print 函数include $(BUILD_SHARED_LIBRARY)
可以看到,主要是修改LOCAL_SRC_FILES指向源文件的名称!
还有一点很重要,如果要使用调试LOG 打印,也就是__android_log_print 函数。要在LOCAL_LDLIBS中添加-llog,如上面的Android.mk所示。
4、编译JNI模块
#cd /home/workspace/android-ndk-r4b/sources/LEDSJNI
进到刚才写的JNI目录
#ndk-build
编译JNI,编译成功后,会在LEDSJNI文件夹下生成libs和obj两个文件夹,并在
LEDSJNI/libs/armeabi下得到目标文件libvib-jni.so
(目前LEDSJNI文件夹只有3个目录jni,libs,obj)
二、JAVA程序
1、Eclipse新建工程
拷贝LEDSJNI目录到Windows下,例如C盘下。然后在它里面新建Eclipse 工程。
新键工程后,
如果出现如下错误:
ERROR: Unable to open class file C:/LEDSJNI/gen/com/auly/control/R.java: No such file or directory
解决方法如下:
对着该工程鼠标右键 》bulid path 》configure build path》java build path》order and Export
把里面的android 2.1勾上,Build project,就OK了
然后 Run as & Android application,就会出现android的模拟器了,里面跑个helloworld出来。
2、加入button和文本输出
程序到上面为止代码是ADT自动生成的,似乎与我们一点关系也没有。那我们来改一下代码,因为我们调用JNI接口是为了访问驱动程序操作硬件的,例如写,读,打开LED,关闭LED等等,由按钮触发的动作。
第一步是,增加两个Button,,在main.xml里描述一下:打开Res & layout& main.xml 文件
&?xml version="1.0" encoding="utf-8"?&&LinearLayout xmlns:android="/apk/res/android"
androidrientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&&TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/& &Button android:id="@+id/led_on"/*这表示需要一个唯一的UID来作为Button的ID,它的引用名是led_on。*/
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/LEDon"&/*表示这个按钮的文本是来源于另一个资源描述文件strings.xml里的文:字资源LEDon */
&requestFocus/&&/Button& &Button android:id="@+id/led_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/LEDoff"&
&requestFocus/& &/Button& &/LinearLayout&
实际代码中,把注释去掉,否则编译不过的。
3、加入输出字符串资源
工程 & values & strings.xml 文件
&?xml version="1.0" encoding="utf-8"?&
&resources&
&string name="hello"&Led 控制程序&/string&
&string name="app_name"&LEDAPP&/string&
&string name="LEDon"&打开LED&/string&
&string name="LEDoff"&关闭LED&/string&
&/resources&
上面的”打开LED”等资源,就是用在按钮上显示出来的字符串
经过上面的修改,现在程序界面上,已经有如下效果了
鼠标右键工程名&Run as & Android application 运行程序。
4、加入按钮对应的动作
“打开LED”按扭:调用JNI的IOCTLVIB(VIB_ON);
“关闭LED”按钮:调用JNI的 IOCTLVIB(VIB_OFF);
在LEDAPP & src & com.auly.control & vibrator.java文件
package com.auly./**定义头文件*/import android.widget.TextVimport android.app.Aimport android.os.Bimport android.view.Vimport android.widget.Bimport android.widget.EditTimport android.widget.TextVimport android.util.Limport android.app.Aimport android.os.Bpublic class vibrator extends Activity {
/** 定义变量 */
VIB_ON = 0x11;
VIB_OFF = 0x22;
vibClass mvibC/**定义类*/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); /**----------------初始化------------- */
mvibClass = new vibClass();/*声明类*/
mvibClass.Init(); //调用JNI库里的初始化函数 /**----------------按钮:打开LED------------- */
Button btn1 = (Button)findViewById(R.id.led_on);/*这里用到的ID,就是在main.xml里定义的 led_on*/
btn1.setOnClickListener(new View.OnClickListener()
public void onClick(View v) /**当按钮按下*/
mvibClass.IOCTLVIB(VIB_ON);
});/**----------------按钮:关闭LED------------- */
Button btn2 = (Button)findViewById(R.id.led_off);/*声明按钮,id main.xml里有定义*/
btn2.setOnClickListener(new View.OnClickListener()
public void onClick(View v) /**当按钮按下*/
mvibClass.IOCTLVIB(VIB_OFF);
如果在保存时遇到说 save problems,无法保存,请先复制上面的代码,然后,关闭vibrator.java,提示保存时选不保存,然后在左边资源窗中再次双击打开该文件,把几日才复制下来的内容,粘贴上去,一般就能正常保存,不知道是不是Eclipse的不稳定造成的。
5、添加类vibClass
鼠标右键com.auly.control & new & Class
Finish后,在/src/com/auly/control/得到如下的类文件
vibClass.java
package com.auly./*Class for Vibrator --peter*/public class vibClass {
System.loadLibrary("vib-jni");/*加载JNI库*/
/*声明 函数*/
public static native String stringFromJNI();/*输出字符串
对应于JNI里面的
jstring Java_com_auly_control_vibClass_stringFromJNI( JNIEnv* env,jobject thiz )
public static native int Init();/*初始化函数,对应于JNI里面的
jint Java_com_auly_control_vibClass_Init( JNIEnv*
public static native int IOCTLVIB(int controlcode);
/*IO CTRL 接口
* 对应于JNI里的 jint Java_com_auly_control_vibClass_IOCTLVIB( JNIEnv*
env, jobject
thiz, jint controlcode ) */}
三、 编译运行
鼠标右键工程名,弹出菜单,选择 Run as & Android Application 就可以看到编译过程,编译完成后,会自动调用android模拟器,看到如下效果
安装到开发板:
在C:/LEDSJNI目录下,会看到bin文件夹,里面的LEDAPP.apk就是这个程序的安装文件,可以把它安装的开发板上,运行本程序,看控制开发板上的LED灯的效果。
1、开发板上跑的kenel就已经把了LED驱动编译在里面了,
可以参考《android驱动例子(LED灯控制)》
2、开发板android跑起来后,PC机打开串口工具例如DNW,打开与开发板连接的COM口,然后敲打回车,就会在终端里看到“#”并有光标,表面进入了开发板的命令行终端,
输入命令:
#chmod 777 /dev/vib
&&&&& 这是为了使得vib这个节点可以被我们写的JNI操作,不然会open失败的,因为APK安装的JNI模块,权限不够,这个节点是我们的LED驱动生成的控制节点。
也可以在android文件系统yaffs编译时,通过init.rc 文件来实现这个操作,就是在该文件里随便一行,写上面的命令行,启动时会自动执行!这样就不用手动的改变该节点的属性了。
3、拷贝LEDAPP.apk到开发板上,通过安装工具把它安装到开发板上,如果不会安,可以GOOGLE一下,
4、运行程序,就能按程序上的近钮来控制开发板上的LED亮灭了!
要学好嵌入式,还是建议买一个开发板,因为在枯燥学习中,要实践才会记忆深刻,而且,在看到自已学的知道能做出一些功能,会很有成就感,更能积累信心往深处学。例如学驱动开发,能在开发板上做出一个应用,调用自已写的驱动程序,控制LED灯的亮灭,这就很能鼓励自已,让自已更有兴趣往下学,这样学习来会更快!
推荐下面4款,你可以根据你的经济能力来选一个
1、高级嵌入式开发板 ARM-A8内核,价格在
(代码开放度高,XBOOT很牛) &&
(友善的板子,有沉淀)
2、入门级嵌入式开发板 ARM11内核 &,价格在500~650之间
&& &(友善之臂经典之作) & &&
&& &(特点是支持WINCE7.0)
可以去风火轮团队的店里看一下,在他们那里买板有个好处,他们提从更周到的技术支持
风火轮技术开发团队 &
官方淘宝店:
===============================================================================================
本例子,讲述在android2.1上完全自已开发一个驱动去控制硬件口并写应用测试该驱动,通过这样一个例子,解析android下的驱动开发流程的应用调用流程,可以说是很好的入门引导
要达到的效果:通过android的应用,调用驱动程序,在开发板上控制4个LED的亮灭。
一、硬件原理
如上图,通过4个IO口控制这LED,低电平LED亮,
这4个IO口分别是GPM1, GPM2, GPM3, GPM4,
二、驱动程序
1、在kernel文件夹下的driver目录,新键驱动文件夹
# cd kernel_android_2.6.28.6/drivers
进到开发板的kernel目录,建驱动文件夹
#mkdir ledtest
2、在/driver/ledtest目录下,新建leddriver.c ,leddriver.h , Kconfig, Makefile 等4个文件
leddriver.c
#include &linux/kernel.h&
#include &linux/sched.h&
#include &linux/timer.h&
#include &linux/init.h&
/* For __init/__exit/... */
#include &linux/module.h&
#include &mach/hardware.h&
#include &asm/io.h&
#include &asm/uaccess.h&
#include &plat/gpio-cfg.h&
#include &plat/regs-clock.h&
#include &plat/regs-lcd.h&
#include &plat/regs-gpio.h&
#include &mach/map.h&
#include &linux/gpio.h&
#include &plat/gpio-bank-m.h&
#include &linux/cdev.h&
#include &linux/fs.h& //for register_chrdev()
#include &linux/device.h&
#include &mach/map.h&
#include "leddriver.h"
#include &linux/miscdevice.h&
/* For MODULE_ALIAS_MISCDEV
(WATCHDOG_MINOR) */
#include &linux/watchdog.h&
/* For the watchdog specific items */
#include &linux/fs.h&
/* For file operations */
#define Viberator_MAJOR
//主设备号
#define SCULL_NR_DEVS
#define SCULL_QUANTUM
#define SCULL_QSET
//---do as the GIO driver
#define DEVCOUNT
#define GIO_MINOR
/* GIO minor no. */
static dev_
static struct cdev *cdev_p;
static int openC
//--全局变量------------
int VIB_major
= 97;//we asigment it for test
int VIB_minor = 0;
int VIB_nr_devs = SCULL_NR_DEVS;
int VIB_quantum = SCULL_QUANTUM;
int VIB_qset = SCULL_QSET;
static struct class *vib_dev_
#define GPNCON
S3C64XX_GPNCON
#define GPNDAT
S3C64XX_GPNDAT
#define GPNPUD
S3C64XX_GPNPUD
#define GPMCON S3C64XX_GPMCON
#define GPMDAT
S3C64XX_GPMDAT
#define GPMPUD S3C64XX_GPMPUD
#define VIB_ON 0x11
VIB_OFF 0x22
static const struct file_operations GPIO_Viberator_ctl_ops={
= THIS_MODULE,
= GPIO_VIB_open,
=GPIO_VIB_read,
=GPIO_VIB_write,
= GPIO_VIB_ioctl,
=GPIO_VIB_release,
ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t * f_ops)
char sdas[5]={1,3,8,1,6};
status = 5;
unsigned long
missing = copy_to_user(buf, sdas, status);
if (missing == status)
status = -EFAULT;
status = status -
printk(" GPIO_VIB_read = %d ,count = %d/r/n",status,count);
gpio_direction_output(S3C64XX_GPM(3), 0);//
ssize_t GPIO_VIB_write (struct file * file,const char * buf, size_t count,loff_t * f_ops)
unsigned long
char inbuffer[512]={0};
missing = copy_from_user(inbuffer, buf, count);
printk(" GPIO_VIB_write count = %d missing =%d /r/n",count,missing);
gpio_direction_output(S3C64XX_GPM(3), 1);//
for(i=0;i&i++)
printk("Write:inbuffer[%d]=%d /r/n",i,inbuffer[i]);
//ssize_t GPIO_VIB_ioctl(struct inode *
inode,struct file * file,unsigned int cmd, long data)
static int GPIO_VIB_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
printk(KERN_ERR"VIB:GPIO_VIB_ioctl --CMD=%x /n",cmd);
switch(cmd)
case VIB_ON:
gpio_direction_output(S3C64XX_GPM(1), 0);//
gpio_direction_output(S3C64XX_GPM(2), 0);//
gpio_direction_output(S3C64XX_GPM(3), 0);//
gpio_direction_output(S3C64XX_GPM(4), 1);//
printk(KERN_ERR"VIB:GPIO_VIB_ioctl --VIB_ON/n");
case VIB_OFF:
printk(KERN_ERR"VIB:GPIO_VIB_ioctl --VIB_OFF/n");
gpio_direction_output(S3C64XX_GPM(1), 1);//
gpio_direction_output(S3C64XX_GPM(2), 1);//
gpio_direction_output(S3C64XX_GPM(3), 1);//
gpio_direction_output(S3C64XX_GPM(4), 0);//
default:break;
//gpio_free(S3C64XX_GPN(7));
ssize_t GPIO_VIB_open(struct inode * inode,struct file * file)
//MOD_INC_USE_COUNT;
printk("GPIO_VIB_open() /n");
ssize_t GPIO_VIB_release(struct inode * inode, struct file * file)
// MOD_DEC_USE_COUNT;//模块数减1
printk("GPIO_VIB_release() /n");
static int GPIO_VIB_CTL_init(void)
= -ENODEV;
printk("---------------------------------------------- /r/n");
//初始化端口
s3c_gpio_cfgpin(S3C64XX_GPM(1), S3C_GPIO_SFN(1));//GPM1 output
s3c_gpio_cfgpin(S3C64XX_GPM(2), S3C_GPIO_SFN(1));//GPM2 output
s3c_gpio_cfgpin(S3C64XX_GPM(3), S3C_GPIO_SFN(1));//GPM3 output
s3c_gpio_cfgpin(S3C64XX_GPM(4), S3C_GPIO_SFN(1));//GPM4 output
#if 1 /*静态方式注册驱动*/
ret = register_chrdev(Viberator_MAJOR, "viberator", &GPIO_Viberator_ctl_ops);
if (ret & 0) {
printk(KERN_ERR "VIB: unable to get major %d/n", ret);
//创建class
vib_dev_class = class_create(THIS_MODULE, "viberator");
if (IS_ERR(vib_dev_class)) {
unregister_chrdev(Viberator_MAJOR, "capi20");
return PTR_ERR(vib_dev_class);
//创建节点,
device_create(vib_dev_class, NULL, MKDEV(Viberator_MAJOR, 0), NULL, "vib");
// create a point under /dev/class/vib
//通过上面这两步,驱动加载后,就会在/dev/class/下面生成vib节点,应用程序可以像操作文件那样操作这个节点,通过open ,write,read 等函数操作,详情可以看后面的应用示例程序。
#if 0/* 注册动态 */
if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "vibrate")) & 0)
printk(KERN_ERR
"VIB: Couldn't alloc_chrdev_region, error=%d/n",
printk("dev = %d
cdev_p = cdev_alloc();
cdev_p-&ops = &GPIO_Viberator_ctl_
error = cdev_add(cdev_p, dev, DEVCOUNT);
if (error) {
printk(KERN_ERR
"VIB: Couldn't cdev_add, error=%d/n", error);
vib_dev_class = class_create(THIS_MODULE, "vib-dev");
if (IS_ERR(vib_dev_class)) {
res = PTR_ERR(vib_dev_class);
goto out_unreg_
out_unreg_class:
class_destroy(vib_dev_class);
static int __init S3C6410_VIB_init(void)
int ret = -ENODEV;
//调用函数
printk(KERN_ERR "Auly: S3C6410_VIB_init---/n");
ret = GPIO_VIB_CTL_init();
printk(KERN_ERR "Auly: S3C6410_VIB_init--Fail !!!/n");
static void __exit cleanup_GPIO_VIB(void)
//注销设备
devfs_unregister_chrdev(Viberator_MAJOR,"gpio_vib_ctl");
cdev_del(cdev_p);
unregister_chrdev_region(dev, DEVCOUNT);
class_destroy(vib_dev_class);
device_destroy(vib_dev_class, MKDEV(Viberator_MAJOR, 0));
class_destroy(vib_dev_class);
unregister_chrdev(Viberator_MAJOR, "viberator");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Peter first driver");
MODULE_ALIAS_CHARDEV(Viberator_MAJOR, 0);
module_init(S3C6410_VIB_init);
module_exit(cleanup_GPIO_VIB);
leddriver.h文件
leddriver.h文件
ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t * f_ops);
ssize_t GPIO_VIB_write (struct file * file,constchar * buf, size_t count,loff_t * f_ops);
static int GPIO_VIB_ioctl(struct inode *inode,struct file *file,
unsigned int cmd,
unsigned long arg);
ssize_t GPIO_VIB_open(struct inode * inode,struct file * file);
ssize_t GPIO_VIB_release(struct inode * inode,struct file * file);
int GPIO_VIB_CTL_init(void);
Kconfig 文件
Kconfig 文件
config LEDTEST &&tristate "LED test for ARMeasy"
&&default n &&help &&this is a LED driver
for ARMEASY with S3C6410
Makefile文件
Makefile文件
obj-$(CONFIG_LEDTEST)+=leddriver.o
3、在内核配置里菜单里加入本驱动的配置项
达到的效果是,可以通过内核配置来选择是否把本驱动编译进内核里,也就是出现在make menuconfig 后出来的界面里,可以参考9.8章&android添加新驱动方法&
1)在arch/arm/Kconfig文件里 menu "Device Drivers"与 endmenu之间添加
source "drivers/ledtest/Kconfig"
2)在drivers/Kconfig menu "Device Drivers" 和 endmenu之间添加
source "drivers/ledtest/Kconfig"
3)修改/drivers/Makefile文件
Obj-$(CONFIG_LEDTEST) +=ledtest/
4、编译驱动
在kernel目录下,终端输入
#make menuconfig
“Device Drivers” 下面会看到 “LED test for ARMeasy”,选择它,
保存并退出
这样,就会在/drivers/ledtest目录下得到leddrivr.ko文件,它就是驱动目标文件,已级编译进了zImage 里了,只要用这个kernel烧录到开发板,开机就会自动加载本驱动,
PS,如果发现如上编译,没有在ledtest目录下生成leddriver.ko文件,也就是本根没有去编译本驱动,那就把ledtest目录入到/drivers/misc目录下,相应的修改misc下面,然后,在makefile里,不用选直接写成obj-y += leddriver.o,这样强制的包含进去编译。
三、 应用程序(测试驱动)
用C语言写一个应用,测试上面写的驱动是否工作正常,这是一般的驱动开发流程
主要有两个文件:Android.mk和ledtest.c
在$(YOUR_ANDROID)/external/LEDTEST/目录编写ledtest.c文件,
#include &stdio.h&
&stdlib.h& #include &fcntl.h&// contact the open(),close(),read(),write() and so on!
&&#define DEVICE_NAME"/dev/vib"//device point
#define LED_ON &&&&0x11 #define LED_OFF &&&&0x22
int main(int argc,char **argv)
{&&& &&&&int &&&&int &&&&char *i; &&&&printf("\n start gpio_led_driver test \r\n");
&&&&fd = open(DEVICE_NAME,O_RDWR);//Open device ,get the handle
&&&&printf("fd = %d \n",fd);
&&&&if(fd == -1)
//open fail &&&&{ &&&&&&printf("open device %s error \n",DEVICE_NAME);
&&&&} &&&&else &&&&{ &&&&&&&&while(1) &&&&&&&&{ &&&&&&&&&&ioctl(fd,LED_OFF); //call the output function to off LEDs
&&&&&&&&&&sleep(1);//wait 1 second
&&&&&&&&&&ioctl(fd,LED_ON); &&&&&&&&&&sleep(1); &&&&&&&&} &&&&&&&&ret = close(fd);
//close device &&&&&&&&printf("ret = %d \n",ret); &&&&&&&&printf("close gpio_led test \n");
&&&&} &&return 0; }
2、在$(YOUR_ANDROID)/external/ LEDTEST /目录编写Android.mk文件。这是Android Makefile的标准命名,不要更改。Android.mk文件的格式和内容可以参考其他已有的Android.mk文件的写法,针对helloworld程序的Android.mk文件内容如下:
Android.mk
& LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \/par&&&&&hello.c LOCAL_MODULE := ledtestapp include $(BUILD_EXECUTABLE)
注意上面LOCAL_SRC_FILES用来指定源文件;
LOCAL_MODULE指定要编译的模块的名字,下一步骤编译时就要用到;
include $(BUILD_EXECUTABLE)表示要编译成一个可执行文件,如果想编译成动态库则可用BUILD_SHARED_LIBRARY,这些可以在
$(YOUR_ANDROID)/build/core/config.mk查到。
3、 回到Android源代码顶层目录进行编译:
# cd $(YOUR_ANDROID) && make ledtestapp
例如我这里的实际操作是
#cd android2.1
#make ledtestapp
注意make ledtestapp中的目标名ledtestapp就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。编译结果如下
make ledtestapp
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.1-update1
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=ECLAIR
============================================
/bin/bash: line 0: cd: sdk/layoutopt/app/src/resources: No such file or directory
target thumb C: ledtestapp &= external/LEDTEST/ledtest.c
Install: out/host/linux-x86/bin/apriori
Install: out/host/linux-x86/bin/soslim
target Executable: ledtestapp (out/target/product/generic/obj/EXECUTABLES/ledtestapp_intermediates/LINKED/ledtestapp)
target Non-prelinked: ledtestapp (out/target/product/generic/symbols/system/bin/ledtestapp)
target Strip: ledtestapp (out/target/product/generic/obj/EXECUTABLES/ledtestapp_intermediates/ledtestapp)
Install: out/target/product/generic/system/lib/libdl.so
Install: out/target/product/generic/system/lib/libc.so
Install: out/target/product/generic/system/lib/libstdc++.so
Install: out/target/product/generic/system/lib/libm.so
Install: out/target/product/generic/system/bin/ledtestapp
4、如上面的编译结果所示,编译后的可执行文件存放在
out/target/product/generic/system/bin/目录 可执行文件是ledtestapp
5、拷贝ledtestapp可执行文件到T卡,插入开发板
6、开电,在启动进入android的过程中,串口终端 按回车,进入命令行模式
7、拷贝可执行文件到根目录
#cp /sdcard/ledtestapp /
8、执行程序
#./ledtestapp
通过上面的步骤,可以看到开发板上相应的LED在闭,每秒钟闪一次!
发表评论:
TA的最新馆藏[转]&

我要回帖

更多关于 android 主activity 的文章

 

随机推荐