0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

英创信息技术Android平台启动Linux C/C++应用程序

英创信息技术 来源:英创信息技术 作者:英创信息技术 2020-02-06 11:25 次阅读

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

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

本文PDF下载:Android双应用进程工控方案(一)——在Android平台启动Linux 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++程序的重新编译。

图1Android和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文件。

图8Android 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端的当前目录

本文PDF下载:Android双应用进程工控方案(一)——在Android平台启动Linux C/C++应用程序

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式主板
    +关注

    关注

    7

    文章

    6085

    浏览量

    35349
  • 安卓
    +关注

    关注

    5

    文章

    2131

    浏览量

    57215
收藏 人收藏

    评论

    相关推荐

    android手机上emulate应用程序的方法

    Android手机上模拟(emulate)应用程序的方法通常涉及到使用Android模拟器(Emulator)或类似的工具来模拟Android环境,以便在没有实际物理设备的情况下运行
    的头像 发表于 12-05 15:33 286次阅读

    AWTK-WEB 快速入门(1) - C 语言应用程序

    导读AWTK可以使用相同的技术栈开发各种平台应用程序。有时我们需要使用Web界面与设备进行交互,本文介绍一下如何使用C语言开发AWTK-WEB应用
    的头像 发表于 11-27 11:46 213次阅读
    AWTK-WEB 快速入门(1) - <b class='flag-5'>C</b> 语言<b class='flag-5'>应用程序</b>

    C语言和C++中结构体的区别

    同样是结构体,看看在C语言和C++中有什么区别?
    的头像 发表于 10-30 15:11 242次阅读

    C7000优化C/C++编译器

    电子发烧友网站提供《C7000优化C/C++编译器.pdf》资料免费下载
    发表于 10-30 09:45 0次下载
    <b class='flag-5'>C</b>7000优化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>编译器

    TMS320C6000 DMA示例应用程序

    电子发烧友网站提供《TMS320C6000 DMA示例应用程序.pdf》资料免费下载
    发表于 10-26 10:17 0次下载
    TMS320<b class='flag-5'>C</b>6000 DMA示例<b class='flag-5'>应用程序</b>

    为I2C启动加载准备TMS320C645x应用程序

    电子发烧友网站提供《为I2C启动加载准备TMS320C645x应用程序.pdf》资料免费下载
    发表于 10-16 11:30 0次下载
    为I2<b class='flag-5'>C</b><b class='flag-5'>启动</b>加载准备TMS320<b class='flag-5'>C</b>645x<b class='flag-5'>应用程序</b>

    使用OpenVINO GenAI API在C++中构建AI应用程序

    许多桌面应用程序是使用 C++ 开发的,而将生成式AI(GenAI)功能集成到这些应用程序中可能会很具有挑战性,尤其是因为使用像 Hugging Face 这样的 Python 库的复杂性。C
    的头像 发表于 10-12 09:36 387次阅读
    使用OpenVINO GenAI API在<b class='flag-5'>C++</b>中构建AI<b class='flag-5'>应用程序</b>

    C++中实现类似instanceof的方法

    并执行特定于类型的操作。无论是在编译时检查类型,还是在运行时动态标识对象类型,C++ 都提供了强大的机制来获取类型信息
    的头像 发表于 07-18 10:16 596次阅读
    <b class='flag-5'>C++</b>中实现类似instanceof的方法

    SEGGER编译器优化和安全技术介绍 支持最新CC++语言

    SEGGER编译器是专门为ARM和RISC-V微控制器设计的优化C/C++编译器。它建立在强大的Clang前端上,支持最新的CC++语言功能。 除其他外,其主要功能包括: 1) 尺寸
    的头像 发表于 06-04 15:31 1470次阅读
    SEGGER编译器优化和安全<b class='flag-5'>技术</b>介绍 支持最新<b class='flag-5'>C</b>和<b class='flag-5'>C++</b>语言

    在嵌入式系统中集成Rust和Qt的实践

    Rust 拥有丰富的库生态系统,用于序列化和反序列化、异步操作、解析不安全输入、线程、静态分析等,而 Qt 是一个 C++ 工具包,支持跨各种平台的丰富的、基于 GUI 的应用程序,从 iOS 到嵌入式
    发表于 05-03 10:26 1819次阅读
    在嵌入式系统中集成Rust和Qt的实践

    c语言,c++,java,python区别

    C语言、C++、Java和Python是四种常见的编程语言,各有优点和特点。 C语言: C语言是一种面向过程的编程语言。它具有底层的特性,能够对计算机硬件进行直接操作。
    的头像 发表于 02-05 14:11 2403次阅读

    C++Linux内核开发中从争议到成熟

    Linux 内核邮件列表中一篇已有六年历史的老帖近日再次引发激烈讨论 —— 主题是建议将 Linux 内核的开发语言从 C 转换为更现代的 C++
    的头像 发表于 01-31 14:11 633次阅读
    <b class='flag-5'>C++</b>在<b class='flag-5'>Linux</b>内核开发中从争议到成熟

    PSoC4固件更新,应用程序无法启动是为什么?

    我正在使用 CY8CKIT-148 (PSoC CY8C4147AZI-S475),并且我正在尝试在不使用DFU库的情况下使固件更新正常工作。 唯一的区别是我没有使用 DFU 协议。下载应用程序可以
    发表于 01-30 06:38

    C++简史:C++是如何开始的

    MISRA C++:2023,MISRA® C++ 标准的下一个版本,来了!为了帮助您做好准备,我们介绍了 Perforce 首席技术支持工程师 Frank van den Beuken 博士撰写
    的头像 发表于 01-11 09:00 600次阅读
    <b class='flag-5'>C++</b>简史:<b class='flag-5'>C++</b>是如何开始的

    如何构建linux开发环境和编译软件工程、应用程序

    前文介绍了如何使用官方提供的镜像文件启动开发板,本文将说明如何构建linux开发环境和编译软件工程、应用程序
    的头像 发表于 01-03 12:31 2064次阅读
    如何构建<b class='flag-5'>linux</b>开发环境和编译软件工程、<b class='flag-5'>应用程序</b>