2025-08-26 3:45 AM
Hello,
I am developing an embedded project using the STM32H7 microcontroller, integrating FreeRTOS, FatFs file system, USB mass storage device (USB flash drive) functionality, SD card reading/writing,
UART communication, and ADC sampling. My system uses LVGL as the graphical user interface (GUI) library and drives the LCD through LTDC.
Core issue phenomenon:
I observed that the system's functional behavior has a direct and consistent correlation with the on/off state of the LVGL screen:
DISPLAY_ENABLE is a macro definition I created to control whether to use the screen.
When the screen is off (DISPLAY_ENABLE = 0):
All functional modules (USB mass storage mounting and writing, UART communication, ADC sampling, SD card reading/writing, database operations) work normally.
When the screen is on (DISPLAY_ENABLE = 1), two different phenomena occur:
Phenomenon 1: When test buffers (writeBuffer/readBuffer, 512 bytes each) are located in the data segment:
USB mass storage device fails to mount (output log shows "Mount failed with error: 1")
UART communication functions work normally
ADC sampling functions work normally
SD card reading/writing and database operations work normally
Phenomenon 2: When test buffers (writeBuffer/readBuffer) are declared inside functions (i.e., in stack space):
USB mass storage device mounts and writes normally
UART communication functions fail to work properly
ADC sampling functions fail to work properly
SD card reading/writing and database operations work normally
Code snippets related to my LVGL/LTDC:
#define LCD_WIDTH 320
#define LCD_HEIGHT 240
static uint16_t fb[LCD_WIDTH * LCD_HEIGHT] = {0};
// Only modified this line after CubeMX generation:
pLayerCfg.FBStartAdress = LCD_GetFrameBufferAddress();
// When DISPLAY_ENABLE = 0; LCD_GetFrameBufferAddress() returns 0
// When DISPLAY_ENABLE = 1; LCD_GetFrameBufferAddress() returns (uint32_t)fb
void InitTft(void)
{
lv_init();
lv_port_disp_init();
tftTaskHandle = osThreadNew(TftTask, NULL, &tftTask_attributes);
LVGLTaskHandle = osThreadNew(LVGLTask, NULL, &LVGLTask_attributes);
lvglMutexHandle = osMutexNew(&lvglMutex_attributes);
}
/**
* LVGL requires a buffer where it internally draws the widgets.
* Later this buffer will be passed to your display driver's `flush_cb` to copy its content to your display.
* The buffer has to be greater than 1 display row
*
* There are 3 buffering configurations:
* 1. Create ONE buffer:
* LVGL will draw the display's content here and writes it to your display
*/
/* Example for 1) */
static lv_disp_draw_buf_t draw_buf_dsc_1;
static lv_color_t buf_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/
lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/
InitTft is the main screen thread.
I suspect that when LVGL is active, USB, UART, and ADC fail. I strongly suspect that the large static frame buffer (fb) is causing RAM address conflicts and impacting the consistency of critical peripheral DMA buffers and L1 Cache.
The above is the phenomenon I discovered and my doubts during testing. I want to know if this is the cause, or tell me what is causing it. I hope you can help me solve it. Thank you very much.
Thanks.