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
