APM32芯得 EP.38 | TinyMaix赋予APM32F411 AI推理能力
《APM32芯得》系列内容为用户使用APM32系列产品的经验总结,均转载自21ic论坛极海半导体专区,全文未作任何修改,未经原文作者授权禁止转载。
1. TinyMaix简介
TinyMaix 是矽速科技(Sipeed)专门为微控制器设计的轻量级开源机器学习库,可以在任意的MCU上运行轻量级深度学习模型。
TinyMaix 所消耗的资源非常小,在只有 2KB RAM,32KB Flash 的 Arduion ATmega328上都可以运行mnist(手写数字识别)。
关于 TinyMaix 详细介绍,可以到 Sipeed 科技的官网 Wiki 查看。
下面是引用自官网 Wiki 对于 TinyMaix 的关键特性介绍:
关键特性
· 核心代码少于400行(tm_layers.c+tm_model.c+arch_cpu.h), 代码段(.text)少于3KB
· 低内存消耗,甚至Arduino ATmega328 (32KB Flash, 2KB Ram) 都能基于TinyMaix跑mnist(手写数字识别)
· 支持INT8/FP32/FP16模型,实验性地支持FP8模型,支持keras h5或tflite模型转换
· 支持多种芯片架构的专用指令优化: ARM SIMD/NEON/MVEI,RV32P, RV64V
· 友好的用户接口,只需要load/run模型~
· 支持全静态的内存配置(无需malloc)
· MaixHub 在线模型训练支持
2. 源码准备
2.1 APM32F411 SDK
我们是要在 APM32F411 上运行 TinyMaix 框架,需要准备的源码自然是APM32F411相关的SDK,与 TinyMaix 源码。
APM32F411的源码,可以到极海的官网获取:
下载了他们的SDK之后,在SDK目录下的Example目录,复制一份Template目录下的文件夹,改名为TinyMaix。我们会基于这个模板工程,实现TinyMaix在APM32F411上运行。
2.2 TinyMaix源码
TinyMaix 源码可以到他们官方的 Github 仓库进行下载:
直接 clone 到本地,或者下载压缩包都行。
下载完之后,我们把 TinyMaix 源码放到 APM32F411 SDK 目录下的 Middlewares 子目录里面备用。
TinyMaix 源码目录结构如下图:
各目录结构介绍如下:
· doc:存放 TinyMaix 各个硬件平台接口的说明文档。
· examples:TinyMaix官方提供的部分例程实例,比如手写数字识别、分类检测、物体识别等。
· include:头文件,包括要移植TinyMaix的接口头文件也在该目录
· src:TinyMaix的源码
· tools:存放TinyMaix的一些工具。比如可以把图片文件,生成一个C语言数组,这样方便我们代码调用
3. TinyMaix源码简单介绍
下面简单介绍一下与移植有关的 TinyMaix 源码,以及 TinyMaix 提供了哪些 API 给用户使用。
3.1 底层硬件依赖
根据官方的介绍文档,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支持相应的汇编指令,才可以正常编译、运行。
3.2 编译等级选择
TinyMaix 目前支持两种等级:
· 选择最少代码和buf
· 选择速度,需要更多代码和buf
#define TM_OPT0 (0) //default, least code and buf
#define TM_OPT1 (1) //opt for speed, need more code and buf
#define TM_OPT2 (2) //TODO
3.3 计时和调试宏
TinyMaix 有相关的计时和调试的宏定义,这些宏是需要我们移植的时候,针对不同的硬件平台要实现的部分接口代码,如下:
/******************** DBG TIME CONFIG ****************************/
#include <sys/time.h>
#include <time.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();}
3.4 核心API函数
对于 TinyMaix 框架对上层应用程序提供的核心 API 函数主要位于代码仓的 tinymaix.h 头文件中。
1、与模型相关的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
函数原型如上,包括模型加载、卸载、预处理、运行模型4个函数。
2、用于输出模型中间层信息的统计函数
/*********************** STAT FUNCTION *****************************/
#if TM_ENABLE_STAT
tm_err_t tm_stat(tm_mdlbin_t* mdl); //stat model
#endif
3、FP32 和 uint8 类型的互转工具函数
/*********************** UTILS FUNCTION ****************************/
uint8_t TM_WEAK tm_fp32to8(float fp32);
float TM_WEAK tm_fp8to32(uint8_t fp8);
4. 移植TinyMaix到APM32F411
前面我们已经把准备好的 TinyMaix 源码放到了 APM32F411 SDK 的 Middlewares 目录了,接下来的移植过程就需要用到了该目录下的源码了。下面基于 MDK-Keil 介绍下移植适配的过程。
4.1 Keil工程包含TinyMaix源码
Keil 工程中,主要添加的文件有:
src目录下的 C 文件
example目录下实例代码,比如 mnist, cifar10, vww 等,我们会在接下来的适配中,移植这3个实例代码,所以这3个相关的 C 文件也一起加进来。
由于 mnist, cifar10, vww 这3个实例代码,他们在 TinyMaix 源码中默认的文件名是 main.c ,由于我们已经有了 main.c 文件了,为了不冲突,我们在加入 Keil 工程之前,先把这些实例代码名称改一下。
接下来,打开 Keil 软件的工程分组管理,然后在工程下新建 TinyMaix 子目录,然后把所需要的文件添加进来。
4.2 添加文件包含路径
前面添加了 TinyMaix 源码之后,它相关的头文件路径要告诉 Keil 才能知道去哪里找到。
打开 Keil 配置界面,找到 C/C++ 配置选项,然后添加路径即可,如下图:
4.3 编译器选择 gun 扩展模式配置
在后面的编译中,我发现 TinyMaix 库的编译需要选择 gun externsions 模式,不热会有很多的报错,所以我们勾选上该模式即可。
4.4 解决编译报错
1、解决头文件找不到错误
添加了头文件路径之后,编译有如下报错,主要就是说找不到 sys/time.h 的头文件。
前面我们介绍过, TinyMaix 需要计时,这个头文件其实就是获取时间相关的函数在该文件声明,但是我们移植到 APM32F411 平台,是没有这个文件的,我们后面需要使用嘀嗒定时器去实现时间获取,所以此处暂时屏蔽该代码。
然后,计时的宏定义我们改为通过嘀嗒定时器获取,如下:
其中,uint32_t systick_get_us(void); 这个函数,是我们后面需要通过嘀嗒定时器去实现的函数,这里先写上。
2、解决 main 函数名重复定义错误
当再次编译报错如下:
只剩下链接报错了,这些报错都是因为 TinyMaix 的实例代码中,都有一个 main.c 函数重复定义造成的,我们找到对应的函数,修改下函数名即可。这里不多介绍。
3、解决 TinyMaix 实例代码中,变量名重复定义错误
再次编译,还剩下变量名的重复定义错误,这个是因为我们添加了 TinyMaix 的 3 个实例代码进Keil工程里面,然后他们使用了相同的变量名,我们找到这些变量,然后添加 static 关键字限制即可。
4、解决 systick_get_us 没有定义的报错
最后编译,只剩下 systick_get_us 这个函数没有定义的错误了,这个函数其实就是我们需要通过嘀嗒定时器实现的 us 获取函数。
这个函数的实现,我们在下面的代码中给出了。
4.5 systick_get_us函数实现
TinyMaix 需要使用计时,来获取时间。对于 APM32F411 我们就使用 Systick 来获取计时即可。实现代码如下:
static volatile uint32_t tick = 0;
/* Millisecond timer */
void systick_init(void)
{
/* SystemFrequency / 1000 = 1ms */
if (SysTick_Config(RCM_ReadSYSCLKFreq() / 1000))
{
/* Capture error */
while (1);
}
}
/* Get millisecond */
uint32_t systick_get_ms(void)
{
return tick;
}
/* Get microsecond */
uint32_t systick_get_us(void)
{
return tick / 1000;
}
/* Syctick handler */
void SysTick_Handler(void)
{
tick++;
}
另外,还需要用到串口进行打印输出调试信息,我们还需要实现串口的打印输出,这里不多介绍了,自己实现就行。
4.6 修改堆空间的大小
TinyMaix 的实例在运行是,需要使用到堆空间的内存。而且,在运行人像识别的实例时,需要至少 54KB 的RAM (手写数字识别不需要这么多),所以我们定义堆空间为 60KB 大小就肯定够用了。
对于 APM32F411 来说,堆空间的大小是在启动文件 startup_apm32f411.s 定义的,我们在该文件定义堆空间的大小为 60KB 。代码如下:
5. TinyMaix运行效果
我们运行 TinyMaix 提供手写数字识别、分类检测、识别人像等实例。
5.1 mnist实例
该实例可以识别图像数字。我们在 main.c 文件的主函数中调用之前修改了名字的 main_mnist 这个函数即可。
代码如下:
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] Main program
*
* @param None
*
* @retval None
*/
int main(void)
{
USART_Config_T usartConfigStruct;
usartConfigStruct.baudRate = 115200;
usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
usartConfigStruct.mode = USART_MODE_TX;
usartConfigStruct.parity = USART_PARITY_NONE;
usartConfigStruct.stopBits = USART_STOP_BIT_1;
usartConfigStruct.wordLength = USART_WORD_LEN_8B;
APM_MINI_COMInit(COM1, &usartConfigStruct);
APM_MINI_LEDInit(LED2);
APM_MINI_LEDInit(LED3);
//printf("\r\n========== TinyMaix ==========\r\n");
/* SysTick Initialization */
systick_init();
main_mnist(0, NULL);
//main_cifar10(0, NULL);
//main_vww(0, NULL);
while (1)
{
APM_MINI_LEDToggle(LED2);
APM_MINI_LEDToggle(LED3);
/* Precise Delay 1ms */
//SysTick_Delay_ms(1000);
}
}
然后编译运行效果如下图:
5.2 vww实例
vww实例,是检测图片有没有人,TinyMaix使用的人像图片如下:
然后运行结果是:
可以看出识别到了图片中有人。
5.3 cifar10实例
该实例进行分类检测,然后识别出有鸟的图片,TinyMaix 使用的鸟图片如下:
运行结果如下:
- |
- +1 赞 0
- 收藏
- 评论 0
本文由samsara转载自Geehy极海半导体公众号,原文标题为:APM32芯得 EP.38 | TinyMaix赋予APM32F411 AI推理能力,本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。
相关推荐
【经验】如何在JFLASH中添加极海半导体Geehy APM32系列MCU
本文主要介绍极海半导体MCU产品如何使用第三方Segger公司的JFLASH配合J-Link仿真器对指定型号MCU的Flash进行擦除、写入及读取操作的目的。
tandby模式下,如何唤醒MCU APM32的RTC与WKUP?
APM32F103系列低功耗模式有三种:睡眠模式、停止模式和待机模式。通过关闭内核、时钟源、设置调压器来降低功耗。本文极海半导体解析了APM32的tandby模式下的RTC唤醒与WKUP唤醒功能如何实现。
APM32芯得 | 基于极海APM32E103系列MCU的SPI转CAN芯片MCP2515移植测试
极海半导体APM32E103系列MCU支持CAN协议2.0A和2.0B,通信波特率最大为1Mbit/s,并且拥有双CAN接口,能适应更多的应用场合。将杜邦线按照引脚配置,接好线后仿真就能测试回环模式下收发数据了。可以看到断点打到接收部分,可以接收到CAN数据,与发送的数据一致。
极海半导体32位MCU-M0选型表
极海半导体的APM32系列是基于Arm® Cortex®-M0+/M3/M4内核的优质国产32位通用MCU,具有低功耗、高性能、高集成度以及快速移植等特性。凭借优异的系统性能、丰富的协处理功能以及灵活的使用体验,有助于用户缩短产品设计时间、降低开发成本、实现性能最优化。
产品型号
|
品类
|
内核
|
Frequency(MHz)
|
FLASH(KB)
|
SRAM(KB)
|
I/Os
|
Vmin(V)
|
Vmax(V)
|
GPTMR(16bit)
|
GP TMR(32bit)
|
Advanced TMR(16bit)
|
Basic TMR
|
Systick(24bit)
|
ADC 12-bit Cell
|
ADC 12-bit channels
|
DAC 12-bit Cell
|
DAC 12-bit channels
|
Analog Comparator
|
TSC (Channels)
|
SPI
|
I2S
|
I2C
|
U(S)ART
|
CAN
|
SDIO
|
USB Device
|
Package
|
对照型号
|
APM32F072V8T6
|
32位MCU
|
ARM Cortex-M0
|
48MHz
|
64KB
|
16KB
|
87
|
2V
|
3.6V
|
5
|
1
|
1
|
2
|
1
|
1
|
16
|
1
|
2
|
2
|
24
|
2
|
2
|
2
|
4
|
1
|
0
|
1
|
LQFP 100
|
-
|
选型表 - 极海半导体 立即选型
极海半导体32位MCU-M3选型表
极海半导体的APM32系列是基于Arm® Cortex®-M0+/M3/M4内核的优质国产32位通用MCU,具有低功耗、高性能、高集成度以及快速移植等特性。凭借优异的系统性能、丰富的协处理功能以及灵活的使用体验,有助于用户缩短产品设计时间、降低开发成本、实现性能最优化。
产品型号
|
品类
|
内核
|
Frequency(MHz)
|
FLASH(KB)
|
SRAM(KB)
|
SDRAM
|
FPU
|
I/Os
|
Vmin(V)
|
Vmax(V)
|
GPTMR(16bit)
|
GP TMR(32bit)
|
Advanced TMR(16bit)
|
Basic TMR
|
Systick(24bit)
|
ADC 12-bit Cell
|
ADC 12-bit channels
|
DAC 12-bit Cell
|
DAC 12-bit channels
|
Analog Comparator
|
EMMC
|
SPI
|
I2S
|
I2C
|
U(S)ART
|
CAN
|
SDIO
|
Package
|
对照型号
|
APM32E103CET6
|
32位MCU
|
ARM Cortex-M3
|
120MHz
|
512KB
|
128KB
|
0
|
1
|
37
|
2V
|
3.6V
|
4
|
0
|
1
|
2
|
1
|
2
|
10
|
2
|
2
|
0
|
0
|
3
|
2
|
2
|
3
|
2
|
0
|
LQFP48
|
STM32F103RET6
|
选型表 - 极海半导体 立即选型
极海G32R5系列实时控制MCU荣获2024年度全球电子成就奖
极海G32R5系列实时控制MCU荣获“年度微控制器/接口产品”奖,该芯片是基于Cortex-M52双核架构的实时控制MCU,支持Arm Helium™矢量扩展技术,可实现高级机器学习(ML)和数字信号处理(DSP)功能;内置自研的紫电数学指令扩展单元,可极大程度提升算法执行效率;同时还集成了高性能感知、丰富控制外设和灵活外设互联系统,满足中高端应用对芯片的高性能、高集成、高安全、高可靠等要求。
【经验】极海MCU APM32F103 IAP的实现方式
拿到了一块APM32F103VC的MINI开发板,在学习了一段时间后发现其有非常丰富的外设资源,主频能达到96Mhz。最近在项目中使用到了IAP(In Application Programming)功能,特来评估一下APM32F103的IAP实现方式。
极海半导体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
|
选型表 - 极海半导体 立即选型
APM32芯得 | 基于APM32F411控制的一个软开关电路设计分享
本文介绍的软开关电路,并不是开关电源里面的软开关概念,而是系统供电的开关,结合MCU等控制芯片,控制系统供电的开启或关断。
【选型】APM32F411 MCU的电机控制方案可实现PMSM的无感FOC双电机控制,支持三电阻、单电阻电流采样
面向电机市场,极海半导体APM32F411 双电机控制系统提供了高适用性与高性价比的单芯片控制方案,以满足高端消费电子与工业控制领域的不同需求。随着电机应用产品智能化及物联网升级,极海半导体将持续在产品、方案与支持等各方面寻求创新,为用户打造优质的应用生态环境。
APM32芯得 EP.33 | 栈回溯方法自动分析定位APM32 Hardfault错误
《APM32芯得》系列内容为用户使用APM32系列产品的经验总结。以 APM32F411 为例进行分析,介绍使用栈回溯方法自动分析定位 Hard Fault 错误。
APM32芯得 EP.35 | APM32F411为什么要有ISP,你知道多少?
APM32F411支持ISP启动,适合在不同编程阶段使用。ISP不占额外flash,节省成本,且适用于量产和远程维护。该芯片支持USART/I2C/SPI/USB等多种通信总线进行flash编程,使用Geehy评估软件可轻松完成程序下载与运行。
【视频】极海APM32F407xG系列MCU培训
型号- APM32F405VGT6,APM32F091VCT6,APM32F051K6T6,APM32F091CCT6,APM32F003F6P6,APM32F051K8T6,APM32F103CCT6,APM32F405RGT6,APM32F003F6P7,APM32F103VET6,APM32E103VCT6,APM32F051C8T6,APM32F103RCT6,APM32E103ZET6,APM32F103RCT7,APM32F103VCT6,APM32F103ZET6,APM32E103RCT6,APM32E103VET6,APM32F415RGT6,APM32F407RGT6,APM32F030RCT6,APM32F091RCT6,APM32F003F6U7,APM32E103CET6,APM32F407RET6,APM32F407VGT6,APM32F415VGT6,APM32F407VET6,APM32F051K8U6,APM32F051C8U6,APM32F103TBU6,APM32F417VGT6,APM32F103RET6,APM32F051R8T6,APM32F417ZGT6,APM32F405ZGT6,APM32F051K6U6,APM32F030CCT6,APM32F030C8T6,APM32F103CBT6,APM32F103C8T6,APM32F030K6T6,APM32F030R8T6,APM32F103VBT6,APM32F103RBT6,APM32F407ZET6,APM32F407ZGT6,APM32F072VBT6,APM32F072RBT6,APM32F072RBT7,APM32F415ZGT6,APM32F407IET6,APM32F072CBT6,APM32F407IGT6,APM32F030K6U6,APM32E103RET6
极海半导体APM32F407系列MCU支持国密算法,助力国产安全可控,适用于新能源等领域
极海推出的APM32F407系列MCU,结合当前环境要求,设计出了支持国密算法(SM2,SM3,SM4)的IP, 符合国家密码管理局认定和公布的密码算法标准及其应用规范,并凭借显著的性能优势,已应用至新能源、工业控制、医疗设备等众多领域。
还可以这样玩?极海半导体APM32F411系列MCU与pyocd的火花
前段时间笔者学习了一下如何使用pyocd配合APM32F411VCTINY板在命令行下给它进行各种骚操作,在使用一段时间后就想着:pyocd是基于python的,那是不是也可以使用python脚本+pyocd使用起来呢?本文中极海半导体与大家分享能够自动化完成重复操作的设计经验。
电子商城
现货市场
服务
可定制显示屏的尺寸0.96”~15.6”,分辨率80*160~3840*2160,TN/IPS视角,支持RGB、MCU、SPI、MIPI、LVDS、HDMI接口,配套定制玻璃、背光、FPCA/PCBA。
最小起订量: 1000 提交需求>
可烧录IC封装SOP/MSOP/SSOP/TSOP/TSSOP/PLCC/QFP/QFN/MLP/MLF/BGA/CSP/SOT/DFN;IC包装Tray/Tube/Tape;IC厂商不限,交期1-3天。支持IC测试(FT/SLT),管装、托盘装、卷带装包装转换,IC打印标记加工。
最小起订量: 1pcs 提交需求>
登录 | 立即注册
提交评论