Skip to main content
er3481
Associate III
August 9, 2016
Question

stemwin gui without external ram

  • August 9, 2016
  • 11 replies
  • 2275 views
Posted on August 09, 2016 at 15:04

Hi,

I want to use stemwin gui library with my stm32f429 board without any external ram for driving 320*240 tft LCD, so i will use mcu internal ram. when i use ''GUI_DispString(''Hello world!'')'' function , i can not see anything on the screen. For discovery board there is a external sdram and in ''LCDConf.c'' file the frame buffer is defined as :

#define LCD_LAYER0_FRAME_BUFFER ((uint32_t)0xD0200000)

So, if this is the problem for my board ( i am not sure), what must this value be ? Any advise ? ( when i use the value '' 0x20000000 for buffer adress that is the mcu internal ram adress, the code crashes.)

    This topic has been closed for replies.

    11 replies

    Tesla DeLorean
    Guru
    August 9, 2016
    Posted on August 09, 2016 at 16:55

    When i use the value '' 0x20000000 for buffer address that is the mcu internal ram address, the code crashes.

    Ok, it is important to tell the linker to NOT use that same space for stacks and variables.

    This is accomplished by carving out a hole in what you describe in the Linker Script, Scatter File, or Target Dialog, depending on the tool chain.

    If you tell the linker it can use 0x20000000..0x20003FFF, you can then place the buffer at 0x20004000, for example.

    You'll still need to consider if you have enough RAM to serve as a buffer, or not.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    er3481
    er3481Author
    Associate III
    August 9, 2016
    Posted on August 09, 2016 at 18:33

    Hi @clive1

    I am using IAR embedded workbench and according to linker->Memory Regions settings, The RAM start adress is 0x20000000 and end adress is 0x2002FFFF, so when i use the buffer adress as 0x20004000 is does not work again. The stm32f429xx_flash.icf file has the following values and which values must i change or edit? If i have misunderstood, please correct me with the rigth way.

    /*###ICF### Section handled by ICF editor, don't touch! ****/

    /*-Editor annotation file-*/

    /* IcfEditorFile=''$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml'' */

    /*-Specials-*/

    define symbol __ICFEDIT_intvec_start__ = 0x08000000;

    /*-Memory Regions-*/

    define symbol __ICFEDIT_region_ROM_start__    = 0x08000000;

    define symbol __ICFEDIT_region_ROM_end__      = 0x081FFFFF;

    define symbol __ICFEDIT_region_RAM_start__    = 0x20000000;

    define symbol __ICFEDIT_region_RAM_end__      = 0x2002FFFF;

    define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;

    define symbol __ICFEDIT_region_CCMRAM_end__   = 0x1000FFFF;

    /*-Sizes-*/

    define symbol __ICFEDIT_size_cstack__ = 0x400;

    define symbol __ICFEDIT_size_heap__ = 0x200;

    /**** End of ICF editor section. ###ICF###*/

    define memory mem with size = 4G;

    define region ROM_region      = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];

    define region RAM_region      = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

    define region CCMRAM_region   = mem:[from __ICFEDIT_region_CCMRAM_start__   to __ICFEDIT_region_CCMRAM_end__];

    define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };

    define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

    initialize by copy { readwrite };

    do not initialize  { section .noinit };

    place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

    place in ROM_region   { readonly };

    place in RAM_region   { readwrite,

                            block CSTACK, block HEAP };

    Tesla DeLorean
    Guru
    August 9, 2016
    Posted on August 09, 2016 at 19:16

    If you were to shrink the memory visible to the linker, you'd change

    define symbol __ICFEDIT_region_RAM_end__      = 0x2002FFFF;

    to

    define symbol __ICFEDIT_region_RAM_end__      = 0x20003FFF;

    Alternatively you could make the heap very large and malloc() your frame buffer.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    er3481
    er3481Author
    Associate III
    August 10, 2016
    Posted on August 10, 2016 at 08:40

    Hi @clive1

    when i assign the ram define symbol __ICFEDIT_region_RAM_end__  =  x20003FFF;

    the compiler gives error for section placement like this:

    ''unable to allocate space for sections/blocks with a total estimated minimum size of 0x288b8 bytes (max align 0x8) in <[0x20000000-0x20003fff]> (total uncommitted space 0x4000).''

    So i have changed the RAM end value to 2001B000, then the compiler gives no error but code crashes again ( it goes to HardFault_Handler() function) . Can you give any other advise ? How can i make huge heap and how can i use malloc for frame buffer define?

    qwer.asdf
    Senior
    August 10, 2016
    Posted on August 10, 2016 at 12:16

    Why can't it be done by just declaring a buffer in a global variable and using its address (given there is really enough internal SRAM)?

    Something like this:

    unsigned char buf[FRAMEBUFFER_SIZE];

    ...

    #define LCD_LAYER0_FRAME_BUFFER  ((uint32_t)&buf[0])
    er3481
    er3481Author
    Associate III
    August 10, 2016
    Posted on August 10, 2016 at 13:06

    Hi @qwer.asdf

    I have defined the fram buffer as you said and used it as fram buffer , the GUI_Init() function crashed again. My GUI_COnfig() function is :

    #define GUI_NUMBYTES  (1024) * 150

    void GUI_X_Config(void) {

      static  U32 aMemory[GUI_NUMBYTES / 8 ];

      //

      // Assign memory to emWin

      //

      GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);

      //

      // Set default font

      //

      GUI_SetDefaultFont(GUI_FONT_6X8);

    }

    And my build output for stm32f429VIT mcu is:

       50 898 bytes of readonly  code memory

       13 462 bytes of readonly  data memory

      118 707 bytes of readwrite data memory

    So i think there is enough ram area.

    qwer.asdf
    Senior
    August 10, 2016
    Posted on August 10, 2016 at 13:23

    > (1024) * 150

    So, you are declaring 1024x150 = 19200 sized array of 4-byte U32 values (76800 bytes). Which is the same as 240x320. So 1 byte per pixel? Why not just use a U8 array of 240x320 size? Anyway, it shouldn't matter.

    Are you sure you are using the 4/6/8-bit RGB color mode (like L8, AL44, A8 modes) and not 16-bit mode (which would require 2 times more RAM)?

    There is another thing, according to the datasheet, there are 4 SRAM regions sized 112KB (0x20000000-0x2001BFFF), 16KB, 64KB, and another 64KB of CCM SRAM. Only the first block is big enough to have your 240x320 sized buffer. If your project compiles and links without problems then it must be OK but just in case check your map file to make sure the buffer has successfully ended up in the 0x20000000-0x2001BFFF range.
    daemynnur
    Associate II
    August 10, 2016
    Posted on August 10, 2016 at 13:35

    from my experience of STemWin,  without doing some detaled tweaking I don't think you have enougn internal RAM in STM32F429 to do what you're trying to.

    STM32F429 has 256K of internal ram

    320*24l LCD has 76800 pixels

    I believe STemWin, in it's default setting uses 32 bit ARGB colour format, (which is 4 bytes per pixel), so you frame buffer is 300K !

    even converting to one of the 16 bit colour formats (e.g. RGB565), it would still be 150K, which is leaving little for everything else, including the GUI.

    your only real chance, I think, would be to to convert to one of the 8 bit per pixel, palleted formats. (the emWin user manual (chapter 15) has a lot about colour formats)

    Unfortunately my experience of STemWin doesn't extend far enough to help you achieve that (although I'd love to know how if you manage it)

    BTW, IIRC, the '' GUI_ALLOC_AssignMemory'' is the memory allocated to running the GUI & nothing to do with frame buffer size

    quote from 

    emWin User manual Pg 1248

    GUI_ALLOC_AssignMemory()

    Description 

    The function assigns the one and only memory block to emWin which is used by the internal memory management system.

    ... It is never used as frame buffer.

    BTW, (although not affecting frame buffer) I think your ''

      static  U32 aMemory[GUI_NUMBYTES / 8 ];

    '' should be

      static  U32 aMemory[GUI_NUMBYTES / 4 ];

     (U32 is 4 bytes wide, not 8) otherwise you're only reserving half the amount of memory that you're telling emWin it can use

    good luck

    er3481
    er3481Author
    Associate III
    August 11, 2016
    Posted on August 11, 2016 at 09:25

    Hi,

    I have figured it out with some troubles. I have specified the ram area from linker settings between 0x20000000  and 0x2002B000, i have defined the frame buffer adress as 0x2002B001. My assign memory define is ''

    static  U32 aMemory[GUI_NUMBYTES / 5 ];'' (

    It does not permit to use /4 for space allocation error).

    For now i can write something with GUI_DispStringAt() function but i can not use the whole screen coordinates, for example if i use x=30 and y = 30 the string disappears, i can only use coordinates x=10 y = 10.

    By the way when i use gui_color for red, it appears as blue and, if i use gui_color for blue it appears red, i can not understand why it Works as inverted.  

    daemynnur
    Associate II
    August 11, 2016
    Posted on August 11, 2016 at 13:34

    Hi rapid84,

    STM32F4 SRAM is from 0x20000000 to 0x2002FFFF ( 192KB)

    you've set your Buffer Start @ 0x2002B001

    as per my previous, unless you've changed the colour format settings of emWin, it'll probably be 32bits (4 byetes) per pixel.

    so the 320x240 pixel display will need 300K of memory for the buffer

    actual memory mapped to the buffer will only be 0x0x2002B001 to 0x2002FFFF (which is only 20KB,... well 2 bytes under actually)

    The GUI & LCD driver won't care that there isn't actually any memory where the buffer is mapped to, the GUI will just write to empty space & the display will show nothing, where there is no RAM

    so, 20K @ 4 bytes per pixel is 5120 pixels, which on the raster scan of the display is only the top 21 lines of the display

    that seems to fit what you're getting.

    as for the colour (red vs blue)

    I read something (in the emWin manual I think) that the GUI uses ABGR8888 (Alpha, Blue, Green, Red) format while the LCD driver in the stm32F4 uses ARGB8888 (Alpha, Red, Green, Blue),..  so effectively red & blue are swapped over, which is probably what's causing it.

    if you want to get this to work (e.g full screen buffer), you'll need to find out how to change emWin to an 8 bit per pixel format and set & set your buffer address to 0x2001D400

    That'll leave you 117K of ram for everything else, which should be OK, but you'll have to change the amount allocated to the GUI as you've currently got that at 150K

    (if you're not looking to use emWin's 'memory devices' (for sprites, floating windows or the like) & just want to do basic text & line-draw etc, you should be able to set that to 20K or less.

    Cheers,.. Daemy