cancel
Showing results for 
Search instead for 
Did you mean: 

How to Store Font Table in Flash with GCC?

infoinfo991
Associate III
Posted on July 16, 2012 at 18:26

I have a large 5x7 pixel font table that I want to store in flash memory instead of RAM memory. I am using Eclipse with the ARM GCC plugin.

I am hoping there is something similar to avr/pgmspace.h but obviously for STM32, or ARM Cortex in general.

How do I store the table in flash memory without having it reside in RAM at all?

To get started, I declared it like so

static unsigned char oled_font[] __attribute__ ((section(''.text''),used)) = {

...

};

but now the challenge is, how do I access this table? do I just access it ''normally'' or do I need some specific flash reading functions? is ''__LDREXB'' what I am looking for?

#flash
9 REPLIES 9
frankmeyer9
Associate II
Posted on July 16, 2012 at 19:56

Doesn't do the

const

keyword the job ?

In the most toolchains I know, something like

const char array[] = ''what so ever'';

is automatically placed in the code section, i.e. in flash.

infoinfo991
Associate III
Posted on July 31, 2012 at 23:51

Well it worked

I made a test

The data is stored like:

static unsigned char test_table[] __attribute__ ((section(''.text''),used)) = {

'a', 'b', 'c',

};

The output is generated with:

printf(''test_table %c %c %c\r\n'', __LDREXB(&(test_table[0])), __LDREXB(&(test_table[1])), __LDREXB(&(test_table[2])));

And the final output is:

test_table a b c

Also, increasing the amount of data inside the table does not increase the size of ''data'', it only increases the size of ''text''

Posted on August 01, 2012 at 02:09

And something like this does not?

static const unsigned char test_table[] = { 'a', 'b', 'c' };

printf(''test_table %c %c %c\r\n'', test_table[0], test_table[1],test_table[2]);

I fail to see what ''__LDREXB'' brings to the table other than portability issues.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
infoinfo991
Associate III
Posted on August 02, 2012 at 23:30

I work with AVR microcontrollers a lot, so it's a habit to explicitly state whether or not a string is stored in flash or RAM because flash memory is separate from RAM and one pointer can be either pointing into flash or RAM depending on the instruction you use. From what you are saying, ARM has both flash and RAM in the same memory space and can't possibly have the same pointer and thus I don't need to explicitly choose the instructions.

If so, you have a point, but now I have to think about writing code for ARM that is compatible with AVR as well.

Also I find that the ''used'' attribute more important in this case, there will be data blocks I have in the future, and the way I access it might be convoluted enough for the compiler to optimize it away. Your code seems to work but I added some data into the table and the compiled size didn't increase until I put in the ''used'' attribute.

Posted on August 03, 2012 at 00:07

Unlike 8051, and presumably the AVR, the ARM does not have code vs data address spaces. Access speeds can vary wildly, depending on buses or TCM, etc.

printf(''where is test_table %p %d\r\n'', test_table, sizeof(test_table));

Should be evident if the table is in FLASH (>=0x08000000), the apparent size might depend on alignment.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
enc0der
Associate II
Posted on September 10, 2013 at 04:43

I was trying to do something the same as this with a font table, if I put const or not, ld returns the same amount of RAM overflow.  

static const unsigned char  font[] = {...

or

static unsigned char  font[] = {...

both produce:

arm-none-eabi/bin/ld: region `ram' overflowed by 87100 bytes

Posted on September 10, 2013 at 05:50

Sounds like some fail on the link script front.

Should probably make sure the Read Only stuff gets parked in FLASH.

 *(.rodata)

 *(.rodata*)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
enc0der
Associate II
Posted on September 10, 2013 at 05:54

I will look deeper into that, thanks!  I discovered that the STM32F4 RAM is in smaller banks than I realized.  What I have is a frame buffer that is now larger than the RAM which is also what is my problem.  Having to go look at SRAM now to add.

I am switching to the STM32F429 but I am not sure how that RAM is split up.  I *might* have enough room, but it would be cutting it close so I think adding some SRAM is probably the best bet.

Posted on September 10, 2013 at 06:17

I'm not really satisfied with how linkers generally deal with sparse memory maps, most need far too much manual nudging to place things in a reasonably optimal fashion. I suppose the preferred method is to do two passes and have a script shuffle things around.

My .MAP with 240K of ''static const unsigned char font[]''

.rodata.str1.1
0x080040ac 0xf out/ff.o
.rodata.font 0x080040bb 0x3c0d3 out/main.o
.rodata.str1.1
0x0804018e 0x22 out/main.o

I'd have to dig up my 429 notes, but I'm pretty sure the SRAM is placed 64 KB at 0x10000000 (can't DMA) 192 KB at 0x20000000 4KB at 0x40024000 SDRAM at 0xC0000000 and/or 0xD0000000
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..