Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Linker wastes ram

  1. #1
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,345

    Linker wastes ram

    TD wastes some RAM.
    Is there a way to tell the linker not to insert these huge gaps?
    Here is an excerpt from a map file
    Code:
    20000840 B _sbss
    20000840 00000001 b completed.1
    20000844 00000018 b object.0
    2000085c 00000004 B scale_cpu_cycles_to_microseconds
    20000860 00000004 B systick_cycle_count
    20000864 00000004 B systick_millis_count
    20000868 00000004 B systick_safe_read
    20000c00 000002c0 B _VectorsRam
    20000ec0 00000001 B external_psram_size
    20000ec4 00000010 B extmem_smalloc_pool
    20000ed4 00000004 b s_hotCount
    20000ed8 00000004 b s_hotTemp
    20000edc 00000004 b s_hot_ROOM
    20000ee0 00000004 b s_roomC_hotC
    20000ee4 00000008 b endpoint0_buffer
    20000eec 00000004 b endpoint0_notify_mask
    20000ef0 00000008 b endpoint0_setupdata
    20000f00 00000020 B endpoint0_transfer_ack
    20000f20 00000020 B endpoint0_transfer_data
    20000f40 00000004 b endpointN_notify_mask
    20001000 00000280 B endpoint_queue_head
    20001280 00000008 b reply_buffer
    20001288 00000001 b sof_usage
    20001289 00000001 B usb_configuration
    2000128a 00000001 B usb_high_speed
    2000128b 00000001 b usb_reboot_timer
    2000128c 00000004 B usb_timer0_callback
    20001290 00000004 B usb_timer1_callback
    20001294 00000004 b rx_available
    20001298 00000010 b rx_count
    200012a8 00000001 b rx_head
    200012ac 00000010 b rx_index
    200012bc 00000009 b rx_list
    200012c6 00000002 b rx_packet_size
    200012c8 00000001 b rx_tail
    200012e0 00000100 b rx_transfer
    200013e0 00000002 b tx_available
    200013e2 00000001 b tx_head
    200013e3 00000001 b tx_noautoflush
    200013e4 00000002 b tx_packet_size
    20001400 00000080 b tx_transfer
    20001480 00000008 B usb_cdc_line_coding
    20001488 00000001 B usb_cdc_line_rtsdtr
    2000148c 00000004 B usb_cdc_line_rtsdtr_millis
    20001490 00000004 B EventResponder::firstYield
    20001494 00000004 B EventResponder::lastInterrupt
    20001498 00000004 B EventResponder::firstInterrupt
    2000149c 00000001 B EventResponder::runningFromYield
    200014a0 00000004 B EventResponder::lastYield
    200014a4 00000001 b yield::running
    200014a5 00000001 b calibrating
    200014a8 00000020 B HardwareSerial::s_serials_with_serial_events
    200014c8 00000001 B HardwareSerial::s_count_serials_with_serial_events
    20001500 B _ebss
    And this is just "blink" - and only the worst are marked red. The first marked is almost 1 kB!

    also, something like this:
    Code:
    20001298 00000010 b rx_count
    200012a8 00000001 b rx_head
    200012ac 00000010 b rx_index
    is pretty inefficient (paces a 1-bytes variabale between larger ones that are aligned) And would work better if the default "sort by size" would do its job..(sorting seems to be disabled somewhere, or does not work for a unknown reason)
    Ok, you could make extra sections for the vectors etc, but this is no general solution.
    Is there any way to tell the linker to do it smarter and sort it?
    The known "fix" to add "-fno-common" to gcc seems not to help.

    Edit: Note, this was with GCC10, but the 5.4 is not much different.
    Edit: No, I don't believe this is a bug in GCC/LD - Looks more like wrong usage by Teensyduino.
    Last edited by Frank B; 08-16-2021 at 11:38 AM.

  2. #2
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,075
    This doesn't help?

    -fno-common -fdata-sections -Wl,--sort-section=alignment

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,345
    Not really (or i have a mistake somewhere)
    Code:
    20001000 00000280 B endpoint_queue_head
    20001400 000002c0 B _VectorsRam
    [...]
    Code:
    20001880 00000008 b endpoint0_setupdata
    20001888 00000001 b completed.1
    2000188c 00000018 b object.0
    200018a4 00000004 B scale_cpu_cycles_to_microseconds
    also, it sorts by alignment. not sure wether this is correct (is it, perhaps?) .. i know, some vars (like Vectors) need a special, huge alignment.

    Overall, it is even worse for blink with gcc10 and needs a kB more.
    Last edited by Frank B; 08-16-2021 at 02:05 PM.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,088
    I've been intending to someday try "--sort-section=alignment".

    Here's my best guess for editing boards.txt

    Code:
    teensy41.build.flags.ld=-Wl,--gc-sections,--relax,--sort-section=alignment "-T{build.core.path}/imxrt1062_t41.ld"
    If anyone tries this, please let me know it if makes a worthwhile improvement? And do programs still work properly?

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,345
    Yes, it is worse (for blink & gcc 10) (and with -fno-common added)

    Not sure.. would'nt be a sort by size (with consideration of special alignments) more efficient? <- have to think about that...
    And, I thought, sort by size was the default?
    Anyway, as soon we have huge alignments, it is not that easy And simple sorting is not smart enough. The gaps could be filled, which, with simple sorting, can not be archieved.
    I'd guess a gcc in 2021 can be smarter..
    Last edited by Frank B; 08-16-2021 at 02:23 PM.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,110
    Funny that 920 byte gap:
    Code:
    20000868 00000004 B systick_safe_read
    20000c00 000002c0 B _VectorsRam
    Comes from the micros() use of :: __LDREXW(&systick_safe_read);

    Maybe there is a better way to express that, or maybe that has special support requirements?

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,345
    Quote Originally Posted by defragster View Post
    Funny that 920 byte gap:
    Code:
    20000868 00000004 B systick_safe_read
    20000c00 000002c0 B _VectorsRam
    Comes from the micros() use of :: __LDREXW(&systick_safe_read);

    Maybe there is a better way to express that, or maybe that has special support requirements?
    That's due to the required 1024 byte alignment of _VectorsRam. But yes, the systick variable could be placed elsewhere. It doesn't need to be a global variable and can be on the stack.
    Last edited by Frank B; 08-16-2021 at 07:07 PM.

  8. #8
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,345
    With using
    Code:
    void (* volatile _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void) = {unused_interrupt_vector};
    _VectorsRam will be in the data section and, starts at 0x200000 (perhaps by accident ; - its the first var in the program in ".data")
    This is a little bit better. Still there is a var (endpoint_queue_head) which is aligned (4096).. the both together are the problem.

    i'd suggest an own section for _VectorsRam at the start of .data
    Last edited by Frank B; 08-17-2021 at 09:19 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •