update TFlite_Micro_Demo移植参考指南.md
@@ -1,27 +1,29 @@
|
||||
# TensorFlow Lite Micro移植参考指南(Keil版)
|
||||
|
||||
作者:
|
||||
**作者:**
|
||||
|
||||
日期:
|
||||
Github ID: [Derekduke](https://github.com/Derekduke) E-mail: dkeji627@gmail.com
|
||||
|
||||
联系方式:
|
||||
Github ID: [QingChuanWS](https://github.com/QingChuanWS) E-mail: bingshan45@163.com
|
||||
|
||||
Github ID: [yangqings](https://github.com/yangqings) E-mail: yangqingsheng12@outlook.com
|
||||
|
||||
## 概述
|
||||
|
||||
本教程是基于STM32 NUCLEO-L496ZG(Cortex-M4, 80Mhz)开发板,在运行TencentOS tiny的基础上,使用Tensorflow Lite Micro框架和CMSIS-NN库(算子加速),在STM32L496ZG上实现了**行人检测模型**的推理。
|
||||
|
||||
关于Tensorflow Lite Micro组件的详细介绍可以参考`TencentOS-tiny\components\tflite_micro`目录下的TFlite_Micro_Component_User_Guide.md文档。
|
||||
关于Tensorflow Lite Micro组件的详细介绍可以参考`TencentOS-tiny\components\ai\tflite_micro`目录下的TFlite_Micro_Component_User_Guide.md文档。
|
||||
|
||||
本例程中,传入神经网络的RGB图像大小为 18kb(96*96 * 2byte),在STM32L496平台消耗的内存资源(经过优化后)如下:
|
||||
|
||||
- SRAM:168 Kbyte
|
||||
- Flash:314 Kbyte
|
||||
|
||||
理论上满足以b上内存要求的STM32 Cortex-M系列MCU可以参考本指南进行移植。
|
||||
理论上满足以上内存要求的STM32 Cortex-M系列MCU可以参考本指南进行移植。
|
||||
|
||||
## 一、移植前的准备
|
||||
|
||||
### 1. 准备目标硬件(开发板/传感器/模组)
|
||||
#### 1. 准备目标硬件(开发板/传感器/模组)
|
||||
|
||||
需要准备如下硬件:
|
||||
|
||||
@@ -35,24 +37,25 @@
|
||||
<img src="image/all.jpg" width=50% />
|
||||
</div>
|
||||
|
||||
### 2.准备TencentOS tiny基础keil工程代码
|
||||
#### 2.准备TencentOS tiny基础keil工程代码
|
||||
|
||||
- 首先,参考TencentOS tiny基于keil的移植教程进行移植:
|
||||
https://github.com/Tencent/TencentOS-tiny/blob/master/doc/10.Porting_Manual_for_KEIL.md
|
||||
- 值得注意的是,为了方便初始化MCU的外设,后续要继续使用STM32CubeMX软件,请确保安装了该软件;
|
||||
- 为了方便初始化MCU的外设,后续要继续使用STM32CubeMX软件,请确保安装了该软件;
|
||||
|
||||
- 移植成功后,工程可以进行线程任务切换,通过串口打印"hello world",基础keil工程代码准备完毕。
|
||||
|
||||
|
||||
|
||||
### 3. 获取Tensorflow Lite Micro
|
||||
#### 3. 获取Tensorflow Lite Micro
|
||||
|
||||
有两种方式获取tflite_micro源码:
|
||||
有三种方式获取tflite_micro:
|
||||
|
||||
1. 从TencentOS tiny 代码仓库 `components/tflite_micro`目录获取;
|
||||
2. 从Tensorflow代码仓库获取,TFlite_Micro的源码已经开源,github下载地址为:https://github.com/tensorflow/tensorflow ,TFlite_Micro的代码位于`tensorflow/tensorflow/lite/micro/`目录下。
|
||||
1. 从TencentOS tiny 代码仓库 `components\ai\tflite_micro`目录获取;
|
||||
2. 以lib文件的形式使用tflite_micro组件,lib文件`TencentOS-tiny\components\ai\tflite_micro`的ARM_CortexM4_lib、ARM_CortexM7_lib和ARM_CortexM55_lib文件夹
|
||||
3. 从Tensorflow代码仓库获取,TFlite_Micro的源码已经开源,github下载地址为:https://github.com/tensorflow/tensorflow ,TFlite_Micro的代码位于`tensorflow\tensorflow\lite\micro\`目录下。
|
||||
|
||||
如果没有tflite_micro开发经验,建议您以**第一种方式**获取tflite_micro源码,如果您希望自行获取最新tflite_micro源码,请参考`TencentOS-tiny\components\tflite_micro`目录的TFlite_Micro_Component_User_Guide.md文档。
|
||||
如果没有tflite_micro开发经验,建议以**第一种**或者**第二种**方式获取tflite_micro,希望自行获取最新源码,或者编译lib文件,请参考`TencentOS-tiny\components\tflite_micro`目录的TFlite_Micro_Component_User_Guide.md文档,本指南将直接使用TencentOS tiny 代码仓库内的tflite_micro组件。
|
||||
|
||||
## 二、BSP准备
|
||||
|
||||
@@ -86,28 +89,67 @@
|
||||
<div align=center>
|
||||
<img src="./image/spi init.png" width=100% />
|
||||
</div>
|
||||
#### 2.2 打开keil的Manage Project Items
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_keil_manage_project.png" width=60% />
|
||||
</div>
|
||||
|
||||
#### 2.3 在project中加入新的文件夹hal
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_添加hal.png" width=80% />
|
||||
</div>
|
||||
|
||||
|
||||
#### 2.3 添加驱动代码
|
||||
|
||||
添加`lcd_2inch4.c`和`lcd_config.c`,
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_add lcd driver file.png" width=80% />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
#### 2.2 添加驱动代码
|
||||
添加头文件`lcd_2inch4.h`和`lcd_config.h`路径
|
||||
|
||||
添加`lcd_2inch4.c`和`lcd_config.c`,添加头文件`lcd_2inch4.h`和`lcd_config.h`路径。
|
||||
<div align=center>
|
||||
<img src="./image/bsp_include_path.png" width=80% />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_include_lcd_path.png" width=80% />
|
||||
</div>
|
||||
外设驱动的头文件.h文件都在`TencentOS-tiny\board\NUCLEO_STM32L496ZG\BSP\Hardware\Inc`路径下。
|
||||
|
||||
### 3. 摄像头驱动
|
||||
|
||||
|
||||
|
||||
#### 3.1 外设初始化
|
||||
|
||||
进入`TencentOS-tiny\board\NUCLEO_STM32L496ZG\BSP`目录,打开TencentOS_tiny.ioc工程,初始化DCMI外设,打开DCMI全局中断,并打开DMA通道,DMA的Direction设置为Peripheral To Memory。
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_cubemx_dcmi.png" width=100% />
|
||||
</div>
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_cubemx_dcmi_2.png" width=100% />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
#### 3.2 添加驱动代码
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/bsp_add camera driver file.png" width=80% />
|
||||
</div>
|
||||
|
||||
**在mcu_init函数重写DCMI帧中断回调函数:**
|
||||
|
||||
**在main函数重写DCMI帧中断回调函数:**
|
||||
值得注意的是,代码需要写在CubeMx生成的注释语句内,当使用CubeMX重新配置外设并生成代码时,所添加的代码才不会被覆盖掉,如下所示,代码添加在/* USER CODE BEGIN 4 */ 和 /* USER CODE END 4 */注释语句之间:
|
||||
|
||||
```C
|
||||
/* USER CODE BEGIN 4 */
|
||||
@@ -120,11 +162,32 @@ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
|
||||
/* USER CODE END 4 */
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 4. LCD显示摄像头图像
|
||||
|
||||
经过以上步骤,BSP就准备完毕了。
|
||||
本例程的任务函数在
|
||||
|
||||
`TencentOS-tiny\examples\tflitemicro_person_detection\tflitemicro_person_detection.c`
|
||||
|
||||
```c
|
||||
void task1(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
if(frame_flag == 1){
|
||||
|
||||
if(HAL_DCMI_Stop(&hdcmi))Error_Handler(); //stop DCMI
|
||||
LCD_2IN4_Display(camera_buffer,OV2640_PIXEL_WIDTH,OV2640_PIXEL_HEIGHT);
|
||||
//display
|
||||
frame_flag = 0;
|
||||
if(HAL_DCMI_Start_DMA(&hdcmi,DCMI_MODE_CONTINUOUS,\ //restart DCMI
|
||||
(uint32_t)camera_buffer ,\
|
||||
(OV2640_PIXEL_WIDTH*OV2640_PIXEL_HEIGHT)/2))
|
||||
Error_Handler();
|
||||
osDelay(50);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
经过以上步骤,如果能顺利地驱动摄像头,并在LCD实时显示图像,BSP就准备完毕了,如果使用的是不同的LCD或者Camera,请根据实际情况进行外设初始化和驱动的移植。
|
||||
|
||||
## 三、Tensorflow Lite Micro移植
|
||||
|
||||
@@ -132,7 +195,7 @@ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
|
||||
|
||||
由于NUCLEO-L496ZG芯片中的内核为ARM Cortex M4,所以本次我们可以直接使用ARM Cortex M4版本的tensorflow_lite_micro.lib库来简化tflite_micro搭建流程。
|
||||
|
||||
#### 1.1 在project中加入新的文件夹tensorflow:
|
||||
#### 1.1 在project中加入新的文件夹tensorflow
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/tflu_tensorflow文件夹增加的内容.png" width=80% />
|
||||
@@ -152,13 +215,13 @@ tensorflow_lite_micro.lib的路径为:`TencentOS-tiny\components\ai\tflite_mic
|
||||
|
||||
其余.cc文件均在当前目录下的`tflu_person_detection`文件夹中。
|
||||
|
||||
#### 1.3 关闭Keil的MicroLib库:
|
||||
#### 1.3 关闭Keil的MicroLib库
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/tflu_取消Microlib.png" width=80% />
|
||||
</div>
|
||||
|
||||
#### 1.4 添加tflite_micro需要的头文件:
|
||||
#### 1.4 添加tflite_micro需要的头文件
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/tflu_添加include.png" width=80% />
|
||||
@@ -178,9 +241,12 @@ TencentOS-tiny\components\ai\tflite_micro\ARM_CortexM4_lib\tensorflow\lite\micro
|
||||
|
||||
其中宏`NUCLEO_STM32L496ZG`是指定Nucleo STM32L496的hlpuart1为系统printf函数的输出串口,具体定义在Nucleo STM32L496的BSP文件夹中的`mcu_init.c`中。
|
||||
|
||||
|
||||
### 2. 编写Person_Detection 任务函数
|
||||
|
||||
本例程的任务函数在
|
||||
|
||||
`TencentOS-tiny\examples\tflitemicro_person_detection\tflitemicro_person_detection.c`目录下
|
||||
|
||||
#### 2.1 图像预处理
|
||||
|
||||
<div align=center>
|
||||
@@ -211,7 +277,7 @@ void input_convert(uint16_t* camera_buffer , uint8_t* model_buffer)
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 行人检测线程任务函数
|
||||
#### 2.2 行人检测线程任务函数
|
||||
|
||||
```c
|
||||
void task1(void *arg)
|
||||
@@ -245,8 +311,21 @@ void task2(void *arg)
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3 运行效果
|
||||
|
||||
通过串行输出实时打印信息,移动摄像头,镜头没有对准行人时,输出如下:
|
||||
|
||||
## 四、Benchmark
|
||||
<div align=center>
|
||||
<img src="./image/reasult_no_person.png" width=70% />
|
||||
</div>
|
||||
|
||||
当镜头对准行人时,输出如下:
|
||||
|
||||
<div align=center>
|
||||
<img src="./image/reasult_person.png" width=70% />
|
||||
</div>
|
||||
|
||||
执行一帧图像推理,耗时约633 ms。
|
||||
|
||||
更多关于tflite_micro的介绍,请参考[tensorflow](https://tensorflow.google.cn/lite/microcontrollers?hl=zh_cn)官网以及`TencentOS-tiny\components\tflite_micro`目录的TFlite_Micro_Component_User_Guide.md
|
||||
|
||||
|
@@ -16,8 +16,8 @@
|
||||
<TargetCommonOption>
|
||||
<Device>STM32L496ZGTx</Device>
|
||||
<Vendor>STMicroelectronics</Vendor>
|
||||
<PackID>Keil.STM32L4xx_DFP.2.5.0</PackID>
|
||||
<PackURL>https://www.keil.com/pack/</PackURL>
|
||||
<PackID>Keil.STM32L4xx_DFP.2.4.0</PackID>
|
||||
<PackURL>http://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000-0x2004FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(8000000) FPU2 CPUTYPE("Cortex-M4")</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile></StartupFile>
|
||||
@@ -739,15 +739,20 @@
|
||||
<GroupName>hal</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>lcd_config.c</FileName>
|
||||
<FileName>delay.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\BSP\Hardware\Src\lcd_config.c</FilePath>
|
||||
<FilePath>..\..\BSP\Hardware\Src\delay.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>lcd_2inch4.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\BSP\Hardware\Src\lcd_2inch4.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>lcd_config.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\BSP\Hardware\Src\lcd_config.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>ov2640.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -758,11 +763,6 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\BSP\Hardware\Src\sccb.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>delay.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\BSP\Hardware\Src\delay.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |