[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] RFC: index-redirection with PROGMEM and linker symbol
From: |
Dale Whitfield |
Subject: |
Re: [avr-libc-dev] RFC: index-redirection with PROGMEM and linker symbol use |
Date: |
Thu, 19 Feb 2009 10:12:19 +0200 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
Hi Stu >@2009.02.18_00:08:04_+0200
> I have an interesting idea/problem and I'm looking for ideas.
>
Similarly and I pinged Joerg on this recently and will raise it again
another time. The gist is that I want to create code that is shared
between boot and app code. That code needs to access program-memory too.
One simple example is to call a function from either boot or app that
fills in a structure which describes my SPI-flash partitioning. Its
related but has an added level of complexity. Another time.
> I'm using an ATmega2560 and my string tables are getting large enough to
> be bumping real code out of the bottom page of flash. So far,
> everything has been done with the standard PROGMEM macros/calls and I've
> been happy. However, I'm thinking of adding quite a few more strings
> and I'm not happy with dedicating all of my most precious bottom flash
> to "constants".
>
Also on 2560 and I have fonts and strings which now take up just short
of 32k.
> I'm quite familiar with the standard PROGMEM macros and routines. I'm
> also familiar with Carlos Lamas' morepgmspace.h routines and use them
> with my bootloader. This is not a request for instructions on their
> use. (Or, maybe it is, if the below can be done with them.)
>
> The idea is this: PROGMEM is based on the idea that we can represent
> all the direct addressing to flash constants in the 16-bit GCC pointer
> value. So far, so good. What I want to do is generate a relocation
> offset for all flash constants. I would place all of PROGMEM (or some
> other related call, perhaps "PROGMEM_INDEXED" or "PROGMEM_HIGH")
> starting at address 0x37000 (byte address), for example. Then 16-bit
> pointers to constants would be a direct offset from the linker address
> of the base of this table. Perhaps I would call the section .proghigh.
> Finally, the functions used to dereference pointers to this area would
> auto-magically add the .proghigh offset to the passed in 16-bit
> "pointer", to generate the real 24-bit (okay, 32-bit) address to hand
> off to the ELPM intruction.
>
> In other words, I want an indexed-dereference of the pointer passed in
> from the based of the constant table. Even more important, I want the
> linker to store this index in my flash table instead of the standard
> variable pointer I use now.
>
> Placing the constants up in my special section is a no-brainer. I can
> do it with a section attribute. I do it now with my boot string table.
>
> I think I can generate the proper assembly, although I'm not quite sure
> how to bring in the relocation address. That could be done simply
> enough with a symbol define, I think.
>
> The hard part is generating the 16-bit offset values and placing those
> in the tables referencing the constants. For example, my error string
> table looks something like:
>
> const char et_ERR_NO_ERROR [] PROGMEM = "No Error";
> const char et_ERR_TIMEOUT [] PROGMEM = "Timeout;
>
> PGM_P ErrorTextTable[2] PROGMEM = {
> et_ERR_NO_ERROR,
> et_ERR_TIMEOUT
> };
>
As you said, this is not the hard part. I think its a case of swings and
roundabouts though. You either have 32-bit pointers or you have fix-up
code. And since its unlikely you'll get the compiler to generate direct
accesses to that far/high memory, you'll need to go via RAM.
My possible solution is as follows:
Put strings in STRING_SECTION (high-memory)
const char et_ERR_NO_ERROR [] STRING_SECTION = "No Error";
const char et_ERR_TIMEOUT [] STRING_SECTION = "Timeout;
Table in PROGMEM
PGM_P ErrorTextTable[2] PROGMEM = {
et_ERR_NO_ERROR,
et_ERR_TIMEOUT
};
#this in the Makefile
STRING_ADDRESS=0x37000
CFLAGS += -DSTRING_ADDRESS=$(STRING_ADDRESS)
LDFLAGS += -Wl,-section-start=.stringsection=$(STRING_ADDRESS)
What happens now, and this may not be safe forever since its
compiler-dependent, is that the addresses in ErrorTextTable are 16-bit.
They are the truncated portion of the full 24-bit address.
Now all that is required is a function to load that string into RAM
(unfortunately) with the fixup applied.
Something like this:
#define STRING_SECTION __attribute__ ((section (".stringsection")))
void load_string(char *dst, const prog_char *src)
{
uint32_t s = (((uint32_t)STRING_ADDRESS & 0xffff0000UL) |
(uint32_t)src);
char ch;
do {
ch = pgm_read_byte_far(s);
*dst++ = ch;
s++;
} while (ch);
}
from code eg.
char buf[20];
load_string(buf, ErrorTextTable[[1]);
I use a variation on this in a boot-loader, so it works. Its just
annoying that the compiler whinges about casting to 32-bit:
"warning: cast from pointer to integer of different size"
Maybe I need to try harder to convince it I know what I'm doing...:-)
> So, in the current code, I have defined two strings in program flash and
> placed pointers to those strings in ErrorTextTable.
>
> I would like to place et_ERR_NO_ERROR and et_ERR_TIMEOUT in high flash
> (easy), BUT I then want to place the index dereferenced from .proghigh
> (where all of these constants are placed) in ErrorTextTable[].
>
> The reason for this request is (I hope) obvious. A good portion my
> strings are accessed through pointer tables (think error text and
> parsing command text). If those pointer tables suddenly go from being
> 2-byte based to 4-byte based (of which the top byte for every entry will
> *always* be zero!), my tables will get significantly bigger.
>
> For the moment, I'm ignoring the problem and using PROGMEM. My flash
> table size is currently around 9 Kbytes, so I have plenty of more room.
> But I'm going to be adding quite a bit more (a logging function was
> requested and I don't eant to store the strings real time in my external
> SRAM), so the problem is looming.
>
> Ideas? Suggestions? I'm open! BTW, this is not a request for code
> (but I'll take it if you have it!), just ideas
>
Hope my suggestions help and maybe spark improvements from someone else.
> Best regards,
>
> Stu Bell
> DPHI, Inc. (DataPlay)
>
>
>
> _______________________________________________
> AVR-libc-dev mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
>
--
This message has been scanned for viruses and
dangerous content by Pinpoint, and is
believed to be clean.