32位MCU APM32F407IG测评:移植轻量级AI推理框架TinyMaix如何实现手写数字识别
本文将介绍如何为APM32F407IG芯片移植轻量级AI推理框架——TinyMaix,并在开发板上运行TinyMaix的手写数字识别示例。本文将首先介绍TinyMaix是什么,以及APM32F407IG芯片的主要参数。然后,介绍如何为APM32F407IG芯片创建一个支持基于SysTick计时,以及printf输出到UART的Keil项目。接着,介绍如何将TinyMaix项目核心框架和手写数字识别示例源码添加到支持SysTick计时和printf输出的Keil项目中。最后,介绍如何将编译好的二进制程序下载到APM32F407IG Tiny开发板上,并运行手写数字识别示例程序。
一、背景介绍
开始之前,首先介绍一下轻量级AI推理框架——TinyMaix,以及本次使用活动的APM32F407IG Tiny Board的主控芯片APM32F407IGT6。
1.1 TinyMaix框架简介
TinyMaix是国内sipeed团队开发一个轻量级AI推理框架,官方介绍如下:
TinyMaix是面向单片机的超轻量级的神经网络推理库,即TinyML推理库,可以让你在任意单片机上运行轻量级深度学习模型。根据官方介绍,在仅有2K RAM的 Arduino UNO(ATmega328, 32KB Flash, 2KB RAM) 上,都可以基于 TinyMaix 进行手写数字识别。对,你没有看错,2K RAM + 32K Flash的设备上都可以使用TinyMaix进行手写数字识别!TinyMaix官网提供了详细介绍,可以在本文末尾的参考链接中找到。
TinyMaix项目源码是以Apache-2.0协议开源的,GitHub代码仓:https://github.com/sipeed/tinymaix,TinyMaix项目源代码仓中,包含了TinyMaix核心框架代码、示例程序、常用模型、测试图片、文档等内容。
1.2 TinyMaix上层API
TinyMaix框架对上层应用程序提供的核心API主要位于代码仓的tinymaix.h文件中,核心API如下:
/******************************* MODEL FUNCTION ************************************/
tm_err_t tm_load (tm_mdl_t* mdl, const uint8_t* bin, uint8_t*buf, tm_cb_t cb, tm_mat_t* in); //load model
void tm_unload(tm_mdl_t* mdl); //remove model
tm_err_t tm_preprocess(tm_mdl_t* mdl, tm_pp_t pp_type, tm_mat_t* in, tm_mat_t* out); //preprocess input data
tm_err_t tm_run (tm_mdl_t* mdl, tm_mat_t* in, tm_mat_t* out); //run model
/******************************* UTILS FUNCTION ************************************/
uint8_t TM_WEAK tm_fp32to8(float fp32);
float TM_WEAK tm_fp8to32(uint8_t fp8);
/******************************* STAT FUNCTION ************************************/
#if TM_ENABLE_STAT
tm_err_t tm_stat(tm_mdlbin_t* mdl); //stat model
#endif
主要分为三类:
模型函数,包括模型加载、卸载、预处理、推理;
工具函数,包含FP32和uint8的互转;
统计函数,用于输出模型中间层信息;
这里的模型,通常是预训练模型经过脚本转换生成的TinyMaix格式的模型。
1.3 TinyMaix底层依赖
TinyMaix可以简单理解为一个矩阵和向量计算库,目前已支持如下几种计算硬件:
#define TM_ARCH_CPU (0) //default, pure cpu compute
#define TM_ARCH_ARM_SIMD (1) //ARM Cortex M4/M7, etc.
#define TM_ARCH_ARM_NEON (2) //ARM Cortex A7, etc.
#define TM_ARCH_ARM_MVEI (3) //ARMv8.1: M55, etc.
#define TM_ARCH_RV32P (4) //T-head E907, etc.
#define TM_ARCH_RV64V (5) //T-head C906,C910, etc.
#define TM_ARCH_CSKYV2 (6) //cskyv2 with dsp core
#define TM_ARCH_X86_SSE2 (7) //x86 sse2
对于ARM-Cortex系列MCU,可以支持纯CPU计算和SIMD计算。其中CPU计算部分无特殊依赖(计算代码均使用标准C实现)。SIMD部分,部分计算代码使用了C语言内嵌汇编实现,需要CPU支持相应的汇编指令,才可以正常编译、运行。
TinyMaix的示例代码依赖于精准计时和打印输出能力,具体是项目的tm_port.h中的几个宏定义:
#define TM_GET_US() ((uint32_t)((uint64_t)clock()*1000000/CLOCKS_PER_SEC))
#define TM_DBGT_INIT() uint32_t _start,_finish;float _time;_start=TM_GET_US();
#define TM_DBGT_START() _start=TM_GET_US();
#define TM_DBGT(x) {_finish=TM_GET_US();\
_time = (float)(_finish-_start)/1000.0;\
TM_PRINTF("===%s use %.3f ms\n", (x), _time);\
_start=TM_GET_US();}1.4 APM32F407IGT6芯片简介
本次试用的APM32F407IG Tiny Board,主控芯片是APM32F407IGT6,它的主要参数为:
CPU: Cortex-M4F内核,168 MHz
Flash: 1 MB
RAM: 192 KB
TinyMaix的手写数字识别示例,在32KB Flash 2KB RAM的Arduino UNO R3上都可以运行。在我们这次试用的主角APM32F407IG Tiny Board上运行是完全没有任何压力的。开发板正面特写,可以看到主控芯片型号为APM32F407IGT6:
二、开发环境搭建2.1 下载APM32F407资料
极海官网APM32F07资料下载页: APM32F405/407 (geehy.com),具体下载链接参见本文末尾的参考链接部分,必须下载的文件包括:
APM32F405xG 407xExG数据手册
APM32F4xxx用户手册
APM32F407IG Tiny 原理图
APM32F4xx_SDK
APM32F4xx_DFP Pack
2.2 安装Keil MDK
ARM官网Keil MDK安装包下载页面(需要填写问卷):
https://www.keil.com/download/product/
填写完问卷之后,可以看到,最新版本5.38a安装包文件下载页面:
这里的安装包文件的链接可以直接复制:
https://www.keil.com/fid/g6daezwlgtwj1wzt54w1lz01v1lvsy2w9vmud1/files/eval/mdk538a.exe
MD5: 6792e5e0c0b5207b4db8339e043d7461
PS:使用下载工具下载完成后,记得验证一下MD5值。Keil本身的安装没啥难度,一路下一步就好了,这里不再详细介绍。
2.3 安装ARM Compiler 5
APM32F4xx_SDK需要ARM Compiler 5才可以顺利编译,用Keil MDK较新版本默认附带ARM Compiler 6无法正常编译。因此,需要下载ARM Compiler 5。
ARM Compiler下载页面为: https://developer.arm.com/documentation/ka005198/latest,可以看到ARM Compiler 5最后一个版本是:5.06 update 7 (build 960)。
点击中间的ACOMP5蓝色链接,可以跳转到该版本编译器的下载页面(需要注册登录):
这里下载下方的Win32版本即可。ARM Compiler下载页面的文件链接是动态生成的,无法直接复制出来。我用某雷下载之后,转存了一个云盘链接,方便国内用户下载,链接:https://pan.xunlei.com/s/VN_A6-Wskfwt4IYWpJLHgsGkA1?pwd=h23k#MD5: 56a3c52585e7ce4d95fc75ae6ff6b9df
2.4 安装APM32F4xx支持包
Keil MDK APM32F4系列MCU支持包: https://www.geehy.com/uploads/tool/Geehy.APM32F4xx_DFP.1.0.3.pack
下载完成后,双击安装即可(PS:成功安装Keil MDK之后,.pack文件会自动关联到Keil)。到这里,基础开发环境已经搭建完成了。
三、运行SysTick示例程序
现在,我们需要为APM32F407IGT6芯片创建一个同时支持SysTick计时和printf输出的Keil项目。
3.1 下载APM32F4xx_SDK
首先,从极海官网上下载APM32F4xx_SDK,解压后可以在它的 Examples 子目录下找到 SysTick和USART示例,如下图所示:
3.2 编译SysTick示例程序
接着,打开SysTick目录下,SysTick_TimeBase\Project\MDK 子目录中的 SysTick_TimeBase.uvprojx 文件,可以看到该示例参与编译的源代码文件:
按F7键,进行编译,编译成功可以看到Build Output输出如下:
3.3 修改调试器设置
接下来,将APM32F407 Tiny开发板通过USB Type-C线连接到电脑。注意,开发板注意接在调试的USB口上。按照如下步骤修改调试器设置。在Project视图中,鼠标右键APMFF407,弹出悬浮菜单,如下图所示:
单击”Options for Target ‘APM32FF407’“,将会弹出,如下图所示:
点击Debug标签页,界面如下图所示:
下来”ULINK2/ME Cortex Debugger“菜单,选中CMSIS-DAP,如下图所示:
继续点击刚刚的调试器下拉菜单右侧的”Settings“按钮,弹出CMSIS-DAP Cortex-M Target Driver Setup窗口,如下图所示:
PS:这里SW Device中已经成功识别到了ARM CoreSight SW-DP,说明调试和MCU之间通信正常。点Flash Download标签页,界面显示如下图所示:
查阅数据手册,这里参数都是正确的,不需要修改。为了方便调试,建议将这里的Rest and Run勾选上,如下图所示:
勾选之后,记得点OK保存。
3.4 下载和运行SysTick示例程序
完成上述调试设置之后,就可以按F8或Download按钮开始下载成了。Download按钮,位置如下图所示:
开始下载后,Build Output窗口将会显示下载进度,下载成功后可以看到:
其中,Application running … 是勾选了Reset and Run才会有的。如果没有意外,将会看到开发板上的LED灯已经开始闪烁了:
3.5 分析SysTick示例程序主要代码
我们继续看Project视图下的文件:
其中,各源码目录中的对应作用分别为:
CMSIS目录,启动(.s)和初始化(.c)
StdPeriphDriver目录,外设驱动库
Boards目录,APM32F407系列开发板条件编译
Application目录,中断处理(apm32f4xx_int.c)和应用代码(main.c)
接下来,看下main.c中的主要代码:
可以看到这里是一个点灯的代码,其中while循环调用了另外两个函数:
APM_MINI_LEDToggle,用于实现LED3灯状态翻转;
SysTick_Delay_ms,用于实现延时,单位毫秒;
这个while循环,就是闪灯不断LED2和LED,再延时一秒。另外,还可以看到上面的截图中:
75行有一行对COM1的初始化,查看实现代码可以知道就是USART1,串口参数为8n1;
80行有一行printf打印语句,打印了一行文本,前后各有一个换行;
除此之外,main.c文件中还有如下代码:
通过注释,可以知道,这个函数实现了printf到串口的重定向。
3.6 查看SysTick示例程序的串口输出
前面分析知道,SysTick示例程序的main函数中初始化了USART1,并且有一行字符串打印,另外还实现了printf到串口的重定向。因此,如果没有什么意外的话,我们应该可以通过USART1看到这一行打印的输出。接下来,查阅原理图的APM32-Link部分:
可以看到,APM32-Link预留了USART1的跳线。然而不幸的是:
开箱之后发现,APM32F407-Tiny开发板的J3、J5并没有附带跳线帽;
通过USB线将APM32-Link连接到PC之后,并没有在设备管理器中看到串口设备;
没有跳线帽简单,从其他板子上扣下来一对就行了。而APM32-Link连接到PC之后没有识别到串口设备,可能原因有两个:
APM32-Link固件不支持USB转UART;
APM32-Link的主控芯片APM32F103C8T6不支持USB功能;
通过极海官网查阅APM32F103C8T6参数发现,它是支持USBD功能的,理论上可以实现USB转UART功能。那这里PC没有识别到串口设备的原因就是——APM32-Link固件暂时还不支持USB转UART。查阅极海官网APM32-Link介绍信息,发现确实如此,没有找到对USB转UART功能的说明。所以,需要外接一个USB转UART用来查看串口输出,连接如下图:
其中,
开发板的U2TX,连接到USB转串口的RX
开发板的U2RX,连接到USB转串口的TX
接着,USB转串口和调试器插上PC,打开MobaXterm,设置如下参数:
打开新的会话之后,按下开发板的RESET按键,将会看到:
成功接收到了printf打印的字符串!继续查阅原理图的USART1_TX和USART1_RX标号部分:
可以看到,
USART1_TX,对应PA9
USART1_RX,对应PA10
这也项目代码能够对应起来:
在Keil中一路查看:
APM_MINI_COMInit函数定义;
COM_TX_PORT、COM_TX_PIN_SOURCE数组定义;
MINI_COM1_TX_GPIO_PORT、MINI_COM1_TX_PIN_SOURCE宏定义;
找到的Board_APM32F407_MINI.h文件,在Keil的Project视图也可以看到:
该文件的完整路径为:APM32F407\APM32F4xx_SDK_v1.3\Boards\Board_APM32F407_MINI\inc\Board_APM32F407_MINI.h
我们试用的是APM32F407_Tiny开发板,实际上不应该用这个文件。但因为两个板子的串口配置代码是一样的,所以只使用串口输出的话,不修改也并不会影响串口输出。
两个开发板对应的头文件的主要差异在于,按键相关的宏定义不一样:
如果想要修改为方法是,在Options for Target ‘APM32F407’窗口的C/C++标签页中:
将APM32F407_MINI宏修改为APM32F407_TINY。修改之后,main.c中的也要响应修改:
APM_MINI_COMInit 替换为 APM_TINY_COMInit
APM_MINI_LEDInit 替换为 APM_TINY_LEDInit
APM_MINI_LEDToggle 替换为 APM_TINY_LEDToggle
四、移植TinyMaix核心库和手写数字识别示例
简单起见,接下来我们不再新建Keil项目,而是直接将TinyMaix核心库和手写数字识别示例代码拷贝到SysTick示例目录中(虽然这么做不太规范)。
4.1 下载TinyMaix源码到本地
首先,使用 git 命令下载TinyMaix最新源码:git clone https://github.com/sipeed/tinymaix.git4.2 拷贝TinyMaix源码到Keil项目目录;接着,在SysTick示例的SysTick_TimeBase目录下,创建TinyMaix目录:
将TinyMaix源码的examples、include、src目录,拷贝到刚刚创建的TinyMaix目录中:
另外,创建tools目录,并将tools目录下的tmdl目录拷贝过去;拷贝的exmaples中包含了多个示例,可以把不需要的删除掉,只保留mnist目录,即手写数字识别示例。
4.3 将TinyMaix源文件添加到Keil项目中
首先,在Keil的Project视图右击APM32F407,选择Manage Project Items:
接着,在弹出的Manage Project Items窗口中,进行如下两步骤操作:
然后,点击Add Files,在弹出的文件添加界面中,依次添加刚刚拷贝过来的TinyMaix目录src目录和examples/mnist目录下的.c文件到项目中:
添加完成后,点击OK确认。
4.4 解决Keil项目的编译问题
完成上述修改后,直接编译,将会报错:
首先,按照如下步骤,添加必要的include搜索路径,在Project视图右键APM32F407,选择”Options for Target ‘APM32F407’“,如下图所示:
在弹出的Options for Target ‘APM32F407’窗口中,点击C/C++标签页,如图下图所示:
在C/C++标签页,点击Include Paths右侧的”…”按钮,会弹出Folder Setup界面,如下图所示:
在Folder Setup界面中,分别点击如下两处,选择目录进行添加:
在弹出的文件夹选择界面中,选择拷贝的TinyMaix的include目录,选择之后,如下图所示:
此时,再次编译项目,报错已经不一样了:
这里报错说,找不到”sys/time.h“文件。直接双击error信息行,主编辑器区可以看到tm_port.h文件对应位置:
回顾开头1.4节,这里就是TinyMaix依赖的几个计时宏。将其修改为:
接下来编译,遇到如下错误:
需要打开GNU扩展选项:
再次编译,报链接错误:
这两个连接错误说有两个main函数定义。找到手写数字识别的main.c,将其中的main函数重命名为mnist_main:
再次编译,报错如下:
这次说,SysTick_Get没有定义。打开Application下的main.c,Ctrl+F搜索TimingDelay:
找到如下引用:
将其全部替换掉为SysTickCount:
然后,修改main.c中的SysTick_Delay_ms和TimingDelay_Decrement函数,并新增SysTick_Get函数:
再次编译,终于成功了:
4.5 调用mnist示例程序
接下来,在main.c文件的main函数中添加两行代码:
记得保存Ctrl+S。然后重新编译、下载,下载完成后,自动开始运行,可以看到串口输出:
运行报错了。这里是因为,TinyMaix需要试用malloc申请内存,APM32F407的SysTick示例程序默认的堆大小配置不够。需要修改 startup_apm32f40x.s 文件:
将其中的Heap_Size修改为0x1000(4096),默认的是0x200(512)。再次重新编译、下载、运行,串口可以看到:
这次成功运行了,耗时4毫秒,识别了手写数字2。原始图片数据为:
可以看出来,识别结果是正确的。
- |
- +1 赞 0
- 收藏
- 评论 0
本文由逍遥哥哥转载自极海半导体,原文标题为:【APM32F407IG Tiny Board测评】移植轻量级AI推理框架TinyMaix实现手写数字识别,本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。
相关推荐
【经验】基于VScode搭建极海APM32F103x的GCC开发环境添加J-LINK芯片型号的方法
在使用VSCODE搭建32位MCU的GCC开发环境时,若需要用到J-LINK作为下载调试工具,需要确定J-LINK工具里面有目标芯片的型号。本文将为大家解析基于VScode搭建极海半导体APM32F103x的GCC开发环境添加J-LINK芯片型号的方法。
【经验】如何使用极海半导体官方ISP上位机软件Geehy-ISP下载程序?
ISP是一种常用的下载或者升级程序的方式,通常会选择使用UART进行操作。Geehy-ISP是极海半导体的通用的上位机软件,支持极海全部的32位MCU。本文以APM32F072VBT6为例介绍使用Geehy-ISP给极海MCU下载程序的方法。
【经验】如何使用极海半导体官方ISP上位机软件Geehy-ISP读出芯片中的程序?
Geehy-ISP支持极海半导体全部的32位MCU,在开发产品的过程中,可能会遇到芯片出现工作不正常的情况,可以选择将芯片内的程序读出来做进一步分析。本文以APM32F072VBT6为例介绍使用Geehy-ISP读出极海MCU中程序的方法。
APM32F405xG APM32F407xEXG基于ARM®Cortex®-M4内核的32位MCU
描述- 本资料介绍了APM32F405xG和APM32F407xExG系列基于Arm® Cortex®-M4核心的32位微控制器(MCU)的特性。该系列MCU具备高性能、低功耗的特点,适用于多种嵌入式应用。主要内容包括核心架构、内存与接口、时钟系统、复位与管理、低功耗模式、DMA、调试接口、I/O端口、通信外设、模拟外设、定时器、实时时钟、CRC计算单元等。
型号- APM32F407ZGT6,APM32F405VGT6,APM32F407RET6-R,APM32F405RGT6,APM32F407IET6,APM32F407RGT6-R,APM32F405XG,APM32F407XE,APM32F407IGT6,APM32F405XG SERIES,APM32F407ZGT6XXX,APM32F407RGT6,APM32F407XG,APM32F407VGT6,APM32F407RET6,APM32F405ZGT6,APM32F405RGT6-R,APM32F407XG SERIES,APM32F407VET6,APM32F407ZET6,APM32F407XE SERIES
【应用】国产32位MCU APM32F415VGT6应用于激光切割机,Flash最高容量达1MB,外设资源丰富
激光切割机大型设备,主要利用激光聚焦后产生的高功率密度能量来实现切割。组成部分一般由机床、激光发生器、光束传输组件、切割头等等;本文笔者主要给大家介绍一款国产极海半导体M4内核的32位微控制器APM32F415VGT6 在激光切割机上的应用。
【应用】国产32位MCU APM32F407RET6用于便携式超声波探伤仪,工温-40~+85℃,最高主频168MHz
便携式超声波探伤仪是一种能够快速,便捷,精确地对工件内部的缺陷进行检测、定位、诊断的仪器。 推荐采用国产极海32位MCU APM32F407RET6为主控, 该MCU最高主频168MHz,工作温度范围-40~+85℃,工作电压范围1.8 ~ 3.6V。
APM32F411xCXE基于ARM®Cortex®-M4F内核的32位MCU规格书
描述- 本资料详细介绍了APM32F411xCxE系列32位微控制器的产品特性,包括核心处理器、内存和接口、时钟、电源管理、低功耗模式、DMA、调试接口、I/O、通信外设、模拟外设、定时器、RTC、CRC计算单元和96位唯一设备ID等。资料还提供了产品信息、引脚信息、功能描述、系统架构、电气特性、封装信息和订购信息等内容。
型号- APM32F411RCT6,APM32F411VET6,APM32F411VCT6,APM32F411XCXE SERIES,APM32F411CET6,APM32F411CEU6,APM32F411CCT6,APM32F411CCU6,APM32F411XCXE,APM32F411RET6,APM32F411VET6XXX
【应用】主频96MHz的32位MCU APM32F103RBT6用于多路温度测试仪,采用ARM Cortex –M3内核
多路温度测试仪是一种可以接入多个传感器信号的仪器,用以显示各测试点的温度数据,也可以设定各测试点温度的报警值,推荐采用国产极海32位MCU APM32F103RBT6为主控,该MCU最高主频96MHz。
极海半导体APM32F407系列MCU支持国密算法,助力国产安全可控,适用于新能源等领域
极海推出的APM32F407系列MCU,结合当前环境要求,设计出了支持国密算法(SM2,SM3,SM4)的IP, 符合国家密码管理局认定和公布的密码算法标准及其应用规范,并凭借显著的性能优势,已应用至新能源、工业控制、医疗设备等众多领域。
极海半导体32位MCU-M4选型表
极海半导体的APM32系列是基于Arm® Cortex®-M0+/M3/M4内核的优质国产32位通用MCU,具有低功耗、高性能、高集成度以及快速移植等特性。凭借优异的系统性能、丰富的协处理功能以及灵活的使用体验,有助于用户缩短产品设计时间、降低开发成本、实现性能最优化。
产品型号
|
品类
|
内核
|
Frequency(MHz)
|
FLASH(KB)
|
SRAM(KB)
|
SDRAM
|
Voltage
|
GPTMR(16bit)
|
GP TMR(32bit)
|
Advanced TMR(16bit)
|
Basic TMR
|
Systick
|
IWDG
|
WWDG
|
ADC 12-bit Cell
|
ADC 12-bit channels
|
DAC 12-bit channels
|
EMMC
|
SPI
|
I2S
|
I2C
|
U(S)ART
|
CAN
|
SDIO
|
USB OTG_FS
|
DCI
|
Ethernet
|
Package
|
对照型号
|
APM32F407IET6
|
32位MCU
|
ARM Cortex-M4
|
168MHz
|
512KB
|
192+4KB
|
1
|
1.8~3.6
|
8
|
2
|
2
|
2
|
1
|
1
|
1
|
3
|
24
|
2
|
1
|
3
|
2
|
3
|
4+2
|
2
|
1
|
1
|
1
|
1
|
LQFP176
|
STM32F407IET6
|
选型表 - 极海半导体 立即选型
极海车规级MCU凭借可靠的产品品质,斩获“2023汽车芯片50强”与“MCU创新先锋”两项大奖
近日,极海车规级MCU凭借可靠的产品品质、专业周到的客户技术支持服务,以及量产级解决方案良好的市场表现,相继斩获“2023汽车芯片50强”、“MCU创新先锋奖”两项行业大奖。作为国内领先的32位车规级芯片设计企业,极海积极布局以服务汽车智能化、电动化、网联化的快速融合。
APM32F103xCxDxE 基于 Arm® Cortex®-M3 内核的 32 位微控制器用户手册
型号- APM32F103XCXDXE,APM32F103XDXE,APM32F103XCXDXE 系列,APM32F103XC,APM32F
电子商城
现货市场
服务
可定制显示屏的尺寸0.96”~15.6”,分辨率80*160~3840*2160,TN/IPS视角,支持RGB、MCU、SPI、MIPI、LVDS、HDMI接口,配套定制玻璃、背光、FPCA/PCBA。
最小起订量: 1000 提交需求>
可定制PCB最高层数:32层;板材类型:罗杰斯高频板/泰康尼高频板/ZYF中英天线板/F4B高频板/高频电路板/高频混压板/高频纯压板等;最大加工尺寸:609*889mm。
最小起订量: 1 提交需求>
登录 | 立即注册
提交评论