Android是移动设备的主流操作系统,近年来越来越多的工业领域的客户开始关注基于Android操作系统的设备在工控领域的应用。鉴于Android是基于Linux内核的事实,我们发展了一种以双应用进程为特色的Android工控应用方案,并在ESM6802工控主板上加以实现。具体说来,就是在Linux平台上运行一个直接操作硬件接口的控制通讯管理进程,为保证运行效率,该进程采用C/C++语言编写(以下简称C进程或控制进程);另一方面在Android平台采用标准Java语言编写一个人机界面进程(以下简称Java进程)。底层的控制进程并不依赖与上层的Java进程而独立运行,两个进程之间通过本地IP进行通讯,控制进程处于服务器侦听模式,Java进程则为客户端模式。本方案的主要优点是客户可以直接继承已有的现成应用程序作为底层控制进程的基础,仅仅增加标准的Socket侦听功能,即可快速完成新的底层应用程序的设计。而界面的Java程序,由于不再涉及具体的工控硬件接口,属于单纯的Android程序,编程难度也大大降低。

  我们将通过多篇技术报告来具体介绍双进程方案在ESM6802主板上实现的相关技术。本文是《Android双应用进程工控方案》的第一篇,主要介绍在Android环境中,如何编译C/C++应用程序,下载并配置为开机启动程序。

1、重新编译C/C++应用程序

  如图1所示,由于传统的Linux程序依赖的是glibc库,而Android程序需要的是谷歌公司在AOSP(Android Open Source Project)中提供的Bionic库(比glibc小,提供了Android特定的函数)。所以,原来Linux上的C/C++程序要运行在Android系统上,必须要在Android的编译环境中重新编译。英创推荐使用Android官方开发工具Android Studio,下载CMake和NDK工具,进行C/C++程序的重新编译。

图1 Android和Linux依赖库区别

  下面开始介绍使用Android Studio的NDK编译工具重新编译C/C++程序的过程。

  1.1 搭建Android Studio NDK编译环境

  Android Studio的安装具体过程请参考文档《Android Studio 应用开发简介》的第一章,在SDK Tools页面中一定要勾选NDK和CMake。

  1.2 在Android Studio中新建C++项目

图2 新建C++项目

  首先新建一个Android Studio项目,并勾选Include C++ support选项,此处的Application name是Android app的名字,与最终需要的C++程序无关,用户可随意设定。然后一直点击下一步“Next”,直到图3页面,使用默认的工具链,点击Finish。

图3 默认工具链

  点击finish后会进入项目编辑页面,进入到图4所示的项目视图,可以看到所有的目录结构,其中app/src/main/cpp目录、app/build.gradle和app/CMakeLists.txt是用户需要编辑修改的。然后,点击左上角File >> Project Structure进入图5的页面,检查NDK环境路径是否正确设置。

图4 项目目录结构及要修改的文件

图5 环境路径设置检查

  1.3 复制C/C++应用程序源码

  将原C/C++应用程序的所有源文件拷贝到app/src/main/cpp目录。

  1.4 修改CMakeLists.txt

  新的Android Studio已经支持使用cmake编译c++项目,这里提供对于简单项目使用的CMakeLists.txt,对于更复杂的需求,用户可以参考cmake官网文档https://cmake.org/cmake/help/v3.4/自行修改。

  app/CMakeLists.txt:

  cmake_minimum_required(VERSION 3.4.1)

  # Android 5.0 以上需要在此处设置PIE

  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")

  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")

  # 头文件目录

  include_directories(

  src/main/cpp

  )

  # 源文件目录

  aux_source_directory(src/main/cpp DIR_SRCS)

  # 添加要编译的可执行文件

  add_executable(serialControlDaemon ${DIR_SRCS})

  其中,add_executable表明要生成的是可执行文件,名字为SerialControlDaemon,源文件为DIR_SRCS变量代表的文件,而aux_source_directory将src/main/cpp目录下的所有文件赋给了变量DIR_SRCS。

  1.5 修改build.gradle

  app/build.gradle文件主要是设置构建app的一些参数,这里主要往android>> defaultConfig>>externalNativeBuild>>cmake添加targets和abiFilters两个参数。其中,targets表示生产目标文件的名字,与CmakeLists.txt中的相同;abiFilters表示要生产哪种cpu架构下的目标文件,这里使用armeabi-v7a。修改之后会在右上角提示需要同步项目,点击即可。

图6 修改build.gradle

  1.6 编译cpp项目

  在Android Studio中直接使用Build>>Make Project即可编译整个项目,包括cpp和java。生成的目标文件在目录app/.externalNativeBuild/cmake/debug/armeabi-v7a目录下,名字为serialControlDaemon。

  1.7 下载目标文件到Android

  Android Studio集成了Android开发的所有工具,在Android Studio中使用adb push命令可以将编译得到的目标文件下载到Android目标板上。首先,要使用usb otg的调试线连接PC和目标板;然后点击左下角的Terminal窗口会弹出所在项目的命令行窗口;输入命令:

  adb push app\.externalNativeBuild\cmake\debug\armeabi-v7a\serialControlDaemo      /data/local

  这样,serialControlDaemon便下载到了目标板的/data/local目录下。这时,使用adb shell登陆到Android目标板的命令行,修改目标文件的运行权限并运行,整个过程如图7所示。程序正常运行起来后,表明整个编译过程没有问题,用户可以在命令行中按Ctrl+c停止运行应用程序,并输入exit命令退出adb shell登陆,然后进行下一步的开机自启动配置。

图7 下载目标文件到Android

2、开机自启动配置

  ESM6802上电后通过uboot引导进入linux内核,内核完成一系列系统配置后会启动第一个用户进程:init进程。Android相关的启动过程也是从init开始的。在init进程中会挂载Android的文件系统,运行init.rc脚本。init进程启动过后,会fork出子进程去开启init.rc文件中配置的service。

  为了满足用户运行不同名字的应用程序,英创在init.rc中配置了一个usersh服务。usersh服务开机自动运行,具体过程用户不用关心。 要想开机自启动C/C++程序,用户只需要做两件事:

  ● 编辑userinfo.txt文件

  ● 复制userinfo.txt以及C/C++程序的目标文件到指定目录/sdcard/Download

  2.1 编辑userinfo.txt

  Android启动后,usersh服务会自动检测/sdcard/Download/userinfo.txt文件。如果userinfo.txt文件存在,usersh会去解析并启动userinfo.txt文件中指定的应用;如果userinfo.txt不存在,则结束usersh服务。userinfo.txt起到一个配置文件的作用,其格式如下:

  Name=serialControlDaemon

  Param=2

  其中,Name指定程序名字,Param指定要带的参数,没有可以不写。用户可以直接在Android Studio中创建并编辑userinfo.txt文件。

图8 Android Studio中新建userinfo.txt

  2.2 复制userinfo.txt以及C/C++程序到指定目录/sdcard/Download

  Android系统中,不是每个目录都有读写以及可执行的权限,这里我们选择/sdcard/Download作为存储userinfo.txt和C/C++程序的指定目录。复制userinfo.txt以及C/C++程序到指定目录有两种方法:通过usb_otg接口使用Android Studio的adb push命令下载到ESM6802,或者通过U盘从PC端拷贝到ESM6802。用户按其中一种方法下载文件到指定目录后,重启ESM6802即可以开机启动userinfo.txt中指定的C/C++程序。

  1、Android Studio命令行下载userinfo.txt和C/C++程序到ESM6802

  使用Android Studio命令行下载文件到ESM6802,首先需要使用调试线连接PC和目标板的usb_otg接口。然后,在Android Studio的Terminal窗口输入:

  adb push app\.externalNativeBuild\cmake\debug\armeabi-v7a\serialControlDaemo      /sdcard/Download

  adb push app\userinfo.txt  /sdcard/Download

  重启设备即可实现开机自启动serialControlDaemon。

  2、U盘拷贝userinfo.txt和C/C++程序到ESM6802

  使用U盘拷贝userinfo.txt和C/C++程序到ESM6802,只需要将userinfo.txt和目标文件(serialControlDaemon)拷贝到U盘,插到ESM6802的USB接口上,打开Android的文件管理应用ES File Explorer,将userinfo.txt和serialControlDaemon拷贝到/sdcard/Download目录,重新启动即可。

  2.3 查看程序是否开机运行

  通过以上设置之后,Android开机boot_completed=1之后会启动应用程序serialControlDaemon,用户可以通过命令adb shell登陆consolo控制台,输入命令getprop | grep init.svc | grep usersh来查看usersh服务的运行状态;当然usersh实际运行的应用程序serialControlDaemon的进程状态可以通过ps | grep serialControlDaemon查看。

图9 检测usersh服务运行状态

3、Q & A

  Q1:查看C/C++程序输出

  在Android控制台上看不到开机启动的C/C++程序输出信息,开发中如何在Android上调试C/C++程序?

  A1:使用kill命令终止掉已经启动的C/C++程序;然后,在Android命令行中执行命令:user.sh,即可手动启动C/C++应用程序,并且C/C++应用程序的输出信息将打印到Android控制台。

  Q2:关于userinfo.txt和C/C++程序指定目录的说明

  A2:userinfo.txt和C/C++程序指定目录要具有读写可执行权限,在2.2节中,adb push命令将C/C++应用程序(serialControlDaemon)下载到了/sdcard/Download目录,其实下载到/data/local也是可以的,而U盘却只能拷贝到/sdcard/Download/。这是因为usersh服务会比较/sdcard/Download/serialControlDaemon是否比/data/local/serialControlDaemon更新,如果是,则先用新文件覆盖旧文件,再运行/data/local/serialControlDaemon。因此,使用adb push命令的指定目录用/sdcard/Download/或者/data/local都是可以的;而使用U盘,则受限于ES File Manager应用不能访问/data/local目录,只能拷贝到/sdcard/Download。

  Q3:关于Android Studio的Terminal窗口

  A3:Android Studio的Terminal窗口在进入的时候,工作在PC的文件系统上,操作的文件都是PC上的;当使用adb shell登陆Android目标板之后,工作在Android目标板的文件系统上,操作的文件、执行的命令都是Android目标板上的;在使用adb shell登陆之后,可以使用exit命令退出登陆状态,返回到PC端的工作目录。

  Q4:adb连接不上设备

  使用adb devices查看一下是否有已连接的设备;检查usb_otg和PC端的物理连接;重新插拔一下调试线或者重启系统。

  如果ethernet正常工作,可以使用ethernet代替usb_otg,在Terminal中输入一下命令:

  $ adb usb

  restarting in USB mode

  $ adb devices

  List of devices attached

  ????????????    device

  $ adb tcpip 5555

  restarting in TCP mode port: 5555

  $ adb connect YOUR_IP_ADDRESS

  connected to YOUR_IP_ADDRESS:5555

  $ adb devices

  List of devices attached

  ????????????    device

  YOUR_IP_ADDRESS:5555 device

  退出:

  adb disconnect YOUR_IP_ADDRESS

  Q5:常用命令

  查看所有service运行状态:getprop | grep init.svc

  adb相关:

  adb devices  查看usb_otg已连接的设备

  adb push localfile remotepath 将PC端的localfile下载到Android端的remotepath目录下。

  adb pull remotefile 复制Android端的remotefile文件到PC端的当前目录

成都英创信息技术有限公司 http://www.emtronix.com

原文下载:http://www.emtronix.com/download/android_c_cpp.pdf

在Android平台启动Linux C/C++应用程序相关推荐

  1. 【2022/1/7】Android平台启动图制作.9.png图片

    Android平台启动图制作.9.png图片 可以先了解4条黑边的意义,当然如果不了解也是可以的,我们制作.9.png使用android studio 顶部:水平拉伸时,只有这一部分进行拉伸 左边:竖 ...

  2. 在Android平台上发现新的恶意程序伪装成杀毒软件挟持设备

    Android平台恶意程序:不支付$100隐私就泄漏]6月25日消息,安全公司赛门铁克发布报告,在Android平台上发现新的恶意程序伪装成杀毒软件挟持设备,消费者支付$100才能让设备正常运作.这些 ...

  3. android开机图片格式,Android平台启动图使用.9.png图片

    概述 目前HBuilder|HBuilderX中仅定义几种标准分辨率的启动图配置,而实际上存在很多不同分辨率的手机,导致启动图会进行拉伸或压缩引起变形,Android平台为了解决此问题就出现了可以适配 ...

  4. lxd容器运行Android,对于启动Linux时自动启动 LXD 容器的方法解析

    Q:我正在使用基于 LXD("Linux 容器")的虚拟机.如何在 Linux 系统中启动时自动启动 LXD 容器? 当 LXD 在启动时运行,你就可以随时启动容器.你需要将boo ...

  5. Android平台Qt开发入门教程

    很多人会问,Android平台可以不使用Java开发应用程序?? 我做Android平台native开发之前,也有这么想过,但是我又想,底层系统全是c/c++代码,用c/c++开发Android平台程 ...

  6. 米狗族 Android平台Qt开发入门教程

    很多人会问,Android平台可以不使用Java开发应用程序?? 我做Android平台native开发之前,也有这么想过,但是我又想,底层系统全是c/c++代码,用c/c++开发Android平台程 ...

  7. 1.0 Android平台概述

    Android,可能在iphone引入中国之前,对很多人还是相当陌生的.套用一句古话,"既生瑜,何生亮".那么已经有了iphone,为什么又非得搞一个Android呢.但是假如你对 ...

  8. Android平台研发人才缺口30万

    随着采用Android系统的谷歌手机.平板电脑等产品逐渐扩大市场占有率,Android平台人才的缺口日益显现.据业内统计,目前国内的3G研发人才缺口有三.四百万,其中Android研发人才缺口至少30 ...

  9. 基于NDK编译Android平台的FFmpeg动态库

    需求 FFmpeg在Linux平台(如Ubuntu)上的支持已经比较完善了,如前述文章介绍 http://blog.csdn.net/ericbar/article/details/73702061, ...

最新文章

  1. 有一段时间没来这里了,
  2. Git复习(七)之自定义git、忽略特殊文件、配置文件
  3. python中变量不需要事先声明_第二章 Python 变量
  4. 神经网络与深度学习——TensorFlow2.0实战(笔记)(三)(python运算符和表达式)
  5. Spring 字符编码过滤
  6. ValidateInput(false)与this.ValidateRequest = false无效的解决方案
  7. 百度地图隐藏地名_官宣,鲁能公馆是“怪地名”,以后我只是秦新名邸
  8. 语义分割Swin Transformer
  9. 《概率论与数理统计》(浙大第四版)第六章总结笔记(纯手写)
  10. 中国各省所处的经纬度范围
  11. vs2015 ankhsvn插件(AnkhSVN) v2.7.0.6493
  12. 即将到来的Xcode8 都更新了什么?
  13. 正确插入目录并且自由更新
  14. EXCEL数据改动自动标记功能怎么实现
  15. Excel VBA连接ORACLE数据库
  16. MapReduce 原理与实践
  17. matlab整流桥和电感怎么连接,整流桥四脚接法实物图手把手教学
  18. Unity中常用到的基础函数
  19. 史上最全的python的web开发和网络编程【附属详细解释+案例】
  20. discuz ckplayer视频

热门文章

  1. June 11th 模拟赛C T1 Sandcas Solution
  2. 旧版Chrome浏览器的安装和使用——chrome63
  3. 为了更有效率地偷钱,Android root木马开始试水短信扣费诈骗
  4. SDN初步:Mininet(SDN测试平台)Ryu(SDN控制器)
  5. IPX:互联网分组交换协议--网络大典
  6. lumina电源维修XLB-650-25-20-R-H激光氙灯电源维修
  7. 怎么用ai做出适量插画_如何用AI把照片制作成矢量线条插画
  8. SAP会计基础知识(会计借贷关系)
  9. MySQL查看数据库表中的重复记录并删除
  10. 2020美亚个人赛复盘