Given that what you're doing is highly HIGHLY representation-specific,
assembly language is probably the most direct and reliable approach. There
might be a gcc __attribute__ hack to help, but then you'd be just trading
assembly language for something compiler-specific AND
representation-specific.

It's inevitable that when data spills over into a memory space with a
different access schema, a C compiler goes nuts: the machine abstraction
that C is defined around supports no such concept. That's doubly so for a
general-purpose compiler like gcc, where exceptions to those rules all have
to be dealt with outside the compiler's main workflow.

b.g.


On Thu, Aug 31, 2017 at 1:14 PM Bob Paddock <[email protected]>
wrote:

> Not sure if your issue is the related to this one?:
>
> https://lists.nongnu.org/archive/html/avr-libc-dev/2010-09/msg00046.html
>
> As Bob Paddock wrote:
>
> > From the error that I'm getting, below, I belive that __data_load_end
> > is only 16 bits wide?
>
> No, obviously it's wider:
>
>  0x0003c370   __data_load_start = LOADADDR (.data)
>  0x0003c378   __data_load_end = (__data_load_start + SIZEOF (.data))
>
> (That's from a map file.)
>
> Note that the linker has no notion of what C knows as a "type".  It
> only has symbols.
>
> >   uint16_t flash_end_u16 = (uint16_t) &(__data_load_end[0]);
>
> Your problem is that the & operator makes a pointer out of something
> else, and pointers in AVR-GCC are fixed to 16 bits in size.  You have
> to avoid turning the large integer __data_load_end actually is into a
> pointer (syntactically).  I couldn't find any way using C syntax for
> this, unless resorting straight to assembly:
>
> static inline uint32_t get_data_load_end(void)
> {
>   uint32_t tmp;
>
>   asm volatile("ldi %A0, lo8(__data_load_end)" "\n"
>                "ldi %B0, hi8(__data_load_end)" "\n"
>                "ldi %C0, hlo8(__data_load_end)" "\n"
>                "ldi %D0, hhi8(__data_load_end)"
>                : "=r"(tmp));
>   return tmp;
> }
>
>
>
> On Fri, Aug 25, 2017 at 5:02 AM, Bob von Knobloch <[email protected]>
> wrote:
> > Hi,
> > I'm rewriting a project I originally had running on a ATMega 644.
> > Now I need more space, so an ATMega 1284 is my choice.
> > I need to have a very large amount of constant data in flash (more than
> fits
> > under the 64k address range).
> > My problem is that I must get the address of some constants in high
> (above
> > 0x10000) memory and here the 'address of' a char[] does not return the
> right
> > value.
> >
> > Example:
> > I have string constant 'mystring' at address  0x11808 (can see it in the
> > .map and .lst files). Using 'print_func(mystring);', which should print
> this
> > address, albeit truncated to 16bits, returns '0x1e57'. I cannot see a
> > connection here.
> > Anyone tried to do similar things?
> >
> > Regards,
> >
> > Bob von Knobloch
> > --
> > The Sun is out, the sky is blue, it's time to drive the MR2.
> >
> > _______________________________________________
> > AVR-chat mailing list
> > [email protected]
> > https://lists.nongnu.org/mailman/listinfo/avr-chat
>
> _______________________________________________
> AVR-chat mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/avr-chat
>
-- 

Bill Gatliff
Embedded Linux training and consulting
[email protected]
(309) 453-3421
_______________________________________________
AVR-chat mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avr-chat

Reply via email to