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

    文章

    6107

    浏览量

    37204
  • 安卓
    +关注

    关注

    5

    文章

    2187

    浏览量

    60625
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用VectorCAST/C++的AI辅助测试功能

    从2026版本开始,VectorCAST/C++推出首批AI辅助测试功能,旨在帮助开发团队解决单元测试过程中的两个核心难点:
    的头像 发表于 04-27 14:37 399次阅读

    C++与lua联合编程

    硬件服务器折旧率的降低。 四、 构建技术护城河,获取“系统级联调”的稀缺溢价 在游戏开发、高频交易系统和嵌入式控制领域,业务逻辑的变更极其频繁。如果每次修改业务都用 C++ 重新编译,不仅编译时间长
    发表于 04-19 16:27

    MTK平台LK阶段mt_boot.c配置:SELINUX_STATUS 2的作用与影响

    在 MTK(联发科)平台的 Bootloader(以 LK/Little Kernel 为例)中,mt_boot.c是负责 Linux 内核启动逻辑的核心文件,此次代码变更(新增#de
    的头像 发表于 02-03 15:46 1021次阅读
    MTK<b class='flag-5'>平台</b>LK阶段mt_boot.<b class='flag-5'>c</b>配置:SELINUX_STATUS 2的作用与影响

    深入解析rk平台Android Bootloader核心代码:从启动流程到AVB验证

    android_bootloader.c的核心代码,带你读懂Android设备从Bootloader到内核的完整启动逻辑,以及开发者关注这些代码的核心价值。 一、代码整体定位 这份代码是Rockchip(瑞芯微)
    的头像 发表于 01-22 07:06 587次阅读
    深入解析rk<b class='flag-5'>平台</b><b class='flag-5'>Android</b> Bootloader核心代码:从<b class='flag-5'>启动</b>流程到AVB验证

    深入解析RK平台Android/Linux Bootloader核心文件:android_bootloader.c

    Bootloader是Android设备启动的第一道“关卡”,负责初始化硬件、加载系统镜像并完成内核启动的前置准备。在基于U-Boot的Android设备中,
    的头像 发表于 01-09 10:58 1551次阅读
    深入解析RK<b class='flag-5'>平台</b><b class='flag-5'>Android</b>/<b class='flag-5'>Linux</b> Bootloader核心文件:<b class='flag-5'>android_bootloader.c</b>

    C语言与C++的区别及联系

    C语言和C++到底是什么关系? 首先C++C语言本来就是两种不同的编程语言,但C++确实是对C
    发表于 12-24 07:23

    CC++之间的联系

    1、语法兼容性: C++完全兼容C语言的语法,这意味着任何有效的C语言程序都可以直接在C++编译器下编译通过。 2、底层控制:
    发表于 12-11 06:51

    C语言和C++之间的区别是什么

    (inheritance)、多态(polymorphism)等面向对象编程概念。程序员可以通过定义类来创建对象,并利用类的实例进行操作。 2、类型系统与安全性: C++具有更为严格的类型检查机制
    发表于 12-11 06:23

    C++程序异常的处理机制

    1、什么是异常处理? 有经验的朋友应该知道,在正常的CC++编程过程中难免会碰到程序不按照原本设计运行的情况。 最常见的有除法分母为零,数组越界,内存分配失效、打开相应文件失败等等。 一个
    发表于 12-02 07:12

    rtsmart开启C++特性支持后,工具链编译内核不通过怎么解决?

    各位大佬好,本人在rtsmart项目中需要使用C++11特性,在menuconfig那里配置了支持C++特性后,使用7.3.0版本的arm-linux-musleabi编译器编译内核时出现 错误
    发表于 09-29 07:49

    佛瑞亚如何通过信息技术推动业务增长

    在数字化、信息化的浪潮下,信息技术已经不仅是后台工具,更成为驱动企业发展的关键力量。本期Women Inspiring Mobility,我们采访了佛瑞亚中国区信息技术总监马瑛,了解她和团队如何将
    的头像 发表于 07-29 14:00 1103次阅读

    CY8C4128LQI-BL543无法扫描PC和Android手机,为什么?

    。 为什么?(PC和Android手机 CAN 广告和s同时CAN )。 我使用的是 Psoc 4 ble 4.2 版本的设备和 Psoc creator 4.4 版本。 扫描 PC 和 Android 手机需要配置或应用程序
    发表于 07-07 08:09

    使用英特尔® NPU 插件C++运行应用程序时出现错误:“std::Runtime_error at memory location”怎么解决?

    使用OpenVINO™工具套件版本 2024.4.0 构建C++应用程序 使用英特尔® NPU 插件运行了 C++ 应用程序 遇到的错误: Microsoft
    发表于 06-25 08:01

    请问是否可以在通用Windows平台中构建OpenVINO™ GenAI C++ 应用程序

    无法在通用 Windows 平台中构建OpenVINO™ GenAI C++ 应用程序
    发表于 06-24 07:35

    科普|信是什么?一文读懂“信息技术应用创新”战略

    什么是信?信,即“信息技术应用创新”,是国家推动IT系统自主可控、安全可控的重要战略工程。它不仅是技术层面的创新,更承载着保障国家网络安全、推动产业升级和实现数字主权的重任。简单来
    的头像 发表于 06-13 10:06 9887次阅读
    科普|信<b class='flag-5'>创</b>是什么?一文读懂“<b class='flag-5'>信息技术</b>应用创新”战略