STM32U5G9J-DK2开发板获取RAM占用
1、更改STM32U5G9ZJTXQ_FLASH.ld文件,将原有的FramebufferSection (NOLOAD) :和VideobufferSection (NOLOAD) :内容注释,改为下面的形式;
/*
******************************************************************************
**
** @file : LinkerScript.ld
**
** @author : Auto-generated by STM32CubeIDE
**
** @brief : Linker script for STM32U5G9ZJTxQ Device from STM32U5 series
** 4096KBytes FLASH
** 3008KBytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
******************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*//* Entry Point */
ENTRY(Reset_Handler)/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */_Min_Heap_Size = 0x1000; /* required amount of heap */
_Min_Stack_Size = 0x1000; /* required amount of stack *//* Memories definition */
MEMORY
{RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 3008KFLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096KEXT_FLASH (r) : ORIGIN = 0xA0000000, LENGTH = 128M
}/* Sections */
SECTIONS
{/* The startup code into "FLASH" Rom type memory */.isr_vector :{. = ALIGN(4);KEEP(*(.isr_vector)) /* Startup code */. = ALIGN(4);} >FLASH/* The program code and other data into "FLASH" Rom type memory */.text :{. = ALIGN(4);*(.text) /* .text sections (code) */*(.text*) /* .text* sections (code) */*(.glue_7) /* glue arm to thumb code */*(.glue_7t) /* glue thumb to arm code */*(.eh_frame)KEEP (*(.init))KEEP (*(.fini)). = ALIGN(4);_etext = .; /* define a global symbols at end of code */} >FLASH/* Constant data into "FLASH" Rom type memory */.rodata :{. = ALIGN(4);*(.rodata) /* .rodata sections (constants, strings, etc.) */*(.rodata*) /* .rodata* sections (constants, strings, etc.) */. = ALIGN(4);} >FLASH.ARM.extab : {. = ALIGN(4);*(.ARM.extab* .gnu.linkonce.armextab.*). = ALIGN(4);} >FLASH.ARM : {. = ALIGN(4);__exidx_start = .;*(.ARM.exidx*)__exidx_end = .;. = ALIGN(4);} >FLASH.preinit_array :{. = ALIGN(4);PROVIDE_HIDDEN (__preinit_array_start = .);KEEP (*(.preinit_array*))PROVIDE_HIDDEN (__preinit_array_end = .);. = ALIGN(4);} >FLASH.init_array :{. = ALIGN(4);PROVIDE_HIDDEN (__init_array_start = .);KEEP (*(SORT(.init_array.*)))KEEP (*(.init_array*))PROVIDE_HIDDEN (__init_array_end = .);. = ALIGN(4);} >FLASH.fini_array :{. = ALIGN(4);PROVIDE_HIDDEN (__fini_array_start = .);KEEP (*(SORT(.fini_array.*)))KEEP (*(.fini_array*))PROVIDE_HIDDEN (__fini_array_end = .);. = ALIGN(4);} >FLASH/* Used by the startup to initialize data */_sidata = LOADADDR(.data);/* Initialized data sections into "RAM" Ram type memory */.data :{. = ALIGN(4);_sdata = .; /* create a global symbol at data start */*(.data) /* .data sections */*(.data*) /* .data* sections */*(.RamFunc) /* .RamFunc sections */*(.RamFunc*) /* .RamFunc* sections */. = ALIGN(4);_edata = .; /* define a global symbol at data end */} >RAM AT> FLASH/* Uninitialized data section into "RAM" Ram type memory */. = ALIGN(4);.bss :{/* This is used by the startup in order to initialize the .bss section */_sbss = .; /* define a global symbol at bss start */__bss_start__ = _sbss;*(.bss)*(.bss*)*(COMMON). = ALIGN(4);_ebss = .; /* define a global symbol at bss end */__bss_end__ = _ebss;} >RAM/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */._user_heap_stack :{. = ALIGN(8);PROVIDE ( end = . );PROVIDE ( _end = . );. = . + _Min_Heap_Size;. = . + _Min_Stack_Size;. = ALIGN(8);} >RAM/* Remove information from the compiler libraries *//DISCARD/ :{libc.a ( * )libm.a ( * )libgcc.a ( * )}.ARM.attributes 0 : { *(.ARM.attributes) }/*FramebufferSection (NOLOAD) :{*(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4); *(Nemagfx_Stencil_Buffer Nemagfx_Stencil_Buffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4); *(Nemagfx_Memory_Pool_Buffer Nemagfx_Memory_Pool_Buffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);} >RAMVideobufferSection (NOLOAD) :{*(Video_RGB_Buffer Video_RGB_Buffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);} >RAM*/FramebufferSection (NOLOAD) :
{. = ALIGN(0x4);__TouchGFX_Framebuffer_start__ = .;*(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);__TouchGFX_Framebuffer_end__ = .;. = ALIGN(0x4);__Nemagfx_Stencil_Buffer_start__ = .;*(Nemagfx_Stencil_Buffer Nemagfx_Stencil_Buffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);__Nemagfx_Stencil_Buffer_end__ = .;. = ALIGN(0x4);__Nemagfx_Memory_Pool_Buffer_start__ = .;*(Nemagfx_Memory_Pool_Buffer Nemagfx_Memory_Pool_Buffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);__Nemagfx_Memory_Pool_Buffer_end__ = .;
} >RAMVideobufferSection (NOLOAD) :
{. = ALIGN(0x4);__Video_RGB_Buffer_start__ = .;*(Video_RGB_Buffer Video_RGB_Buffer.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);__Video_RGB_Buffer_end__ = .;
} >RAMExtFlashSection :{*(ExtFlashSection ExtFlashSection.*)*(.gnu.linkonce.r.*). = ALIGN(0x4);} >EXT_FLASH
}
2、获取实际用到的RAM占用
/* USER CODE BEGIN Header */
/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "jpeg_utils_conf.h"
#include "cmsis_os2.h"
#include "app_touchgfx.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "Components/mx66uw1g45g/mx66uw1g45g.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "task.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */// 这些符号由链接脚本自动生成,可以在C代码中直接使用
extern uint32_t _sdata; // 数据段开始地址
extern uint32_t _edata; // 数据段结束地址
extern uint32_t _sidata; // Flash中数据段的加载地址
extern uint32_t _sbss; // BSS段开始地址
extern uint32_t _ebss; // BSS段结束地址
extern uint32_t _estack; // 栈顶地址
extern uint32_t end; // 堆开始地址
extern uint32_t _end; // 堆开始地址(别名)typedef struct {uint32_t dataSize; // 初始化数据段大小uint32_t bssSize; // 未初始化数据段大小uint32_t staticTotal; // 静态内存总使用
} StaticMemoryInfo_t;StaticMemoryInfo_t getStaticMemoryInfo() {StaticMemoryInfo_t info;// 数据段大小(已初始化的全局变量)info.dataSize = (uint32_t)&_edata - (uint32_t)&_sdata;// BSS段大小(未初始化的全局变量)info.bssSize = (uint32_t)&_ebss - (uint32_t)&_sbss;// 静态内存总使用info.staticTotal = info.dataSize + info.bssSize;return info;
}typedef struct {uint32_t heapStart; // 堆开始地址uint32_t heapEnd; // 堆结束地址uint32_t stackStart; // 栈开始地址uint32_t stackEnd; // 栈结束地址uint32_t maxHeapSize; // 最大可用堆大小
} HeapStackInfo_t;extern uint32_t _Min_Stack_Size;
HeapStackInfo_t getHeapStackInfo() {HeapStackInfo_t info;// 堆开始地址(紧接在BSS段后面)info.heapStart = (uint32_t)&_end;// 栈结束地址(栈顶)info.stackEnd = (uint32_t)&_estack;// 栈开始地址(向下增长,预留最小栈空间)info.stackStart = info.stackEnd - (uint32_t)&_Min_Stack_Size;// 堆结束地址(不能超过栈开始)info.heapEnd = info.stackStart;// 最大可用堆大小info.maxHeapSize = info.heapEnd - info.heapStart;return info;
}uint32_t getTouchGFXMemoryUsage() {uint32_t touchgfxMemory = 0;// 帧缓冲区大小(从链接脚本的FramebufferSection)extern uint32_t __TouchGFX_Framebuffer_start__;extern uint32_t __TouchGFX_Framebuffer_end__;if (&__TouchGFX_Framebuffer_end__ > &__TouchGFX_Framebuffer_start__) {touchgfxMemory += (uint32_t)&__TouchGFX_Framebuffer_end__ - (uint32_t)&__TouchGFX_Framebuffer_start__;}// 视频缓冲区大小extern uint32_t __Video_RGB_Buffer_start__;extern uint32_t __Video_RGB_Buffer_end__;if (&__Video_RGB_Buffer_end__ > &__Video_RGB_Buffer_start__) {touchgfxMemory += (uint32_t)&__Video_RGB_Buffer_end__ - (uint32_t)&__Video_RGB_Buffer_start__;}return touchgfxMemory;
}uint32_t estimateAllTaskStackUsage() {uint32_t totalStackUsed = 0;TaskStatus_t *taskStatusArray;UBaseType_t taskCount;UBaseType_t i;// 获取任务数量taskCount = uxTaskGetNumberOfTasks();// 分配内存存储任务状态taskStatusArray = pvPortMalloc(taskCount * sizeof(TaskStatus_t));if (taskStatusArray != NULL) {// 获取所有任务的状态信息taskCount = uxTaskGetSystemState(taskStatusArray, taskCount, NULL);for (i = 0; i < taskCount; i++) {// 获取每个任务的栈高水位标记UBaseType_t stackHighWaterMark = uxTaskGetStackHighWaterMark(taskStatusArray[i].xHandle);// 计算已使用的栈空间// 栈总大小 - 剩余空间 = 已使用空间uint32_t stackUsed = (taskStatusArray[i].usStackHighWaterMark - stackHighWaterMark) * sizeof(StackType_t);totalStackUsed += stackUsed;}vPortFree(taskStatusArray);}return totalStackUsed;
}typedef struct {uint32_t totalRAM; // 总RAM大小uint32_t staticUsed; // 静态内存使用uint32_t heapUsed; // 堆内存使用uint32_t stackUsed; // 栈内存使用(估算)uint32_t touchgfxUsed; // TouchGFX专用内存uint32_t freeRAM; // 剩余可用RAMuint8_t usagePercent; // 使用率百分比
} PreciseMemoryInfo_t;PreciseMemoryInfo_t getPreciseMemoryInfo() {PreciseMemoryInfo_t info;// 从链接脚本获取总RAM大小(3008KB)info.totalRAM = 3008 * 1024;// 静态内存使用StaticMemoryInfo_t staticInfo = getStaticMemoryInfo();info.staticUsed = staticInfo.staticTotal;// 堆内存使用(FreeRTOS提供)info.heapUsed = configTOTAL_HEAP_SIZE - xPortGetFreeHeapSize();// 栈内存使用(估算所有任务栈)info.stackUsed = estimateAllTaskStackUsage();// TouchGFX专用内存(需要专门计算)info.touchgfxUsed = getTouchGFXMemoryUsage();// 计算剩余内存uint32_t totalUsed = info.staticUsed + info.heapUsed + info.stackUsed + info.touchgfxUsed;info.freeRAM = info.totalRAM - totalUsed;// 计算使用率百分比info.usagePercent = (totalUsed * 100) / info.totalRAM;return info;
}/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void UART_Printf(char* fmt, ...);
/* USER CODE END PM *//* Private variables ---------------------------------------------------------*/CRC_HandleTypeDef hcrc;DCACHE_HandleTypeDef hdcache1;
DCACHE_HandleTypeDef hdcache2;DMA2D_HandleTypeDef hdma2d;GPU2D_HandleTypeDef hgpu2d;XSPI_HandleTypeDef hxspi1;I2C_HandleTypeDef hi2c2;JPEG_HandleTypeDef hjpeg;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
DMA_HandleTypeDef handle_GPDMA1_Channel0;LTDC_HandleTypeDef hltdc;UART_HandleTypeDef huart1;/* USER CODE BEGIN PV */
TaskHandle_t ledSparkTaskHandle;// 通过链接脚本符号获取RAM使用情况
extern uint32_t _sdata; // 数据段开始
extern uint32_t _edata; // 数据段结束
extern uint32_t _sbss; // BSS段开始
extern uint32_t _ebss; // BSS段结束
extern uint32_t _estack; // 栈顶uint32_t getStaticRAMUsage() {uint32_t dataSize = (uint32_t)&_edata - (uint32_t)&_sdata;uint32_t bssSize = (uint32_t)&_ebss - (uint32_t)&_sbss;return dataSize + bssSize;
}uint8_t getTotalRAMUsagePercent() {uint32_t staticUsage = getStaticRAMUsage();uint32_t heapUsage = configTOTAL_HEAP_SIZE - xPortGetFreeHeapSize();uint32_t totalUsage = staticUsage + heapUsage;return (uint8_t)((totalUsage * 100) / (3008 * 1024));
}/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void SystemPower_Config(void);
void MX_FREERTOS_Init(void);
static void MX_GPIO_Init(void);
static void MX_GPDMA1_Init(void);
static void MX_ICACHE_Init(void);
static void MX_DCACHE1_Init(void);
static void MX_DCACHE2_Init(void);
static void MX_CRC_Init(void);
static void MX_LTDC_Init(void);
static void MX_DMA2D_Init(void);
static void MX_GPU2D_Init(void);
static void MX_HSPI1_Init(void);
static void MX_I2C2_Init(void);
static void MX_JPEG_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */void led_spark_task(void *pvParameters)
{PreciseMemoryInfo_t info;while(1) {// 获取RAM占用率info = getPreciseMemoryInfo();UART_Printf("u8RamUsedPercent: %d%%, touchgfxUsed: %d\n", info.usagePercent, info.touchgfxUsed);vTaskDelay(pdMS_TO_TICKS(1000));}
}/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//*** @brief 发送单个字符到串口* @param ch: 要发送的字符* @retval None*/
void UART_SendChar(uint8_t ch)
{HAL_UART_Transmit(&huart1, &ch, 1, HAL_MAX_DELAY);
}/*** @brief 发送字符串到串口* @param str: 要发送的字符串* @retval None*/
void UART_SendString(char* str)
{HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
}/*** @brief 格式化打印到串口* @param fmt: 格式化字符串* @param ...: 可变参数* @retval None*/
void UART_Printf(char* fmt, ...)
{char buffer[256];va_list args;va_start(args, fmt);vsnprintf(buffer, sizeof(buffer), fmt, args);va_end(args);UART_SendString(buffer);
}/*** @brief 重定向printf到串口* @param ch: 要发送的字符* @param f: 文件指针* @retval 发送的字符*/
int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);return ch;
}/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the System Power */SystemPower_Config();/* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_GPDMA1_Init();MX_ICACHE_Init();MX_DCACHE1_Init();MX_DCACHE2_Init();MX_CRC_Init();MX_LTDC_Init();MX_DMA2D_Init();MX_GPU2D_Init();MX_HSPI1_Init();MX_I2C2_Init();MX_JPEG_Init();MX_USART1_UART_Init();MX_TouchGFX_Init();/* Call PreOsInit function */MX_TouchGFX_PreOSInit();/* USER CODE BEGIN 2 */UART_Printf("\r\n=== STM32U5 UART Debug Console ===\r\n");xTaskCreate(led_spark_task, "ledSpark", 512, NULL, 2, &ledSparkTaskHandle );/* USER CODE END 2 *//* Init scheduler */osKernelInitialize();/* Call init function for freertos objects (in app_freertos.c) */MX_FREERTOS_Init();/* Start scheduler */osKernelStart();/* We should never get here as control is now taken by the scheduler *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1;RCC_OscInitStruct.PLL.PLLM = 4;RCC_OscInitStruct.PLL.PLLN = 80;RCC_OscInitStruct.PLL.PLLP = 2;RCC_OscInitStruct.PLL.PLLQ = 2;RCC_OscInitStruct.PLL.PLLR = 2;RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_0;RCC_OscInitStruct.PLL.PLLFRACN = 0;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2|RCC_CLOCKTYPE_PCLK3;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){Error_Handler();}
}/*** @brief Power Configuration* @retval None*/
static void SystemPower_Config(void)
{/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral*/HAL_PWREx_DisableUCPDDeadBattery();/** Switch to SMPS regulator instead of LDO*/if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK){Error_Handler();}
/* USER CODE BEGIN PWR */
/* USER CODE END PWR */
}/*** @brief CRC Initialization Function* @param None* @retval None*/
static void MX_CRC_Init(void)
{/* USER CODE BEGIN CRC_Init 0 *//* USER CODE END CRC_Init 0 *//* USER CODE BEGIN CRC_Init 1 *//* USER CODE END CRC_Init 1 */hcrc.Instance = CRC;hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;if (HAL_CRC_Init(&hcrc) != HAL_OK){Error_Handler();}/* USER CODE BEGIN CRC_Init 2 *//* USER CODE END CRC_Init 2 */}/*** @brief DCACHE1 Initialization Function* @param None* @retval None*/
static void MX_DCACHE1_Init(void)
{/* USER CODE BEGIN DCACHE1_Init 0 *//* USER CODE END DCACHE1_Init 0 *//* USER CODE BEGIN DCACHE1_Init 1 *//* USER CODE END DCACHE1_Init 1 */hdcache1.Instance = DCACHE1;hdcache1.Init.ReadBurstType = DCACHE_READ_BURST_INCR;if (HAL_DCACHE_Init(&hdcache1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN DCACHE1_Init 2 *//* USER CODE END DCACHE1_Init 2 */}/*** @brief DCACHE2 Initialization Function* @param None* @retval None*/
static void MX_DCACHE2_Init(void)
{/* USER CODE BEGIN DCACHE2_Init 0 *//* USER CODE END DCACHE2_Init 0 *//* USER CODE BEGIN DCACHE2_Init 1 *//* USER CODE END DCACHE2_Init 1 */hdcache2.Instance = DCACHE2;hdcache2.Init.ReadBurstType = DCACHE_READ_BURST_INCR;if (HAL_DCACHE_Init(&hdcache2) != HAL_OK){Error_Handler();}__HAL_RCC_SYSCFG_CLK_ENABLE();HAL_SYSCFG_DisableSRAMCached();/* USER CODE BEGIN DCACHE2_Init 2 *//* USER CODE END DCACHE2_Init 2 */}/*** @brief DMA2D Initialization Function* @param None* @retval None*/
static void MX_DMA2D_Init(void)
{/* USER CODE BEGIN DMA2D_Init 0 *//* USER CODE END DMA2D_Init 0 *//* USER CODE BEGIN DMA2D_Init 1 *//* USER CODE END DMA2D_Init 1 */hdma2d.Instance = DMA2D;hdma2d.Init.Mode = DMA2D_R2M;hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB888;hdma2d.Init.OutputOffset = 0;hdma2d.Init.BytesSwap = DMA2D_BYTES_REGULAR;hdma2d.Init.LineOffsetMode = DMA2D_LOM_PIXELS;if (HAL_DMA2D_Init(&hdma2d) != HAL_OK){Error_Handler();}/* USER CODE BEGIN DMA2D_Init 2 *//* USER CODE END DMA2D_Init 2 */}/*** @brief GPDMA1 Initialization Function* @param None* @retval None*/
static void MX_GPDMA1_Init(void)
{/* USER CODE BEGIN GPDMA1_Init 0 *//* USER CODE END GPDMA1_Init 0 *//* Peripheral clock enable */__HAL_RCC_GPDMA1_CLK_ENABLE();/* GPDMA1 interrupt Init */HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 5, 0);HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 5, 0);HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);/* USER CODE BEGIN GPDMA1_Init 1 *//* USER CODE END GPDMA1_Init 1 *//* USER CODE BEGIN GPDMA1_Init 2 *//* USER CODE END GPDMA1_Init 2 */}/*** @brief GPU2D Initialization Function* @param None* @retval None*/
static void MX_GPU2D_Init(void)
{/* USER CODE BEGIN GPU2D_Init 0 *//* USER CODE END GPU2D_Init 0 *//* USER CODE BEGIN GPU2D_Init 1 *//* USER CODE END GPU2D_Init 1 */hgpu2d.Instance = GPU2D;if (HAL_GPU2D_Init(&hgpu2d) != HAL_OK){Error_Handler();}/* USER CODE BEGIN GPU2D_Init 2 *//* USER CODE END GPU2D_Init 2 */}/*** @brief HSPI1 Initialization Function* @param None* @retval None*/
static void MX_HSPI1_Init(void)
{/* USER CODE BEGIN HSPI1_Init 0 *//* USER CODE END HSPI1_Init 0 *//* USER CODE BEGIN HSPI1_Init 1 *//* USER CODE END HSPI1_Init 1 *//* HSPI1 parameter configuration*/hxspi1.Instance = HSPI1;hxspi1.Init.FifoThresholdByte = 4;hxspi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;hxspi1.Init.MemoryType = HAL_XSPI_MEMTYPE_MACRONIX;hxspi1.Init.MemorySize = HAL_XSPI_SIZE_1GB;hxspi1.Init.ChipSelectHighTimeCycle = 2;hxspi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;hxspi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;hxspi1.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED;hxspi1.Init.ClockPrescaler = 0;hxspi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;hxspi1.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE;hxspi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE;hxspi1.Init.MaxTran = 0;hxspi1.Init.Refresh = 0;if (HAL_XSPI_Init(&hxspi1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN HSPI1_Init 2 */// Reset flashMX66UW1G45G_ResetEnable(&hxspi1, MX66UW1G45G_SPI_MODE, MX66UW1G45G_STR_TRANSFER);MX66UW1G45G_ResetMemory(&hxspi1, MX66UW1G45G_SPI_MODE, MX66UW1G45G_STR_TRANSFER);HAL_Delay(MX66UW1G45G_RESET_MAX_TIME);/* Enable write operations */MX66UW1G45G_WriteEnable(&hxspi1, MX66UW1G45G_SPI_MODE, MX66UW1G45G_STR_TRANSFER);/* Write Configuration register 2 (with new dummy cycles) */MX66UW1G45G_WriteCfg2Register(&hxspi1, MX66UW1G45G_SPI_MODE, MX66UW1G45G_STR_TRANSFER, MX66UW1G45G_CR2_REG3_ADDR, MX66UW1G45G_CR2_DC_6_CYCLES);/* Enable write operations */MX66UW1G45G_WriteEnable(&hxspi1, MX66UW1G45G_SPI_MODE, MX66UW1G45G_STR_TRANSFER);/* Write Configuration register 2 (with Octal I/O SPI protocol) */MX66UW1G45G_WriteCfg2Register(&hxspi1, MX66UW1G45G_SPI_MODE, MX66UW1G45G_STR_TRANSFER, MX66UW1G45G_CR2_REG1_ADDR, MX66UW1G45G_CR2_DOPI);/* Wait that the configuration is effective and check that memory is ready */HAL_Delay(MX66UW1G45G_WRITE_REG_MAX_TIME);MX66UW1G45G_EnableDTRMemoryMappedMode(&hxspi1, MX66UW1G45G_OPI_MODE);/* USER CODE END HSPI1_Init 2 */}/*** @brief I2C2 Initialization Function* @param None* @retval None*/
static void MX_I2C2_Init(void)
{/* USER CODE BEGIN I2C2_Init 0 *//* USER CODE END I2C2_Init 0 *//* USER CODE BEGIN I2C2_Init 1 *//* USER CODE END I2C2_Init 1 */hi2c2.Instance = I2C2;hi2c2.Init.Timing = 0x00F07BFF;hi2c2.Init.OwnAddress1 = 0;hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;hi2c2.Init.OwnAddress2 = 0;hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;if (HAL_I2C_Init(&hi2c2) != HAL_OK){Error_Handler();}/** Configure Analogue filter*/if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK){Error_Handler();}/** Configure Digital filter*/if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK){Error_Handler();}/* USER CODE BEGIN I2C2_Init 2 *//* USER CODE END I2C2_Init 2 */}/*** @brief ICACHE Initialization Function* @param None* @retval None*/
static void MX_ICACHE_Init(void)
{/* USER CODE BEGIN ICACHE_Init 0 *//* USER CODE END ICACHE_Init 0 *//* USER CODE BEGIN ICACHE_Init 1 *//* USER CODE END ICACHE_Init 1 *//** Enable instruction cache in 1-way (direct mapped cache)*/if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK){Error_Handler();}if (HAL_ICACHE_Enable() != HAL_OK){Error_Handler();}/* USER CODE BEGIN ICACHE_Init 2 *//* USER CODE END ICACHE_Init 2 */}/*** @brief JPEG Initialization Function* @param None* @retval None*/
static void MX_JPEG_Init(void)
{/* USER CODE BEGIN JPEG_Init 0 *//* USER CODE END JPEG_Init 0 *//* USER CODE BEGIN JPEG_Init 1 *//* USER CODE END JPEG_Init 1 */hjpeg.Instance = JPEG;if (HAL_JPEG_Init(&hjpeg) != HAL_OK){Error_Handler();}/* USER CODE BEGIN JPEG_Init 2 *//* USER CODE END JPEG_Init 2 */}/*** @brief LTDC Initialization Function* @param None* @retval None*/
static void MX_LTDC_Init(void)
{/* USER CODE BEGIN LTDC_Init 0 *//* USER CODE END LTDC_Init 0 */LTDC_LayerCfgTypeDef pLayerCfg = {0};/* USER CODE BEGIN LTDC_Init 1 *//* USER CODE END LTDC_Init 1 */hltdc.Instance = LTDC;hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;hltdc.Init.HorizontalSync = 4;hltdc.Init.VerticalSync = 4;hltdc.Init.AccumulatedHBP = 12;hltdc.Init.AccumulatedVBP = 12;hltdc.Init.AccumulatedActiveW = 812;hltdc.Init.AccumulatedActiveH = 492;hltdc.Init.TotalWidth = 820;hltdc.Init.TotalHeigh = 506;hltdc.Init.Backcolor.Blue = 0;hltdc.Init.Backcolor.Green = 0;hltdc.Init.Backcolor.Red = 0;if (HAL_LTDC_Init(&hltdc) != HAL_OK){Error_Handler();}pLayerCfg.WindowX0 = 0;pLayerCfg.WindowX1 = 800;pLayerCfg.WindowY0 = 0;pLayerCfg.WindowY1 = 480;pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;pLayerCfg.Alpha = 255;pLayerCfg.Alpha0 = 0;pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;pLayerCfg.FBStartAdress = 0;pLayerCfg.ImageWidth = 800;pLayerCfg.ImageHeight = 480;pLayerCfg.Backcolor.Blue = 0;pLayerCfg.Backcolor.Green = 0;pLayerCfg.Backcolor.Red = 0;if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK){Error_Handler();}/* USER CODE BEGIN LTDC_Init 2 *//* USER CODE END LTDC_Init 2 */}/*** @brief USART1 Initialization Function* @param None* @retval None*/
static void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK){Error_Handler();}if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK){Error_Handler();}if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOE_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOF_CLK_ENABLE();__HAL_RCC_GPIOH_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOI_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOE, LCD_DISP_EN_Pin|LCD_BL_CTRL_Pin, GPIO_PIN_SET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, VSYNC_FREQ_Pin|RENDER_TIME_Pin|FRAME_RATE_Pin|MCU_ACTIVE_Pin, GPIO_PIN_RESET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOD, USER_LD2_RED_Pin|USER_LD3_GREEN_Pin, GPIO_PIN_SET);/*Configure GPIO pin : LCD_DISP_EN_Pin */GPIO_InitStruct.Pin = LCD_DISP_EN_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(LCD_DISP_EN_GPIO_Port, &GPIO_InitStruct);/*Configure GPIO pin : TP_IRQ_Pin */GPIO_InitStruct.Pin = TP_IRQ_Pin;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(TP_IRQ_GPIO_Port, &GPIO_InitStruct);/*Configure GPIO pin : LCD_BL_CTRL_Pin */GPIO_InitStruct.Pin = LCD_BL_CTRL_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(LCD_BL_CTRL_GPIO_Port, &GPIO_InitStruct);/*Configure GPIO pin : USER_BUTTON_Pin */GPIO_InitStruct.Pin = USER_BUTTON_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(USER_BUTTON_GPIO_Port, &GPIO_InitStruct);/*Configure GPIO pins : VSYNC_FREQ_Pin RENDER_TIME_Pin FRAME_RATE_Pin MCU_ACTIVE_Pin */GPIO_InitStruct.Pin = VSYNC_FREQ_Pin|RENDER_TIME_Pin|FRAME_RATE_Pin|MCU_ACTIVE_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pins : USER_LD2_RED_Pin USER_LD3_GREEN_Pin */GPIO_InitStruct.Pin = USER_LD2_RED_Pin|USER_LD3_GREEN_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI5_IRQn, 5, 0);HAL_NVIC_EnableIRQ(EXTI5_IRQn);/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief Period elapsed callback in non blocking mode* @note This function is called when TIM6 interrupt took place, inside* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment* a global variable "uwTick" used as application time base.* @param htim : TIM handle* @retval None*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* USER CODE BEGIN Callback 0 *//* USER CODE END Callback 0 */if (htim->Instance == TIM6) {HAL_IncTick();}/* USER CODE BEGIN Callback 1 *//* USER CODE END Callback 1 */
}/*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */