2012-07-16 09:26 AM
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 sostatic 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? #flash2012-07-16 10:56 AM
Doesn't do the
const
keyword the job ? In the most toolchains I know, something likeconst char array[] = ''what so ever'';
is automatically placed in the code section, i.e. in flash.2012-07-31 02:51 PM
2012-07-31 05:09 PM
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.2012-08-02 02:30 PM
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.2012-08-02 03:07 PM
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.2013-09-09 07:43 PM
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[] = {...orstatic unsigned char font[] = {...both produce:arm-none-eabi/bin/ld: region `ram' overflowed by 87100 bytes2013-09-09 08:50 PM
Sounds like some fail on the link script front.
Should probably make sure the Read Only stuff gets parked in FLASH. *(.rodata) *(.rodata*)2013-09-09 08:54 PM
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.2013-09-09 09:17 PM
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