Google年底突然发布Android Thing生态系统,还有一堆芯片公司站台。公布的已支持硬件里面,能买到的只有intel和rasperry pi开发板了,IMX6的基本无货。本文先以Raspberry Pi3B作为开发板,体验Android Things系统,并运行官方例程。

Android Things 官网

具体的镜像或工具,直接从官网下载就可以了。

下载Raspberry Pi的系统镜像后,用dd命令写入到TF卡。建议在Linux或macOS下来完成。Raspberry Pi的镜像大小有4.5GB,所以TF卡最好16GB以上吧。最重要的是,一般TF卡的写入速度都是20MB/s ~ 30MB/s之间,我在实际写入时使用SanDisk Ultra 16GB,用了将近三个小时,平均速度为22MB/s。建议购买写入速度在80MB/s以上的TF卡比较合适,比如SamSung Extreme 16GB V30。

写完后发现,Android Things使用了GPT的分区方案。Linux下使用parted命令可以查看卡片上的分区。从分区看,Android Things除了基本的Android风格的分区,还有A/B分区方案。ubuntu core上也是同样的做法。对于没有显示屏和过多的操作按键的系统,双分区还是很有必要的,而Android Things上大部分都是双分区,所以镜像约有4GB,也就可以理解了。

Number  Start   End     Size    File system  Name      Flags
 1      20.5kB  67.1MB  67.1MB  fat16        rpiboot
 2      67.1MB  68.2MB  1049kB               uboot_a
 3      68.2MB  69.2MB  1049kB               uboot_b
 4      69.2MB  103MB   33.6MB               boot_a
 5      103MB   136MB   33.6MB               boot_b
 6      136MB   673MB   537MB   ext4         system_a
 7      673MB   1210MB  537MB                system_b
 8      1210MB  1210MB  65.5kB               vbmeta_a
 9      1210MB  1210MB  65.5kB               vbmeta_b
10      1210MB  1211MB  1049kB               misc
11      1211MB  1245MB  33.6MB  ext4         oem_a
12      1245MB  1278MB  33.6MB               oem_b
13      1278MB  1547MB  268MB   ext4         gapps_a
14      1547MB  1815MB  268MB                gapps_b
15      1815MB  4563MB  2748MB  ext4         userdata

上电后,HDMI上看到有boot kernel前的信息,约20~30秒的时间,系统基本启动完成,HDMI上显示Android Things的Logo画面。Raspberry Pi3B的硬件是4核1.2GHz芯片,1GB内存,这个配置对于手机来说很一般了。但对于嵌入式行业,属于中低级配置吧,毕竟Raspberry Pi已经很便宜了。

启动后查看当前运行应用,从液晶上看,没有明显的应用。后台运行状况也确实如此,多了几个特有的应用程序。

rpi3:/ # ps
USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAME
root      1     0     7336   1552  SyS_epoll_ 0008c6f8 S /init
root      2     0     0      0       kthreadd 00000000 S kthreadd
root      3     2     0      0     smpboot_th 00000000 S ksoftirqd/0
root      5     2     0      0     worker_thr 00000000 S kworker/0:0H
root      7     2     0      0     rcu_gp_kth 00000000 S rcu_preempt
root      8     2     0      0     rcu_gp_kth 00000000 S rcu_sched
root      9     2     0      0     rcu_gp_kth 00000000 S rcu_bh
root      10    2     0      0     smpboot_th 00000000 S migration/0
root      11    2     0      0     smpboot_th 00000000 S migration/1
root      12    2     0      0     smpboot_th 00000000 S ksoftirqd/1
root      13    2     0      0     worker_thr 00000000 S kworker/1:0
root      14    2     0      0     worker_thr 00000000 S kworker/1:0H
root      15    2     0      0     smpboot_th 00000000 S migration/2
root      16    2     0      0     smpboot_th 00000000 S ksoftirqd/2
root      18    2     0      0     worker_thr 00000000 S kworker/2:0H
root      19    2     0      0     smpboot_th 00000000 S migration/3
root      20    2     0      0     smpboot_th 00000000 S ksoftirqd/3
root      21    2     0      0     worker_thr 00000000 S kworker/3:0
root      22    2     0      0     worker_thr 00000000 S kworker/3:0H
root      23    2     0      0      devtmpfsd 00000000 S kdevtmpfs
root      24    2     0      0     rescuer_th 00000000 S netns
root      25    2     0      0     rescuer_th 00000000 S perf
root      26    2     0      0       watchdog 00000000 S khungtaskd
root      27    2     0      0     rescuer_th 00000000 S writeback
root      28    2     0      0     ksm_scan_t 00000000 S ksmd
root      29    2     0      0     rescuer_th 00000000 S crypto
root      30    2     0      0     rescuer_th 00000000 S bioset
root      31    2     0      0     rescuer_th 00000000 S kblockd
root      32    2     0      0     worker_thr 00000000 S kworker/0:1
root      33    2     0      0     rescuer_th 00000000 S cfg80211
root      34    2     0      0     rescuer_th 00000000 S rpciod
root      35    2     0      0         kswapd 00000000 S kswapd0
root      36    2     0      0     rescuer_th 00000000 S vmstat
root      37    2     0      0     fsnotify_m 00000000 S fsnotify_mark
root      38    2     0      0     rescuer_th 00000000 S nfsiod
root      64    2     0      0     rescuer_th 00000000 S kthrotld
root      65    2     0      0     rescuer_th 00000000 S bioset
root      66    2     0      0     rescuer_th 00000000 S bioset
root      67    2     0      0     rescuer_th 00000000 S bioset
root      68    2     0      0     rescuer_th 00000000 S bioset
root      69    2     0      0     rescuer_th 00000000 S bioset
root      70    2     0      0     rescuer_th 00000000 S bioset
root      71    2     0      0     rescuer_th 00000000 S bioset
root      72    2     0      0     rescuer_th 00000000 S bioset
root      73    2     0      0     rescuer_th 00000000 S bioset
root      74    2     0      0     rescuer_th 00000000 S bioset
root      75    2     0      0     rescuer_th 00000000 S bioset
root      76    2     0      0     rescuer_th 00000000 S bioset
root      77    2     0      0     rescuer_th 00000000 S bioset
root      78    2     0      0     rescuer_th 00000000 S bioset
root      79    2     0      0     rescuer_th 00000000 S bioset
root      80    2     0      0     rescuer_th 00000000 S bioset
root      81    2     0      0     rescuer_th 00000000 S bioset
root      82    2     0      0     rescuer_th 00000000 S bioset
root      83    2     0      0     rescuer_th 00000000 S bioset
root      84    2     0      0     rescuer_th 00000000 S bioset
root      85    2     0      0     rescuer_th 00000000 S bioset
root      86    2     0      0     rescuer_th 00000000 S bioset
root      87    2     0      0     rescuer_th 00000000 S bioset
root      88    2     0      0     rescuer_th 00000000 S bioset
root      89    2     0      0     down_inter 00000000 S VCHIQ-0
root      90    2     0      0     down_inter 00000000 S VCHIQr-0
root      91    2     0      0     down_inter 00000000 S VCHIQs-0
root      92    2     0      0     rescuer_th 00000000 S iscsi_eh
root      93    2     0      0     kthread_wo 00000000 S spi0
root      95    2     0      0     rescuer_th 00000000 S dwc_otg
root      96    2     0      0     worker_thr 00000000 S kworker/2:1
root      97    2     0      0     rescuer_th 00000000 S DWC Notificatio
root      98    2     0      0     vchiq_keep 00000000 S VCHIQka-0
root      99    2     0      0     rescuer_th 00000000 S dm_bufio_cache
root      101   2     0      0     irq_thread 00000000 S irq/92-mmc1
root      102   2     0      0     rescuer_th 00000000 S bioset
root      103   2     0      0     mmc_queue_ 00000000 S mmcqd/0
root      104   2     0      0     rescuer_th 00000000 S binder
root      105   2     0      0     rescuer_th 00000000 S ipv6_addrconf
root      106   2     0      0     down_inter 00000000 S SMIO
root      107   2     0      0     rescuer_th 00000000 S deferwq
root      108   2     0      0     worker_thr 00000000 S kworker/u8:2
root      109   2     0      0     worker_thr 00000000 S kworker/1:1
root      110   2     0      0     worker_thr 00000000 S kworker/2:2
root      111   2     0      0     rescuer_th 00000000 S brcmf_wq/mmc1:0
root      112   2     0      0     brcmf_sdio 00000000 S brcmf_wdog/mmc1
root      113   2     0      0     worker_thr 00000000 S kworker/0:2
root      114   2     0      0     kjournald2 00000000 S jbd2/mmcblk0p6-
root      115   2     0      0     rescuer_th 00000000 S ext4-rsv-conver
root      116   1     2932   1132  poll_sched 0008c798 S /sbin/ueventd
root      121   2     0      0     kjournald2 00000000 S jbd2/mmcblk0p15
root      122   2     0      0     rescuer_th 00000000 S ext4-rsv-conver
root      123   2     0      0     kjournald2 00000000 S jbd2/mmcblk0p11
root      124   2     0      0     rescuer_th 00000000 S ext4-rsv-conver
root      125   2     0      0     kjournald2 00000000 S jbd2/mmcblk0p13
root      126   2     0      0     rescuer_th 00000000 S ext4-rsv-conver
logd      127   1     11676  2648  sigsuspend b42735a8 S /system/bin/logd
root      128   1     5344   2244  __skb_recv afcd01c0 S /system/bin/debuggerd
root      129   1     11784  4560  hrtimer_na b27b3288 S /system/bin/vold
root      134   2     0      0     kauditd_th 00000000 S kauditd
root      135   128   5088   504   __skb_recv afcd13f4 S debuggerd:signaller
root      143   2     0      0     worker_thr 00000000 S kworker/2:1H
root      145   1     2992   496   SyS_epoll_ 00051078 S /sbin/healthd
root      146   1     4560   2380  SyS_epoll_ a8a94260 S /system/bin/lmkd
system    147   1     4600   1988  binder_thr b2ba33a4 S /system/bin/servicemanager
system    148   1     37724  18600 SyS_epoll_ aab0f260 S /system/bin/surfaceflinger
shell     150   1     3872   24    poll_sched 00074670 S /sbin/adbd
root      151   1     966456 94616 poll_sched a7cdd44c S zygote
audioserver 152   1     22876  7616  binder_thr b44993a4 S /system/bin/audioserver
cameraserver 153   1     14512  6512  binder_thr adaff3a4 S /system/bin/cameraserver
drm       154   1     13316  5972  binder_thr a70fd3a4 S /system/bin/drmserver
root      155   1     4972   2088  unix_strea a6e7b3f4 S /system/bin/installd
keystore  156   1     7476   3696  binder_thr ab15c3a4 S /system/bin/keystore
mediacodec 157   1     12968  5756  binder_thr b59063a4 S media.codec
media     158   1     17108  7472  binder_thr b26463a4 S /system/bin/mediadrmserver
mediaex   159   1     37784  6972  binder_thr a8c203a4 S media.extractor
media     160   1     39664  9000  binder_thr b0e563a4 S /system/bin/mediaserver
root      161   1     23372  3876  binder_thr a74bb3a4 S /system/bin/netd
root      162   1     9016   3928  SyS_epoll_ b6aa2260 S /system/bin/peripheralman
root      164   1     3540   1912  poll_sched b06664a4 S /system/bin/sh
system    165   1     7236   3548  binder_thr ad5d43a4 S /system/bin/gatekeeperd
system    166   1     7060   3776  SyS_epoll_ b2e3a260 S /system/bin/userinputdriverservice
metrics_coll 167   1     9024   4716  SyS_epoll_ ad1e4260 S /system/bin/metrics_collector
metricsd  168   1     10868  4928  SyS_epoll_ afd7d260 S /system/bin/metricsd
root      169   1     4100   1848  hrtimer_na b1d19288 S /system/xbin/perfprofd
root      170   1     10072  6116  SyS_epoll_ b37f8260 S /system/bin/update_engine
mdnsr     180   1     2004   688   poll_sched 000464f4 S /system/bin/mdnsd
root      364   2     0      0     worker_thr 00000000 S kworker/u8:3
root      406   2     0      0     worker_thr 00000000 S kworker/3:1H
system    408   151   1080320 122968 SyS_epoll_ a7cdd260 S system_server
root      436   2     0      0     worker_thr 00000000 S kworker/0:1H
media_rw  479   129   8236   2696  wait_woken b1c1a3f4 S /system/bin/sdcard
wifi      516   1     7572   3976  poll_sched a908b4a4 S /system/bin/wpa_supplicant
root      525   2     0      0     worker_thr 00000000 S kworker/3:3
system    542   151   1069296 73160 SyS_epoll_ a7cdd260 S com.android.settings
u0_a5     574   151   1038404 57240 SyS_epoll_ a7cdd260 S android.ext.services
u0_a4     603   151   1044800 70444 SyS_epoll_ a7cdd260 S android.process.media
system    619   151   1048128 74948 SyS_epoll_ a7cdd260 S com.android.iotlauncher
u0_a7     645   151   1179976 95000 SyS_epoll_ a7cdd260 S com.google.android.gms.feedback
u0_a7     652   151   1215664 147520 SyS_epoll_ a7cdd260 S com.google.android.gms.persistent
u0_a8     687   151   1039576 57872 SyS_epoll_ a7cdd260 S com.android.managedprovisioning
u0_a9     701   151   1038328 57096 SyS_epoll_ a7cdd260 S com.android.onetimeinitializer
u0_a1     717   151   1041232 63952 SyS_epoll_ a7cdd260 S com.android.providers.calendar
u0_a7     734   151   1053780 71040 SyS_epoll_ a7cdd260 S com.google.process.gapps
u0_a7     769   151   1339176 159176 SyS_epoll_ a7cdd260 S com.google.android.gms
radio     856   151   1039964 62820 SyS_epoll_ a7cdd260 S com.android.phone
u0_a2     899   151   1047752 73232 SyS_epoll_ a7cdd260 S android.process.acore
u0_a7     950   151   1179328 94660 SyS_epoll_ a7cdd260 S com.google.android.gms.ui
root      1024  2     0      0     worker_thr 00000000 S kworker/1:1H
shell     1049  1     4052   1948  sigsuspend afa035a8 S /system/bin/sh
root      1066  2     0      0     worker_thr 00000000 S kworker/u8:0
root      1073  1049  3540   1908  sigsuspend adf325a8 S /system/bin/sh
root      1079  1073  4528   2084           0 b24fb3f4 R ps

运行sample例程

由于之前没有做过Android相关开发,在配置开发环境上花了很多时间。说到这里,想到周围有做不同方向开发的朋友,大家普遍感觉,前端的工具变化是比较快的,种类也比较多。其次是后端,再就是iOS和Android应用开发类的。像嵌入式方向,工具万年不变的命令行,对初学开发者确实不够友好。这几年各种社区开发板,都在推动图形化编程,以便让初学者快速入门。

Android Studio下载最新版就好了,编译时需要SDK包中的API24,所以也要提前下载好。

https://github.com/androidthings/sample-simplepio.git
https://github.com/androidthings/sample-simpleui.git

下载例程到本地后,先执行gradle会下载gradle相关库,这个需要翻墙。然后就可以构建或运行项目了。Android Studio中可以选择导入项目,命令行下可以用gradle build直接构建。

第一个例程是点灯,使用J8上的GPIO6连接LED灯就可以了,另一脚接GND。

要把例程部署在Raspberry Pi开发板上,需要先用adb连接到开发板。这里支持WiFi和以太网,我使用以太网

./adb connect 192.168.2.7

Android Studio上直接点运行就可以了,命令行可以执行如下命令:

./gradlew blink:installDebug
./adb shell am start com.example.androidthings.simplepio/.BlinkActivity

运行后HDMI上有一个空白的Activity,标提是Blink,LED灯有亮灭变化。

Android Things和Brillo相比,还是保留了java vm相关的模块,这样才保证了和Android上层应用开发的一致性,我觉得这个是比较有趣的地方。先是拆掉java相关,推出Brillo,了无音信几个月后。然后又回到Android上,裁剪掉手机或移动设备相关的API,推出Android Things。这两张图片分别是Brillo和Android Things的结构图,Brillo看起来更适合简单的功能设备,Android Things则有了一定的管理和服务属性。

brillostructure-790452-edited.png

platform-architecture.png

NXP网站已经有了I.MX6UL和Android Things的宣传页面。从Pico-I.MX6UL提供的文档看到,构建Android Things的源代码还在之前Brillo的地址上。
PICO –i.MX6UL Development Platform User Guide

自从2015年Google在IO大会上提出Brillo和Weave进军IoT行来后,这一年多基本音信全无,2016年的IO大会基本没有提到,没想到年底又出了个Android Things的大新闻。结合上次分析IoT操作系统,不负责的揣测下事情经过。Google一向对硬件兴趣不大,毕竟硬件高收益都是处于市场垄断时,溢价才会更高。然后互联网都是服务大众,Google还是要做网络服务为主的业务,最早收购Nest就想用他家的协议,想整合到Android上。Brillo发布后,从官方文档和系统架构图上了解,应用是用C/C++来编写NDK应用,这样就做到了官方宣称的,内存32MB,存储128MB的配置,也可以运行。但是C/C++对开发者并不友好,上层应用还是要用更高级的面向对象语言编写更合适。Google的其它开发组又放出了个新的系统Fuchsia,连内核都是重新写了,上层应用使用Dart语言开发,从内核机制了解到时,可能是适用于VR,IoT方向的产品。然后,Microsoft和Amazon接连在部署IoT相关系统和业务,就连ubuntu都出IoT版系统,Google应该是等不了Fuchsia开发完成,先联合硬件公司发布一个基于Android的IoT系统,毕竟有几个好处:

1.有了Android Things后,Android的产品阵营更加丰富,对于其他已加入Android联盟的合作伙伴,可以直接享用成果。Qualcomm也站队到支持的列表,给小弟有带头作用
2.当年的Java大战和收购Moto,Android有一些自我保护的专利。经过几年发展Linux社区也开始接纳这个臃肿的小绿人,毕竟Android已经让Linux内核部署到亿级别的用户人群中了
3.手机经过几年的快速增长,硬件厂商已经把相关技术参数基准线拉高了。IoT中的大部分产品属于单一功能设备,但联网时的软硬资件源消耗也很大,现在硬件设计上死守低配置反而成本比较高。Android Things需要大量硬件性能,对硬件公司来说是好事,他们肯定愿意站队背书
4.Android Things发布后,至少正面回应了Microsoft, Amazon, Apple的嘲笑
5.对于想抢先入场IoT行业的终端产品公司来说,Android开发积累的资源,还能继续使用,一个Android团队只需增加嵌入式开发人员,适配硬件层支持即可
6.IoT的设备,最终还是靠云端提供给用户功能或服务,这对于Google来说也是愿意看到的景象,符合其认同价值观念。Android上各大手机厂商都可以定制自己的应用市场,Android Things上主要是Weave保持通一就可以了,至于服务是否跑在Google服务器上也就无所谓了
7.最近几年,硅谷主要都是由互联网型公司在独挡一面,越来越多的人进入软件开发行来。自从Apple推出AppStore模式后,各大公司开始讨好开发者。Apple也推出更易用的Swift编程语言,以博得更多初级开发者的兴趣。Android一开始就选用的Java语言,也是每年的语言排行榜前三名了。Android Things沿用Java语言,也就不需要开发者的导入过程,上手即用

上面是我对Android Things的不可靠分析,欢迎拍砖。