This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I am very interested in the gcc port for MSP430 and its integration in CCSv6. I am very glad about the effort done by TI (and RedHat) to offer this opensource and free development option.
However, I have some issues with the code placement in ROM
Release notes of the 4.9 (fist production) version states:
But linker scripts provided with CCSv6 (and the ones downloadables at the TI GCC MSP page) are configured only to use the lowest ROM memory region. I have been able to manually place code in the far region by modifying these files, for example like this (and of course using the -mlarge flag when compiling and linking):
/* This is just for crt0.S and interrupt handlers. */
.lowtext :
{
PROVIDE (_start = .);
. = ALIGN(2);
KEEP (*(SORT(.crt_*)))
KEEP (*(.lowtext))
} > ROM
.lower.text :
{
. = ALIGN(2);
*(.lower.text.* .lower.text)
} > ROM
.text :
{
. = ALIGN(2);
*(.text .stub .text.* .gnu.linkonce.t.* .text:*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.interp .hash .dynsym .dynstr .gnu.version*)
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(2);
KEEP (*(.init))
KEEP (*(.fini))
KEEP (*(.tm_clone_table))
} > FAR_ROM
However this places almost all code in far ROM region, except for the interrupt subroutines and some other (few) functions. This is not optimal, since a significant amount of Flash is in the low address space and would be wasted.
Of course, I can manually place code in the low rom by using the section attribute, but I would prefer the linker to automatically split the code bewteen the two region, as hinted in the release notes, so I do not have to manually state where each function is placed.
Is this possible? If so, How? I have not been able to figure it out so far.
Regards, and Thank you,
Jose
Automatic code splitting requires a completely different strategy that what the existing linkers used before.
For optimum linking, this would require a multi-pass linking process, while the current algorithms are one-pass straight.
What happens if low flash is full and there comes an ISR? And if low flash is reserved for ISRs, then what if there comes none? (your “wasted space”)
Best strategy without a complete rewrite of the linking algorithms would be placing all code into far flash except for ISRs and constant data (if small data model is active).
An improved version could place normal code in low flash when far flash is full. However, this again can lead to situations where the could would fit but due to the order in which it appears to the linker, it doesn’t fit, leaving two holes that would together be large enough, but aren’t one alone.
It’s easy to forget that things that seem so simple for a human, are really difficult to explain to a linear-working machine.
Thank you for your reply.
I am not talking about fully optimizing the code split between two region, I am just talking about using both flash regions to store the generated program code without having to do so manually (of course some gap could be still wasted at the end of the low rom region, but not almos all the low rom region). Both IAR and CCS's TI compiler for MSP430 perform this, when the code is big enough, some subroutines are automatically placed in low rom whereas others are placed in the high rom, thus using (almost) all the available program memory. This is what I meant in my previous post, sorry if I did not explain myself clearly.
Of course GCC is an opensource and license free tool andI appreciate all the effort TI and RedHat (and other contributors) have been doing to provide us with such a tool, for free. For me, free use of the tool is a very important feature, and I perfectily understand that we must accept it will probably lack some features that alternative commercial tools have.
However, the Release notes of the 4.9 version of MSP GCC specifically mention "Support for intelligently splitting code and data between low and high memory" as one of the added features. I am just wondering if this feature has been actualy added (As I said, I would understand it is still not supported, but I just would like to know), and if it is indeed supported, how can it be activated, since apparently it does not work.
The patch for the linker script I provided above, exactly implements your first suggestion, place all code into far flash except for ISRs and constant data (and variable data initialization). This is the best result I have achieved so far, but If your project does not include much constant data or ISR code, a significant amount of the low rom/flash is still wasted. What I was asking for is what you define as an "improved version" that could place normal code in low flash when far flash is full. This I think is which CCS and IAR are capable of doing, but I have not managed to configure GCC to do it, and I am not even sure if it can.
Regards, and thank you again for your great effort.
Jose
I am curious as to the answer for this as well. I understand the linker script challenges, just ... wonder what TI means by "intelligently splitting code" as a new feature :) If it's just something we need to light up with a few linker script "hints", that would be awesome!
I didn’t know that this “intelligently splitting code” support has been announced as added. In this case, one would expect it to be working (even if still buggy) and there should be hints on how to enable/use it.
However, your existing and apparently working solution doesn’t “waste” more flash than the ‘improved’ version, as long as all code fits into upper memory: it makes no difference whether the remaining unused flash is in upper or lower memory.
The only problem is when code is larger than upper memory. Then the ‘improved’ version would be necessary for automatic placement. Well, in this case, one can easily put some selected functions into lower memory by hand. Not too much effort, I’d say. Just less convenient. But should do until it is finally solved in the linker.
Many years ago, at times of DOS, there was the problem of conventional and upper memory too. Drivers could be loaded low or high (and low memory was needed for applications). The challenge was to pack as many drivers into upper memory. Worse, the drivers often needed more memory when being launched than they needed after initialization.
There was a commercial product called QEMM386 (an EMS virtual memory driver) that came with an analyzer tool. It did boot the PC several times while measuring the space each driver needed for launching and after initialization, then reordered driver loading, to get the drivers optimally packed into upper memory. Quite a time-consuming process, but worth the effort.
Well, if the increased link time for multiple passes is not an issue, it should be not a big problem to implement this. Especially as the size of each code block is static. It’s not a new problem and has been solved before.
Apparently Redhat has already committed patches to gcc, newlib and so on, to get it working.
See this thread: https://sourceware.org/ml/newlib/2015/msg00466.html
@TI, when will this be available in Code Composer Studio?
I don’t know if the question still is how to split code over two or more Sections, then this can be done by;
Chance “} > FAR_ROM” to “} > ROM | FAR_ROM” and the compiler will first fill ‘ROM’ and the remainder to ‘FAR_ROM’ with ‘.text’. Does this not work with GCC?
Optional use ‘>>’ to create a contiguous Section, if possible.
**Attention** This is a public forum