Keil Logo

ARMCLANG: Cannot Allocate Memory for GLCD Frame Buffer


Information in this knowledgebase article applies to:

  • Arm Compiler Version 6.9
  • Keil MDK

SYMPTOM

I am trying to port an earlier Keil MDK project that uses an LCD screen. It was originally designed for Arm compiler version 5, but I'd like to transition to Arm compiler version 6. I receive a linker error message, L6406E, similar to the following:

.\Flash\Demo.axf: Error: L6406E: No space in execution regions with .ANY selector matching glcd_mcb1800.o(.bss.frame_buf).

Looking carefully over the build output, I can see a related warning, unknown attribute 'at' ignored:

C:/Keil_v5/ARM/PACK/Keil/LPC1800_DFP/2.8.0/Boards/Keil/MCB1800/Common/GLCD_MCB1800.c(131): warning: unknown attribute 'at' ignored [-Wunknown-attributes]
static uint16_t   frame_buf[GLCD_WIDTH*GLCD_HEIGHT]__attribute__((at(SDRAM_BASE_ADDR)));

What is going on?

CAUSE

The "at" attribute, which places the LCD frame buffer in external SDRAM, is accepted by Arm compiler version 5, but it is not accepted by Arm compiler version 6. The linker tries to recover, and assign the buffer to a known memory region, but then it cannot fit the rest of the RW data into the RAM execution regions passed to the linker, by a scatter file.

RESOLUTION

In Arm compiler version 6, you can now use the section attribute, with a special section name, to quickly place the variable in a specific location:

//COPYRIGHT NOTICE
/*-----------------------------------------------------------------------------
 * Name:    GLCD_MCB1800.c
 * Purpose: Graphic LCD interface (240x320 pixels) for Graphic LCD with
 *          SPI interface (in RGB mode) for MCB1800 evaluation board
 * Rev.:    1.00
 *----------------------------------------------------------------------------*/

/* Copyright (c) 2013 - 2014 ARM LIMITED
//Convert the following line:
static uint16_t   frame_buf[GLCD_WIDTH*GLCD_HEIGHT]__attribute__((at(SDRAM_BASE_ADDR)));

//==>>

static uint16_t   frame_buf[GLCD_WIDTH*GLCD_HEIGHT]__attribute__((section(".ARM.__at_0x28000000")));

Alternatively, if you want to take a macro-based approach:

#define SDRAM_BASE_ADDR       0x28000000
//...
static uint16_t   frame_buf[GLCD_WIDTH*GLCD_HEIGHT]__attribute__((at(SDRAM_BASE_ADDR)));

//==>>

#define SDRAM_BASE_ADDR       0x28000000
#define str_SDRAM_BASE_ADDR   "0x28000000"
//...
static uint16_t   frame_buf[GLCD_WIDTH*GLCD_HEIGHT]__attribute__((section(".ARM.__at_"str_SDRAM_BASE_ADDR)));

MORE INFORMATION

Last Reviewed: Tuesday, January 12, 2021


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.