Android版本:2.3.7_r1

Linux内核版本:android-goldfish-2.6.29

本文介绍基于Android系统的C应用程序开发。我们知道,Android应用程序开发使用的是JAVA语言,但有时候我们也需要一些基于命令行的小程序,这些小程序一般使用C语言开发,程序的写法与PC平台的C程序没有区别,但需要把C程序注册到Android系统中,使其能在Android平台上运行。在这篇博客中,我们就写一个基于Android平台的C应用程序,该程序用来访问我们在上篇博客中创建的底层Linux驱动程序example。

创建development/example_test/example_test.c文件,其代码如下:

[cpp] view plain copy print ?
  1. 1#include<stdio.h>
  2. 2#include<unistd.h>
  3. 3#include<fcntl.h>
  4. 4#include<string.h>
  5. 5#include<sys/types.h>
  6. 6#include<sys/stat.h>
  7. 7
  8. 8#defineDEVICE_FILE"/dev/example"
  9. 9
  10. 10intmain(intargc,char*argv[])
  11. 11{
  12. 12intret=0,num=12,val=0,fd=0;
  13. 13
  14. 14fd=open(DEVICE_FILE,O_RDWR);
  15. 15if(fd<0)
  16. 16{
  17. 17printf("opendeviceerror!\n");
  18. 18return-1;
  19. 19}
  20. 20
  21. 21ret=write(fd,&num,sizeof(int));
  22. 22if(ret<0)
  23. 23{
  24. 24printf("writedeviceerror!\n");
  25. 25return-1;
  26. 26}
  27. 27
  28. 28printf("writeval%dtodevice!\n",num);
  29. 29
  30. 30ret=read(fd,&val,sizeof(int));
  31. 31if(ret<0)
  32. 32{
  33. 33printf("readdeviceerror!\n");
  34. 34return-1;
  35. 35}
  36. 36
  37. 37printf("readval=%d\n",val);
  38. 38
  39. 39return0;
  40. 40}
 1#include <stdio.h> 2#include <unistd.h> 3#include <fcntl.h> 4#include <string.h> 5#include <sys/types.h> 6#include <sys/stat.h> 7 8#define DEVICE_FILE "/dev/example" 910int main(int argc, char *argv[])11{12    int ret = 0, num = 12, val = 0, fd = 0;1314    fd = open(DEVICE_FILE, O_RDWR);15    if(fd < 0)16    {17        printf("open device error!\n");18        return -1;19    }2021    ret = write(fd, &num, sizeof(int));22    if(ret < 0)23    {24        printf("write device error!\n");25        return -1;26    }2728    printf("write val %d to device!\n", num);2930    ret = read(fd, &val, sizeof(int));31    if(ret < 0)32    {33        printf("read device error!\n");34        return -1;35    }3637    printf("read val = %d\n", val);3839    return 0;40}

这个C程序打开/dev/example,向该设备寄存器写入一个数字12,再读取设备寄存器,所以读取得到的值应该也是12。

创建development/example_test/Android.mk文件,该文件用于注册本模块到Android系统中,其内容如下:

[cpp] view plain copy print ?
  1. 1LOCAL_PATH:=$(callmy-dir)
  2. 2include$(CLEAR_VARS)
  3. 3
  4. 4LOCAL_SRC_FILES:=$(callall-subdir-c-files)
  5. 5
  6. 6LOCAL_MODULE:=example_test
  7. 7LOCAL_MODULE_TAGS:=optional
  8. 8include$(BUILD_EXECUTABLE)
1LOCAL_PATH:= $(call my-dir)2include $(CLEAR_VARS)34LOCAL_SRC_FILES := $(call all-subdir-c-files)56LOCAL_MODULE := example_test7LOCAL_MODULE_TAGS := optional8include $(BUILD_EXECUTABLE)

要看明白这个Android.mk,需要对Android编译系统有一个全面了解,这里,我不打算全面分析Android编译系统,只对这个Android.mk进行单独的分析。

第1行,定义变量LOCAL_PATH,其内容是通过$(call my-dir)语句调用自定义函数my-dir赋值的。这个my-dir函数定义在build/core/definitions.mk文件中的106-120行,其作用是返回这个Android.mk所在的目录。

第2行,包含变量CLEAR_VARS,这个变量定义在build/core/config.mk文件的第54行:

CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk

变量BUILD_SYSTEM定义在build/core/main.mk文件的第46行

BUILD_SYSTEM := $(TOPDIR)build/core

所以,变量CLEAR_VARS就是build/core/ clear_vars.mk。打开该文件,可以看到,这个文件的作用就是将除LOCAL_PATH以外的全部编译相关变量清零。

第4行,设置变量LOCAL_SRC_FILES,其内容是通过$(call all-subdir-c-files)语句调用自定义函数all-subdir-c-files赋值的。all-subdir-c-files函数定义在build/core/definitions.mk文件中的195-202行,其作用是返回当前目录及其子目录下的所有".c"文件文件名。

第6行,设置变量LOCAL_MODULE为example_test。即模块名。

第7行,设置变量LOCAL_MODULE_TAGS为optional。

第8行,包含变量BUILD_EXECUTABLE,该变量定义在build/core/config.mk文件的第60行:

BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk

即包含build/core/executable.mk,包含这个文件表明是要编译成一个可执行程序。

编写完C程序源码和Android.mk,我们就可以编译C应用程序了。有两种编译方法
方法一:在模块Android.mk所在目录下执行mm命令,系统就会对该模块进行编译。

方法二:在Android主目录下执行mmm 模块路径名,这里即mmm development/example_test,系统也同样能开始对模块进行编译。

mmm和mm分别表示对指定目录和当前目录下的模块进行编译,这两个命令都定义在build/envsetup.sh文件中,我们在编译Android之前,首先要执行source build/envsetup.sh命令,这样才能使用这两个命令。

编译完模块后,在out/target/product/generic/system/bin目录下就能看到example_test程序,这就是我们写的C应用程序。

下一步是重新打包文件系统system.img,把example_test程序包含进文件系统镜像中,命令如下:

# make snod

重新启动Android模拟器:

# emulator -kernel kernel/goldfish/arch/arm/boot/zImage

进入命令行界面,执行C应用程序:

# adb shell

# example_test

write val 12 to device!

read val = 12

可以看到我们的C应用程序example_test访问Linux内核驱动程序example成功了。

更多相关文章

  1. [原]Android应用程序消息处理机制(Looper、Handler)分析
  2. Android中数据存储——文件存储数据
  3. 转:RTC搭建android下三层应用程序访问服务器MsSql-服务器端
  4. 老罗的Android之旅——Android应用程序的Activity启动过程简要介
  5. Android系统集成第三方pre-build库和程序
  6. 深入探究Android的WebView下载网络文件的盗链问题
  7. [Android设计模式]Android退出应用程序终极方法

随机推荐

  1. Android6.0源码开发之修改默认音量defaul
  2. android中Matrix之一(图片二维转动)
  3. android Looper& Handler
  4. React Native嵌入Android原生项目中
  5. Android---配置adb环境变量
  6. Android parcelable 解析
  7. Android屏幕常亮防息屏
  8. EditText的focus问题
  9. Android的一些开发资料
  10. android 使用Yasea和ijkplayer集成到自己