Skip to main content
b1aze
Associate III
December 8, 2025
Question

LTDC worked without FreeRTOS; not with

  • December 8, 2025
  • 5 replies
  • 752 views

HI all i have been working with LTDC to drive an external RGB parallel display . i made it working by placing the framebuffer inside internal RAM . i got output with good update speed. but when i try to incoperate  FREERTOS with this project the output is gone . any one encountered such issues like this , any solution for this now? ;)

5 replies

Andrew Neil
Super User
December 8, 2025

An RTOS (any RTOS) is not really something that you can just bolt-on to an existing project - it is a fundamental change to the project architecture.

You'll need to do some debugging to find why your code is not working ...

  • Are basic things like UART and LEDs still working ?
  • Is your display driver getting initialised properly ?
  • Is your display driver getting called at all ?
  • Is your display driver getting called sufficiently often ?
A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Technical Moderator
December 9, 2025

Hello @b1aze 

When using FreeRTOS, it is essential to ensure that all peripheral interrupts are assigned a priority that is equal to or lower than (i.e., numerically higher than) the value specified by configMAX_SYSCALL_INTERRUPT_PRIORITY. Therefore, the priorities of the LTDC and DMA interrupts should be configured to levels that comply with this requirement to maintain system stability and proper FreeRTOS operation.

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question.Saket_Om"
b1aze
b1azeAuthor
Associate III
December 9, 2025

Hi guys thanks for the response , right now all i know is that LTDC is being initialized , beacuse in my code 

b1aze_0-1765298899172.png

starting address of internal RAM is given to LTDC and LTDC seems to read from the RAM , before RTOS i get full display output, but after output i get this scrambled red color on the screen , so without LTDC or clock signal i wouldn't have got anything on the display. so my assumption is that something is happeing with priority timing or my framebuffer is being scrambled somehow . whats your thoughts or ideas. 

Andrew Neil
Super User
December 9, 2025

Please see  How to insert source code - not as an image.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
b1aze
b1azeAuthor
Associate III
December 10, 2025

This is from linker script

 .framebuffer (NOLOAD) :
 {
 		. = ALIGN(32);
 		KEEP(*(.framebuffer))
 		. = ALIGN(32) ;
 		
 }>RAM

and in my code for frame buffer this 

__attribute__((section(".framebuffer"),aligned(32))) uint16_t framebuffer[LCD_WIDTH * LCD_HEIGHT];
lv_color_t lvgl_buf[LCD_WIDTH * LVGL_BUF_SIZE];
lv_disp_draw_buf_t drawbuf;
lv_disp_drv_t dispdrv;

void init_lvgl(void)
{
	lv_disp_draw_buf_init(&drawbuf, lvgl_buf,lvgl_buf, LCD_WIDTH * LVGL_BUF_SIZE);
		 /* Initialize display driver */
	lv_disp_drv_init(&dispdrv);
	dispdrv.hor_res = LCD_WIDTH;
	dispdrv.ver_res = LCD_HEIGHT;
	dispdrv.flush_cb = flush_cb;
	dispdrv.draw_buf = &drawbuf;
	dispdrv.full_refresh = 0 ;
	dispdrv.direct_mode = 0 ;
	lv_disp_drv_register(&dispdrv);
}

static void flush_cb(lv_disp_drv_t*disp, const lv_area_t *area, lv_color_t* px_map)
{
	uint32_t w = (area->x2 - area->x1 + 1);
 uint32_t h = (area->y2 - area->y1 + 1);
 uint16_t *dst = framebuffer + area->y1 * disp->hor_res + area->x1;
 uint16_t *src=(uint16_t *)px_map;
 //HAL_DMA2D_Start(&hdma2d,*(src),*(dst),w,h);
 for (uint32_t y = 0; y < h; y++) {
 	//HAL_DMA2D_Start();
 memcpy(dst, src, w * sizeof(uint16_t));
 dst += disp->hor_res;
 src += w;
 }
 lv_disp_flush_ready(disp);
}

 this is it . ask if you need anything

MM..1
Chief III
December 10, 2025

Still not  show 0x24000000 and framebuffer ... LTDC

b1aze
b1azeAuthor
Associate III
December 11, 2025

This is my linker script and i declared my framebuffer like this in main.c file

__attribute__((section(".framebuffer"),aligned(32))) uint16_t framebuffer[LCD_WIDTH * LCD_HEIGHT];
lv_color_t lvgl_buf[LCD_WIDTH * LVGL_BUF_SIZE];

 this is it nothing else i done for frmabuffer. and inside the LTDC i gave the RAM start address

pLayerCfg.FBStartAdress = 0x24000000;

 

 

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
 ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
 DTCMRAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
 DTCMRAM2 (xrw) : ORIGIN = 0x20010000, LENGTH = 64K
 RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 1024K
 RAM_CD (xrw) : ORIGIN = 0x30000000, LENGTH = 128K
 RAM_SRD (xrw) : ORIGIN = 0x38000000, LENGTH = 32K
}

/* Define output sections */
SECTIONS
{
 /* The startup code goes first into FLASH */
 .framebuffer (NOLOAD) :
 {
 		. = ALIGN(32);
 		KEEP(*(.framebuffer))
 		. = ALIGN(32) ;
 		
 }>RAM
 
 .isr_vector :
 {
 . = ALIGN(4);
 KEEP(*(.isr_vector)) /* Startup code */
 . = ALIGN(4);
 } >FLASH

 /* The program code and other data goes into FLASH */
 .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