ARMmbed / target-kinetis-k64-gcc

base yotta target description for compiling for the Freescale Kinetis K64 chip family using gcc
Apache License 2.0
1 stars 4 forks source link

Kinetis K64F target clamining RAM to be continuous. #4

Open SeppoTakalo opened 8 years ago

SeppoTakalo commented 8 years ago

Linker map claims K64F have continuous RAM from 0x1FFF0200 to 0x20030000 while there are actually two RAM regions SRAM_L and SRAM_U.

This causes problems when misaligned memory copy happens between these regions, it will cause Hard Fault handler to be called.

Manual is saying:

3.5.3.1 SRAM sizes
This device contains SRAM tightly coupled to the ARM Cortex-M4 core. The on-chip SRAM is split into SRAM_L and SRAM_U regions where the SRAM_L and SRAM_U ranges form a contiguous block in the memory map anchored at address 0x2000_0000. As such:
• SRAM_L is anchored to 0x1FFF_FFFF and occupies the space before this ending address.
• SRAM_U is anchored to 0x2000_0000 and occupies the space after this beginning address.
NOTE
Misaligned accesses across the 0x2000_0000 boundary are not supported in the ARM Cortex-M4 architecture.
SeppoTakalo commented 8 years ago

Quick and dirty fix might be to statically reserve something at the edge between these two regions in linker file, like this:

    .RAM_U_START 0x20000000 :
    {
        BYTE(1);
    } > RAM
kjbracey commented 8 years ago

There may need to be more care taken for dlmalloc, which I believe is currently handed a single contiguous "end of static data to end of RAM" region. Need to consider the cases where static data ends above and below the discontinuity.

ghost commented 8 years ago

I'm fairly sure the quick n dirty fix proposed above:

.RAM_U_START 0x20000000 : { BYTE(1); } > RAM

will not behave as expected, it will simply place the dummy object at the boundary then place all remaining output sections after the dummy object leaving the lower region unused. It would be broadly equivalent to simply dropping the 0x1fff0198-0x20000000 region from the map completely (if there is a trick to making the linker play ball here, please elaborate).

SeppoTakalo commented 8 years ago

Yes, I agree. I'm not a expert on linker scripts, therefore I'm not suggesting to use that "dirty" fix.

Somebody with more knowledge should study how to make the linker to use both regions, but prevent it placing anything in the boundary.

0xc0170 commented 8 years ago

They fixed it in the newer KSDK (where the ld files come from), where there are 2 ram regions. this comes from KSDK 2.0:

MEMORY
{
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400
  m_flash_config        (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000010
  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x000FFBF0
  m_data                (RW)  : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
  m_data_2              (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00030000
}

m_data_2 for the stack and the heap, the lower one for the rest. We might update one day to KSDK 2.0. There's already PR in the mbed SDK, I'll have a look if this ld changes were propagated there.

ghost commented 8 years ago

This form of static allocation of sections to memory regions is perhaps better described as a "workaround". It will be good enough for the majority of users. For some users, particularly those pushing the RAM limit of the board it won;t cut it.

I can't see an alternative solution. The linker won't support:

This issue is particularly painful, because:

The workaround is better than nothing in the short term.

Splitting the region into two and adjusting the the ld script is a straight forward standalone fix, I don;t think we need to conflate this with updating to ksdk2.0 ??

ghost commented 8 years ago

For reference, upstream binutils feature request related to this issue: https://sourceware.org/bugzilla/show_bug.cgi?id=14299

ciarmcom commented 8 years ago

ARM Internal Ref: IOTSFW-2414