妥协下的联姻——为rt-thread适配最新k210 kendryte-standalone-sdk的nncase

在上一篇文章中,我们已经成功在maix go上跑起来了rt-thread。可是,rtt官方的bsp只是对kendryte-standalone-sdk v0.5.6及之前的个别版本有支持。而在kendryte最新开发的sdk中,对老sdk中的部分内容做出了较大的改动,并且引入了最新的模型处理程序nncase,以取代之前的kmodel。对于之前的kmodel将不再提供更新支持,全面使用最新的nncase。本文将给大家介绍最新sdk移植的方法以及一些注意事项。

1.编译选项设置

nncase是由c++17编写完成,运用了较多c++17的功能,因此在编译之前首先需要打开工具链对c++17的支持。打开k210文件目录下的rtconfig.py,修改其CXXFLAGS选项如下图:

2.打开rtt的c++支持

  • 在rtt的env工具中,输入menuconfig进入配置页面,在RT-Thread Components->C++ feature选项下找到"Support C++ feature"并选中。

  • RT-Thread中对全局对象构造函数的实现中,在 rt-thread\components\cplusplus 目录下的 crt_init.c 文件中对 C++ 进行了系统初始化, 连接脚本文件 link.lds 为 C++ 全局构造函数的代码分配了段。为了使 C++ 全局对象构造函数链接后能够存放在指定的段中,我们需要修改工程中的链接脚本,打开k210文件目录下的link.lds,对其进行如下修改:

如果想更深入的了解在rtt上应用c++,可以参考这篇文章:RT-Thread--C++应用笔记

3.解决rtt中的libc_signal.c和工具链产生冲突的问题

如果这个时候直接编译,就可能会碰到如下报错:

这个问题貌似是rtt的一个bug,在rtt未来的版本中可能就不会有这个问题了,但如果还有这个错误,那么可以通过以下几个步骤来解决。

  • 打开k210文件路径下的cconfig.h文件,注释掉其中三条语句

删掉HAVE_SIGEVENT、HAVE_SIGINFO、HAVE_SIGVAL

  • 打开工具链路径下\RISC-V Embedded GCC\8.3.0-1.1\riscv-none-embed\include\sys中的signal.h,删除其中关于sigval、sigevent、siginfo的定义如下图。删完记得保存。

4.将最新sdk中新增的内容加入工程中

修改rt-thread\bsp\k210\packages\kendryte-sdk-v0.5.5路径下的SConscript文件,将新增的源文件与头文件路径添加至工程中,修改后的文件如下:

from building import *

cwd     = GetCurrentDir()
src     = Split('''
kendryte-standalone-sdk/lib/bsp/entry.c
kendryte-standalone-sdk/lib/bsp/entry_user.c
kendryte-standalone-sdk/lib/bsp/locks.c
kendryte-standalone-sdk/lib/bsp/sleep.c
kendryte-standalone-sdk/lib/drivers/aes.c
kendryte-standalone-sdk/lib/drivers/apu.c
kendryte-standalone-sdk/lib/drivers/clint.c
kendryte-standalone-sdk/lib/drivers/dmac.c
kendryte-standalone-sdk/lib/drivers/dvp.c
kendryte-standalone-sdk/lib/drivers/fft.c
kendryte-standalone-sdk/lib/drivers/fpioa.c
kendryte-standalone-sdk/lib/drivers/gpio.c
kendryte-standalone-sdk/lib/drivers/gpiohs.c
kendryte-standalone-sdk/lib/drivers/i2c.c
kendryte-standalone-sdk/lib/drivers/i2s.c
kendryte-standalone-sdk/lib/drivers/iomem.c
kendryte-standalone-sdk/lib/drivers/kpu.c
kendryte-standalone-sdk/lib/drivers/plic.c
kendryte-standalone-sdk/lib/drivers/pwm.c
kendryte-standalone-sdk/lib/drivers/rtc.c
kendryte-standalone-sdk/lib/drivers/sha256.c
kendryte-standalone-sdk/lib/drivers/spi.c
kendryte-standalone-sdk/lib/drivers/sysctl.c
kendryte-standalone-sdk/lib/drivers/timer.c
kendryte-standalone-sdk/lib/drivers/uart.c
kendryte-standalone-sdk/lib/drivers/uarths.c
kendryte-standalone-sdk/lib/drivers/utils.c
kendryte-standalone-sdk/lib/drivers/wdt.c
kendryte-standalone-sdk/lib/nncase/nncase.cpp
kendryte-standalone-sdk/lib/nncase/runtime/interpreter.cpp
kendryte-standalone-sdk/lib/nncase/runtime/kernel_registry.cpp
kendryte-standalone-sdk/lib/nncase/runtime/cpu/cpu_ops.cpp
kendryte-standalone-sdk/lib/nncase/runtime/k210/k210_ops.cpp
kendryte-standalone-sdk/lib/nncase/runtime/k210/interpreter.cpp
kendryte-standalone-sdk/lib/nncase/runtime/neutral/neutral_ops.cpp
''')
CPPPATH = [cwd + '/kendryte-standalone-sdk/lib/drivers/include', 
cwd + '/kendryte-standalone-sdk/lib/bsp/include',
cwd + '/kendryte-standalone-sdk/lib/utils/include',
cwd + '/kendryte-standalone-sdk/lib/nncase/include',
cwd + '/kendryte-standalone-sdk/lib/nncase/kernels',
cwd + '/kendryte-standalone-sdk/lib/nncase/runtime',
cwd + '/kendryte-standalone-sdk/lib/nncase/targets',
cwd + '/kendryte-standalone-sdk/lib/nncase/runtime/cpu',
cwd + '/kendryte-standalone-sdk/lib/nncase/runtime/k210',
cwd + '/kendryte-standalone-sdk/lib/nncase/runtime/neutral',
cwd + '/kendryte-standalone-sdk/third_party/xtl/include'
]
CPPDEFINES = ['CONFIG_LOG_COLORS', 'CONFIG_LOG_ENABLE', 'CONFIG_LOG_LEVEL=LOG_VERBOSE', 'FPGA_PLL', 'LOG_KERNEL', '__riscv64']

group = DefineGroup('SDK', src, depend = ['PKG_USING_KENDRYTE_SDK'], CPPPATH = CPPPATH, LOCAL_CPPDEFINES = CPPDEFINES)

Return('group')

可以看到,相比原来的文件,添加了不少的内容。

5.对SDK中的部分源码进行修改

5.1动态内存

在k210最新的sdk中,底层的外设驱动包括kpu的代码实现采用了动态内存。为此kendryte特地开发了一个用于管理动态内存的源文件,为\kendryte-standalone-sdk\lib\drivers路径下的iomem.c,该文件实现了动态内存的初始化、申请动态内存、删除动态内存、查询剩余内存空间的功能。这些功能被同目录下的众多其他外设的驱动代码所引用。而rtt本身有动态内存的管理功能,这样一来就会产生冲突,我们需要替换iomem.c中的内容,将rtt的内存管理接口替换上去。

iomem.c中的代码可做如下替换:

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "iomem.h"
#include "printf.h"
#include "atomic.h"

#include "rtthread.h"


void iomem_free(void *paddr)
{
    rt_free(paddr); 
}

void *iomem_malloc(uint32_t size)
{
    return rt_malloc(size);
}

uint32_t iomem_unused()
{
    rt_uint32_t total, used, max;

    rt_memory_info(&total, &used, &max);

    return total - used;
}

只要保留iomem_free,iomem_malloc,iomem_unused这三个函数供其他文件调用就可以了。查询剩余内存这部分的内容会和原有bsp下driver目录中的heap.c冲突。可以删去heap.c中查询剩余内存的代码。

5.2调试模式

最新的sdk中还加入了调试功能相关的代码,不过这也和rtt的功能相冲突,同时这部分代码也会因为引用的sdk代码不全(sdk中有部分冗余代码,所以并没有完全加入工程)导致编译报错。在外设驱动uart.c中,我们需要删除以下和调试相关的代码。

5.3 修改nncase target

最新bsp中的nncase有两种工作模式,一种是将运算交给cpu来完成,还有一种是给kpu完成。如果使用kendryte官方的工具进行开发的话会对target进行配置。不过我们如果要用rtthread的话就少了这一过程,需要我们手动添加。我们打开这个路径下的文件。kendryte-standalone-sdk\lib\nncase\include\target_config.h

在其头部添加一个定义即可,如下图:

添加 #define NNCASE_TARGET k210

6.完成

通过以上的操作,包含最新sdk的工程终于可以编译通过了,将代码烧写至开发板中,打开串口终端,就可以看到熟悉的rtt界面了。

后记

经过这么一番操作,可能大家也能看出来为什么叫妥协之作了,我们为了能够将最新的sdk引入到工程中不但修改了sdk的源码,还修改了工具链中代码、cconfig.h中的代码。这些操作很难通过在rtt上提交一个新的bsp实现,有点难登大雅之堂,实在是权宜之计。如果广大网友有什么更好的适配方法,欢迎一起讨论。

 

还不知道怎么编译?查看文章:在sipeed maix go上用上rt-thread以及vs code

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
您好!针对Mx-yolov3模型的训练和K210模型的使用,您可以按照以下步骤进行操作: 1. 准备数据集:首先,您需要准备一个包含标记好的目标边界框的数据集。确保每个图像文件都有对应的标签文件,标签文件的格式可以是YOLO格式或者其他常用格式,如Pascal VOC。 2. 配置Mx-yolov3模型:根据您的需求,您可以在MxNet中下载预训练的yolov3模型,然后根据您的数据集和目标进行微调。您可以参考MxNet官方文档来了解如何配置和使用Mx-yolov3模型。 3. 数据增强和预处理:为了提高模型的泛化能力,您可以使用数据增强技术来扩充您的数据集。数据增强包括随机裁剪、缩放、旋转、翻转等操作。此外,还需要对输入图像进行预处理,例如归一化和调整大小。 4. 模型训练:使用准备好的数据集和配置好的模型,您可以开始训练过程了。根据您的硬件资源和实际情况,可以选择在本地或者云端进行训练。通常情况下,训练过程需要花费一定的时间和资源。 5. 模型转换和部署:在训练完成后,您需要将模型转换为适用于K210芯片的格式。K210芯片使用的是KPU神经网络加速器,所以您需要将模型转换为KPU可以识别的格式。您可以使用K210提供的工具和库来进行模型转换和部署。 请注意,以上步骤仅为一般指导,具体操作可能因您的环境和需求而有所不同。建议您参考相关文档和教程,以获得更详细的指导和支持。祝您成功训练和使用K210模型!如果您有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

果菌药

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值