在android系统上写C语言程序--开机启动该程序不进入安卓系统

千金一刻莫空度,老大无成空自伤。这篇文章主要讲述在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/这个目录下
【在android系统上写C语言程序--开机启动该程序不进入安卓系统】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,有可能你的就跟我不一样了。


关于上面说的这个应用,应用范围,一些PCBA的产测工具可以在这个时候进行实现,或者手动OTA更新等等,应用非常广泛,需要大家在工作中孰能生巧。

       



    推荐阅读