Toybrick

中文 / EN

TB-RK1808S0 AI 计算棒规格书

产品简介

RK1808 人工智能计算棒是瑞芯微旗下 Toybrick 系列产品中的一员,计算棒搭载瑞芯微的 RK1808 神经网络处理器,具有低功耗、高性能的特点,可应用于人工智能的各个应用领域。上位机通过 RK1808 人工智能计算棒,即可获得强大的深度学习推理能力。借助 RK1808 人工智能计算棒的强大算力,嵌入式设备可在网络边缘侧构建人工智能算法,使得传统嵌入式设备轻松完成人工智能升级。

RK1808 人工智能计算棒可用于辅助推理计算,也支持通过二次开发完成独立人工智能计算功能。

产品技术规格

CPU RK1808
内存 1GB LPDDR
存储 8GB EMMC
尺寸 82×31×13mm
接口 USB3.0 Type-A
最小系统要求 Ubuntu 16.04或win 7的x86_64计算机;USB 2.0 Type-A端口;2 GB RAM;4 GB可用存储空间;
温度 0℃~40℃

产品外观尺寸

TB-RK1808S0 AI 计算棒开发指南

被动模式开发介绍和环境安装

被动模式开发流程简介

注:计算棒默认就是被动模式,不要对计算棒做配置修改,也就是说计算棒无需更改模式,统一固定采用默认的被动模式。

被动模式下:RK1808 人工智能计算棒是一个通用AI加速器。上位机通过RKNN-Toolkit将模型及前处理后的数据传输给RK1808 人工智能计算棒,RK1808 人工智能计算棒完成推理,并把结果返回上位机,上位机进行后处理以及显示等操作。

目前以下平台及系统支持被动模式:

PC端Linux系统、Windows系统、Mac OS

RK3399、RK3399Pro平台Linux系统、Android系统

其他不支持被动模式的平台及系统,用户可以使用主动模式,主动模式请参考Wiki教程--TB-RK1808S0--主动模式开发

被动模式开发流程图如下:

被动模式整体数据流图如下:

被动模式下,有提供python和C两套API供上位机编程使用。

  1. Python编程上位机需安装RKNN-Toolkit,http://repo.rock-chips.com/python/链接下,提供了RKNN-Toolkit安装包,用户可以使用这些安装包安装RKNN-Toolkit 。RKNN-Toolkit的具体开发使用请参见《Rockchip_User_Guide_RKNN_Toolkit》。RKNN-Toolkit的更多文档请参考链接http://repo.rock-chips.com/rk1808/rknn-toolkit_doc/。
  2. 在http://repo.rock-chips.com/rk1808/rknn-api/链接下,有供上位机C编程使用的库文件和头文件。C编程的具体开发使用请参见:《Rockchip_User_Guide_RKNN_API》。上位机在执行编译出来的C语言的可执行程序前,需要先运行npu_transfer_proxy和计算棒进行通信,npu_transfer_proxy的下载链接为http://repo.rock-chips.com/rk1808/npu_transfer_proxy/。
  3. Windows下的RKNN-Toolkit使用需要预先安装ntb驱动,ntb驱动请从http://repo.rock-chips.com/rk1808/driver/windows/ntb/链接地址下载,ntb驱动安装以及windows下RKNN-Toolkit使用请参考:《RKNN_Toolkit_Windows_Platform_Quick_Start_CN.pdf》。

被动模式Linux上位机环境安装

PC上运行计算棒

本节主要描述RK1808 AI计算棒如何在Ubuntu18.04的PC上,基于python3.6使用RKNN-Toolkit快速运行深度神经网络模型mobilenet_v1的例子。

PC环境准备

• 装有 ubuntu 18.04 操作系统的 intel 酷睿 i3 以上的 x86 的 64 位 PC(CPU指令集需支持SSE4.2 AVX AVX2, 若不支持则需要用户自行下载tensorflow源码,去掉指令集依赖再编译安装)。

• RK1808 人工智能计算棒 。

• 将 RK1808 AI计算棒插入PC的USB接口上,使用lsusb命令查看,如下(其中红色字体部分 2207:0018即为我们的RK1808 人工智能计算棒):

  1. 输入命令如下:
lsusb
  1. 执行结果如下:
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 009: ID 2207:0018

PC上安装RKNN-Toolkit

RKNN-Toolkit是瑞芯微为用户提供的基于python接口编程的模型转换、推理和性能评估的NPU开发套件,本节以装有ubuntu 18.04 操作系统的x86的64位PC为例,说明当Python版本为 3.6时如何安装 RKNN-Toolkit, 以下是在终端下执行的命令:

• 安装 Python3.6

sudo apt-get install python3.6

• 安装 OpenCV

 sudo apt-get install -y  python3-opencv

• 安装 pip3

sudo apt-get install python3-pip

• 插入TB-RK1808人工智能计算棒,PC上会显示U盘设备,U盘设备的目录结构如下:

• 执行以下步骤:(注:以下的软件版本只为演示使用,由于版本迭代更新,请自行安装最新版本。https://github.com/rockchip-linux/rknn-toolkit)

  1. 在当前用户目录创建rknn目录, 并进入rknn目录:
mkdir ~/rknncd ~/rknn
  1. 安装 wget:
sudo apt-get install -y wget
  1. 从官方FTP文件服务器下载RKNN-Toolkit:
wget http://repo.rock-chips.com/python/rknn_toolkit-1.2.1-cp36-cp36m-linux_x86_64.whl
  1. 安装 Python 依赖,tensorflow最低版本要求1.11.0,这里以安装1.13.1为例:
pip3 install --user tensorflow==1.13.1
  1. 安装 RKNN-Toolkit:
pip3 install --user rknn_toolkit-1.2.1-cp36-cp36m-linux_x86_64.whl

注:RKNN-Toolkit包必须与python版本一致, ubuntu18.04缺省默认是python3.6。

  1. 检查 RKNN-Toolkit 是否安装成功。
  • 在终端下输入以下命令:
python3
  • 在python3运行环境下输入以下代码, 导入RKNN模块:
from rknn.api import RKNN
  • RKNN模块导入成功的情况如下:
$ python3
>>> from rknn.api import RKNN
>>>
  • 如果导入RKNN 模块没有报错,然后输入quit()退出Python3(跳过以下步骤)。

  • 如果导入RKNN模块报以下错误,这是由于RKNN依赖的Tensorflow的安装包使用的是SSE4.2指令集,这些指令无法在旧版的CPU上运行,请检查并更换一台支持SSE4.2指令集的PC。

$ python3
>>> from rknn.api import RKNN
2019-06-25 20:10:25.255397: F tensorflow/core/platform/cpu_feature_guard.cc:37] The TensorFlow library was compiled to use SSE4.2 instructions, but these aren't available on your machine.

PC上设备访问权限修改

  1. 插入RK1808 人工智能计算棒,需要修改其USB设备访问权限,操作步骤如下:

1)返回至U盘根目录, 拷贝tool/update_rk1808_ai_cs_rule.sh到当前HOME目录的rknn目录下, 修改update_rk1808_ai_cs_rule.sh为可执行权限。

cp tool/update_rk1808_ai_cs_rule.sh  ~/rknn -f
chmod +x ~/rknn/update_rk1808_ai_cs_rule.sh

2)返回至rknn目录,update_rk1808_ai_cs_rule.sh必须以root权限执行。

cd  ~/rknnsudo 
./update_rk1808_ai_cs_rule.sh

注:这一步只有在安装的时候需要执行一次,以后都不需要执行。

  1. 执行完脚本后,查看RK1808 人工智能计算棒的USB设备编号。
  • 输入以下命令:
lsusb
  • 执行结果如下:
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 009: ID 2207:0018

注:其中Bus 003 Device 009是计算棒的设备编号。

  1. 根据计算棒的USB设备编号, 确认RK1808 人工智能计算棒设备的读写权限
  • 输入以下命令:
ls -l /dev/bus/usb/003/009

注:以上的003/009,不同的PC得到编号可能不一样,视具体情况而定。

  • 执行结果如下:
crw-rw-rw- 1 root root 189, 264 6 月 14 16:02 /dev/bus/usb/003/009 

PC上运行示例

这里以mobilenet_v1为例,mobilenet_v1示例实现的功能是对一张图片进行特征提取,并识别这张图片所属分类。

以下是mobilenet_v1示例的目录结构及说明如下:

• dataset.txt: 包含测试图片路径的文本文件。

• dog_224x224.jpg: 作为mobilenet_v1示例的测试图片。

• mobilenet_v1.tflite: TensorFlow Lite模型文件。

• mobilenet_v1.rknn: rknn模型文件。由非rknn模型文件(这里是TensorFlow Lite模型)经过RKNN-Toolkit模型转换生成的该rknn模型文件。

• test.py: 示例运行脚本(包含rknn模型转换部分)。

• test_inference.py: 示例运行脚本(仅加载rknn模型进行推理)。

示例运行步骤如下:

  1. 从官方FTP文件服务器下载mobilenet_v1压缩包,并解压出来:
wget http://repo.rock-chips.com/rk1808/mobilenet_v1.tar.gz
tar xvf mobilenet_v1.tar.gz
  1. 进入mobilenet_v1目录, 并执行test.py 脚本:
cd mobilenet_v1/
python3 test.py
  1. 得到如下结果
--> config model
done
--> Loading model
done
--> Building model
done
--> Export RKNN model
done
--> Init runtime environment
done
--> Running model
mobilenet_v1
-----TOP 5-----
[156]: 0.8837890625
[155]: 0.0677490234375
[188 205]: 0.00867462158203125
[188 205]: 0.00867462158203125
[263]: 0.0057525634765625

done
--> Begin evaluate model performance
========================================================================
                               Performance                              
========================================================================
Total Time(us): 7140
FPS: 140.06
========================================================================

done
  1. 根据以上执行结果可知,TOP5表示模型预测出来的排名前5的分类的结果,其中[156]表示狗的标签,0.8837890625表示预测为该标签的概率,可以看出预测结果为狗的可能性最大,从测试图片(dog_224x224.jpg)可以看出预测结果是准确的。

RK3399ProD上运行计算棒

本节主要描述RK1808 AI计算棒如何在RK3399ProD(fedora系统)上运行,基于python3.6使用RKNN-Toolkit快速运行深度神经网络模型mobilenet_v1的例子。

RK3399ProD环境准备

• Toybrick RK3399ProD开发板(固件版本为V1.5),rk1808人工智能计算棒(固件版本为V1.3.4)。

• 将 RK1808 AI计算棒插入RK3399ProD的USB接口上,使用lsusb命令查看,如下(其中红色字体部分 2207:0018即为我们的RK1808 人工智能计算棒):

  1. 输入命令如下:
lsusb
  1. 执行结果如下,可以看到两个NPU,0018是计算棒的NPU,1808是开发板自带的NPU

Bus 004 Device 004: ID 2207:0018

*Bus 004 Device 003: ID 2207:1808*

RK3399ProD上RKNN-Toolkit安装

sudo dnf install -y cmake gcc gcc-c++ protobuf-devel protobuf-compiler lapack-devel opencv-devel
sudo dnf install -y python3-devel python3-opencv python3-numpy-f2py python3-h5py python3-lmdb  python3-grpcio

• 插入TB-RK1808人工智能计算棒,RK3399ProD开发板上会显示U盘设备,U盘设备的目录结构如下:

• 执行以下步骤:

  1. 在当前用户目录创建rknn目录, 并进入rknn目录:
mkdir ~/rknncd ~/rknn
  1. 安装 wget:
sudo dnf install wget
  1. 从官方FTP文件服务器下载RKNN-Toolkit:
wget http://repo.rock-chips.com/python/rknn_toolkit-1.2.1-cp36-cp36m-linux_aarch64.whl
  1. 安装 tensorflow
pip3 install --user tensorflow
  1. 安装 RKNN-Toolkit:
pip3 install --user rknn_toolkit-1.2.1-cp36-cp36m-linux_aarch64.whl

注:RKNN-Toolkit包必须与python版本一致, 目前开发板fedora系统缺省默认是python3.6。

  1. 检查 RKNN-Toolkit 是否安装成功。

1)在终端下输入以下命令:

python3

2)在python3运行环境下输入以下代码, 导入RKNN模块:

from rknn.api import RKNN

​ (a)RKNN模块导入成功的情况如下:

$ python3
>>> from rknn.api import RKNN
>>>

​ (b) 如果导入RKNN 模块没有报错,然后输入quit()退出Python3。

RK3399ProD上设备访问权限修改

  1. 插入RK1808 人工智能计算棒,需要修改其USB设备访问权限,操作步骤如下:

1)返回至U盘根目录, 拷贝tool/update_rk1808_ai_cs_rule.sh到当前HOME目录的rknn目录下, 修改update_rk1808_ai_cs_rule.sh为可执行权限。

cp tool/update_rk1808_ai_cs_rule.sh  ~/rknn -f
chmod +x ~/rknn/update_rk1808_ai_cs_rule.sh

2)返回至rknn目录,update_rk1808_ai_cs_rule.sh必须以root权限执行。

cd  ~/rknn
sudo 
./update_rk1808_ai_cs_rule.sh

注:这一步只有在安装的时候需要执行一次,以后都不需要执行。

  1. 执行完脚本后,查看RK1808 人工智能计算棒的USB设备编号。

1)输入以下命令:

lsusb

2)执行结果如下:

Bus 004 Device 004: ID 2207:0018
Bus 004 Device 003: ID 2207:1808

注:其中Bus 004 Device 004是计算棒的设备编号, *Bus 004 Device 003是rk3399proD内部NPU的编号*

  1. 根据计算棒的USB设备编号, 确认RK1808 人工智能计算棒设备的读写权限

1)输入以下命令:

ls -l /dev/bus/usb/004/004

注:以上的004/004,不同的设备得到编号可能不一样,视具体情况而定。

2)执行结果如下(正确的读写权限如红色字体部分所示):

crw-rw-rw- 1 root root 189, 387 Sep 23 21:49 /dev/bus/usb/004/004

RK3399ProD上运行示例

这里以mobilenet_v1为例,mobilenet_v1示例实现的功能是对一张图片进行特征提取,并识别这张图片所属分类。

以下是mobilenet_v1示例的目录结构及说明如下:

• dataset.txt: 包含测试图片路径的文本文件。

• dog_224x224.jpg: 作为mobilenet_v1示例的测试图片。

• mobilenet_v1.tflite: TensorFlow Lite模型文件。

• mobilenet_v1.rknn: rknn模型文件。由非rknn模型文件(这里是TensorFlow Lite模型)经过RKNN-Toolkit模型转换生成的该rknn模型文件。

• test.py: 示例运行脚本(包含rknn模型转换部分)。

• test_inference.py: 示例运行脚本(仅加载rknn模型进行推理)。

示例运行步骤如下:

  1. 从官方FTP文件服务器下载mobilenet_v1压缩包,并解压出来:
wget http://repo.rock-chips.com/rk1808/mobilenet_v1.tar.gztar xvf mobilenet_v1.tar.gz
  1. 进入mobilenet_v1目录, 并执行test.py 脚本:
cd mobilenet_v1/
python3 test.py
  1. 运行会报如下错误
E More than 1 device detected to usb ntb. Please specify the device to use with device id parameter.

这是因为有2个NPU,而代码没有指定使用哪个NPU导致的

修改test.py指定device id,其中TS018080000000055是计算棒的device id,每个计算棒都不同,用户根据自己的设备来修改

ret = rknn.init_runtime(target='rk1808', device_id='TS018080000000055')

若用户想枚举出所有计算棒设备的device id可以在代码中加入

_, ntb_devices = rknn.list_devices()
  1. 再次运行python3 test.py得到如下结果
--> config model
done
--> Loading model
done
--> Building model
done
--> Export RKNN model
done
--> Init runtime environment
done
--> Running model
mobilenet_v1
-----TOP 5-----
[156]: 0.8837890625
[155]: 0.0677490234375
[188 205]: 0.00867462158203125
[188 205]: 0.00867462158203125
[263]: 0.0057525634765625

done
--> Begin evaluate model performance
========================================================================
                               Performance                              
========================================================================
Total Time(us): 7140
FPS: 140.06
========================================================================

done
  1. 根据以上执行结果可知,TOP5表示模型预测出来的排名前5的分类的结果,其中[156]表示狗的标签,0.8837890625表示预测为该标签的概率,可以看出预测结果为狗的可能性最大,从测试图片(dog_224x224.jpg)可以看出预测结果是准确的。

有关RKNN-Toolkit更详细的用法和接口说明,请参考《Rockchip_RK1808_AI_Compute_Stick_User_manual_CN.pdf》手册。

被动模式Windows上位机环境安装

本章节说明如何在Windows系统、Python3.6环境中使用RKNN-Toolkit。

安装文件下载地址:点击下载

准备工作

  1. 操作系统确认:Windows 7(x64)及以上, intel 酷睿 i3 以上的 x86 的 64 位 PC(CPU指令集需支持SSE4.2 AVX AVX2, 若不支持则需要用户自行下载tensorflow源码,去掉指令集依赖再编译安装)。Windows 10某些系统版本会缺失运行库,需要用户自行安装vc_redist.x64.exe,点击下载

  2. 配置环境变量,“右击计算机”--“属性”--“高级系统设置”--“环境变量”--“用户变量”--“新建”

  1. 将TB-RK1808 AI计算棒通过USB连接到PC上

  2. 运行演示需要摄像头,本机如果没有摄像头要外接USB摄像头

  3. 环境包下载:win_rknn_env.zip

  4. 环境包文件介绍:

• download.bat:双击运行,会自动下载相关的软件包到packages,以及演示用的demo(yolov3)

• install.bat:先手动安装packages目录下ntb驱动,以及python3.6.8;再双击运行install.bat,会自动安装rknn-toolkit

• run_yolov3.bat:双击运行,会自动运行yolov3 演示demo,该文件在运行install.bat后生成

软件包安装

安装包下载

双击运行download.bat,等待下载完成,下载完成后,会增加两个目录packages和yolov3。

驱动安装

进入packages目录,以管理员身份运行zadig-2.3.exe程序安装计算棒的驱动,如下图所示:

  1. 确认待安装的设备及需要安装的驱动。

注:待安装的设备其USB ID应该是2207:0018;安装的驱动选择libusb-win32(v1.2.6.0),确认完后点Install Driver开始安装驱动。

  1. 安装成功后会出现如下界面:

安装完后如果windows设备管理器的USB没有感叹号,且如下所示,说明安装成功:

注:安装完驱动后需要重启计算机。

安装Python3.6

  1. 进入packages目录。

  2. 双击python-3.6.8-amd64.exe进行安装,必须勾选添加PATH。

安装RKNN-Toolkit

安装RKNN-Toolkit前需要确保系统里已经安装有Python3.6。这可以通过cmd里执行python –version确定,如下说明系统已经安装有Python3.6:

双击install.bat,等待自动安装完成。

运行demo

确保计算棒已插入,确保电脑上有摄像头,如果没有内置摄像头,需要插入USB摄像头。

双击run_yolov3.bat(该文件在运行install.bat后生成),等待一会,演示画面,如果要退出,则鼠标点击显示框,按’Esc’键退出。

被动模式macOS上位机环境安装

本章节说明如何在MacOS-系统、Python3.6环境中使用RKNN-Toolkit。

安装文件下载地址:点击下载

前期准备

  1. 操作系统确认:MacOS 10.12(x64)及以上

  2. 将TB-RK1808 AI计算棒通过USB连接到PC上

  3. 运行演示需要摄像头,本机如果没有摄像头要外接USB摄像头

  4. 环境包下载:mac_rknn_env.zip

  5. 将mac_rknn_env.zip放到PC的Downloads目录下,进行解压

  6. 环境包文件介绍:

• download.sh.command:自动下载相关的软件包到packages,以及演示用的demo(yolov3)

• install.sh.commad:先手动安装Horndis驱动,以及python3.6.8;再双击运行install.sh.commad,会自动安装rknn-toolkit

• rknn_camera_tiny.py.command:自动运行yolov3 演示demo

安装包下载

双击运行download.sh.command,此时电脑会安装一些程序,会弹出窗口,提示安装软件,输入密码后,点确认即可

等待下载完成,下载过程中,会自动安装下载工具,有可能需要输入密码,下载工具安装耗时会比较久,下载完成后,会新增packages目录。

若出现无法安装第三方应用的错误,需要执行sudo spctl --master-disable,允许任何来源应用安装

软件包安装

驱动安装

  1. 进入packages目录

  2. 双击安装HoRNDIS-9.2.pkg

安装Python3.6

  1. 进入packages目录

  2. 双击安装python-3.6.8-macosx10.9.pkg

安装RKNN-Toolkit

双击运行install.sh.command,电脑会自动安装一些程序包,请耐心等待安装完成。

运行demo

以上步骤安装完成后,后续只需要运行下面的操作,即可启动演示程序。

  1. 确保计算棒已插入,确保电脑上有摄像头,如果没有内置摄像头,需要插入USB摄像头。

  2. 双击运行run_yolov3.sh.command(该文件在运行install.sh.command后生成)

  3. 等待一会,将会出现演示画面,如果要退出,则鼠标点击显示框,按’Esc’键退出。

主动模式开发介绍和环境安装

主动模式开发流程简介

概述

注:不要对计算棒做配置修改,也就是说计算棒无需更改模式,统一固定采用默认的被动模式即可。

主动模式下,RK1808人工智能计算棒是一个专用AI应用模块。RK1808人工智能计算棒作为主动设备,RK1808人工智能计算棒内部默认已安装rknn-toolkit和rknn-api,上位机(也称宿主机)无需安装rknn-toolkit和rknn-api,模型及算法固化在RK1808人工智能计算棒中,上位机只需通过USB口向计算棒输入数据(例如图片和视频流),RK1808人工智能计算棒自动完成数据的前处理、推理、后处理,然后把处理结果通过USB口输出给上位机。这里的上位机可以是任何带有USB接口的平台及任何操作系统,包括了x86/x64/arm32/arm64的linux/windows/mac os及单片机、树莓派等等...

为了方便用户通过USB口传输数据,RK1808人工智能计算棒会把USB口虚拟成网卡等标准设备,用户只需通过标准设备接口的操作(例如网络的socket编程)即可完成对RK1808人工智能计算棒数据的输入和输出。

细节如下

  1. RK1808计算棒插入上位机后,会被虚拟成网卡设备

  2. 上位机进行虚拟网卡配置,配置IP为192.168.180.1,保证上位机和1808中间的网络连接正常

  3. 计算棒默认IP为192.168.180.8,账号密码皆为toybrick,用户可以SSH登录计算棒,拷贝模型和server服务程序到计算棒

  4. 计算棒端运行server服务程序,用来接收上位机的连接请求,并调用RKNN进行处理,再返回结果

  5. 上位机运行client程序,连接server成功之后,发送推理请求,从1808端获取返回结果

主动开发模式总体流程图:

主动模式下AI开发过程

主动模式下开发的AI程序分为两个部分:计算棒server程序和上位机client应用程序。

• 模型预先部署在计算棒的存储上,计算棒server程序初始化环境并加载模型,启动socket server,接收上位机推送过来的数据,进行推理,然后把推理的结果返回给上位机。

• 上位机client应用程序采集数据(如抓取摄像头数据),通过socket client把数据推送给计算棒,同时通过socket client接收计算棒返回的处理结果,并做进一步的处理(如显示)。

主动模式下的RK1808 人工智能计算棒上RKNN API调用参考:《Rockchip_RK1808_Developer_Guide_Linux_RKNN》。

RK1808人工智能计算棒上已经提供了RKNN API C/C++语言所需的库和头文件,同时也预装了RKNN API的python 3.6库,用户可以在RK1808人工智能计算棒上开发部署C/C++或python的主动AI程序。

主动模式下会提供ssh登录进行开发调试:RK1808人工智能计算棒的linux操作系统为fedora,用户可以通过ssh登录fedora系统进行开发和调试,root根用户的密码为toybrick,普通用户toybrick的密码为toybrick。

基于Toybrick平台的开发流程

  1. RK1808人工智能计算棒作为网卡设备(rndis),通过web配置成主动模式,详见web配置介绍(如需恢复被动模式,请重新设置选择被动模式)。

  2. 设置toybrick_deploy 登录密码。

  3. 通过主动模式开发工具toybrick_deployc对RK1808人工智能计算棒中的系统软件包进行升级,保证RK1808人工智能计算棒中系统软件包处于最新版本。toybrick有维护自己的源服务器,会不定期的进行系统软件包更新,增加系统稳定性,该步骤视用户需要自行选择是否更新,在现有系统可以满足开发需要的情况下,可不更新。

  4. RK1808人工智能计算棒与上位机通过网络socket进行通信,编写上位机服务程序以及RK1808人工智能计算棒中下位机程序,通过主动模式开发工具toybrick_deployc安装RK1808人工智能计算棒中rpm及python依赖包(如有需要),把模型以及运行程序固化于RK1808人工智能计算棒,并在RK1808人工智能计算棒上运行推理及相关处理程序,上位机程序接收RK1808人工智能计算棒中推理及相关数据处理结果。

  5. 通过主动模式开发工具toybrick_deployc设置固化于RK1808人工智能计算棒中的程序开机启动,并重启RK1808人工智能计算棒,验证是否设置成功,为部署做准备。

产品部署过程

  1. 把模型及算法固化于RK1808人工智能计算棒,并设置固化于RK1808人工智能计算棒中的程序开机自启动。

  2. RK1808人工智能计算棒插入目标设备,如网络摄像头设备、PC机、无人机、智能小车等。

  3. 目标设备上运行上位机服务程序,显示处理结果。

  4. 具体案例详见wiki教程中yolov3主动模式案例。

主动模式Android 上位机环境安装

主体流程

  1. 操作系统确认:Android 8.1.0(演示设备为Toybrick TB-RK3399ProD V1.3版本的安卓系统,其他安卓平台开发流程仅供参考)。

  2. 将TB-RK1808 AI计算棒通过USB连接到(win、Mac、linux)等PC上,配置TB-RK1808 AI计算棒服务端环境,拷贝需要运行的服务端程序到TB-RK1808 AI计算棒并设置开机启动服务端程序。

  3. 将TB-RK1808 AI计算棒通过USB连接到安卓设备,配置TB-RK1808 AI计算棒和安卓本地的网络共享(配置前请确认安卓设备已安装rndis驱动,能正确识别计算棒网卡)。

  4. 运行演示需要摄像头,如果安卓设备没有自带摄像头则需要外接USB摄像头。

  5. 安装master_yolov3_demo.apk并运行demo程序

详情请直接参考:yolov3主动模式Android平台开发流程

主动模式其他系统上位机环境安装

主动模式适用于任意平台任意系统,上位机只需要能通过USB进行Socket通信即可,RK1808人工智能计算棒内部默认已安装rknn-toolkit和rknn-api,上位机无需安装rknn-toolkit和rknn-api,上位机只需通过Socket发送数据到计算棒,计算棒接收数据并推理,计算棒把推理结果通过socket发送给上位机,上位机显示结果即可。

主动模式开发请直接参考“示例”中主动模式相关Demo即可。

针对树莓派开发板使用RK1808计算棒情况,用户可参考http://t.rock-chips.com/forum.php?mod=viewthread&tid=1380&extra=page%3D1

配置计算棒网络共享

Linux系统配置计算棒网络共享

RK1808人工智能计算棒可以通过配置Linux上位机的NAT功能和桥接功能进行网络共享,实现计算棒联网,推荐使用NAT。

Linux系统配置NAT功能

  1. 若上位机使用Fedora系统
  • 打开“Preferences”->“Network Connections”,Ubuntu系统打开“Settings”->“Network Connections”,“Wired connection 1”是本地网卡链接,“Wired connection 2”是RK1808人工智能计算棒网卡链接,选择“Wired connection 2”,点击“配置”如下图中所示。

  • 进入“Wired connection 2”配置界面,选择“IPv4 Settings”,连接方式选择“Manual”模式,点击“Add”,输入Address和Netmask,如下图中5所示。点击“Save”,保存退出。

  1. 若上位机使用Ubuntu系统
  • 运行ifconfig,可以看到eno1为本地网卡,用于访问外网,enp0s20u12u2i1为USB网卡(RK1808人工智能计算棒虚拟网卡)。不同的系统网卡名称可能不一样,以实际网卡名称为准。

  • 命令行方式,执行如下命令,其中enp0s20u12u2i1需要修改成用户本地实际值;正常情况只要设置一次即可,若拔插设备发现网卡名称改变了或者用户手动删除该网卡,则需要重新设置。
sudo nmcli connection add con-name toybrick type ethernet ifname enp0s20u12u2i1 autoconnect yes ip4 192.168.180.1/24
  1. 配置NAT功能,执行如下命令,其中eno1需要修改成用户本地实际值;关机失效,所以每次电脑重启都要重新设置。
sudo sysctl   -w net.ipv4.ip_forward=1
sudo iptables -F
sudo iptables -t nat -F
sudo  iptables  -t  nat  -A POSTROUTING -o eno1 -j MASQUERADE

Linux系统配置桥接功能(配套dhcp使用)

  1. 计算棒需要开启DHCP,参考宿主机网络配置与WEB登录设置。

  2. 创建配置脚本bridge-setup.sh,内容如下:

#!/bin/bash

if [ $# -lt 2 ]; then
    echo "Invalid argument"
    exit 0
fi

count=`nmcli con show | awk '$(NF-1)=="bridge"' | wc -l`
for i in $(seq 1 $count)
do
    uuid=`nmcli con show | awk '$(NF-1)=="bridge"' | awk '{print $(NF-2)}'`
    sudo nmcli con del $uuid
    sleep 1
done

count=`nmcli con show | awk '$(NF-1)=="802-3-ethernet" || $(NF-1)=="ethernet"' | wc -l`
for i in $(seq 1 $count)
do
    uuid=`nmcli con show | awk '$(NF-1)=="802-3-ethernet" || $(NF-1)=="ethernet"' | awk 'NR==1{print $(NF-2)}'`
    sudo nmcli con del $uuid
    sleep 1
done

nmcli con add con-name br0 type bridge ifname br0 -- ipv4.routes 192.168.180.0/24 ipv4.method auto bridge.stp no
#nmcli con add con-name $1 type bridge-slave ifname $1 master br0
#nmcli con add con-name $2 type bridge-slave ifname $2 master br0
for var in $@
do
    nmcli con add con-name $var type bridge-slave ifname $var master br0
done
nmcli con up br0
ip addr add 192.168.180.1/24 dev br0
  1. 创建清除脚本bridge-clean.sh,内容如下:
#!/bin/bash

if [ $# -ne 2 ]; then
    echo "Invalid argument"
    exit 0
fi

count=`nmcli con show | awk '$(NF-1)=="bridge"' | wc -l`
for i in $(seq 1 $count)
do
    uuid=`nmcli con show | awk '$(NF-1)=="bridge"' | awk '{print $(NF-2)}'`
    nmcli con del $uuid
    sleep 1
done

count=`nmcli con show | awk '$(NF-1)=="802-3-ethernet" || $(NF-1)=="ethernet"' | wc -l`
for i in $(seq 1 $count)
do
    uuid=`nmcli con show | awk '$(NF-1)=="802-3-ethernet" || $(NF-1)=="ethernet"' | awk 'NR==1{print $(NF-2)}'`
    nmcli con del $uuid
    sleep 1
done

nmcli con add con-name $1 type ethernet ifname $1
nmcli con up $1
nmcli con add con-name $2 type ethernet ifname $2 ipv4.addr 192.168.180.1/24 ipv4.method manual
nmcli con up $2 
  1. 以Ubuntu系统为例,eno1为本地网卡,用于访问外网。enp0s20u12u2i1为USB网卡(RK1808人工智能计算棒虚拟网卡)。不同的系统网卡名称可能不一样,以实际网卡名称为准。

  1. 配置桥接功能,执行如下命令:
sudo ./bridge-setup.sh eno1 enp0s20u12u2i1

如果存在多个USB网卡的情况下,可以根据实际需要把USB网卡名称作为参数进行桥接功能配置。

  1. 清除桥接功能,执行如下命令:
sudo ./bridge-clean.sh eno1 enp0s20u12u2i1

注意事项:

*1.计算**棒在DHCP模式下,如果出现获取地址异常,请执行*

sudo rm /var/lib/dhclient/dhclient.leases

删除记录,然后重启计算棒。

2.若上位机的nat或桥接配置失败,导致计算棒无法联网,请找一台新安装系统的上位机来配置nat或桥接,避免由于上位机的系统不干净导致nat或桥接配置失败。

Window7/10系统配置计算棒网络共享

RK1808人工智能计算棒可以通过配置Windows上位机的NAT功能和桥接功能进行网络共享,实现计算棒联网,推荐使用NAT。

Window7/10系统****配置NAT功能

  1. 打开“网络和共享中心”->“更改适配器设置”,“本地连接”是本地网卡设备,“本地连接 2”是计算棒网卡设备(带有RNDIS的表示计算棒网卡设备)。

  1. 选择“本地连接”,右键打开“属性”->“共享”,勾选“允许其他网络用户用过此计算机的Internet连接来连接”,点击“请一个专用网络链接”,选择“本地连接 2”,点击“确定”退出,点击“确定”后会提示虚拟网卡的ip地址可能会改变,所以需要修改ip地址,参考步骤3修改ip地址。

注意:若是Windows10系统可能没有“本地连接2”选项,请更换其他windows 10电脑,重新进行配置。

  1. 选择“本地连接2”,右键打开“属性”->“网络”,选择“Internet 协议版本 4 (TCP/IPv4)”,点击“属性”,把“IP 地址”修改成192.168.180.1,点击“确定”退出。

  1. 打开“Windows 防火墙”->“自定义设置”,关闭防火墙,点击“确定”退出。

Windows7/10系统桥接配置

  1. 计算棒需要开启DHCP,参考宿主机网络配置与WEB登录设置。

  2. 打开“控制面板”->“网络和共享中心”,进入“更改适配器配置”。

其中“本地连接”是本地网卡,“本地连接 2”是计算棒网卡。

  1. 同时选择“本地连接”和“本地连接 2”,点击右键选择“桥接”,完成桥接配置。

  1. 用管理员权限打开命令提示符窗口,输入“route PRINT”查看网桥接口序号,如下图所示,网桥接口序号为51,具体网桥接口序号以实际情况为准。

  1. 用管理员权限打开命令提示符窗口,比如计算棒IP地址为192.168.180.8,输入“route ADD 192.168.180.8 MASK 255.255.255.255 192.168.180.8 IF 51”,添加路由信息。

  2. 如果PC没有连接外网时进行配置桥接,需要把网桥接口配置成静态地址:192.168.180.1。

注意事项:

若上位机的nat或桥接配置失败,导致计算棒无法联网,请找一台新安装系统的上位机来配置nat或桥接,避免由于上位机的系统不干净导致nat或桥接配置失败。

macOS配置计算棒网络共享

macOS配置网络共享(NAT)

  1. 打开“System Preference”,选择“Network”。

  2. 选择RK1808S0,配置ip地址

  1. 使能转发
sudo sysctl -w net.inet.ip.forwarding=1
sudo sysctl -w net.inet6.ip6.forwarding=1
  1. 在/etc/pf.anchors目录下新建toybrick文件,内容如下(其中en0为本地网卡,en6为计算棒网卡,值不固定,以用户本地实际值为准,用户可通过ifconfig查看):
nat on en0 from en6:network to any -> (en0)
  1. 修改/etc/pf.conf如下:
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
nat-anchor "toybrick"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
anchor "toybrick"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
load anchor "toybrick" from "/etc/pf.anchors/toybrick"
  1. 使能配置文件
sudo pfctl -ef /etc/pf.conf

macOS配置桥接网络

  1. 计算棒需要开启DHCP,参考宿主机网络配置与WEB登录设置。

  2. 打开“System Preference”,选择“Network”。

  1. 选择“Manage Virtual Interfaces...”,配置桥接。

  1. 选中“Ethernet”和“RK1808S0”,其中“Ethernet”是本地网卡,“RK1808S0”是计算棒网卡。

  1. 点击“Create”创建桥接配置,最后点击“Apply”完成桥接配置。

  2. 配置IP地址:

ifconfig *** alias 192.168.180.1

说明:***指实际Bridge Name

注意事项:

若上位机的nat或桥接配置失败,导致计算棒无法联网,请找一台新安装系统的上位机来配置nat或桥接,避免由于上位机的系统不干净导致nat或桥接配置失败。

Android配置计算棒网络共享

手动运行配置脚本

演示设备为Toybrick TB-RK3399ProD V1.3版本的安卓系统, 其他安卓平台开发流程仅供参考。

需注意:安卓配置网络的命令需要root安卓机器请确保安卓机器正确获取root权限和安装rndis驱动。若需要开机运行脚本需要按照标准的安卓开机启动流程修改安卓源码重新烧写安卓固件, 如果没有设置开机启动则每次重启都需要重新设置。

  1. 计算棒需要开启DHCP,参考宿主机网络配置与WEB登录设置。

  2. 下载脚本并下载到安卓设备

配置脚本:cfgainetd.sh

网络工具:ethtool

下载地址:imgcfgainetd.zip

使用adb push 将脚本推到安卓设备中

adb root && adb remount
adb push cfgainetd.sh /data
adb push ethtool /data
  1. 设置脚本执行权限

使用adb push的脚本文件是没有可执行权限的我们需要使用chmod命令添加可执行权限

E:\master_yolov3_demo>adb shell
rk3399_mid:/ # cd data/
rk3399_mid:/data # ls -la cfgainetd.sh ethtool
-rw-rw-rw- 1 root root    2052 2020-01-02 08:01 cfgainetd.sh
-rw-rw-rw- 1 root root 1369842 2019-12-31 09:42 ethtool
rk3399_mid:/data # chmod a+x cfgainetd.sh ethtool
rk3399_mid:/data # ls -la cfgainetd.sh ethtool
-rwxrwxrwx 1 root root    2052 2020-01-02 08:01 cfgainetd.sh
-rwxrwxrwx 1 root root 1369842 2019-12-31 09:42 ethtool 
rk3399_mid:/data #
  1. 运行脚本

插入RK1808人工智能计算棒到安卓设备中。然后后台执行脚本即可。

E:\master_yolov3_demo>adb shell
rk3399_mid:/ # nohup /data/cfgainetd.sh > /dev/null 2>&1 &
[1] 4180
rk3399_mid:/ #
  1. 验证cfgainetd.Sh执行是否成功

当插入RK1808人工智能计算棒并且脚本正常执行之后,通过ifconfig可以查看到RK1808人工智能计算棒的网卡被分配到ip,出现异常则没有分配到ip。

失败情况:

rk3399_mid:/ # ifconfig -a
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:29981 errors:0 dropped:0 overruns:0 frame:0
          TX packets:29981 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:2752109 TX bytes:2752109

eth1      Link encap:Ethernet  HWaddr ec:26:ae:2a:b6:e4
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 TX bytes:0

eth0      Link encap:Ethernet  HWaddr f2:16:66:a4:5b:0b
          inet addr:172.16.9.10  Bcast:172.16.9.255  Mask:255.255.255.0
          inet6 addr: fe80::f016:66ff:fea4:5b0b/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1585 errors:0 dropped:0 overruns:0 frame:0
          TX packets:94 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:118419 TX bytes:8392
          Interrupt:24

rk3399_mid:/ # route    //或者  busybox route 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.9.0      *               255.255.255.0   U     0      0        0 eth0
rk3399_mid:/ #

配置成功,可以看到 inet addr:192.168.180.1

130|rk3399_mid:/ # ifconfig -a
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:36959 errors:0 dropped:0 overruns:0 frame:0
          TX packets:36959 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:3391375 TX bytes:3391375

eth1      Link encap:Ethernet  HWaddr ec:26:ae:2a:b6:e4
          inet addr:192.168.180.1  Bcast:192.168.180.255  Mask:255.255.255.0
          inet6 addr: fe80::ee26:aeff:fe2a:b6e4/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:59 errors:0 dropped:0 overruns:0 frame:0
          TX packets:53 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2048 TX bytes:4978

eth0      Link encap:Ethernet  HWaddr f2:16:66:a4:5b:0b
          inet addr:172.16.9.10  Bcast:172.16.9.255  Mask:255.255.255.0
          inet6 addr: fe80::f016:66ff:fea4:5b0b/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1854 errors:0 dropped:0 overruns:0 frame:0
          TX packets:94 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:139777 TX bytes:8392
          Interrupt:24

rk3399_mid:/ # route    //或者  busybox route 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.9.0      *               255.255.255.0   U     0      0        0 eth0
192.168.180.0   *               255.255.255.0   U     0      0        0 eth1
rk3399_mid:/ #

注意事项:

若上位机的nat或桥接配置失败,导致计算棒无法联网,请找一台新安装系统的上位机来配置nat或桥接,避免由于上位机的系统不干净导致nat或桥接配置失败。

宿主机网络配置与WEB登录

注:计算棒的web默认是关闭的,若要开启web可以通过ssh登录计算棒,在root用户权限下修改/etc/toybrick.conf这个配置文件,设置web = on;

RK1808 人工智能计算棒支持使用web界面进行系统配置,下面介绍如何访问这一配置界面,以及界面的主要功能。

宿主机网络配置

Windows 7/10下网络配置:

  1. 插入RK1808 人工智能计算棒。

  2. 打开设备管理器,网络适配器模块中,会出现“Remote NDIS based Internet Sharing Device”。

注: 有些电脑会出现无法识别的设备,卸载无法识别的设备,等待RNDIS驱动重新安装。

  1. 打开网络和Internet设置,点击“以太网”->“更改适配器选项”。

  1. 右键“以太网*”(远程NDIS兼容设备),->“属性”->“Internet协议版本4”,->“属性”, 选择“使用下面的IP地址”,输入IP地址和子网掩码,点击“确认”。

  1. 确认IP地址。

Linux下网络配置(以ubuntu18.04为例)

  1. 在插入RK1808 AI计算棒之前,先在上位机打开终端,输入命令ifconfig。

  1. 然后插入RK1808 人工智能计算棒,再次在上位机输入命令ifconfig,发现多了图中红框这一项。

  1. 打开系统设置,选择网络,找到第二步中新添那一项Mac地址相同的设备,点击右上角设置。

  1. 按照下图,选择ipv4,手动,添加新的ip -- 192.168.180.1 255.255.255.0,点击应用后,即完成网络配置。

MAC OS下网络配置

  1. 打开“System Preference”,选择“Network”。

  2. 选择RK1808S0,配置ip地址。

WEB登录

  1. 网络配置完成后修改/etc/toybrick.conf,将web设置为on模式,浏览器输入http://192.168.180.8即进入RK1808人工智能计算棒登录页面。

若忘记密码,请点击下方链接,此操作不仅会重置密码,而且会将计算棒web配置恢复至出厂设置,请谨慎操作:

  1. 输入用户名,密码登录(默认用户名和密码均为toybrick),即可进入Home页面。

模型加解密

简介

部分客户为保护存储在emmc中的模型不被非法拷贝,需要一种加密模型的方法来保护模型。Rockchip为用户提供了统一的数据加解密接口,每一台设备的加解密密钥都不相同,客户可以使用该接口加解密模型,黑客非法拷贝模型到其他设备上将无法正常运行。

安装

使用该功能需要计算棒烧写v1.4.1及以上版本固件,或者使用sudo dnf update命令更新

按照“Wiki教程”-- “TB-RK1808S0”--“配置计算棒网络共享”确认计算棒可以正常联网

ssh toybrick@192.168.180.8登录计算棒

sudo dnf install rk-tee-service

测试

vi test.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rockchip/rk_tee_service_host.h"

int main(int argc, char *argv[])
{
    int test_size = 64*1024+110;
    unsigned char *plaint = malloc(test_size);
    memset(plaint, 0x11, test_size);
    unsigned char *cipher = malloc(test_size);
    unsigned int cipher_len = test_size;
    unsigned char *plaint2 = malloc(test_size);
    unsigned int plaint2_len = test_size;


    rk_encrypt_data(plaint, test_size, cipher, &cipher_len);
    printf("cipher_len=%d\n", cipher_len);
    rk_decrypt_data(cipher, cipher_len, plaint2, &plaint2_len);
    printf("plaint2_len=%d\n", plaint2_len);
    if (memcmp(plaint, plaint2, plaint2_len) == 0)
        printf("success!\n");
    else
        printf("fail!\n");
}

gcc test.c -o test -lrktee_service

sudo ./test

固件在线升级

在线升级可以把计算棒的固件升级到最新版本。

首先按照《配置计算棒网络共享》配置上位机联接外网,然后把计算棒插入上位机的USB口,待计算棒启动完成后,有两种方式可以执行计算棒升级:

一个方式是通过web登录计算棒的网页http://192.168.180.8, 在Update页面上点击Update按钮进行升级;

另外一个方式是通过ssh登录计算棒,在shell下执行sudo dnf update -y命令进行升级,升级完成后执行sudo sync同步一下;

升级完成后,通过web页面查看软件版本信息,或者在shell下通过执行rpm -qa | grep toybrick-server查看版本信息。

rknn-toolkit-lite的python轮子包在线升级:

  1. ssh登陆计算棒: ssh toybrick@192.168.180.8,密码toybrick

  2. 依次按照以下命令执行pip3升级:(注:一定是在root用户下)

    sudo su;

    pip3 install --upgrade pip;

    ln -s /usr/local/bin/pip /usr/bin/pip;

    ln -s /usr/local/bin/pip3 /usr/bin/pip3;

    ln -s /usr/local/bin/pip3.6 /usr/bin/pip3.6;

    exit;

  3. 在shell下执行pip3 install rknn-toolkit-lite --user --upgrade。(注:一定是在toybrick用户下)

注:出现升级不成功的时候,首先要查看是否计算棒通过上位机联网可用,可以ssh登录计算棒,在计算棒上执行sudo ping imgwww.baidu.com看看是否可以ping通外网。

固件烧写

windows需先安装USB驱动

资料下载页面下载烧写工具及固件

先在PC上插入计算棒1分钟确认PC识别到计算棒,再将计算棒在PC上连续拔插5次,每次插入时间3~8秒,计算棒变成可烧写的maskrom状态。

然后再执行以下烧写步骤:

1、windows下:双击运行windows目录下的windows_flash.exe,打开烧写工具,点击执行按钮,开始烧写,等待烧写完成。

2、Mac下:双击运行unix目录下的mac_flash.sh.command, 根据提示,输入开机使用的密码,等待烧写完成。

3、Linux下:在命令行下,cd unix,然后运行./linux_flash.sh,根据提示,输入sudo的密码,等待烧写完。

若用户在PC上拔插5次,无法进入maskrom状态

用户可以参考“wiki--WEB配置介绍”设置宿主机网络配置,然后windows用户打开cmd.exe输入ssh toybrick@192.168.180.8登录计算棒(win7需要先安装openssh),linux用户在命令行输入ssh toybrick@192.168.180.8登录计算棒,计算棒上执行sudo reboot loader让计算棒进入loader模式,再执行上诉的烧写步骤。

注意:

1. 烧写固件有风险,请谨慎操作,烧写固件过程中请勿断电,请严格按照官方操作步骤,禁止烧写除官方发布外的其他固件。

2. 推荐固件在线升级。

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


返回顶部