在android系统上写C语言程序--开机启动该程序不进入安卓系统
今天要写的这篇博文意义重大,也是网上很少有的,这是在我工作中学会的一项技术,当然,它也是由简单的问题组合而来的。如何在安卓中写C语言程序,调试安卓驱动,测试程序的的一项重要技能,下面我就不说废话了,直接说实用的,怎么用这个东西。
关于这个问题,相信很多学Android的都会去关注这个问题,大家普遍会有个这样的疑问:安卓是怎么跑起来的?
最简单的说法,安卓系统是这样加载的:
Bootloader------Kernel(对应平台版本的Linux内核)------filesystem文件系统(这个就是Android了)
所以说,安卓其实不是操作系统,而是一个基于linux内核的文件系统。
那么,我们标题所说的,要在开机的时候就运行我们的程序而不选择进入安卓系统,那么如何来实现呢?首先,得了解一个问题,filesystem是怎么启动的。
从网上搜索的资料还有一些讲Andorid系统的书籍来看,文件系统的加载是从init.rc开始一步步的,创建文件系统所需的目录,还有给这些目录加权限,拷贝相关的程序,等待操作,最重要的,一个文件系统的运行需要加载这些服务才可以实现。至于怎么加载的,原理我就不多说了,说来话长,推荐大家可以去搜索init.rc,init.c这样的字眼就可以明白了。
我们现在讲的是如何来实现开机就执行bin文件,而不进入安卓系统。
1、 为了区别我的服务跟别的服务的不同,我的服务独立于一个on来进行触发。
on YYX class_start core service pppService /system/bin/PPPreboot class core user root group root oneshot
我写的这个服务名字叫做pppService,服务对应需要执行的bin文件是PPPreboot,实现的就是平板一开机打印语句然后就重启,一直反复,这样就不会进入安卓文件系统了,也就看不到我们平常使用的安卓UI界面,而是黑压压的一篇,但是你在串口上可以看到调试信息输出,当然,如果你了解驱动应用编程,你可以在此时在屏幕上画点东西,做你自己的界面,其实就是写C或者C++的程序了,就是写linux的应用程序。
2、源码如下(位置:external/test/ppp.c)
#include stdio.h #include stdlib.h #include android/log.h #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "keymatch", __VA_ARGS__) int main(void) int i ; freopen("/dev/ttyMT0", "a", stdout);setbuf(stdout, NULL); freopen("/dev/ttyMT0", "a", stderr);setbuf(stderr, NULL); LOGD("YYX---- reboot system!!!!!!--- 201612.1\n"); system("reboot"); return 0 ;
对应的Android.mk
LOCAL_PATH:=$(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := eng LOCAL_LDLIBS := -llog LOCAL_SRC_FILES:= \ ppp.c LOCAL_MODULE:= PPPreboot include $(BUILD_EXECUTABLE) #include $(BUILD_SHARED_LIBRARY)
1.对编写好的这个C程序进行编译,用命令mm或者mmm进行编译,编译生成的PPPreboot就位于我们开机启动的安卓文件系统的system/bin/这个目录下
2.在init.rc中调用trigger命令触发这个on YYX,只要再适当的位置加上:trigger YYX 就可以了
3.编译:make –j8
将对应的文件下载到安卓平板,开机你就会发现平板可以打印信息也可以不断的重启了。
如果此时不加上:
freopen("/dev/ttyMT0","a", stdout);setbuf(stdout, NULL);
freopen("/dev/ttyMT0","a", stderr);setbuf(stderr, NULL);
你不会在安卓的串口上看到任何的输出信息,因为串口在init.cpp的时候就已经做了这步设置,详情请查看system/core/init/init.cpp代码:
open_devnull_stdio();
这一句的作用就是将安卓中的标准输入输出重定向到/dev/null,众所周知,这被称为是linux的一个空洞文件,这个文件可以接收一切的信息,它就像一个垃圾桶一样。但是有个特点,它是只进不出的。
所以,我们在自己写的C程序或者C++程序中需要先重定向到标准输入输出,freopen的作用就是这样的,还应该要注意,你的板子的串口输出设备节点是什么,我的是/dev/ttyMT0,有可能你的就跟我不一样了。
C语言总结(第2章算法——程序的灵魂 第3章最简单的C程序设计——顺序程序设计 第4章选择结构程序设计) 算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 6是解决做什么和怎么做的问题。简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵魂。
C语言进阶——程序环境和预处理(下) 宏不仅会因为优先级问题造成影响,还会因为参数传递导致副作用,因为宏参数在传递后,会原封不动的进行替换,某些操作会对参数本身造成影响,而函数就没有这种问题
C语言进阶——程序环境和预处理(上) 在C/C++中,所有的代码在输出结果前都需要经过这五个阶段:预编译 编译 汇编 链接 执行代码。其中前四个阶段是在翻译环境下进行,因为在翻译环境中有编译器和链接器这两个重要工具,二者配合能将文本形式的代码转化为对应的二进制代码和可执行文件;
morixinguan ITGEGE在线教育嵌入式开发讲师。 CSDN博客专家、CSDN-Linux特邀编辑、CSDN博乐、CSDN学院讲师,目前从事嵌入式开发领域,从事与单片机,Linux,android相关的产品开发。
相关文章
- android java epson串口打印机
- 一种提高Android应用进程存活率新方法(上)
- Android 下载Zip文件,并解压到本地
- 安卓开发面试题!Android之Rxjava2-源码解析
- 5年老安卓面试竟然被这3道Android基础题难倒了?附答案
- android内存管理,拿下我人生中第7个Offer,文末领取面试资料
- 解决Android抽屉被击穿问题
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- ***使用Fiddler抓取Android安卓手机的APP请求
- Android之上下滑动的引导页
- Android 开发艺术探索(笔记)--1. Activity 生命周期
- 安卓表格布局android:collapseColumns,android:shrinkColumns和stretchColumn
- android:报错Skipping device ‘emulator-5554‘ (emulator-5554): Device is OFFLINE.
- 【Android】安卓闪电复习
- Android中的线程池 ThreadPoolExecutor
- Android程序员的进阶之路
- 如何对 Android 应用进行性能分析
- Java Android(安卓) 获取所有目录(内部和外部)和存储设备列表(Storage Devices)
- Android includeFontPadding
- Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
- Android 命名规范 (提高代码可以读性)
- android listview中checkbox(购物车,批量操作)
- Lambda for Android
- android 仿易讯客户端loading效果
- 二维码合成,将苹果和安卓(ios和android)合成一个二维码,让用户扫描一个二维码就可以分别下载苹果和安卓的应用
- 手把手教你深度定制tiny4412安卓5.0系统(一)---开发板如何预置文件到android系统
- Android Toast使用的简单小结