Google年底突然发布Android Thing生态系统,还有一堆芯片公司站台。公布的已支持硬件里面,能买到的只有intel和rasperry pi开发板了,IMX6的基本无货。本文先以Raspberry Pi3B作为开发板,体验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灯有亮灭变化。
自从2015年Google在IO大会上提出Brillo和Weave进军IoT行来后,这一年多基本音信全无,2016年的IO大会基本没有提到,没想到年底又出了个Android Things的大新闻。结合上次分析IoT操作系统,不负责的揣测下事情经过。Google一向对硬件兴趣不大,毕竟硬件高收益都是处于市场垄断时,溢价才会更高。然后互联网都是服务大众,Google还是要做网络服务为主的业务,最早收购Nest就想用他家的协议,想整合到Android上。Brillo发布后,从官方文档和系统架构图上了解,应用是用C/C++来编写NDK应用,这样就做到了官方宣称的,内存32MB,存储128MB的配置,也可以运行。但是C/C++对开发者并不友好,上层应用还是要用更高级的面向对象语言编写更合适。Google的其它开发组又放出了个新的系统Fushia,连内核都是重新写了,上层应用使用Dart语言开发,从内核机制了解到时,可能是适用于VR,IoT方向的产品。然后,Microsoft和Amazon接边在部署IoT相关系统和业务,就连ubuntu都出了系统,Google应该是等不了Fushia开发完成,先联合硬件公司发布一个基于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团队只需增加嵌入式开发人员,适配硬件层支持即可
上面是我对Android Things的不负责任的揣测,欢迎拍砖。