On 13.03.13 22:15, Thomas, George wrote: > 1. If __flash5 is used then for placing the code we get only 0x50000 > to the rest of the flash for storing code (.text) . How can we make use > of the space before in a case where __flash1 - 4 are absent ?
As in all things *nix, allowing a high level of flexibility can sometimes seem to allow a user to shoot himself in the foot. In this case, however, we are only talking about the deliberately omitted flash[1-4] not being used. The first 128 kb is unaffected by the user decision not to use flash[1-4], and remains fully available. (See below) Why might a user deliberately choose to leave flash[1-4] unused? Each __flashN exists only for page alignment with EIND page selection, so it is most effective to use the pages in sequence, since all of memory is then used. If a user chooses to skip lower numbered flashN pages, then we must respect his explicit decision to reserve them for future use. It would violate POLA if we tried to engineer some way to thwart the user's decision, AIUI. Does that, in light of the examples below, make sense to you? Here's how I see the above use case: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 -DP0=0x87ff -DP5=0x10000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx #¹ That puts 10 stubs, plus 0x87ff bytes into the lower 128 kb of flash, chooses to reserve flash[1-4], by using flash5 instead, and populates 0x20000 bytes which do not need to be below 128 kB. $ avr-objdump -h flash.elf flash.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .data 00000000 00800200 00080062 00038a01 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .lowtext 0000890b 00000000 00000000 00000094 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .flash5 00010000 00050000 00050000 0000899f 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .hightext 00020062 00060000 00060000 0001899f 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 4 .stab 00000768 00000000 00000000 00038a04 2**2 CONTENTS, READONLY, DEBUGGING 5 .stabstr 00000054 00000000 00000000 0003916c 2**0 CONTENTS, READONLY, DEBUGGING We can see that the low 128 kB remains fully accessible, flash[1-4] were reserved as desired, and the high text butts up to that last used flashN. All exactly as the user has expressed his wishes. ------------------ However ------------------ If the user finds that his flash[1-4] reservation is no longer needed, then the appropriate flashN page choice allows a fully compacted memory layout choice: $ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10 -DP0=0x87ff -DP1=0x10000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx $ avr-objdump -h flash.elf flash.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .data 00000000 00800200 00040062 00038a01 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .lowtext 0000890b 00000000 00000000 00000094 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .flash1 00010000 00010000 00010000 0000899f 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .hightext 00020062 00020000 00020000 0001899f 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 4 .stab 00000768 00000000 00000000 00038a04 2**2 CONTENTS, READONLY, DEBUGGING 5 .stabstr 00000054 00000000 00000000 0003916c 2**0 CONTENTS, READONLY, DEBUGGING Now .hightext is at the VMA of 0x20000, because the user has removed the deliberate memory hole. > 2. If the linker scripts are made generic (Adding in scripttempl/avr.sc), > can we control the number of flashN sections in the linker scripts as > per the size of flash in the device ? Yes. At first I thought that invoking an illegally high flashN, thereby populating flash which does not exist, would generate an acceptable linker error. But trying the new linker script with e.g.: » MEMORY { text (rx) : ORIGIN = 0, LENGTH = 384K « and -DP3=0x10000, I get: /usr/lib/gcc/avr/4.3.4/../../../avr/bin/ld: flash.elf section `.hightext' will not fit in region `text' /usr/lib/gcc/avr/4.3.4/../../../avr/bin/ld: region `text' overflowed by 98 bytes OK, that is not enormously specific, so we probably want to generate one of our choosing, in the linker script. That shouldn't need device-specific linker script tweaking either. (But we'll have three parts to the error message, because the memory region overflow will still be flagged.) I'll add illegal flashN detection. My (initial) plan is to base it on the size of flash specified. The linker script generically provides for all of the envisaged 5 flashN, and so covers all cases, without spurious memory utilisation penalty. The script automatically snugs .hightext down against the highest flashN populated by the user, avoiding unplanned memory holes. So the error message is all we need, then? ... > Adding my understanding of memx (courtesy : > http://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#AVR%20Named%20Address%20Spaces) > Thank you, I thought that there wasn't much more than that. :-) > The __memx qualifier can be use to load and access variables in 24 bit > address spaces which linearizes flash and RAM. If the high bit of the > address is set, data is read from RAM using the lower two bytes as RAM > address. The loading from flash works by making use of the ELPM > instruction available in AVR. That describes a run-time read-interface to memory, AIUI. It is another view of what is more explicitly described in the linker script, in other terms. > > How it does this ? ... > The sbrc instruction checks if the location is a program memory or RAM. > (checking high bits) That run-time flip pretty much confirms it. ;-) AFAICT, __memx is a linear "integrated compiler view" of the AVR's discrete memory spaces, which does not have any need to manifest itself in the linker script. > Also .progmemx.data is the section the data falls into Hmmm ... a real-world memory model which can use that needs to be described, I think. My problem is that __memx is a linear memory space encompassing _all_ of flash and _all_ of RAM. How then is it envisaged that any data requires a __memx attribute (because all data is already within all of flash and all of RAM), and how can all of flash and all of RAM be represented inside one flash input segment, which is less than, and contained within, _all_??? > (So as per current linker scripts goes in flash) As far as I > understand __memx is a qualifier that is intended to be used primarily > as a pointer to access data rather than to store data. (unification of > RAM and FLASH) AIUI, that is all it can be used for. The new linker script has no memx artifact of any kind, and AFAICT, there is as yet no case for adding any. (Well, that's today's level of awareness.) If there's anything I'm missing, please set the record straight. And if there's anything else we need to add to the linker script ... well I've been waiting a little while now for an excuse to tweak it some more. Thank you for giving it some exercise. The thought you're putting into corner cases and architecture-variability handling are just what's needed, I figure. Erik ¹ For casual readers: flash.sx is Johann's test framework, which he has posted (two versions) in one of the two earlier threads on this topic. -- Blessed is he who expects nothing, for he shall never be disappointed. - Alexander Pope _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list