Rokid ALL in ONE 全栈开发套件开箱——强人工智能入门指南[1]
强 AI 很弱,弱 AI 很强。
——薛定饿(作者的猫,图见文末)
首先,感谢 SF 和 Rokid 提供的 试用机会。
SF的小伙伴们,大家好,欢迎收看这一期的 Integ's Hack Show
今天我们来测评的是来自 Rokid 的一款 ALL in ONE 全栈开发套件。
Rokid 原本是一款智能音箱产品,这次测评的套件可以说是 Rokid 智能音箱去掉扬声器后,再加上 debug 接口,给智能硬件爱好者和开发者提供的一套智能硬件开发板,可玩度非常高。
所谓全栈开发套件,应该是说等我们彻底玩转这套智能硬件设备后,软件,硬件,前端,后端,机器学习,这些技能点都会被点亮吧。
硬件
套件拼装完成后效果图:
开箱时 debug 板并没有与核心板安装在一起。自己找来 3 个铜柱把 debug 板装上去。
这套智能套件共分三层从上到下分别是:
- 麦克风+LED:
麦克风*4, 彩色 LED*12
-
核心板:
- SoC:Amlogic S905D A54x4
- Memory: 2GB LPDDR3 + 16GB eMMC
- 博通 AP6255: 802.11ac + bluetooth 4.1/BLE
- debug 板: 调试串口,GPIO, 按键 等
(这个是V1.0的接口图片,这次测评的V1.1版少了一个USB 2.0 OTG 接口,其他大致形同)
从 SoC 方面看,这套 Amlogic S950 的 Android 方案也常被用来开发各种智能电视机顶盒,比如小米盒子3。不过在这块 Amlogic S905D 集成的 Mali-450 GPU 在不接显示器的情况下,是肯定用不上了。
2G + 16G 的存储方案,对于智能音箱这种不需要大量存储本地数据的 Android 智能家居应用来说已经够用。
开机
先把自己的耳机或音箱插到核心板上的耳机口上。再把核心板和 debug 板的两个 USB Type-C 都插上线,分别连接到电脑的两个 USB 口上。
此时电脑会识别到两个USB设备,一个是名为 rn102 的 Android 设备(可用 adb shell
调试),另一个是一个
USB 转串口设备(可输出启动及内核信息)。打开串口工具,选择波特率 115200,可以看到如下启动信息:
GXL:BL1:9ac50e:a1974b;FEAT:ADFC318C;POC:3;RCY:0;EMMC:0;READ:0;0.0;CHK:0;
TE: 214524
BL2 Built : 20:04:24, Aug 17 2017.
gxl g440fda4 - xiaobo.gu@droid12
rn5t618_power_init
set vdd cpu_b to 1050 mv
Board ID = 2
CPU clk: 1200MHz
DQS-corr enabled
DDR scramble enabled
LPDDR3 chl: Rank0+1 @ 768MHz - PASS
Rank0: 1024MB-2T-3
Rank1: 1024MB-2T-3
DataBus test pass!
AddrBus test pass!
-s
Load fip header from eMMC, src: 0x0000c200, des: 0x01400000, size: 0x00004000
New fip structure!
Load bl30 from eMMC, src: 0x00010200, des: 0x01100000, size: 0x0000d600
Load bl31 from eMMC, src: 0x00020200, des: 0x10100000, size: 0x00015400
Load bl33 from eMMC, src: 0x00038200, des: 0x01000000, size: 0x000b5c00
NOTICE: BL3-1: v1.0(debug):fb68908
NOTICE: BL3-1: Built : 18:30:11, Nov 1 2016
aml log : bl31 normal boot !
[Image: gxl_v1.1.3154-065f772 2016-09-29 14:08:54 yan.wang@droid05]
OPS=0x02
17 b9 88 e0 da e1 72 39 6d 2d 1 22 [0.484399 Inits done]
secure task start!
high task start!
low task start!
INFO: BL3-1: Initializing runtime services
WARNING: No OPTEE provided by BL2 boot loader
ERROR: Error initializing runtime service opteed_fast
INFO: BL3-1: Preparing for EL3 exit to normal world
INFO: BL3-1: Next image address = 0x1000000
INFO: BL3-1: Next image spsr = 0x3c9
U-Boot 2015.01-gcd65a08 (Oct 26 2017 - 23:37:46), Build: jenkins-pebble-amlogic- s9xx_nana-t_dev-20
DRAM: 2 GiB
Relocation Offset is: 76ebc000
register usb cfg[0][6] = 0000000077f5d130
register usb cfg[2][0] = 0000000077f5d108
vpu: error: vpu: check dts: FDT_ERR_BADMAGIC, load default parameters
vpu: clk_level = 7
vpu: set clk: 666667000Hz, readback: 666660000Hz(0x300)
vpp: vpp_init
boot_device_flag : 1
Nand PHY Ver:1.01.001.0006 (c) 2013 Amlogic Inc.
init bus_cycle=6, bus_timing=7, system=5.0ns
reset failed
get_chip_type and ret:fffffffe
get_chip_type and ret:fffffffe
chip detect failed and ret:fffffffe
nandphy_init failed and ret=0xfffffff1
MMC: aml_priv->desc_buf = 0x0000000073ebc6b0
aml_priv->desc_buf = 0x0000000073ebe9d0
SDIO Port B: 0, SDIO Port C: 1
emmc/sd response timeout, cmd8, status=0x1ff2800
emmc/sd response timeout, cmd55, status=0x1ff2800
[mmc_startup] mmc refix success
[mmc_init] mmc init success
start dts,buffer=0000000073ec0cf0,dt_addr=0000000073ec0cf0
parts: 11
00: logo 0000000002000000 1
01: recovery 0000000002000000 1
02: rsv 0000000000800000 1
03: tee 0000000000800000 1
04: crypt 0000000002000000 1
05: misc 0000000002000000 1
06: instaboot 0000000020000000 1
07: boot 0000000002000000 1
08: system 0000000080000000 1
09: cache 0000000008000000 2
10: data ffffffffffffffff 4
eMMC/TSD partition table have been checked OK!
mmc env offset: 0xf400000
In: serial
Out: serial
Err: serial
reboot_mode=cold_boot
hpd_state=0
cvbs performance type = 6, table = 0
[store]To run cmd[emmc dtb_read 0x1000000 0x40000]
_verify_dtb_checksum()-932: calc 8c24ddf3, store 8c24ddf3
_verify_dtb_checksum()-932: calc 8c24ddf3, store 8c24ddf3
dtb_read()-1042: total valid 2
dtb_read()-1109: do nothing
PMU fault status:
reg[0x9A] = 0x00
LSI version:00, OTP version:00
PMU type:RN5T618
[RN5T618] DUMP ALL REGISTERS
0x00 - 0f: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10 - 1f: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x20 - 2f: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x30 - 3f: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x40 - 4f: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x50 - 5f: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xb0 - bf: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
USB3.0 XHCI init start
detect usb battery charger mode: SDP (PC)
[pmic] :limit usb current to 500mA && limit ADP current 500mA
[RN5T618]rn5t618_set_dcin_current_limit, set dcin current limit to 500
[RN5T618]rn5t618_set_usb_current_limit, set usb current limit to 500
rn5t618_set_charging_current, 500mA
board_usb_stop cfg: 2
get_cpu_id flag_12bit=1
SARADC channel(1) is 0xa7.
hardwareid :0x2
enter cold_boot mode when detect boot reason
boot_reason: reg[09]: 0, boot reason: 1
Net: dwmac.c9410000
wipe_data=successful
wipe_cache=successful
upgrade_step=2
[OSD]load fb addr from dts
[OSD]failed to get fb addr for logo
[OSD]use default fb_addr parameters
[OSD]fb_addr for logo: 0x3d800000
[OSD]load fb addr from dts
[OSD]failed to get fb addr for logo
[OSD]use default fb_addr parameters
[OSD]fb_addr for logo: 0x3d800000
[CANVAS]canvas init
[CANVAS]addr=0x3d800000 width=3840, height=2160
get_cpu_id flag_12bit=1
enter cold_boot mode
amlkey_init() enter!
[EFUSE_MSG]keynum is 3
[BL31]: tee size: 0
[BL31]: tee size: 0
[BL31]: tee size: 0
[BL31]: tee size: 0
[BL31]: tee size: 0
success:serialno=0001121743000214
[BL31]: tee size: 0
[BL31]: tee size: 0
[BL31]: tee size: 0
[BL31]: tee size: 0
success:rokidseed=0hCg6mu8jen40Sbs947J919jir9338
Hit Enter or space or Ctrl+C key to stop autoboot -- : 0
ee_gate_off ...
## Booting Android Image at 0x01080000 ...
reloc_addr =73f40ec0
copy done
load dtb from 0x1000000 ......
Uncompressing Kernel Image ... OK
kernel loaded at 0x01080000, end = 0x0231d4c0
Loading Ramdisk to 73dc8000, end 73ea9e96 ... OK
Loading Device Tree to 000000001fff3000, end 000000001ffffa6f ... OK
signature:
fdt_instaboot: no instaboot image
Starting kernel ...
uboot time: 2962890 us
[ 0.000000@0] Initializing cgroup subsys cpu
[ 0.000000@0] Initializing cgroup subsys cpuacct
[ 0.000000@0] Linux version 3.14.29-g09f9591 (jenkins@build-4) (gcc version 4 .9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) ) #1 SMP PREEMPT Fri Oct 27 00:00:12 HKT 2017
[ 0.000000@0] CPU: AArch64 Processor [410fd034] revision 4
[ 0.000000@0] no prop version_code
[ 0.000000@0] bootconsole [earlycon0] enabled
[ 0.000000@0] fdt Reserved memory table:
[ 0.000000@0] linux,meson-fb: 0x000000007e000000 - 0x0000000080000 000 (32 MiB)
[ 0.000000@0] linux,di: 0x000000007c200000 - 0x000000007e000 000 (30 MiB)
[ 0.000000@0] DI: DI reserved memory: created CMA memory pool at 0x000000007c 200000, size 30 MiB
[ 0.000000@0] linux,ion-dev: 0x000000007b200000 - 0x000000007c200 000 (16 MiB)
[ 0.000000@0] linux,ppmgr: 0x000000007b200000 - 0x000000007b200 000 (0 MiB)
[ 0.000000@0] linux,codec_mm_cma: 0x0000000075000000 - 0x000000007b000 000 (96 MiB)
[ 0.000000@0] linux,picdec: 0x000000007b200000 - 0x000000007b200 000 (0 MiB)
[ 0.000000@0] Reserved memory: incorrect alignment of CMA region
[ 0.000000@0] linux,codec_mm_reserved: 0x0000000071c00000 - 0x0000000073d00 000 (33 MiB)
[ 0.000000@0] fdt Reserved memory total: 210 MiB
[ 0.000000@0] cma: Reserved 8 MiB at 74800000
[ 0.000000@0] psci: probing function IDs from device-tree
[ 0.000000@0] PERCPU: Embedded 12 pages/cpu @ffffffc07b1a0000 s19968 r8192 d2 0992 u49152
[ 0.000000@0] Built 1 zonelists in Zone order, mobility grouping on. Total p ages: 506004
[ 0.000000@0] Kernel command line: rootfstype=ramfs init=/init console=ttyS0, 115200 no_console_suspend earlyprintk=aml-uart,0xc81004c0 ramoops.pstore_en=1 ra moops.record_size=0x8000 ramoops.console_size=0x4000 androidboot.selinux=permiss ive logo=osd1,loaded,0x3d800000,576cvbs maxcpus=4 vout=576cvbs,enable hdmimode=1 080p60hz cvbsmode=576cvbs hdmitx= cvbsdrv=0 androidboot.firstboot=0 jtag=disable androidboot.serialno=0001121743000214 androidboot.rokidseed=0hCg6mu8jen40Sbs947 J919jir9338 androidboot.hardware=amlogic boardinfo.hardwareid=0x2 androidboot.ft m= androidboot.factory_date= androidboot.mode=
[ 0.000000@0] logo: osd1
[ 0.000000@0] logo: loaded
[ 0.000000@0] logo: 0x3d800000
[ 0.000000@0] logo: 576cvbs
[ 0.000000@0] vout_serve: 576cvbs
[ 0.000000@0] vout_serve: enable: 1
[ 0.000000@0] logo: get hdmimode: 1080p60hz
[ 0.000000@0] logo: get cvbsmode: 576cvbs
[ 0.000000@0] tv_vout: cvbs performance line = 0
[ 0.000000@0] jtag: jtag select -1
[ 0.000000@0] PID hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.000000@0] Dentry cache hash table entries: 262144 (order: 9, 2097152 byte s)
[ 0.000000@0] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes )
[ 0.000000@0] Memory: 1804080K/2060288K available (10640K kernel code, 3213K rwdata, 3936K rodata, 1263K init, 6381K bss, 256208K reserved)
...
很好,U-Boot 先加载 eMMC 中的内核,直到把整个 Android 跑起来。
此时套件还没有连上网,但是蓝牙已经可以使用了。在电脑上搜索附近的蓝牙设备,可以看到一个名为Rokid-pebble-XXXXXX
的蓝牙音箱,配对上去,在电脑上放首歌。嗯,不错,可以通过蓝牙听到电脑上音乐了。
然后是给套件配置网络,图省事的话可以直接在手机上下载 Rokid 的 App,通过手机蓝牙给套件配网。这里我们用adb shell
通过命令配置网络。
先通过 adb 连接上设备
$ adb devices
List of devices attached
0001121743000XXX device
$ adb shell
root@p230:/ # uname -a
Linux localhost 3.14.29 #1 SMP PREEMPT Fri Oct 27 00:00:12 HKT 2017 armv8l
搜索附近的 Wifi:
root@p230:/ # wpa_cli -i wlan0 -p /data/misc/wifi/sockets
wpa_cli v2.5-devel-6.0.1
Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors
This software may be distributed under the terms of the BSD license.
See README for more details.
Interactive mode
> scan
OK
> scan_results
bssid / frequency / signal level / flags / ssid
XX:XX:35:3a:19:18 2447 -43 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] 1202
XX:XX:8e:8f:86:91 2412 -56 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] LY
XX:XX:17:14:d4:40 2437 -67 [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS] wahaha88888
...
如果发现搜不到自己的 Wifi, 一般是因为套件 Wifi 驱动的国家字段跟自己路由器中的设置不一样,用下面的命令修改一下(AU 是澳大利亚,频段比较多):
root@p230:/ # wpa_cli -i wlan0 DRIVER COUNTRY AU
这样每次重启都得要改一下,比较麻烦,用下面的命令可以永久生效:
root@p230:/ # mount -o remount,rw /system
root@p230:/ # sed -i '2c ccode=AU' /system/etc/wifi/6255/config.txt
修改后再 scan 一下就能搜到了。然后是联网:
root@p230:/ # wpa_cli -i wlan0 -p /data/misc/wifi/sockets
wpa_cli v2.5-devel-6.0.1
Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors
This software may be distributed under the terms of the BSD license.
See README for more details.
Interactive mode
> list_networks
network id / ssid / bssid / flags
> add_network
0
> set_network 0 ssid "XXXX" #wifi name
OK
> set_network 0 psk "XXXX" #wifi password
OK
> enable_network 0
OK
> list_networks
network id / ssid / bssid / flags
0 Int&Ade_5G any [current]
> save_config
OK
> quit
好了,现在我们的套件已经连上了网络,你也可以通过语音和 Rokid 交流了。
软件
用 pm
看看套件中都安装了那些 app
root@p230:/ # pm list packages
package:com.android.providers.telephony
package:com.android.providers.calendar
package:com.android.tv.settings
package:com.android.providers.media
package:com.android.wallpapercropper
package:com.rokid.app.timer
package:com.rokid.rkengine
package:com.droidlogic.PPPoE
package:com.android.documentsui
package:com.android.externalstorage
package:com.android.providers.downloads
package:com.rokid.life
package:com.rokid.childstory
package:com.droidlogic
package:com.android.defcontainer
package:com.android.pacprocessor
package:com.rokid.tts
package:com.rokid.runtime
package:com.rokid.networkstarter
package:com.android.certinstaller
package:android
package:com.android.camera2
package:com.alibaba.cloudpushdemo
package:com.rokid.activation
package:com.rokid.crosstalk
package:com.rokid.openvoice.rokidstore
package:com.android.backupconfirm
package:com.rokid.service
package:com.android.provision
package:com.android.statementservice
package:com.rokid.alarm1
package:com.rokid.app.rs
package:com.android.providers.settings
package:com.android.sharedstoragebackup
package:com.droidlogic.service.remotecontrol
package:com.android.dreams.basic
package:com.android.webview
package:com.android.inputdevices
package:com.droidlogic.readlog
package:com.rokid.systemui
package:com.rokid.rkasragent
package:com.android.onetimeinitializer
package:com.android.keychain
package:com.rokid.soundbook
package:com.android.packageinstaller
package:com.example.android.home
package:com.android.proxyhandler
package:com.rokid.fm
package:com.android.dreams.phototable
package:com.rokid.connection
package:com.android.smspush
package:com.rokid.launcher
package:com.rokid.calendar1
package:com.rokid.cloudappclient
package:com.rokid.openlecture
package:com.android.settings
package:com.android.vpndialogs
package:com.android.shell
package:com.rokid.weather1
package:com.android.providers.userdictionary
package:com.rokid.talkshow
package:com.android.location.fused
package:com.rokid.appchannel
package:com.android.systemui
package:com.rokid.server.rkupdate
package:com.rokid.light
package:com.rokid.homebase
package:com.rokid.time1
package:com.rokid.rkfirstguide
package:com.android.bluetooth
package:com.android.providers.contacts
package:com.android.captiveportallogin
package:com.rokid.historicalreading
root@p230:/ #
用 screencap
截个屏
$ adb shell screencap /sdcard/DCIM/screen.png
$ adb pull /sdcard/DCIM/screen.png
看来系统和 Rokid Pebble 是一样的,默认 1920*1080 的分辨率,板子上有 macro HDMI 接口,找机会连个显示器试试。
查看下权限
root@p230:/ # type su
su is /system/xbin/su
root@p230:/ # mount
rootfs / rootfs ro,seclabel 0 0
tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0
devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,seclabel,relatime 0 0
selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
/sys/kernel/debug /sys/kernel/debug debugfs rw,seclabel,relatime 0 0
configfs /sys/kernel/config configfs rw,relatime 0 0
none /acct cgroup rw,relatime,cpuacct 0 0
none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0
tmpfs /mnt tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
none /dev/cpuctl cgroup rw,relatime,cpu 0 0
pstore /sys/fs/pstore pstore rw,seclabel,relatime 0 0
/dev/block/system /system ext4 ro,seclabel,relatime,data=ordered 0 0
/dev/block/data /data ext4 rw,seclabel,nosuid,nodev,noatime,nodelalloc,errors=panic,data=ordered 0 0
/dev/block/cache /cache ext4 rw,seclabel,nosuid,nodev,noatime,nodelalloc,errors=panic,data=ordered 0 0
/dev/block/tee /tee ext4 rw,seclabel,nosuid,nodev,noatime,nodelalloc,errors=panic,data=ordered 0 0
/dev/block/zram0 /swap_zram0 ext4 rw,seclabel,relatime,data=ordered 0 0
tmpfs /storage tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
adb /dev/usb-ffs/adb functionfs rw,relatime 0 0
/dev/fuse /mnt/runtime/default/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /storage/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /mnt/runtime/read/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /mnt/runtime/write/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
已经有了root 权限,/data
和 /storage
是可以读写的,/system
只读。
用下面的命令重新 mount /system 为可读写:
root@p230:/ # mount -o remount,rw /system
这样就可以为所欲为了。
可以 adb pull
Rokid 的 apk 到本地:
adb pull /data/app ./rokid_app
发现系统里一个喜闻乐见的小玩具 node-android
。以后可以利用下,用 express 搭个 web server。
root@p230:/ # node-android --version
v6.9.0
root@p230:/ # node-android -h
Usage: node [options] [ -e script | script.js ] [arguments]
node debug script.js [arguments]
Options:
-v, --version print Node.js version
-e, --eval script evaluate script
-p, --print evaluate script and print result
-c, --check syntax check script without executing
-i, --interactive always enter the REPL even if stdin
does not appear to be a terminal
-r, --require module to preload (option can be repeated)
--no-deprecation silence deprecation warnings
--trace-deprecation show stack traces on deprecations
--throw-deprecation throw an exception anytime a deprecated function is used
--no-warnings silence all process warnings
--trace-warnings show stack traces on process warnings
--trace-sync-io show stack trace when use of sync IO
is detected after the first tick
--track-heap-objects track heap object allocations for heap snapshots
--prof-process process v8 profiler output generated
using --prof
--zero-fill-buffers automatically zero-fill all newly allocated
Buffer and SlowBuffer instances
--v8-options print v8 command line options
--v8-pool-size=num set v8's thread pool size
--tls-cipher-list=val use an alternative default TLS cipher list
--openssl-config=path load OpenSSL configuration file from the
specified path
Environment variables:
NODE_PATH ':'-separated list of directories
prefixed to the module search path.
NODE_DISABLE_COLORS set to 1 to disable colors in the REPL
NODE_REPL_HISTORY path to the persistent REPL history file
Documentation can be found at https://nodejs.org/
最后习惯性地用 nmap 扫一下端口:
$ nmap 192.168.1.12
Nmap scan report for 192.168.1.12
Host is up (0.016s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
5555/tcp open freeciv
MAC Address: CC:B8:A8:09:C2:56 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 1.18 seconds
$ adb connect 192.168.1.12:5555
connected to 192.168.1.12:5555
$ adb -e shell
5555 是 Android 远程调试的端口,应该是为了方便开发者,默认打开了 Android 的远程调试。
结语
好的,本期的开箱体验就告一段落。
未来我还会尝试通过 Rokid 的自定义技能服务,给这块All in One 套件添加一些好玩的功能,敬请期待!
若琪与猫
本文参与了 SegmentFault「Rokid 开发板试用,开启你的嵌入式开发之旅」活动,欢迎正在阅读的你申请试用,一起交流开发心得。
寒蝉效应
利用规则引擎的M2M实现设备之间联动——实践类
阿里云AIoT阅读 172
如何在IoT物联网平台注册私有CA证书,来实现X.509方式设备身份认证?——实践类
阿里云AIoT阅读 156
设备用私有CA签发的X.509证书接入IoT物联网平台——实践类
阿里云AIoT阅读 146
物联网平台华南1(深圳) 实例化开发实战——实践类
阿里云AIoT阅读 135
阿里云物联网平台业务Topic规划最佳实践——实践类
阿里云AIoT阅读 125
百度安全助力小度智能屏通过中国泰尔实验室适老化技术测试认定
百度安全
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。