Firefly集群服务器产品WIKI

一、产品介绍

1. 产品简介

Firefly集群服务器是一款高密度ARM核心板卡的集群服务器。服务器采用机架式服务器规格设计,核心板卡基于Rockchip芯片平台。通过Firefly的创新设计和软件支持,使得集群服务器在云手机、边缘计算等多领域具有良好的适应性。Firefly集群服务器经过多个软硬件版本迭代,现已经具有完善合理的软硬件系统支持,并且具有以下特色:

  • 高密度核心:

R1版集群服务器为1U规格,支持集成11个独立核心板卡。

R2版集群服务器为2U规格,支持集成72个独立板卡。

  • 核心板卡可配置

根据业务场景的需求,集群服务器的核心板卡可以选择不同的规格。并且也支持不同规格板卡混插。如云手机、AI运算、区块链运算等,都可以选用不同规格的核心板卡。

  • 核心板软件系统独立

集群服务器各个核心板卡可独立运行Android/Linux 操作系统。单个核心板故障不会导致整个服务器宕机。

  • BMC可视化管理系统

通过集群服务器的BMC管理单元,可以实现用户在web浏览器对核心板卡的监测、配置、系统更新等操作。

  • 热插拔设计

集群服务器的电源单元、子核心板单元、网络单元、温控单元、扩展存储单元均采用热插拔设计,可以有效降低服务器的部署和维护工作。

  • 冗余设计

集群服务器的电源管理单元和网络管理单元采用冗余设计,可以应对部分电源和网络的突发故障。

  • 温控设计

集群服务器集成温控单元,通过监测服务器内环境温度和核心温度,可以有效调节散热风扇工作状态,优化服务器的整体性能和稳定性。

2. 产品规格

(1). 技术规格

型 号 Cluster Server R1 Cluster Server R2
核心板卡数 11 72 (热插拔设计)
构 架 ARM架构 ARM架构
操作系统 支持Android、Ubuntu、Linux操作系统 支持Android、Ubuntu、Linux操作系统
网 络 1GE千兆RJ45网口4个其中:主核心板网口1个,普通网口3个 双网卡冗余设计,单网卡集成:千兆网口(RJ45)×2、万兆网口(SFP+)×2BMC网络接口
4G 4G/LTE/5G网络(可选配) 不支持
显 示 1×Mini HDMI 2.0,4K@60Hz(控制主板显示) 1×Mini HDMI 2.0,4K@60Hz(控制主板显示)
扩展存储 3.5寸STAT硬盘 3.5寸STAT硬盘 / SD卡
USB 2个USB2.0 HOST1 个 Type-C(处理器核心板调试用) 1 × USB3.0 HOST
电 源 300W AC电源(输入:100V AC~240V AC) 双路冗余电源设计 :AC 100~240V 50/60Hz,1300W / 800W 可选
散 热 散热片 +5个高速散热风扇 散热片 + 2组风扇模组: 风扇模组1(3×2冗余风扇设计)、风扇模组2(2×2冗余风扇设计)
UID UID按键×1
硬件看门狗

(2). 子板规格

型 号 Cluster Server R1 Cluster Server R2
节点数 一体化1U服务器 9个刀片节点
每个节点都能配置8个处理器核心板
节点9可用于安装2个3.5寸SATA/SSD硬盘
核心数 最高可配置11个处理器核心板 最高可配72个处理器核心板
核心板 RK3399(AI)核心板(Core-3399-JD4)
RK3328核心板(Core-3328-JD4)
RK1808(AI)核心板(Core-1808-JD4)
RK3399(AI)核心板(Core-3399-JD4)
RK3328核心板(Core-3328-JD4)
RK1808(AI)核心板(Core-1808-JD4)
内 存 1GB / 2GB / 4GB 1GB / 2GB / 4GB
存 储 eMMC
3.5英寸硬盘
1个SATA/SSD硬盘
eMMC
3.5英寸SATA/SSD硬盘位x2(节点9)
SD卡 x1

说明: Firefly后期会持续推出更高性能,更大内存的的核心子板,支持8 / 16G内存

(3). 物理规格

型 号 Cluster Server R1 Cluster Server R2
尺 寸 标准1U机架式:490mm x 390mm x 44.4mm 标准2U服务器机箱:580mm x 434mm x 88.8mm
重 量 服务器主机:5.8kg 包装总重:7.2 kg 包装总重量:29 kg

(4). 环境规格

型 号 Cluster Server R1 Cluster Server R2
工作温度 0ºC - 40ºC 0ºC - 50ºC
工作湿度 8%RH~95%RH 10%RH~80%RH

二、使用说明

1. 整机说明

  • 集群服务器 Cluster Server R1

    _images/wps102.png

    _images/wps103.png

2. BMC管理系统

BMC管理系统是一套运行集群服务器BMC管理单元上的软件系统,BMC管理单元是一块使用RK3399作为主控芯片的控制板(以下简称主板),主板运行Ubuntu 18.04系统,通过网络和USB接口与集群服务器内其它核心板(以下简称子板)进行数据交互,实现对集群服务器各个核心板卡的监测和管理。其软件栈的组成为:

  • node_exporter: 运行在主板和子板上,负责收集设备的监控数据。

  • Prometheus: 运行在主板上,负责收集和存储各个设备的监控数据。

  • Grafana: 运行在主板上,负责监控图表的集中显示。

该方案的优点是,由主板统一布署 node_exporter 到各个设备上(子板的操作系统可以是 Android 或 Ubuntu),以直观的图表方式显示各个子板的资源使用状况。

(1). 登录

  • 外接HDMI显示器:

通过集群服务器的HDMI接口接显示器,接入鼠标键盘,可以登入BMC管理单元Ubuntu系统,打开系统浏览器,在地址栏输入 http://127.0.0.1:3000 并回车即可访问,⽆需任何配置。

  • 使用BMC扫描工具:

通过BMC扫描工具可获取同一局域网内所有的BMC管理系统IP地址,打开工具后会默认扫描一次局域网,也可通过刷新按钮 _images/wps1.jpg 手动扫描,根据软件界面中呈现的BMC管理系统IP地址列表项,点击ACTIONS下相应的 _images/wps2.jpg 图标即可打开外部浏览器并进入相应IP地址的BMC管理系统登录页面。

_images/wps40.png

  • BMC系统初始用户名:admin 密码:admin,点击登录按钮,进⼊默认的设备列表页⾯。

_images/wps4.png

(2). 设备列表

登录后默认进入设备列表页面。任何时候需要访问设备列表页面,点击左边工具栏上的 _images/wps5.jpg 图标即可进入:

_images/wps6.png

这是集群服务器所有设备的列表,每个卡片代表一块设备。

设备列表页面的左上角,有两个下拉列表:

_images/wps7.jpg

(1). 设备:可以过滤需要显示的设备,这在设备比较多的情况下很有用。

(2). 离线设备:仅供快速查看离线设备的列表。

往下看,这是服务器提供的外设接口图(仅R1 有此面板):4个网口,双层USB,HDMI,OTG,Sim Card,磁盘;

_images/wps8.jpg

U:LAN 表示:上方黄色的LED灯的亮/灭对应着该设备的网络状态;

D:WORK 表示:下方绿色的LED灯的亮/灭对应着该设备的工作状态;

每个设备卡片,根据状态有不同的显示:

  1. 当设备可以通过 adb 访问,并进入正常的操作系统:
    _images/wps9.jpg

    • 卡片顶部左边以绿色字样显示“设备可用”状态,后跟设备的当前操作系统,右边显示的是软件操作系统的版本和硬件版本(硬件版本仅 R2 有);

    • 左边的图标表示核心板的 CPU 型号(CPU 核数和最高频率)、DDR 内存(4G) 和 eMMC 容量(32G);

    • “sub04”: 表示设备的 SUB 编号;

    • _images/wps10.jpg:点击该按钮进入 Shell 终端窗口;

    • _images/wps11.jpg:点击该按钮进入该设备的资源明细终端窗口;

    • _images/wps12.jpg:点击该按钮重置设备电源;

    • 卡片右边第二行显示该设备的主网络接口的 IP 地址及连接速率,鼠标悬停时会显示所有网络接口地址和速率(目前仅主板有多个网络接口);

    • 四个方块图分别显示 CPU、内存和磁盘的使用率,以及 CPU 的温度。

  2. 当设备处于离线状态,即设备由于物理移除、固件失效或操作系统异常等原因导致与主板的 usb 通讯失效时:
    _images/wps13.jpg

    • 卡片顶部以橙色字样显示“设备不可用”状态;

    • _images/wps14.jpg:点击该按钮重置设备电源。

  3. 当设备处理维护状态,即设备处于系统升级模式(loader)、固件升级系统(netrecovery)、安卓急救模式(android_recovery)或 ADB 离线(android_offline),将会显示:
    _images/wps14_1.jpg

    • 卡片顶部以黄色字样显示“设备维护”状态,后跟设备的明细状态。

    • 设备信息均为空,维护状态下不采集监控数据。

    • _images/wps14.jpg:点击该按钮重置设备电源。

(3). 仪表盘列表

在设备列表或其它仪表盘页面中,点击最左上角的仪表盘名称:

_images/wps15.jpg

可以查看更多的仪表盘:

_images/wps16.jpg

目前有以下仪表盘:

  • 设备概览

  • 设备明细

  • CPU 频率与温度监控

在仪表盘页面中,右上角的工具条,可以选择浏览时段,以及多长间隔自动更新。下图就显示最近 6 小时的数据,并每 5 秒更新一次。

_images/wps17.jpg

点击 _images/wps18.jpg 按钮可手工刷新监控数据页面显示。

A. 设备概览

通过仪表盘列表,或点击左边工具栏上的 _images/wps19.jpg 图标即可进入设备概览页面:

_images/wps20.png

设备概览页面将所有设备的 CPU、内存、磁盘和网络这四项数据集中显示在一起:

  • 鼠标悬停在曲线图上即可显示设备的明细数值。

  • 右上的“告警列表”,当 CPU、内存和磁盘超过红色警戒线一段时间,即触发告警动作,例如发送邮件等(此项功能需配置相关参数,待加说明)。

  • 右下的“设备列表”,列出所有在线设备的结点名称和 IP 地址,方便查看。鼠标点击即可查看该设备的设备明细页面。

B. 设备明细

有以下几种方法可以进入设备明细页面:

  1. 设备列表页面中点击设备卡上的 _images/wps21.jpg 按钮;

  2. 设备概览页面中点击右边设备列表上的表格项;

  3. 通过仪表盘列表进入。

_images/wps22.png

设备明细页面,提供资源的详细监控数据,用户可以选择其中一个设备来查看其详细的资源使用情况。

左上的结点下拉选择框可以切换设备的明细显示,IP 地址即为该设备的所有网络接口的 IP 地址(仅作信息显示之用):

_images/wps23.png

右边的快速工具条,点击即可打开该设备的 Shell 终端窗口:

_images/wps24.jpg

利用右边的滚动条往下翻,可见更多的监控项:

_images/wps25.png

C. CPU频率与温度监控

CPU 频率与温度监控页面用作开发阶段比对 CPU 频率与 SOC、GPU 温度的关系,看是否会因为风扇散热性能不足导致温度持续上升,进而导致 CPU 强制降频。

_images/wps27.png

RK3399 有 6 个 CPU 核心,分别是小核 0~3, 大核 4~5。一般观测大核即可,因为页面空间原因,同一时间只显示一个核心。通过上部的下拉条可以切换核心显示:

_images/wps28.jpg

(4). Shell终端窗口

有以下几种方法可以进入设备的 Shell 终端窗口:

  1. 点击设备列表页面中点击设备卡上的 _images/wps29.jpg 按钮;

  2. 点击设备明细页面右上角的快速工具条 _images/wps30.jpg

_images/wps31.png

主板的 Shell 终端窗口是主板 Ubuntu 系统下的 root shell,拥有超级用户的权限,可以执行各种系统维护命令,以及通过 adb 去操作各个子板。

子板的 Shell 终端窗口是 adb shell,可以运行 su 命令切换成 root 用户。

为方便管理,Firefly 集群监控系统引进命令行管理工具 bmc,能快速地进行各种日常子板操作和批量操作,详情请参见《bmc 命令行工具》一章。

(5). 子板固件升级

准备工作:

  • 重要: 主板和要升级的子板都需要获得有效的 DHCP IP 地址,请务必插好网线。

  • 集群服务器的 OTG USB 口与外部 PC 机的连接必须断开。

  • 固件需要以 “.img” 扩展名结尾,并放到主板的 /home/firefly/Firmware 目录里。

点击左边工具栏上的 _images/wps32.jpg 图标即可进入子板固件升级页面:

_images/wps33.png

点击右上角的按钮 _images/wps34.jpg 进入“新增子板固件升级”页面:

_images/wps35.png

  • 选择升级固件,在下拉列表中选择即可。

  • 选择升级设备:左边是可用的设备列表,右边则是待升级的设备列表。

    • 若要升级所有的设备,按“添加全部”按钮,可将所有的可用设备添加到右边的列表中。

    • 若要升级一两个设备,直接鼠标双击对应的设备,可将单个设备添加到右边的列表中。

    • 设备列表上方的编辑框是做筛选之用,可快速筛选出需要的设备。

    • 按“删除全部”按钮,可清空待升级的设备列表。

    • Ctrl+鼠标点击,可以增加或删除单个设备的选择;Shift+鼠标点击则可以增加或删除连续设备的选择。这跟 Windows 上的列表选择操作是一致的。选择设备后,按相应的“添加”或“删除”按钮即可将设备添加或移除到待升级的设备列表。

  • 按“升级固件”按钮,即可开始固件升级。

刚提交的页面是这样的:

_images/wps36.jpg

固件的升级时间较长(涉及到后台一系列切换和读写操作),请耐心等待。后台是隔 15 秒刷新一次进度,界面会显示如下的进度页面:

_images/wps37.jpg

  • 左边是升级设备和进度列表。

  • 右上是升级进度折线图。

  • 右下即是已完成的设备列表(包括成功和出错的)。

(6). 修改密码

鼠标移到左下角用户头像,在弹出菜单中选择“修改密码”:

_images/wps38.jpg

输入旧密码、新密码和确认新密码,最后按“修改密码”按钮即可。

(7). BMC 升级

鼠标移至左下角的帮助图标:

_images/wps38_1.jpg

在弹出菜单中选择“检查更新”。如果 BMC 有新版本,将会弹出对话框,并显示更新日志:

_images/wps38_2.jpg

点击对话框右上角的“安装”按钮,系统将会自动下载安装包、安装并自动刷新界面。

三、应用场景

1. 云手机

Firefly集群服务器的每一个核心板卡都可以独立运行一个Android系统。用户可以将自己的手机应用部署到每个核心板上。针对云手机应用场景,Firefly集群服务器增加了以下功能。

(1). 虚拟硬件设备

包括虚拟摄像头、虚拟声卡等。专业技术支持和更详细资料请联系商务。

  • 虚拟摄像头

智能设备在没有安装摄像头或不能安装摄像头的情况下,会导致需要打开摄像头的应用无法使用;而Firefly的虚拟摄像头技术案例可在Firefly集群服务器上虚拟出多个摄像头,通过虚拟摄像头,用户可把准备好的视频文件/图片等加载进去,让这些虚拟摄像头输出这些图像信息。

  • 虚拟声卡

众所周知在没有声卡的设备上播放音频、视频文件,会出现“没有找到音频设备…”“由于声音,设备出现问题…”等等提示而不能播放。而Firefly的虚拟声卡技术案例可在Firefly集群服务器上虚拟出声卡,可以让没有声卡的设备播放音频文件,而不会因为提示没有设备而不能播放。

(2). NFS,iSCSI网络存储

Firefly 集群服务器上(包括android,linux系统)提供NFS,iSCSI网络存储方案,实现存储资源统一管理。专业技术支持和更详细资料请联系商务。

  • NFS

NFS( Network File System,网络文件系统),对于在同一个网络上的多个用户间共享目录和文件很有用途。通过使用NFS,用户和程序可以像访问本地文件一样访问远程系统上的文件。

  • iSCSI

iSCSI( Internet Small Computer System Interface,Internet小型计算机系统接口)。iSCSI使用了TCP/IP协议(一般使用TCP端口860和3260),透过两部计算机之间利用iSCSI的协议来交换SCSI命令,让计算机可以透过高速的局域网集线来把SAN(存储局域网)模拟成为本地的储存装置。可以使用它来连接服务器计算机 (例如,数据库服务器)和磁盘卷上存储阵列。较NFS其读写效率、稳定性更好。

(3). 虚拟Android系统

虚拟Android系统是指在一个Soc中,利用容器和虚拟设备技术,虚拟出多个Android系统,每个Android系统之间独立运行。对于用户而言,如果一个子核心板虚拟三个Android设备,那么一个集群服务器最多可以虚拟216个Android设备。虚拟Android系统在应用程序测试、社交媒体运营等邻域有着广泛的应用。

2. 云计算

Firefly集群服务器的子核心板有多种配置(参见)。其中RK3399采用双核A72+4核A53架构,集成MaliT860P4 GPU。而RK1126采用RK最新一代NPU架构,AI算力最高可达3T。所以使用Firefly集群服务器作为云计算平台,也是很合适的。针对云计算平台,Firefly集群服务器增强了以下功能支持。

(1). Ubuntu Minimal系统支持

Ubuntu系统在工作环境搭建,部署,更新等环节都非常方便。Firefly集群服务器子核心板搭载的Ubuntu Minimal系统,具有以下优势:

  • 没有桌面环境,占用资源少,在简化网络管理之后,只需40M内存;

  • 针对嵌入式平台,精简系统服务。

  • 提供基于Rockchip VPU + Mpp 的视频硬编解码支持。

  • 提供基于Arm Mali GPU的OpenGL、OpenCL支持。

  • 适配QT、Docker、Electron等开发框架。

  • 提供一系列接口,以操作板载资源设备。

  • 系统采用overlayfs文件系统,支持导出rootfs,二次打包,恢复出厂设置等功能

(2). 多路IPC解码+AI推理

​ Firefly集群服务器,核心板搭配方案采用RK3399 + RK1808 x N,实现了多路网络视频流解码与AI分析。该方案中,集群服务器连接多路网络摄像头进行视频数据采集,利用RK3399强大的视频解码功能对采集到的视频流解码后分发给AI加速芯片RK1808完成AI分析;然后再收集AI分析的结果,实时输出到用户端。

详细介绍参见:多路视频解码与AI分析

四、BMC二次开发

1. 监控数据获取

所有监控数据都存储到主板的 Prometheus 数据库里,可以使用其命令工具 promtool 去获取监控数据。

监控数据是透过 node_exporter 去获取的。

网页的仪表盘定义 json 文件存放在 /var/lib/grafana/dashboards/ 里。

(1). 获取所有子板的即时在线状态

$ promtool query instant http://127.0.0.1:9090 node_cluster_up
node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", state="android", subnode="sub1-01"} => 1 @[1608772515.659]
node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", state="android", subnode="sub1-02"} => 1 @[1608772515.659]
node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", state="android", subnode="sub1-03"} => 1 @[1608772515.659]
node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", state="android", subnode="sub1-04"} => 1 @[1608772515.659]
...
  • subnode: 子板编号

  • state:子板状态

    • android:子板运行的操作系统为 Android。

    • linux:子板运行操作系统为 Linux。

    • netrecovery:子板处于辅助升级系统 netrecovery 状态。

    • offline:子板离线,无法通过 USB 连接检测到。

    • online:子板能通过 USB 连接检测到,但无法解析进一步的状态。

    • loader:子板处于 Loader 状态。

    • fastboot: 子板处于 Fastboot 状态。

    • adb:子板被识别为 adb 设备,但暂未识别到其操作系统。

    • adb_offline: 子板被识别为处于 offline 状态的 adb 设备,无法进行正常 adb 操作。

    • android_recovery: 子板进入了 Android 的 recovery 系统。

  • metric:

    • 1.0: 子板处于 android 或 linux 状态。

    • 0.0: 子板处于 offline 状态。

    • 0.5: 子板处于上述状态之外。

(2). 获取主机温度

A. 获取主板温度(仅R2)

通过读取底板上的热敏电阻来获取其温度(单位:摄氏度):

$ promtool query instant http://127.0.0.1:9090 'node_hwmon_temp_celsius{chip=~"platform_ntc.*"}'
node_hwmon_temp_celsius{chip="platform_ntc", instance="127.0.0.1:60101", job="node", nodename="sub1-01", sensor="temp1"} => 34.779 @[1608773513.849]
node_hwmon_temp_celsius{chip="platform_ntc", instance="127.0.0.1:60102", job="node", nodename="sub1-02", sensor="temp1"} => 42.81 @[1608773513.849]
node_hwmon_temp_celsius{chip="platform_ntc", instance="127.0.0.1:60103", job="node", nodename="sub1-03", sensor="temp1"} => 43.305 @[1608773513.849]
...

B. 获取主机内环境温度(仅R2)

通过读取主机内的 ds18b20 温度传感器的数据来获取主机内的环境温度(单位:摄氏度):

$ promtool query instant http://127.0.0.1:9090 'node_cluster_env_temp_celsius'

(3). 获取风扇的转速(仅R2)

单位:RPM (转/分钟)

$ promtool query instant http://127.0.0.1:9090 node_cluster_fan_speed
node_cluster_fan_speed{fan="fan1", instance="127.0.0.1:9100", job="node", nodename="main"} => 7812 @[1607501007.839]
node_cluster_fan_speed{fan="fan2", instance="127.0.0.1:9100", job="node", nodename="main"} => 7936 @[1607501007.839]
...
  • R2v2 有 10 块能监控转速的风扇。

(4). 获取接入硬盘状态

获取硬盘设备名称和型号:

$ promtool query instant http://127.0.0.1:9090 node_cluster_disk_up
node_cluster_disk_up{device="sda", instance="127.0.0.1:9100", job="node", model="ST1000DM010-2EP1", nodename="main"} => 1 @[1609228221.442]

获取硬盘总容量(单位:字节):

$ promtool query instant http://127.0.0.1:9090 node_cluster_disk_bytes_total
node_cluster_disk_bytes_total{device="sda", instance="127.0.0.1:9100", job="node", nodename="main"} => 1000204886016 @[1609228289.651]

获取硬盘已使用空间(单位:字节):

$ promtool query instant http://127.0.0.1:9090 node_cluster_disk_bytes__used
node_cluster_disk_bytes_used{device="sda", instance="127.0.0.1:9100", job="node", nodename="main"} => 121475072 @[1609228366.843]

(5). 获取所有设备的 IP 地址

$ promtool query instant http://127.0.0.1:9090 node_network_ipaddr
node_network_ipaddr{device="eth0", instance="127.0.0.1:60101", ipaddr="168.168.101.198", job="node", nodename="sub1-01"} => 1 @[1609396443.993]
node_network_ipaddr{device="eth0", instance="127.0.0.1:60102", ipaddr="168.168.100.180", job="node", nodename="sub1-02"} => 1 @[1609396443.993]
node_network_ipaddr{device="eth0", instance="127.0.0.1:60103", ipaddr="168.168.101.145", job="node", nodename="sub1-03"} => 1 @[1609396443.993]
...
  • device: 网络接口名称,各个子板仅有一个以太网接口 eth0, 主板有多个。每个网络接口对应一个 IP 地址。

  • ipaddr:IP 地址,如果尚没有取得 IP 地址,则为 “0.0.0.0”。

  • nodename:子板 sub 编号,或主板 main。

2. 硬件控制

(1). 重置子板电源

  • 功能: 重置子板电源

  • 描述: 通过操控子板的 RESET 脚来重置子板电源,达到强制重启子板的目的。如果子板没有 RESET 脚,则通过关闭、打开电源来实现。

  • 调用:

    • 命令行可运行: /usr/bin/bmc <子板SUB编号> reset

    • Web API:GET http://localhost:7070/api/reset/<子板SUB编号>

(2). 重启子板操作系统

  • 功能: 重启子板操作系统

  • 描述: 首先通过 adb reboot 命令来重启系统,如果 10 秒内没有反应,则通过复位电源的方式强行重启子板。

  • 调用:

    • 命令行可运行: /usr/bin/bmc <子板SUB编号> reboot

    • Web API:GET http://localhost:7070/api/reboot/<子板SUB编号>

(3). 打开子板电源(仅R2)

  • 功能:打开子板电源

  • 描述:通过操控子板的 POWER 脚来打开子板电源。集群服务器开机默认打开所有子板电源。

  • 调用:

    • 命令行可运行: /usr/bin/bmc <子板SUB编号> poweron

    • Web API:GET http://localhost:7070/api/poweron/<子板SUB编号>

(4). 关闭子板电源(仅R2)

  • 功能:关闭子板电源

  • 描述:通过操控子板的 POWER 脚来关闭子板电源。

  • 调用:

    • 命令行可运行: /usr/bin/bmc <子板SUB编号> poweroff

    • Web API:GET http://localhost:7070/api/poweroff/<子板SUB编号>

3. 固件升级

使用脚本添加固件升级任务:

sudo netrecovery-master queue <固件文件绝对路径> <子板SUB编号> [<子板SUB编号> ...]

例如:

sudo netrecovery-master queue /home/firefly/Firmware/xxx.img sub1-01 sub1-02

查看固件升级进度:

$ promtool query instant http://127.0.0.1:9090 node_cluster_firmware_upgrade_stat
node_cluster_firmware_upgrade_stat{firmware="SR-C11G-3399JD4_Android10_HDMI_201202.img", instance="127.0.0.1:9100", job="node", node="sub02", nodename="main", state="done"} => 100 @[1608795873.055]
node_cluster_firmware_upgrade_stat{firmware="SR-C11G-3399JD4_Android10_HDMI_201202.img", instance="127.0.0.1:9100", job="node", node="sub03", nodename="main", state="done"} => 100 @[1608795873.055]
  1. node: 升级固件的子板编号。

  2. state: preparing: 正在准备;flashing: 正在烧写;done: 已完成;error:出错。

  3. metric: 烧写进度百分比,例如 100 表示已全部完成(100%)。

注意:有可能出现同一块子板有两种不同的 state,这时如果存在 state=”flashing” 则表示子板尚在烧写中,因此更稳妥的办法是,先查 flashing 进度,如果有则在升级中,如果没有则再查是完成还是出错:

$ promtool query instant http://127.0.0.1:9090 'node_cluster_firmware_upgrade_stat{node="sub02",state="flashing"}'
$ promtool query instant http://127.0.0.1:9090 'node_cluster_firmware_upgrade_stat{node="sub02",state=~"done|error"}'
node_cluster_firmware_upgrade_stat{firmware="SR-C11G-3399JD4_Android10_HDMI_201202.img", instance="127.0.0.1:9100", job="node", node="sub02", nodename="main", state="done"} => 100 @[1608796078.37]

4. 子板上传下载文件,运行命令

以下命令使用 bmc_adb,此脚本是对 adb 命令的包装,使用户可以方便地使用子板编号去操作对应子板,而不用理会实际的子板 adb 序列号。当然,adb 命令也可以使用。

(1). 从主板上传文件到子板

在主板上运行:

$ bmc_adb -s sub01 push home.json /data/local/tmp

(2). 从子板下载文件到主板

在主板上运行:

$ bmc_adb -s sub01 pull home.json /data/local/tmp

(3). 在子板运行特定命令

在主板上运行:

$ bmc_adb -s sub01 shell ifconfig

5. bmc 命令行工具

bmc 命令行工具必须在主板(即结点名称为 main 的设备)的 Shell 终端窗口下运行,当然,远程通过 ssh 连接到主板也可使用。

获取命令帮助:

$ bmc --help
Usage:

  bmc list [--offline] [<pattern>]
    List all the active nodes usable with adb, optionally matched by pattern

  bmc serials
    List all the active nodes with coresponding adb serial.

  bmc <node> {reset|poweron|poweroff}
    Invoke reset, poweron or power off on <node>

  bmc <node> state
    Show node state

  bmc <node> shell [<command>...]
    Invoke shell with command.

  bmc forall <command> %{node}

(1). 显示 adb 设备列表

列出所有在线(adb 成功连接)设备:

$ bmc list
sub03
sub04
sub05
sub06
sub07
sub08
sub09
sub10

列出所有 adb 状态为 offline 的设备:

$ bmc list --offline

(2). 列出子板编号和 adb 序列号的对应关系

$ bmc serials
sub02 B09CCSUB02 usb:2-1.2.3
sub03 A8232SUB03 usb:2-1.2.4
sub06 4DE1ESUB06 usb:2-1.2.7
sub07 505C3SUB07 usb:2-1.1.2
sub08 FFBCCSUB08 usb:2-1.4
sub09 710AFSUB09 usb:2-1.1.1

(3). 重置子板的电源

$ bmc sub03 reset
  okay

(4). 打开、关闭子板电源(仅R2)

关闭子板电源:

$ bmc sub1-01 poweroff
   okay

打开子板电源:

$ bmc sub1-01 poweron
   okay

(5). 查看子板状态

查看子板的明细状态:

# 单个子板
$ bmc sub1-01 state
android

# 所有子板
$ bmc state
main: linux
sub1-01: android
sub1-02: android
...

# 所有状态为 offline 的子板
$ bmc state | grep offline
sub7-01: offline
sub7-02: offline
sub7-03: offline
...

列出 sub3-01 的 adb 状态和 ifconfig 结果:

$ bmc sub3-01
node: sub3-01
state: android
adb_state: device
ifconfig:
eth0      Link encap:Ethernet  HWaddr ae:bb:8b:e7:b4:38  Driver rk_gmac-dwmac
          inet addr:168.168.100.171  Bcast:168.168.255.255  Mask:255.255.0.0
          inet6 addr: fe80::7298:5297:6ab9:7fd0/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:66181 errors:0 dropped:0 overruns:0 frame:0
          TX packets:190 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4414382 TX bytes:22295
          Interrupt:27

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:715 errors:0 dropped:0 overruns:0 frame:0
          TX packets:715 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:885911 TX bytes:885911

(6). 进入子板 shell 或在子板执行命令

进入 sub03 的 adb shell:

$ bmc sub03 shell
rk3399_firefly_sr_c11g_jd4:/ $

在 sub03 上运行命令:

$ bmc sub03 shell id
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc) context=u:r:shell:s0

(7). 批量执行命令

bmc 提供了可以批量执行命令的快捷方式 bmc forall,此命令从标准输入读入子板编号,替换命令行上的 %{node} 参数再执行命令。例如:

批量获取子板 adb 状态,%{node} 会被替换为实际的设备结点:

$ echo sub03 sub04 | bmc forall adb -s %{node} get-state
>>> adb -s sub03 get-state
device
>>> adb -s sub04 get-state
device

为了简化操作,bmc forallreset, poweronpoweroff 命令提供了快捷支持。

批量重置子板电源:

$ echo sub03 sub04 | bmc forall reset
>>> bmc sub03 reset
    okay
>>> bmc sub04 reset
    okay

# 等价于
$ echo sub03 sub04 | bmc forall bmc %{node} reset

另外,bmc forall 也对 shell 命令还提供了简化。

例如,批量获取子板 Android 序列号:

$ echo sub03 sub04 | bmc forall shell getprop ro.serialno
>>> bmc sub03 shell getprop ro.serialno
A82328MDDT
>>> bmc sub04 shell getprop ro.serialno
2E8178MDDT

# 等价于
$ echo sub03 sub04 | bmc forall bmc %{node} shell getprop ro.serialno

(8). 查询监控数据

promtoolPrometheus 提供的命令行工具,可用于查询数据库等功能。

bmc querypromtool 的快捷查询方式,不加参数默认返回 node_cluster_up 的值:

$ bmc query
node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", state="android", subnode="sub1-01"} => 1 @[1609227870.112]
...

也可以直接指定需要查询的参数,参数请参阅 node_exporter 文档和 BMC 的 API 说明。

以下是插入硬盘后查询其状态:

$ bmc query node_cluster_disk_up
node_cluster_disk_up{device="sda", instance="127.0.0.1:9100", job="node", model="ST1000DM010-2EP1", nodename="main"} => 1 @[1609228042.393]

(9). 写入序列号,以太网 MAC 地址等(v1.3 新增)

命令格式:

bmc {main|sub??} vendor <type> [<data>]
  • <type>:

    • sn: 对应 VENDOR_SN_ID,用来修改 Android 系统的 ro.serialno 属性。

    • lan: 对应 VENDOR_LAN_MAC_ID, eth0 网卡的 MAC 地址,设置后重启生效。

    • 更多类型请在主控板运行:/usr/share/bmc/vendor_storage_linux -h

  • <data>: 该参数可选,若提供则写入,否则是读取。

例如,要对 sub8-09 写入 MAC 地址 ae:0e:fb:84:0f:c2:

# 写入
$ bmc sub8-09 vendor lan ae0efb840fc2

# 读取
$ bmc sub8-09 vendor lan

该命令实际是对 /usr/share/bmc/vendor_storage_linux (Linux 系统) 和 /usr/share/bmc/vendor_storage_android (Android 系统) 的包装,更高级的用法可以直接调用原始命令。

(10). 列出主子板的软硬件版本号(v1.3 新增)

列出主板和所有子板的软硬件版本号:

$ bmc versions
main    linux   OS:Ubuntu18.04.4        HW:v1.0
sub1-01 android OS:CLUSTER-SERVER-R2_20210118   HW:v1.0
sub1-02 android OS:CLUSTER-SERVER-R2_20210118   HW:v1.0
sub1-03 android OS:CLUSTER-SERVER-R2_20210118   HW:v1.0
...

五、系统开发

1. Android SDK

(1). 编译环境搭建

编译 Android 对机器的配置要求较高:

  • 64 位 CPU

  • 16GB 物理内存+交换内存

  • 30GB 空闲的磁盘空间用于构建,源码树另外占用大约 25GB

官方推荐 Ubuntu 14.04 操作系统,经测试,Ubuntu 12.04 也可以编译运行成功,只需要满足 http://source.android.com/source/building.html 里的软硬件配置即可。

编译环境的初始化可参考 http://source.android.com/source/initializing.html 。

  • 安装 OpenJDK 8:

sudo apt-get install openjdk-8-jdk

提示:安装 openjdk-8-jdk,会更改 JDK 的默认链接,这时可用:

$ sudo update-alternatives --config java
$ sudo update-alternatives --config javac

来切换 JDK 版本。SDK 在找不到操作系统默认 JDK 的时候会使用内部设定的 JDK 路径,因此,为了让同一台机器可以编译 Android 5.1 及之前的版本,去掉链接更方便:

$ sudo /var/lib/dpkg/info/openjdk-8-jdk:amd64.prerm remove
  • Ubuntu 12.04 软件包安装:

sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
g++-multilib mingw32 tofrodos gcc-multilib ia32-libs \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386 \
lzop libssl1.0.0 libssl-dev
  • Ubuntu 14.04 软件包安装:

sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev \
libesd0-dev libwxgtk2.8-dev squashfs-tools build-essential zip curl \
libncurses5-dev zlib1g-dev pngcrush schedtool libxml2 libxml2-utils \
xsltproc lzop libc6-dev schedtool g++-multilib lib32z1-dev lib32ncurses5-dev \
lib32readline-gplv2-dev gcc-multilib libswitch-perl \
libssl1.0.0 libssl-dev

(2). 下载 Android10.0 SDK

由于 SDK 较大,可以去下载页面选择云盘下载 Firefly-RK3399_Android10.0_git_20210114.7z:

下载链接

下载完成后,在解压前先校验下 MD5 码:

$ md5sum /path/to/Firefly-RK3399_Android10.0_git_20210114.7z.001
$ md5sum /path/to/Firefly-RK3399_Android10.0_git_20210114.7z.002
10bf3ca46fa629f1965c5c9c8608db7e  Firefly-RK3399_Android10.0_git_20210114.7z.001
bd4c36fe268420bf6efe1a2617ab6b8b  Firefly-RK3399_Android10.0_git_20210114.7z.002

然后解压:

cd ~/proj/
7z x ./Firefly-RK3399_Android10.0_git_20210114.7z.001 -ork3399_Android10.0cd ./rk3399_Android10.0
git reset --hard

注意:解压后务必要先更新下远程仓库。以下为从 gitlab 处更新的方法:

#1. 进入SDK根目录
cd ~/proj/rk3399_Android10.0

#2. 下载远程bundle仓库
git clone https://gitlab.com/TeeFirefly/rk3399-android10.0-bundle.git .bundle

#3. 若下载仓库失败,目前bundle仓库占用空间较大,所以同步的时候可能会出现卡住或失败的问题,
#  可以从下方百度云链接下载并解压到SDK根目录,解压指令如下:
7z x rk3399-android10.0-bundle.7z  -r -o. && mv rk3399-android10.0-bundle/ .bundle/

#4. 更新SDK,并且后续更新不需要再次拉取远程仓库,直接执行以下命令即可
.bundle/update

#5. 按照提示已经更新内容到 FETCH_HEAD,同步FETCH_HEAD到firefly分支

git rebase FETCH_HEAD

(3). 编译方法

A. R1编译方法

a.脚本自动编译
./FFTools/make.sh -d rk3399-firefly-sr-c11g-jd4 -j8 -l rk3399_firefly_sr_c11g_jd4-userdebug
./FFTools/mkupdate/mkupdate.sh -l rk3399_firefly_sr_c11g_jd4-userdebug
b.手动编译

编译前执行如下命令配置环境变量:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
  • 编译 kernel:

cd ~/proj/rk3399_Android10.0/kernel/
make ARCH=arm64 firefly_defconfig android-10.config rk3399.config
make ARCH=arm64 BOOT_IMG=../rockdev/Image-rk3399_firefly_sr_c11g_jd4/boot.img rk3399-firefly-sr-c11g-jd4.img -j8

注意:若进行内核debug,需要将resource.img和kernel.img打包进去boot.img后对boot分区进行烧写才能生效。

  • 编译 uboot:

cd ~/proj/rk3399_Android10.0/u-boot/
./make.sh rk3399
  • 编译 Android:

cd ~/proj/rk3399_Android10.0/
source FFTools/build.sh
lunch rk3399_firefly_sr_c11g_jd4-userdebug
make -j8
./mkimage.sh

打包成统一固件 update.img

编译完可以用Firefly官方的脚本打包成统一固件,执行如下命令:

cd ~/proj/rk3399_Android10.0/
./FFTools/mkupdate/mkupdate.sh -l rk3399_firefly_sr_c11g_jd4-userdebug

打包完成后将在rockdev/Image-rk3399_firefly_sr_c11g_jd4/ 目录下生成统一固件: product名XXX_XXX_日期XXX.img 在 Windows 下打包统一固件 update.img 也很简单,将编译生成的文件拷贝到 AndroidTool 的 rockdev\Image 目录中,然后运行 rockdev 目录下的 mkupdate.bat 批处理文件即可创建 update.img 并存放到 rockdev\Image 目录里。

B. 分区镜像

  • boot.img 包含ramdis、kernel、dtb

  • dtbo.img Device Tree Overlays

  • kernel.img includekernel,目前无法单独烧写,需要打包到boot.img内烧写

  • MiniLoaderAll.bin 包含一级loader

  • misc.img 包含recovery-wipe开机标识信息,烧写后会进行recovery

  • odm.img 包含android odm,包含在super.img分区内,单独烧写需要用fastboot烧写

  • parameter.txt 包含分区信息

  • pcba_small_misc.img 包含pcba开机标识信息,烧写后会进入简易版pcba模式

  • pcba_whole_misc.img 包含pcba开机标识信息,烧写后会进入完整版pcba模式

  • recovery.img 包含recovery-ramdis、kernel、dtb

  • resource.img 包含dtb,kernel和uboot阶段的log及uboot充电logo,目前无法单独烧写,需要打包到boot.img内烧写

  • super.img 包含odm、vendor、system分区内容

  • system.img 包含android system,包含在super.img分区内,单独烧写需要同fastboot烧写

  • trust.img 包含BL31、BL32

  • uboot.img 包含uboot固件

  • vbmeta.img 包含avb校验信息,用于AVB校验

  • vendor.img 包含android vendor,包含在super.img分区内,单独烧写需要同fastboot烧写

  • update.img 包含以上需要烧写的img文件,可以用于工具直接烧写整个固件包

2. Android 系统定制,应用开发

参考 Firefly Android 使用手册

3. Linux SDK

为了方便用户的使用与开发,官方提供了 Linux 开发的整套 SDK,本章详细的说明 SDK 的具体用法。

注意: Linux SDK只适用于集群服务器子板的系统开发。

(1). 准备工作

A. 下载 Firefly_Linux_SDK 分卷压缩包

由于 Firefly_Linux_SDK 源码包比较大,部分用户电脑不支持4G以上文件或单个文件网络传输较慢, 所以我们采用分卷压缩的方法来打包SDK。用户可以通过如下方式获取 Firefly_Linux_SDK源码包:Firefly_Linux_SDK源码包

下载完成后先验证一下 MD5 码:

$ md5sum rk3399_linux_release_v2.5.1_20210301_split_dir/*firefly_split*
2cf71e64d35eb8083a4a0fc30c256484  rk3399_linux_release_v2.5.1_20210301_split_dir/rk3399_linux_release_v2.5.1_20210301_firefly_split.file0
f0e9292b3816a8f1ce0eb1eeb483ad56  rk3399_linux_release_v2.5.1_20210301_split_dir/rk3399_linux_release_v2.5.1_20210301_firefly_split.file1
c6aaa5d761d0e7917bea1cb78a0e7229  rk3399_linux_release_v2.5.1_20210301_split_dir/rk3399_linux_release_v2.5.1_20210301_firefly_split.file2
16022cc729d06a28fec30ac52885d91c  rk3399_linux_release_v2.5.1_20210301_split_dir/rk3399_linux_release_v2.5.1_20210301_firefly_split.file3
565426354c01d56c7d48479dd7f3c35b  rk3399_linux_release_v2.5.1_20210301_split_dir/rk3399_linux_release_v2.5.1_20210301_firefly_split.file4
313d311f1705fbfb7bfc45b7937ecf24  rk3399_linux_release_v2.5.1_20210301_split_dir/rk3399_linux_release_v2.5.1_20210301_firefly_split.file5

解压 Firefly_Linux_SDK 分卷压缩包

确认无误后,就可以解压:

cat rk3399_linux_release_v2.5.1_20210301_split_dir/*firefly_split* | tar -xzv

#本SDK文件夹内包含一个 .repo 目录,解压之后,在当前目录下执行以下操作
cd rk3399_linux_release_v2.5.1_20210301
ls -al

.repo/repo/repo sync -l
.repo/repo/repo sync -c --no-tags
.repo/repo/repo start firefly --all

更新 Firefly_Linux_SDK

后续可以使用以下命令更新 SDK

.repo/repo/repo sync -c --no-tags

(2). Linux_SDK 目录介绍

目录:

── linux_sdk
  ├── app
  ├── buildroot buildroot                   根文件系统的编译目录
  ├── build.sh -> device/rockchip/common/build.sh       全自动编译脚本
  ├── device                          编译相关配置文件
  ├── distro debian                      根文件系统生成目录
  ├── docs                           文档
  ├── envsetup.sh -> buildroot/build/envsetup.sh
  ├── external
  ├── kernel                          内核
  ├── Makefile -> buildroot/build/Makefile
  ├── mkfirmware.sh -> device/rockchip/common/mkfirmware.sh  rockdev链接更新脚本
  ├── prebuilts
  ├── rkbin
  ├── rkflash.sh -> device/rockchip/common/rkflash.sh     烧写脚本
  ├── rootfs                          debian根文件系统编译目录
  ├── tools                          烧写、打包工具
  └── u-boot

(3). 搭建 SDK 编译环境

Ubuntu 固件:(根文件系统请使用官方提供的根文件系统镜像)

sudo apt-get update

sudo apt-get install repo git-core gitk git-gui gcc-arm-linux-gnueabihf u-boot-tools device-tree-compiler \
gcc-aarch64-linux-gnu mtools parted libudev-dev libusb-1.0-0-dev python-linaro-image-tools \
linaro-image-tools gcc-arm-linux-gnueabihf libssl-dev liblz4-tool genext2fs lib32stdc++6 \
gcc-aarch64-linux-gnu g+conf autotools-dev libsigsegv2 m4 intltool libdrm-dev curl sed make \
binutils build-essential gcc g++ bash patch gzip bzip2 perl tar cpio python unzip rsync file bc wget \
libncurses5 libqt4-dev libglib2.0-dev libgtk2.0-dev libglade2-dev cvs git mercurial rsync openssh-client \
subversion asciidoc w3m dblatex graphviz python-matplotlib libc6:i386 libssl-dev texinfo fakeroot \
libparse-yapp-perl default-jre patchutils

注意: Ubuntu17.04 或者更高的系统还需要如下依赖包:

  1. sudo apt-get install lib32gcc-7-dev g++-7 libstdc++-7-dev

(4). 编译 SDK

编译前配置

配置文件 CS-R1-3399-jd4-sub-ubuntu.mk:

./build.sh CS-R1-3399-jd4-sub-ubuntu.mk

文件路径在 device/rockchip/rk3399/

如果配置文件生效会连接到 device/rockchip/.BoardConfig.mk ,检查该文件可以验证是否配置成功

#!/bin/bash
CMD=`realpath $BASH_SOURCE`
CUR_DIR=`dirname $CMD`
source $CUR_DIR/BoardConfig.mk
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=firefly-rk3399
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=firefly_linux_defconfig
# Kernel dts
export RK_KERNEL_DTS=rk3399-firefly
# parameter for GPT table
export RK_PARAMETER=parameter-ubuntu.txt
# packagefile for make update image
export RK_PACKAGE_FILE=rk3399-ubuntu-package-file
# Set rootfs type, including ext2 ext4 squashfs
export RK_ROOTFS_TYPE=ext4
# rootfs image path
export RK_ROOTFS_IMG=ubuntu_rootfs/rk3399_ubuntu_rootfs.img
# recovery ramdisk
export RK_RECOVERY_RAMDISK=recovery-arm64.cpio.gz
# Set userdata partition type
export RK_USERDATA_FS_TYPE=ext4
# Buildroot config
export RK_CFG_BUILDROOT=
# Recovery config
export RK_CFG_RECOVERY=
#OEM config
export RK_OEM_DIR=
#userdata config
export RK_USERDATA_DIR=

注意,十分重要!!

前往下载页面 下载对应的Ubuntu 根文件系统镜像

把得到的镜像放到 SDK 的指定目录:

#解压
tar -xvf rk3399_ubuntu18.04_LXDE.img.tgz

#sdk根目录下
mkdir ubunturootfs
mv rk3399_ubuntu18.04_LXDE.img ubunturootfs/

#修改firefly-rk3399-ubuntu.mk文件
vim device/rockchip/RK3399/firefly-rk3399-ubuntu.mk

#把RK_ROOTFS_IMG属性改成ubuntu文件系统镜像得路径(也就是rk3399_ubuntu18.04_LXDE.img)

RK_ROOTFS_IMG=ubunturootfs/rk3399_ubuntu18.04_LXDE.img

注意: Ubuntu 根文件系统镜像存放路径不能错。

#全自动编译的固件
$ ./build.sh

#部分编译

$ ./build.sh kernel
$ ./build.sh uboot
$ ./build.sh recovery

#运行 ./mkfirmware.sh 会自动更新 rockdev/rootfs.img 的链接。
$ ./build.sh firmware

#固件打包
#每次打包固件前先确保 rockdev/ 目录下文件链接是否正确:
$ ls -l

├── boot.img -> ~/project/linux_sdk/kernel/boot.img
├── idbloader.img -> ~/project/linux_sdk/u-boot/idbloader.img
├── MiniLoaderAll.bin -> ~/project/linux_sdk/u-boot/rk3399_loader_v1.14.115.bin
├── misc.img -> ~/project/linux_sdk/device/rockchip/rockimg/wipe_all-misc.img
├── parameter.txt -> ~/project/linux_sdk/device/rockchip/RK3399/parameter-ubuntu.txt
├── recovery.img -> ~/project/linux_sdk/buildroot/output/rockchip_rk3399_recovery/images/recovery.img
├── rootfs.img -> ~/project/linux_sdk/ubunturootfs/rk3399_ubuntu18.04_LXDE.img
├── trust.img -> ~/project/linux_sdk/u-boot/trust.img
├── uboot.img -> ~/project/linux_sdk/u-boot/uboot.img
└── userdata.img

#打包统一固件
# 注意:打包前请确认 tools/linux/Linux_Pack_Firmware/rockdev/package-file 是否正确。打包会根据此文件进行分区打包。此文件链接会在 ./build.sh firefly-rk3399-ubuntu.mk 命令时更新,如果配置不对请返回编译前配置一节重新配置一次。

整合统一固件:

$ ./build.sh updateimg

(5). 分区介绍

A. parameter.txt

parameter.txt 包含了固件的分区信息十分重要,你可以在 device/rockchip/rk3399 目录下找到一些 parameter.txt 文件,下面以 parameter-debian.txt 为例子做介绍:

FIRMWARE_VER: 8.1
MACHINE_MODEL: RK3399
MACHINE_ID: 007
MANUFACTURER: RK3399
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 3399
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00010000@0x0000a000(boot),0x00010000@0x0001a000(recovery),0x00010000@0x0002a000(backup),0x00020000@0x0003a000(oem),0x00700000@0x0005a000(rootfs),-@0x0075a000(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9

CMDLINE 属性是我们关注的地方。以 Uboot 为例 0x00002000@0x00004000(uboot) 中 0x00004000 为 Uboot 分区的起始位置 0x00002000 为分区的大小。后面的分区规则相同。用户可以根据自己需要增减或者修改分区信息,但是请最少保留 uboot, trust, boot, rootfs 分区,这是机器能正常启动的前提条件。parameter-ubuntu.txt 中使用的就是这样的最简分区方案。

分区介绍:

  1. uboot 分区: 烧写 uboot 编译出来的 uboot.img。

  2. trust 分区: 烧写 uboot 编译出来的 trust.img。

  3. misc 分区: 烧写 misc.img。开机检测进入 recovery 模式。(可省略)

  4. boot 分区: 烧写 kernel 编译出来的 boot.img 包含 kernel 和设备树信息。

  5. recovery 分区: 烧写 recovery.img。(可省略)

  6. backup 分区: 预留,暂时没有用。后续跟 android 一样作为 recovery 的 backup 使用。(可省略)

  7. oem 分区: 给厂家使用,存放厂家的 app 或数据。只读。代替原来音箱的 data 分区。挂载在/oem 目录。(可省略)

  8. rootfs 分区: 存放 buildroot 或者 debian 编出来的 rootfs.img,只读.

  9. userdata 分 区 : 存放 app 临时生成的文件或者是给最终用户使用。可读写,挂载在 /userdata 目录下。(可省略)

B. package-file

package-file文件应当与 parameter 保持一致,用于固件打包。可以在 tools/linux/Linux_Pack_Firmware/rockdev 下找到相关文件。以 rk3399-ubuntu-package-file 为例介绍:

# NAME     Relative path
#
#HWDEF     HWDEF
package-file  package-file
bootloader   Image/MiniLoaderAll.bin
parameter    Image/parameter.txt
trust      Image/trust.img
uboot      Image/uboot.img
boot      Image/boot.img
rootfs:grow   Image/rootfs.img
backup     RESERVED

以上是 SDK 编译后生成的镜像文件。根据 parameter.txt 只打包自己用到的 img 文件。

4. Linux 系统定制, 应用开发

参考Firefly Ubuntu 使用手册

六、资料下载

1. BMC 扫描工具

(1). 下载安装包

工具下载链接:

下载完成后直接解压安装即可。

(2). 访问BMC管理系统

Linux: firefly-bmc-finder

以 Windows 平台为例子,在桌面下双击BMC扫描工具快捷方式 _images/wps39.jpg 打开应用,进入主页面。

应用加载后会默认扫描一次局域网,获取局域网下所有的BMC管理系统IP地址并生成列表项在软件UI界面呈现,如图所示为列表项的呈现效果:

_images/wps40.png

UI界面的列表项包括以下信息:

  • Total devices:列表项总数

  • ID:ID号

  • Devices:集群服务器名称

  • IPV4 ADDRESS:IP地址号

  • PORT:IP端口号

  • SOFTWARE VER:BMC管理系统版本

  • START TIME:系统开启时间

  • ACTIONS:访问BMC管理系统的 _images/wps41.jpg 图标链接

用户可通过列表项提供的信息,点击对应列表项处的 _images/wps42.jpg 图标链接,即可打开外部浏览器,直达相应BMC管理系统的登录页面。

(3). 刷新BMC管理系统

打开工具之后默认进行一次自动刷新,手动刷新可点击按钮 _images/wps43.jpg 。刷新后若无发现相关BMC管理系统IP地址,需要检查集群服务器是否开启、网络接口是否接通、网络是否在同一局域网内等。

若工具扫描局域网后无发现任何BMC管理系统IP地址,则软件UI界面无列表项生成,呈现 “Searching for network devices…” 的信息,如图所示:

_images/wps44.png

(4). 工具设置

点击BMC扫描工具左下角的 _images/wps45.jpg 图标可进入设置界面,如图所示:

_images/wps46.png

设置界面目前支持中文与英文语言切换、软件是否自动在线检查更新。

中文语言界面如图所示:

_images/wps47.png

_images/wps48.png

关于更多Firefly的相关信息可以点击右上角的Logo进入到Firefly官网进一步了解。

七、FAQ

1.main核心板升级(谨慎使用)

使用type-C线连接Cluster-Server-R1的OTG接口到PC:

  • main(主)核心板进入升级模式

#如果是Android系统,使用adb工具输入以下命令,main(主)核心板进入升级模式。大概等待10s,在PC上检测是否有usb设备接入
reboot loader

在(Linux)PC上使用:

# 擦除 flash 使用 ef 参数需要指定 loader 文件或者对应的 update.img
sudo upgrade_tool ef update.img   #update.img :你需要烧写的 Ubuntu 固件
# 重新烧写,等待烧写完成
sudo upgrade_tool uf update.img
# 启动核心板
sudo upgrade_tool rd

具体方法参考: Core-3399-JD4升级方法

2.硬件看门狗如何使用?

硬件看门狗的主体是一个定时电路,其主要作用是监控、管理CPU的运行状态,并对处于异常状态中的CPU进行复位操作,使其能重新工作。

Android10.0 出厂固件没有打开硬件看门狗,如果客户需要可自行实现软件程序去使用硬件看门狗,下面提供硬件看门狗的操作方法:

  • 使能看门狗

echo e > "/dev/wdt_crl"
  • 设置超时时间(喂狗)

支持设置4种超时时间:0.64s、2.56s、10.24s、40.96s,对应往设备节点里写0、1、2、3。客户可根据自己的需要设置不同的超时时间,例如客户需要设置超时时间为2.56s,则为:

echo 1 > "/dev/wdt_crl"

软件程序需要定时设置超时时间对看门狗内的定时器清零(俗称“喂狗”)。

当CPU出现故障,则不能继续提供“喂狗”信号,就使得看门狗内的定时器不断累加而溢出,从而产生复位信号对CPU进行复位重启系统,使CPU重新工作。

  • 关闭看门狗

echo d > "/dev/wdt_crl"

3.BMC 常见问题

BMC 上的设备均显示为不可用

原因有多样,请按照以下顺序逐一排查:

  • 将显示时间范围调整到最近半小时,看有没有输出。

  • 运行 adb devices 看有没有设备列出。

    如果没有,确保 USB OTG 口没有连接到电脑上,如果 USB OTG 口也没有连接,请检查核心板连接和电源,排除硬件问题。

  • 运行 bmc query ,正常情况下有如下返回:

    root@firefly:~# bmc query
    node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", subnode="main"} => 1 @[1603356844.328]
    node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", subnode="sub01"} => 1 @[1603356844.328]
    node_cluster_up{instance="127.0.0.1:9100", job="node", nodename="main", subnode="sub02"} => 1 @[1603356844.328]
    ...
    

    如果没有,检查主板上的 node_exporter 有没有运行:

    root@firefly:~# bmc main metrics | grep node_cluster_up
    # HELP node_cluster_up Value is 1 if the cluster subnode is 'up', 0 otherwise.
    # TYPE node_cluster_up gauge
    node_cluster_up{state="android",subnode="sub02"} 1
    node_cluster_up{state="android",subnode="sub03"} 1
    ...
    

    如果没有输出,则主板上的 node_exporter 运行出错。

    如果有输出, Prometheus 服务并没有去收集主板的 node_exporter 数据,运行出错。

  • 运行 sudo systemctl -u prometheus 查看该服务的状态。

  • 运行 sudo journalctl -u prometheus 查看该服务的运行日志,定位错误的原因。

    • 如果日志含有出错信息:”Handle Corrupt Prometheus Write-Ahead Log (WAL)”

      请尝试删除该坏文件并重启服务:

      sudo systemctl restart prometheus
      
    • 如果日志含有出错信息:”Error on ingesting out-of-order samples”

      当服务器时间和浏览器时间不一致, 例如服务器时间是 7-01, 浏览器是 7-21, 这 会导致浏览器发送的查询命令要求返回对于服务器来讲是未来的数据,当然为空数据, 进而导致显示界面空。这时请重置 Prometheus:

      sudo systemctl stop prometheus
      sudo rm -rf /var/lib/prometheus/metrics2/*
      sudo systemctl start prometheus
      

子板固件升级问题排查

固件升级背景知识

子板固件升级系统分为两部分:

  • Web 前端负责添加固件升级申请和升级进度的显示。

  • 后端netrecovery-master 负责实际的子板固件升级和进度更新。

子板固件升级流程为:

  1. 切换子板到 Loader 模式。

  2. 对处于 Loader 模式的子板设备写入辅助升级固件并重启进入升级系统(下称 netrecovery 模式)。

  3. 对子板设置 DHCP IP 地址。

  4. 子板运行固件升级程序,通过网络下载主板上的固件,同时烧写到 eMMC 存储。

  5. 子板烧写成功,重启。

子板固件升级成功的必要条件:

  1. 确保子板能够获取 DHCP IP 地址,而且主板与子板的网络要能相通。

  2. 集群服务器的 OTG USB 口与外部 PC 机的连接必须断开。

  3. 固件文件放在 /home/firefly/Firmware 目录里,后缀名为 “.img”。

Web 端提交固件升级申请后,进度一直是 0%

这个需要检查一下 netrecovery-master 的日志:

sudo journalctl -f -u netrecovery-master

查看是否有什么出错信息导致程序异常退出。

要重启该服务,可以运行:

sudo systemctl restart netrecovery-master

升级提示 “switch to recovery failed”

设备无法切换到 Loader 模式,或者 Loader 模式下无法刷入 netrecovery 均会出现这种错误。

可以尝试过段时间后重试。如果都不行,只能使用 USB 线刷方式重新烧录固件。

查看子板升级的详细日志

下面以子板 sub1-01 为例子,请换成实际的设备号。

# 看子板端日志
$ bmc sub1-01 shell
$ cd /tmp/log
$ cat history  # 查看命令列表,第一个数字是进程号
$ cat *.err    # 查看错误输出

# 如果子板端看不了,可以看一下主板端的运行结果:
$ cd /var/netrecovery/sub1-01/state
$ cat master-*.out
$ cat history  # 主板会将子板的日志文件下载到本地供查看
$ cat *.err    # 查看错误输出

Prometheus

如何查看 Prometheus 状态

运行服务状态:

sudo systemctl status prometheus

运行服务日志:

sudo journalctl -u prometheus

如果查看 Prometheus 数据库大小

sudo du -hs /var/lib/prometheus/metrics2

如何调整 Prometheus 的数据库存储空间管理策略

请修改 /etc/default/prometheus 配置文件,当前默认的设定是:

ARGS="--storage.tsdb.retention.time=7d --storage.tsdb.retention.size=4GB"

即仅保留 7 天以内、最大 4GB 的数据。

重置 Prometheus

以下操作会删除 Prometheus 所有数据并重启服务:

```shell
sudo systemctl stop prometheus
sudo rm -rf /var/lib/prometheus/metrics2/*
sudo systemctl start prometheus
```

node_exporter 性能参数

打开的文件描述符 node_filefd_allocated

node_filefd_allocated 表示已经分配的文件描述符的数量。这个数字越高表明打开的文件数越多。

参考:

每秒上下文切换次数 node_context_switches_total

node_context_switches_total 表示进程上下文切换的速率。这个数越高,表明进程数比较多而且切换频繁。

参考: