Grant Edwards wrote:
On 2007-04-11, [email protected] <[email protected]> wrote:
The latest compiler supports the extended CPU; the problem is
actually in the linker--I can't seem to make it recognise both
chunks of code space (that below and above the vectors).
Below is my original posting. I'm hoping someone knows the
answer now.
Getting the linker to recognise this extra space is easy. Getting it to
work in an easy, intuitive manner is hard.
Firstly, a CPU with a non-contiguous code space is just plain
f&*cked up.
No, it's not - but it *is* and extra headache. There are many
situations in embedded programming where non-contiguous code space is
either desirable, or unavoidable. In the case of the extended MSP430's,
the issue is backwards compatibility. I've also seen several types of
DSP with different blocks of code memory.
As for intentional usage, I have often put parts of my code in ram -
either for performance reasons, or for specific uses (such as flash
programming routines).
Secondly, this is a question for the binutils mailing list.
It's true that he might get some useful help there, but I think most
people on this list would agree that this list covers the gcc toolchain,
including the library, the assembler, and the linker, and people here
are interested in each step of the process. This thread is about the
changes needed to either the linker scripts, the linker itself, or the
compiler, in order to get better support for the new msp430 devices in
the gcc port. The volume on this list is not so high that we need to
avoid binutils topics.
FWIW the linker will "recognize" both segments just fine. The
problem is that it recognizes them as two separate memory
segments (hey, they _are_ two separate memory segments -- blame
TI for that). AFAIK, gnu ld doesn't support non-contiguous
memory segments. [If you want an authoritative answer, ask on
the binutils mailing list.] That means that the linker script
is going to have to tell the linker which modules go in which
"text" segment.
Supporting non-contiguous memory segments in a efficient manner
is an example of the classic "bin packing problem". It's a
combinatorial NP-hard problem. That's why a CPU with
non-contiguous code space is a bad idea.
Yes, that's the problem. When you know what functions or data you want
in the upper half of memory, it's easy - make a new output section in
the linker (called ".text2", for convenience), and put all ".text2"
input sections there. In the C code, use "__attribute__
((section(".text2"))) to force specific items into this section.
Alternatively, you could specify the ".text" section from specific
object files or libraries to be put in the new section.
It is also perfectly feasible to drop the "vectors" from the "memory"
command, and just have a single "text" section covering the entire
flash. The issue then is how to get the "vectors" input section to link
at the specific absolute address of 0xffc0. It's easy enough to link it
there by specifying it in the "sections" command. The trouble is trying
to get the normal ".text" sections to flow around it. As you say, it
doing this optimally is a hard problem, but doing it lazily is not. I
have used other linkers (for other processors) that handle this
reasonably well. When faced with a selection of normal relocatable
input sections and some fixed absolute input sections, the linker starts
by placing the absolute input sections first. Then it places the
relocatable input sections as normal, starting from the top. If an
input section would crash with an absolute section, the location counter
is set to the end of the absolute section and the process continues.
You'll end up with a sub-optimal gap before the absolute section(s), but
so what? In this particular case, there is only the one absolute
section - and if there is too much space taken up, you can always use
-ffunction-sections for finer grained sections.
I don't know whether ld has this functionality or not - I can't see any
way to get it. But the binutils mailing list is definitely the place to
ask for it if this is the way to go.
I have been using msp430-gcc for several years now and have
just started using the MSP430FG4618 with the mspgcc-win32
20070216 distribution. The ld script MEMORY configuration for
this chip looks like this:
MEMORY
{
text (rx) : ORIGIN = 0x3100, LENGTH = 0xcec0
data (rwx) : ORIGIN = 0x1100, LENGTH = 0x2000
vectors (rw) : ORIGIN = 0xffc0 LENGTH = 64
bootloader(rx) : ORIGIN = 0x0c00, LENGTH = 1K
infomem(rx) : ORIGIN = 0x1000, LENGTH = 256
infomemnobits(rx) : ORIGIN = 0x1000, LENGTH = 256
}
Note that the 64 kB of program flash starting at 0x10000 is
not included, so a 116 kB chip appears to only have 52 kB of
code space. I have tried adding another MEMORY definition as
follows:
text2 (rx) : ORIGIN = 0x10000, LENGTH = 0x10000
However, I cannot find any documentation on how to specify
multiple text segments in the SECTIONS definitions.
Currently, the .text section that is mapped with "> text" to
the program flash below the vectors. I have tried ">
text,text2" and "> text and > text2" but of course they are
not proper syntax. I have also tried a single MEMORY text
definition with two origins and two lengths, but the ld syntax
doesn't permit that, either.
Can someone who groks ld enlighten me on how to gain access to
the all of the non-contiguous program flash in the new 'FG46xx
chips?
Again, why would one look to an MSP430 users mailing list for
questions on binutils linker script syntax?