avr-libc-dev
[Top][All Lists]
Advanced

[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.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]