2

嵌入式AI从入门到放肆【K210篇】-- 硬件与环境

 2 years ago
source link: http://www.pengzhihui.xyz/2019/09/13/k210-1/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

关注我的同学都知道,在搞项目方面我一点也不挑食,有啥玩啥,擅于给自己找麻烦。

由于个人本职工作是搞AI的,在不久之前的一个项目中,我用STM32制作了一个小模块,探讨了一下“推理一个实用神经网络最低需要什么样的算力”这个问题。项目的演示视频如下:

基于Cortex-M的M4CNN模块

在那个项目中,我成功在主频只有不到100MHz,sram只有32K的单片机上推理了一个自己训练的CNN-SLR网络模型,效果甚至还不错。

而这一次我准备来一波反向操作:尽可能用上算力最强的MCU,来看看在上面能跑多复杂的网络,因垂丝汀

注意,我这里指明了使用的是MCU,所以移动设备上的各种SoC就不在讨论范畴了,要说原因的话,是因为移动端SoC之间的battle过于激烈,这个讨论留作后话,在这一篇里面就暂时按下不表了;另一方面由于二者不在一个价位段,没有可比性。

为了引出本篇要使用的MCU型号,首先我们来讨论一下嵌入式处理器的一个守恒定律,也即 功耗-价格-性能 不可兼得,如下图:

img

“天下没有免费的处理器”

稍微解释一下上图的话就是,由于物理定律限制我们可以认为:在其他条件一定的情况下,性能和功耗肯定成正比,更强的性能意味着更大的功耗也就会产生跟多的热量;而要想提升性能的同时还能保证功耗不变甚至更低的话,就只能改进芯片的架构或者改进制程工艺,这又会带来成本的提高。因而根据不同应用方向,我们可以选择兼顾其中两者的一些硬件平台:

  • 成本低,性能弱,功耗也低:代表是各种单片机如STM32/AVR等。
  • 成本低,性能强,但制程不高易发热:代表是各种低端SoC比如全志的H系列。
  • 性能强,制程先进,但价格十分不友好,有钱还不一定给卖系列:代表是现在智能手机上使用的各种旗舰SoC,比如高通骁龙/海思麒麟/苹果A系。

那难道真的就没有三者兼得的芯片平台了吗?

其实还真有,本篇的主角K210就勉强算是一个,这也是我这次选择折腾这个项目的主要原因,接下来请听我仔细分析~

K210是个啥

K210是由一家叫做嘉楠的曾经做挖矿芯片的公司在去年推出的一款MCU,其特色在于芯片架构中包含了一个自研的神经网络硬件加速器KPU,可以高性能地进行卷积神经网络运算。

img

可不要以为MCU的性能就一定比不上高端SoC,至少在AI计算方面,K210的算力其实是相当可观的。根据嘉楠官方的描述,K210的KPU算力有0.8TOPS ,作为对比,拥有128个CUDA单元GPU的英伟达Jetson Nano的算力是0.47TFLOPS (浮点);而最新的树莓派4只有不到0.1TFLOPS

当然了,这个性能跟某些旗舰级别的SoC还是有差距的:A76级别的CPU本身就已经很变态,更何况旗舰SoC上面都会搭载用于AI加速的硬件用于异构运算,比如高通的Hexagon DSP、苹果的Neural Engine、华为的达芬奇架构NPU等等,这些NPU在某些应用下甚至能达到与数百W功耗的桌面级GPU接近的算力(顺便提一下GTX1080Ti的双精度浮点算力是11.3 TFLOPS ),可以说是丧心病狂了。

值得注意的是,芯片的算力不一定和模型推理速度成正比,嵌入式AI的另一个核心是inference框架。对于CPU架构来说,是否使用SIMD(ARM从v7开始就支持NEON指令了)、是否使用多核多线程、是否有高效的卷积实现方式、是否有做汇编优化等等都会极大影响模型运行速度;而对DSP/NPU等硬件架构来说,是否对模型进行量化推理、量化的方式、访存的优化等也会有很大影响。

K210的其他参数如下:

  • 双核 64-bit RISC-V RV64IMAFDC (RV64GC) CPU / 400MHz(可超频到600MHz)
  • 双精度 FPU
  • 8MiB 64bit 片上 SRAM(6MiB通用SRAM+2MiB的AI专用SRAM)
  • 神经网络处理器(KPU) / 0.8TFLOPS
  • 音频处理器(APU)
  • 可编程 IO 阵列 (FPIOA)
  • 双硬件512点16位复数FFT
  • SPI, I2C, UART, I2S, RTC, PWM, 定时器支持
  • AES, SHA256 加速器
  • 直接内存存取控制器 (DMAC)

芯片采用BGA144封装,28nm制程工艺,芯片功耗低至0.35W,而成本,只要20RMB

想一下一块Arduino的板子要多少钱……Arduino的性能和外设在K210面前就是个弟中弟(摊手)。

img

芯片架构图

那么K210又能做哪些事情呢?

多到让你怀疑它是否真的只是个单片机……人脸检测、物体识别、播放视频、声场成像、3D渲染,甚至还能在上面跑FC模拟器玩游戏……

可以参考下面链接里的视频演示,相信看完你会爱了的:

Maix能做哪些事 · MaixPy 文档maixpy.sipeed.com

好了芯片就吹到这里,下面介绍一下市面上已有的一些K210开发板。

如何选择开发板

如果看完上面的介绍对K210产生了兴趣,那么下面我会推荐几款值得入手的K210开发板(如果不小心打了广告麻烦结一下广告费:D)。

其实我早在去年很早的时候就收到过K210的开发板了,当时是别人送的评测套件,只不过我那时不巧刚毕业,没有太多时间折腾,就一直拖到最近才有空仔细研究。另一方面的原因是,当时K210刚出,软件生态还非常的不成熟,而这个情况现在就好多了,不光有官方的IDE(还是develop版本),甚至还有MicroPython这样的固件的移植,可玩性高了很多,值得折腾一番。

我个人是打算后面自己设计一块K210开发板的(已经动工了),用于满足我个人的各种变态要求(主要是要狗迷你)。不过对于普通玩家而言,BGA的芯片可能不太适合自己DIY,所以可以按我下面的推荐进行购买即可,其中很多都是我亲自买过试用的。

1. 官方开发板套件-KD233

img

这个是嘉楠官方的评估板套件,好处呢在于可以和官方IDE中的例程项目无缝对接(当然如果不打算用官方IDE就无所谓了,这个后面软件篇会介绍),IDE中下载的例程都可以直接烧录运行。同时板子上的资源还是挺多的,摄像头、麦克风、LCD屏幕之类的都有,而且可以看到芯片周围有一圈跳线帽,把所有的IO都引出来了,也可以自己取掉跳线帽用杜邦线连接其他硬件。

缺点也很明显,这板子实在是太爱爱爱大了…..反正我是看不顺眼,虽然买了但是只是用来验证官方给的原理图是否无误,调试的时候还是用其他的板子。

价格偏贵,对于想自己设计硬件的同学可以购买,其他的就不推荐了。

2. Widora-AIRV2/BITK210开发板套件

img

与第一个板子完全相反,这个是目前市面上能买到的最小的k210开发板,而且价格非常实惠。

这个开发板采用了核心板和底板分离的设计方式,适合那些想自己做硬件但是又无法设计核心电路的同学。核心板使用的封装是NGFF(Mini-PCIE)接口,把芯片最小系统和电源IC集成在了核心板,剩下的功能全部由金手指引出至底板。

可以看到核心板背面在K210的正下方布置有很多滤波电容,因为在这么高的运行主频下对电源的稳定性由很高要求,基本就是按照ARM CPU的Layout方式来设计PCB的。

板子也有带摄像头和LCD,但是默认摄像头的型号和官方开发板有点区别,官方的是OV5640,而这个带的是OV2640。当然了,这两个摄像头是完全pin-to-pin的,可以自己更换,修改一下软件驱动就行。屏幕也换成了2.4寸的小一点的ST7789驱动LCD,我个人还是觉得这屏幕太大(傲娇)。

还有一个缺点就是,这个板子的配套软件资源很少(可以说没有),当然了只要是K210的板子其实各家的软件都是可以用的,只不过由于硬件上的细微差别,需要自己修改一点源码(比如GPIO编号之类的)。

总的来说非常推荐,性价比也非常的高,适合在玩熟了之后用作以后项目的主力产品。

3. Sipeed Maixduino 开发板

Sipeed就是之前做荔枝派的那家公司了,他们团队也推出了一系列的K210开发板,足以满足各种需求,Sipeed Maixduino就是其中一款。

img

看这个开发板的名字里面还带个duino,该不会支持Arduino编程吧??

是的,但是目前只支持一丢丢。

官网WiKi上的接口目前基本全是空白,有兴趣的同学得再等一等,暂时先收起你那大胆的想法

img只有IO类的API有相关实现

Maixduino显然是冲着兼容Arduino接口设计的,板子是标准的UNO型,相比与上面的两个开发板多了一个ESP32模块(话说ESP32也是一个网红硬件),官方开发板有的功能它都有,体型还挺小巧。

值得一提的是这个板子上面搭载的邮票孔核心板是可以单独购买的,叫做M1 Module,下面会进行介绍。

4. Sipeed M1 开发板套件

img

这个板子使用的就是上面的那个M1 Module,采用核心板加底板的方式,比上面的要小巧很多,同时所有IO都有引出,可以看作一个最小系统洞洞板,我个人比较喜欢这种设计,相比于Widora的板子黑色沉金也更好看一些。

板子不算太贵,Sipeed 系列的K210板子最大的优势是,软件资源做得非常好,官网WiKi、教程、源码的开放都很到位,考虑到硬件和软件双方面的条件,Sipeed 的开发板是我最建议大家购买的。

他家还有其他型号的K210开发板,我就不一一介绍了,大家感兴趣的可以自己去某宝搜。

编程环境

K210是支持好几种编程环境的,从最基本的cmake命令行开发环境,到IDE开发环境,到Python脚本式开发环境都支持,下面会进行分别介绍。

这几种开发方式没有优劣之分,有的人喜欢用命令行+vim,有的人喜欢IDE图形界面,也有的人根本不关心编译环境觉得人生苦短只想写Python。

一般来说越基础的开发方式比如C语言+官方库会自由度越大,能充分发挥出芯片的各种外设功能,但是开发难度比较高,过程很繁琐;越顶层的开发方式比如写脚本,虽然十分地便捷,甚至连下载程序的过程都不需要了,但是程序功能的实现极度依赖于MicroPython的API更新,且很多高级系统功能无法使用。

1. 命令行开发环境

首先说一下,K210的官方SDK支持两种开发模式:FreeRTOSStandalone(裸机)

具体选择哪种模式取决于个人喜好,如果你之前用过FreeRTOS的话,应该可以很快熟悉SDK的相关接口。我个人对于单片机是更愿意使用裸机开发模式,因为如果要跑OS的话,我会倾向于使用能跑完整Linux系统的开发板,比如这个我自己做的Linux-Card

用命令行开发的话建议在Linux环境下(Windows下用命令行总感觉怪怪的),下面介绍环境搭建方式。

1.1 下载SDK

在官网的资源下载页面下载相应的SDK:

https://kendryte.com/downloads/kendryte.com

img

1.2 安装工具链

安装 build-essential 以获取 make 工具

$ sudo apt install build-essential

安装cmake

$ sudo apt install cmake

勘智官网下载Ubuntu版本工具链,放到/opt目录并解压缩。

img

$ sudo mv kendryte-toolchain-ubuntu-amd64-8.2.0.tar.gz /opt$ cd /opt$ sudo tar -zxvf kendryte-toolchain-ubuntu-amd64-8.2.0.tar.gz

打开~/.bashrc文件,在文件末尾添加如下一行,将 /opt/kendryte-toolchain/bin 目录添加到PATH环境变量

export PATH=$PATH:/opt/kendryte-toolchain/bin

使修改生效

$ source ~/.bashrc

1.3 编译 hello world 工程

Kendryte Github下载kendryte-standalone-sdk

$ git clone [email protected]:kendryte/kendryte-standalone-sdk.git

hello world工程在kendryte-standalone-sdk/src/hello_world目录下。

创建一个build目录并进入:

$ mkdir build && cd build

运行cmake

$ cmake .. -DPROJ=hello_world -DTOOLCHAIN=/opt/kendryte-toolchain/bin
$ make

会在build目录下生成.bin文件,接下来把这个文件烧录进芯片就ok了。

1.4 烧录固件

K210使用的是串口ISP进行下载程序(也支持J-Link调试不过个人感觉不太必要,这里就不介绍了)。

IO_16 用于boot 模式选择,上电复位时,拉高进入FLASH 启动,拉低进入ISP 模式。复位后,IO_0、IO_1、IO_2、IO_3 为JTAG 引脚,IO_4、IO_5 为ISP也就是UART0引脚。

上面介绍的K210的开发板都会板载USB-TTL串口的芯片,所以板子直接连上电脑,选择好串口号,就可以下载程序了,跟Arduino一样的体验。只不过下载过程需要用到一个下载工具,叫做K-Flash

K-Flash的软件同样可以在上面的官网地址进行下载,软件操作界面很简单,选择bin文件、板子型号、串口号,点击下载就可以了。

img

1.5 打包Kfpkg固件

K210 的固件包主要有两种格式: .bin 和 .kfpkg。

.kfpkg可以包含多个.bin文件或者模型文件,可以方便地把程序固件和网络模型文件打包到一起一次性烧录,烧录方式是和bin文件一样的,用K-Flash即可。这里介绍如何制作kfpkg文件以及使用:

创建自己的 .kfpkg 文件

.bin文件是固件内容,作为参数传给烧录软件,软件会默认烧录到flash的0地址,完成后重启即可运行。

但是有时候我们需要烧录其它二进制文件到flash,比如模型、文件系统、或者自己定义的其它数据,这时需要指定烧录的地址,光有 .bin文件烧录工具并不知道我们想把数据烧录到flash的哪里,打包一个.kfpkg格式的文件则是为了解决这个问题的。

kfpkg由3部分组成:

  • flash-list.json文本文件:用于储存.bin文件列表以及烧录地址等信息
  • .bin固件
  • 其他文件(二进制文件)

比如我们想同时下载名为XXX.bin的固件,以及YYY.bin的其它文件到Flash的0xA00000地址,则需要写一个 flash-list.json 文件,内容如下:

"version": "0.1.0",
"files": [
"address": 0,
"bin": "XXX.bin",
"sha256Prefix": true
"address": 0x00A00000,
"bin": "YYY.bin",
"sha256Prefix": false

注意sha256Prefix选项, 固件需要校验,所以为true, 而其它数据(比如模型数据)不需要,所以为false。

最后,将这三个文件(XXX.bin, YYY.bin, flash-list.json)压缩成zip文件,然后改后缀名为.kfpkg 即可被烧录工具识别,并按照指定地址烧录到flash。

2. IDE开发环境

对于想在Windows下开发的同学,可以使用官方提供的IDE,这也是我最常用的开放方式。

官方的IDE是基于Visual Studio Code开发的,非常好用,最主要是要有代码自动补全:D

img

2.1 下载IDE

在这个地址下载:

img

下载完启动会自动联网更新组件,按下面的顺序点击下载官方例程:

img

IDE的好处就是可以自动化执行很多依赖项操作,这样操作:

img

然后就可以编译下载了:

img

如果编译报错的话,首先确认已经点了安装所有依赖,另外记得先点一下编译左边的垃圾桶图标进行项目清理,再尝试编译。

IDE下面这一排按钮其实就是顶部菜单栏的Kendryte选项下的内容。

3. MicroPython开发环境

上面介绍的两种开发环境都是编写代码,然后编译下载,而这里介绍的这种方式只需要下载一次固件,然后就可以用串口的方式进行Python交互,或者也可以把脚本存在SD卡里然后开机运行。

这种脚本式的交互固件式基于一个叫MicroPython的开源项目做的。

MicroPython 是基于 Python3 的语法做的一款解析器,包含了 Python3 的大多数基础语法, 主要运行在性能和内存有限的嵌入式芯片上(最早开始火的是STM32上),注意 Micropython 不包含 Python3 的所有语法。

img

MaixPy是将Micropython移植到K210的一个项目, 支持 MCU 常规操作, 也集成了机器视觉和麦克风阵列等模块, 以快速开发智能应用。

Github

Micropython 可以让我们在 K210 上编程更加简单快捷,比如我们需要寻找I2C总线上的设备,只需要使用如下代码即可实现:

from machine import I2C
i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29)
devices = i2c.scan()
print(devices)

同样,实现一个呼吸灯,只需要如下代码:

from machine import Timer,PWM
import time
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
ch = PWM(tim, freq=500000, duty=50, pin=board_info.LED_G)
duty=0
dir = True
while True:
if dir:
duty += 10
else:
duty -= 10
if duty>100:
duty = 100
dir = False
elif duty<0:
duty = 0
dir = True
time.sleep(0.05)
ch.duty(duty)

实时拍照

import sensor
import image
import lcd
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.run(1)
while True:
img=sensor.snapshot()
lcd.display(img)

总之就是非常简单易用,感兴趣的同学可以移步官方WiKi和教程网站:

MaixPy项目

本文从芯片架构,到开发板选型,再到软件开发环境的搭建介绍了关于K210的基础ABC,这块KPU其实有很多有意思的应用,我会在后面的文章中进行更多介绍,包括SDK中各个模块的使用方式,以及如何将自己的AI模型部署到K210上面去运行。

同时我自己也在设计新的开发板,届时项目也会进行开源的,大家可以期待一下~感兴趣的同学赶紧关注啦。

想要订阅的同学,可以关注我的知乎账号:@稚晖

以及Bilibili账号:@稚晖君


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK