k230实验班技术资料

  • 课程主页:https://riscv-edu.cn/course/230

K230芯片是一款基于RISC-V架构的端侧AIoT芯片,具有高精度、低延迟、高性能、超低功耗、快速启动等特点,可广泛适用于各类智能产品场景,如边缘侧大模型多模态接入终端、3D结构光深度感知模组、交互型机器人、开源硬件、智能制造、智能家居、智能教育硬件等众多领域。

K230 参数

计算单元参数
CPUCPU 1: RISC-V处理器,1.6GHz,32KB I-cache, 32KB D-cache, 256KB L2 Cache,128bit; RVV 1.0扩展; CPU 0: RISC-V处理器,0.8GHz,32KB I-cache, 32KB D-cache, 128KB L2 Cache
KPU支持INT8 和INT16 典型网络性能:Resnet 50 ≥ 85fps @INT8 ;Mobilenet_v2 ≥ 670fps @INT8;YoloV5S ≥ 38fps @INT8
DPUH.264和H.265编码器和解码器最大分辨率支持4096*4096 编码器性能:3840*2160@20fps 解码器性能:3840*2160@40fps JPEG编解码器:支持最大8K(8192*8192)分辨率
图像输入支持最大3路 MIPI CSI(1x4lane+1x2lane) 或 3x2lane
显示输出1路MIPI DSI, 1x4 lane 或 1x2 lane 最大分辨率1920*1080@60fps
片上接口5xUART 5xI2C 6xPWM 64xGPIO + 8xPMU GPIO 2xUSB 2.0OTG 2xSDxC: SD3.01, eMMC5.0 3xSPI: 1xOSPI + 2xQSPI WDT / RTC / Timer

开发环境搭建

环境搭建与镜像烧写

  • 编译K230 SDK

    1. 安装必要软件
    sudo apt-get install git docker.io net-tools openssh-server make curl -y
    
    1. 下载SDK
    git clone https://github.com/kendryte/k230_sdk.git
    
    1. 拉取docker镜像
    docker pull ghcr.io/kendryte/k230_sdk
    docker images | grep k230_sdk # 确认拉取成功
    

    说明: docker镜像中默认不包含toolchain,下载源码后,使用命令'make prepare_sourcecode'命令会自动下载toolchain至当前编译目录中。

    1. (可选)配置原生Linux进行编译 根据Dockerfile配置编译环境

    2. 编译SDK

    cd k230_sdk
    make prepare_sourcecode
    

    make prepare_sourcecode 会自动下载Linux和RT-Smart toolchain, buildroot package, AI package等. 请确保该命令执行成功并没有Error产生,下载时间和速度以实际网速为准。

    确认当前目录为k230_sdk源码根目录, 使用如下命令进入docker

    docker run -u root -it -v $(pwd):$(pwd) -v $(pwd)/toolchain:/opt/toolchain -w $(pwd) ghcr.io/kendryte/k230_sdk /bin/bash
    

    根据不同开发板或软件功能,选择不同的配置config进行编译
    编译命令格式:make CONF=xxx,如:
    编译K230-USIP-LP3-EVB板子镜像,执行make CONF=k230_evb_defconfig 命令开始编译
    编译CanMV-K230板子的镜像,执行 make CONF=k230_canmv_defconfig 命令开始编译

    make CONF=k230_canmv_defconfig
    

    编译结束后会得到一个镜像文件

    1. 烧录镜像文件
    • 将已插入TF卡的U盘插入电脑

    如使用Linux烧录TF卡,需要先确认TF卡在系统中的名称/dev/sdx, 并替换如下命令中的/dev/sdx

    sudo dd if=sysimage-sdcard.img of=/dev/sdx bs=1M oflag=sync
    

    如使用Windows烧录, 建议使用the balena Etcher工具

通过串口操作开发板

将烧录完成的TF卡插入开发板TF卡槽中 系统上电后,默认会有两个串口设备,可分别用于访问小核Linux和大核RTSmart

可以使用例如MobaXterm的工具进行连接

小核Linux默认用户名root,密码为空。大核RTSmart系统中开机会自动启动一个应用程序,可按q键退出至命令提示符终端。

K230 SDK基础实验 hello_world

实验步骤

环境准备

k230_sdk中提供了工具链,分别在如下路径。

  • 大核rt-smart工具链
k230_sdk/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu
  • 小核linux工具链
k230_sdk/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0
  • 也可通过以下链接下载工具链
wget https://download.rt-thread.org/rt-smart/riscv64/riscv64-unknown-linux-musl-rv64imafdcv-lp64d-20230222.tar.bz2
wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1659325511536/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0-20220715.tar.gz

代码编写

  • 编写hello.c
#include <stdio.h>
int main (void)
{
    printf("hello world\n");
    return 0;
}
  • 将hello.c放到与k230_sdk同一级目录下
canaan@develop:~/work$ ls
hello.c   k230_sdk
  • 编译适用于小核linux的可执行程序
k230_sdk/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin/riscv64-unknown-linux-gnu-gcc hello.c -o hello
  • 编译适用于大核rt-smart的可执行程序
k230_sdk/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/riscv64-unknown-linux-musl-gcc -o hello.o -c -mcmodel=medany -march=rv64imafdcv -mabi=lp64d hello.c

k230_sdk/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/riscv64-unknown-linux-musl-gcc -o hello.elf -mcmodel=medany -march=rv64imafdcv -mabi=lp64d -T k230_sdk/src/big/mpp/userapps/sample/linker_scripts/riscv64/link.lds  -Lk230_sdk/src/big/rt-smart/userapps/sdk/rt-thread/lib -Wl,--whole-archive -lrtthread -Wl,--no-whole-archive -n --static hello.o -Lk230_sdk/src/big/rt-smart/userapps/sdk/lib/risc-v/rv64 -Lk230_sdk/src/big/rt-smart/userapps/sdk/rt-thread/lib/risc-v/rv64 -Wl,--start-group -lrtthread -Wl,--end-group
  • 拷贝hello、hello.elf至SD卡

    • 需要首先对SD卡的分区(3)进行取消隐藏
      下图为使用DiskGenius取消隐藏的示例,取消隐藏后,点击左上角保存更改:
  • 运行程序 将SD卡插入K230开发板,上电启动

    • 在小核端运行hello
    Welcome to Buildroot
    canaan login: root
    [root@canaan ~ ]#cd /sharefs
    [root@canaan /sharefs ]#./hello
    hello world
    
    • 在大核端运行hello.elf
    msh /sharefs>hello.elf
    hello world
    

K230 音视频编码

以下两个实验注意连接网线, 保证开发板和主机处于同一局域网下

或者使用@linglan111同学编写的连接脚本将开发板连接至wifi

#!/bin/sh

# Enable wlan0 interface
ifconfig wlan0 up

# Start wpa_supplicant with the specified configuration file
wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B

# Scan for available networks
wpa_cli -i wlan0 scan -B

# Display scan results
wpa_cli -i wlan0 scan_result

# Add a new network
wpa_cli -i wlan0 add_network

# Set the network parameters (replace ssid and psk with your actual values)
wpa_cli -i wlan0 set_network 1 psk '"11111111"'
wpa_cli -i wlan0 set_network 1 ssid '"Redmi Note 11T Pro"'

# Select the configured network
wpa_cli -i wlan0 select_network 1

# Obtain an IP address using udhcpc
udhcpc -i wlan0 -q
  • 使用方法
  1. 将net.sh复制进SD卡
    • 修改wifi密码和wifi名
      wpa_cli -i wlan0 set_network 1 psk '"11111111"' # 密码
      wpa_cli -i wlan0 set_network 1 ssid '"Redmi Note 11T Pro"' # wifi
      
  2. 进入linux小核,执行:
cd /sharefs
sh net.sh

rtsp sever搭建和推流实验

通过该实验,我们将学会调用K230开发板上的音视频编码器,将其推流到rtsp server上。其中通过mapi venc&aenc接口实现对音视频的编码;推流之后在VLC中通过url进行拉取,目前该demo支持3路url推拉流。

依赖资源

  • 网线x1,用于将开发板连接到局域网,也可使用wifi连接

源码介绍

K230 SDK采用双核架构,小核运行linux系统,实现网络控制服务。大核运行RTT系统,实现对音视频硬件的控制。小核在启动过程中负责引导大核。大小核通过核间通信进行消息通信和内存共享。 小核网络服务移植了live源码,路径为k230_sdk/src/common/cdk/user/thirdparty/live 音频使用G711编码。 音视频推流中,视频默认最大分辨率与配置的sensor_type相关,默认最大分辨率为1920x1080。

程序主要步骤

音视频推流程序
  1. new StreamingPlayer
    • 初始化核间通信。
    • 配置video buffer。
  2. InitVicap:初始化摄像头。
  3. CreateSession
    • 创建server session。
    • 创建并开启音频输入通道,音频采样率为44.1k,采样宽度16bit。
    • 初始化音频编码,音频采用G711A编码。
    • 创建视频编码通道,使能IDR帧。
  4. Start
    • 开启视频编码通道并绑定到vo。
    • 开启视频编码通道,并将视频输入绑定到视频编码。
    • 开始音视频推流。
语音对讲程序
  1. Init
    • 创建server session。
    • 初始化核间通信。
    • 配置video buffer。
    • 创建并开启音频输入通道,音频采样率为8k,采样宽度为16bit。
    • 创建音频编码通道,音频采用G711U编码。
    • 创建音频输出通道和音频解码通道,并将音频解码绑定到音频输出。
  2. Start
    • 开始推音频流。
    • 开启视频编码通道,并将视频输入绑定到视频编码。

实验步骤

  • 在k230_sdk目录下执行make cdk-user,在k230_sdk/src/common/cdk/user/out/little/目录下生成rtsp_demo

    • 相关源码

      在SDK中包含的rtsp相关demo位于k230_sdk/src/common/cdk/user/samples目录下,其中:

      • rtsp_demo:语音推音视频流程序
      • rtsp_server:语音对讲服务器端程序
      • backchannel_client:语音对讲客户端程序

-. 启动开发板

  1. 将开发板连接局域网

  2. 检查k_ipcm模块是否加载

lsmod # 列出已加载的内核模块
insmod k_ipcm.ko # 若未加载,进行k_ipcm加载

通过 lsmod 检查小核侧是否加载k_ipcm模块,如未加载,执行 insmod k_ipcm.ko 加载k_ipcm模块

  1. 在大核,执行
cd sharefs/app
./sample_sys_init.elf #启动核间通信进程
  1. 在小核,执行
cd /mnt
./rtsp_demo -s 24 -n 1 -t h265 -w 1280 -h 720

参数说明

参数名描述参数范围默认值
help打印命令行参数信息--
nsession个数[1, 3]1
t编码类型h264、h265、mjpegh264
w视频编码宽度[640, 1920]1280
h视频编码高度[480, 1080]720
ssensor类型查看camera sensor文档7
  1. 在VLC中打开网络串流

VLC -> 媒体 -> 网络 -> 输入网络URL -> 播放

实验成功,可以在VLC网络串流中实时看到摄像头拍摄的画面

音视频录制实验

venc_mapi API文档

实验步骤

依赖资源

  • 网线x1,用于将开发板连接到局域网,也可使用wifi连接
  1. 将开发板连接局域网

  2. 检查k_ipcm模块是否加载

lsmod # 列出已加载的内核模块
insmod k_ipcm.ko # 若未加载,进行k_ipcm加载

通过 lsmod 检查小核侧是否加载k_ipcm模块,如未加载,执行 insmod k_ipcm.ko 加载k_ipcm模块

  1. 在大核,执行
cd sharefs/app
./sample_sys_init.elf #启动核间通信进程
  1. 在小核,执行
cd /mnt
./sample_venc -s 24 -n 1 -o /tmp -t 1
  • sample_sys_init.elf 使用说明
# 执行./sample_venc.elf -h后,输出demo的使用说明,如下:
Usage : ./sample_venc.elf [index] -sensor [sensor_index] -o [filename]
index:
    0) H.265e.
    1) JPEG encode.
    2) OSD + H.264e.
    3) OSD + Border + H.265e.

sensor_index: see vicap doc
  1. 在VLC中打开网络串流

VLC -> 媒体 -> 网络 -> 输入网络URL -> 播放

实验成功,可以在视频播放器中播放摄像头拍摄到的视频

K230 GUI实战 - LVGL移植教程

概述

k230使用DRM作为显示驱动,DRM(Direct Rendering Manager) 是 Linux 内核中的一个子系统,相比过时的Framebuffer 可以支持复杂的 GPU 操作,如硬件加速的图形渲染。lvgl可以基于libdrm提供的接口进行GUI的绘制。

SDK中已经移植好lvgl组件,且默认编译了一个可以运行的demo,位于/usr/bin/lvgl_demo_widgets。开机后在小核linux终端输入命令lvgl_demo_widgets回车即可体验。

实验步骤

  1. linux内核中DRM驱动加载成功后会出现以下节点/dev/dri/card0 在小核侧,执行
cd /dev/dri
ls | grep card0

DRM驱动源码介绍

lvgl的drm驱动程序位于src/little/buildroot-ext/package/lvgl/port_src/lv_drivers/display/drm.c。 对DRM的操作需要先open该文件节点。 lvgl使用中主要用到以下几个函数:

  • drm_init() drm初始化。

  • drm_get_sizes() 获取显示器分辨率信息。

  • drm_flush() 显示绘制回调接口。

  • 该drm驱动默认开启了双buffer,但目前在没有硬件加速的情况下,双缓冲刷新率低,可以注释掉下面代码以单缓冲方式刷新,显示效果会更好:

void drm_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
    // 注释以下代码 
    ...
    if (!drm_dev.cur_bufs[0])
        drm_dev.cur_bufs[1] = &drm_dev.drm_bufs[1];
    else
        drm_dev.cur_bufs[1] = drm_dev.cur_bufs[0];
        drm_dev.cur_bufs[0] = fbuf;
    ...
}

lvgl的使用

lvgl的主程序文件位于src/little/buildroot-ext/package/lvgl/port_src/main.c

lvgl配置文件位于:src/little/buildroot-ext/package/lvgl/port_src/lv_conf.h

实验步骤
  1. 编译lvgl_demo

在k230_sdk根目录,执行:

make # 默认编译全部
  1. 拷贝至SD卡

  2. 开发板上电启动 运行lvgl_demo_widgets

./lvgl_demo_widgets

KPU加速模型推理实验

  • nncase Github主页

  • 课程回放

    • nncase是一个为 AI 加速器设计的神经网络编译器, 目前支持的 target有cpu/K210/K510/K230等.

    • nncase提供的功能:

      • 支持多输入多输出网络,支持多分支结构
      • 静态内存分配,不需要堆内存
      • 算子合并和优化
      • 支持 float 和uint8/int8量化推理
      • 支持训练后量化,使用浮点模型和量化校准集
      • 平坦模型,支持零拷贝加载

实验步骤

  1. 进入docker环境
cd /path/to/k230_sdk
sudo docker run -u root -it -v $(pwd):$(pwd) -v $(pwd)/toolchain:/opt/toolchain -w $(pwd) ghcr.io/kendryte/k230_sdk /bin/bash
  1. 安装nncase
pip install -i https://pypi.org/simple nncase==2.5.1 nncase-kpu==2.5.0
  1. 验证nncase是否安装成功
pip list | grep nncase

nncase            2.5.1
nncase-kpu        2.5.0
python3

Python 3.8.10 (default, May 26 2023, 14:05:08) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _nncase
>>> print(_nncase.__version__)
2.5.1
>>> quit()
  1. 编译模型
cd src/big/nncase/examples/
./build_model.sh
ls -l tmp/

total 12
drwxr-xr-x 11 root root 4096 Oct 31 11:23 mbv2_tflite
drwxr-xr-x 11 root root 4096 Oct 31 11:26 mobile_retinaface
drwxr-xr-x 11 root root 4096 Oct 31 11:24 yolov5s_onnx
  1. 编译App
App备注
image_classify图片分类demo, 输入是RGB图片, 推理结果打印到串口
object_detect目标检测demo, 输入是RGB图片, 推理结果打印到串口
image_face_detect人脸检测demo, 输入是RGB图片, 推理结果会输出到画了人脸box和landmark的图片
./build_app.sh

编译app结束后, 默认会将demo及其运行所需文件拷贝到当前目录下的k230_bin子目录

ls -l k230_bin/
total 12
drwxrwxr-x 2 1000 1000 4096 Oct 31 12:41 image_classify
drwxrwxr-x 2 1000 1000 4096 Oct 31 12:42 image_face_detect
drwxrwxr-x 2 1000 1000 4096 Oct 31 12:42 object_detect

上板运行

前置条件

  • gnne频率: 800MHZ

  • noc限速: 3.2GB/s

  • 先进入sharefs

cd sharefs/

图片分类demo

/image_classify>./cpp.sh
case ./image_classify.elf built at Oct 31 2023 11:54:35
interp.run() took: 2.19156 ms
image classify result: tabby(0.453891)
  • 实验成功

目标检测demo

/object_detect>./cpp.sh
case ./object_detect.elf built at Oct 31 2023 11:54:35
od set_input took 0.176074 ms
od run took 16.4843 ms
od get output took 12.759 ms
post process took 55.0952 ms
text = truck:0.300000
text = dog:0.250000
text = bicycle:0.230000
draw result took 31.1012 ms
  • 实验成功

人脸检测demo

/image_face_detect>./cpp.sh
case ./image_face_detect.elf built at Oct 31 2023 11:54:47
Press 'q + enter' to exit!!!
g

推理结果(人脸box和landmark)会生成到face_500x500_result_x.jpg

  • 实验成功

K230端到端探索

  • 课程回放

    • AI Cube 是由嘉楠科技开发的一款通用视觉 AI 计算平台,该平台能够帮助用户迅速训练AI 模型,同时可以将训练完毕的模型轻松部署到嘉楠芯片中,如 Canaan k230。使用该平台能够以零代码成本实现项目管理、数据集拆分、数据集分布预览、模型训练评估及模型部署。

安装步骤

  1. 安装依赖
  1. 下载AI Cube
  • AI Cube下载链接

    • Linux下
    tar -zxvf 'AI Cube.tar.gz'
    cd AI Cube
    ./run.sh
    
    • Windows下

    打开AI Cube.exe

  1. 使用AI Cube