很多时候,我们设计完成一个“完美”的算法,比如无刷电机 FOC,BMS的kalman 滤波SOC,高级AI算法,人工神经网络,人脸识别,运动检测等等复杂算法后, 我们都需要对这个算法进行评测,比如,算法的复杂度,执行时间,效率等等!其中最重要的就是算法运行的时间了,简称执行时间。 作为嵌入式开发人员,我们需要知道自己设计的算法执行了多久。那么有没有一个工具能测试出我们的算法执行时间呢? 这篇测评报告就是来解决算法代码执行时间问题的。本文就以极海G32A1465开发板来运行这个时间检测算法,这个算法可以运行在所有ARM 内核的单片机上,只要单片机具备DWT定时器和Systick定时器,其中DWT是一个32位的定时器,可以精确计时到1us级别,Systick这个大家都非常的熟悉,用来裸机定时和RTOS移植都会用到,它是一个24位的定时器,相比较之下,DWT要比Systick定时精度更高,效果更好,所以本文会以DWT定时器来制作这个原创测量代码和算法运行时间算法库。以飨广大爱好者。 话不多少了,我们直接上干货!!!!!! 1。打开cubemx 选择STM32F769BIH6 2. 2。使能外部时钟,配置时钟树 3。配置串口 4。配置LED1 LED2 5. 6.打开KEIL,重定向printf int fputc(int ch, FILE f) { HAL_UART_Transmit(&huart1, (uint8_t )&ch, 1, 0xFFFF); return ch; } 7。修改代码 / Reset of all peripherals, Initializes the Flash interface and the Systick. / HAL_Init(); / USER CODE BEGIN Init / CODE_TIME_START("开始执行代码时间测量"); / USER CODE END Init / / Configure the system clock / SystemClock_Config(); CODE_TIME_EVENT("SystemClock_Config()"); / USER CODE BEGIN SysInit / / USER CODE END SysInit / / Initialize all configured peripherals / MX_GPIO_Init(); CODE_TIME_EVENT("MX_GPIO_Init()"); MX_USART1_UART_Init(); CODE_TIME_EVENT("MX_USART1_UART_Init()"); / USER CODE BEGIN 2 / printf("测试串口打印功能\r\n"); CODE_TIME_EVENT("测试串口打印功能 "); CODE_TIME_STOP(); / USER CODE END 2 / 烧录,打开串口助手查看 核心代码 ifndef _CODE_TIME_Hdefine _CODE_TIME_Hinclude "main.h"include <stdint.h>include <stdio.h>define MAX_EVENT_COUNT 20void CODE_TIME_START(const char profile_name); void CODE_TIME_EVENT(const char event); void CODE_TIME_STOP(void); endif/ Includes ----------------------------------------------------------/ include "code_time_measurement.h"/ Private Definitions -----------------------------------------------/ define DEBUG_PRINTF printfdefine __PROF_STOPED 0xFF/ External variables ------------------------------------------------/ / Private variables -------------------------------------------------/ static uint32_t time_start; // profiler start time static const char prof_name; // profiler name static uint32_t time_event[MAX_EVENT_COUNT]; // events time static const char event_name[MAX_EVENT_COUNT]; // events name static uint8_t event_count = __PROF_STOPED; // events counter / Private function prototypes ---------------------------------------/ / -------------------------------------------------------------------/ /**
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // DWT->LAR = 0xC5ACCE55; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // enable counter //DWT->CYCCNT = time_start = 0; time_start = DWT->CYCCNT; } /**
if (event_count < MAX_EVENT_COUNT) { time_event[event_count] = DWT->CYCCNT; event_name[event_count] = event; event_count++; } } /**
tick_per_1us = SystemCoreClock / 1000000; if (event_count == __PROF_STOPED) { DEBUG_PRINTF("\r\nWarning: PROFILING_STOP WITHOUT START.\r\n"); return; } DEBUG_PRINTF("Profiling \"%s\" sequence: \r\n" "--函数名----------------------|--总共消耗时间--|----函数消耗时间---\r\n", prof_name); time_prev = 0; for (int i = 0; i < event_count; i++) { timestamp = (time_event[i] - time_start) / tick_per_1us; delta_t = timestamp - time_prev; time_prev = timestamp; DEBUG_PRINTF("%-30s:%9d µs | +%9d µs\r\n", event_name[i], timestamp, delta_t); } DEBUG_PRINTF("\r\n"); event_count = __PROF_STOPED; } [/i][/i] |