Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 50

Thread: How to get a little bit more FLASH room on Teensy 3.x

  1. #1
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527

    Cool How to get a little bit more FLASH room on Teensy 3.x

    Here is the compile results of the Blink example using the Arduino IDE with teensyduino installed:
    Code:
       text    data     bss     dec     hex filename
      12776    1460    1992   16228    3f64 /tmp/build9046952037514765870.tmp/Blink.cpp.elf
    Can we do better? Yes we can!

    Code:
       text    data     bss     dec     hex filename
       5568     164    1444    7176    1c08 build/Blink.elf
    How is this possible? It all has to do with updating one set of tools, and linking things properly.
    Basically there are a whole bunch of variables, unused routines, and even unused code sections linked into your program, even though the linker is told to throw them out, because they were explicitly contained in the object files linked. Hopefully Paul will fix this in the future...

    1: You will need to recompile your tools and install them over the top of your install. You can get it here: https://github.com/xxxajk/ARM-Toolchain

    2: install this where you have your sketches (see the readme) https://github.com/xxxajk/Arduino_Makefile_master

    3: Use create a Makefile containing the following, and change BOARD to teensy3 if you are using that.:
    Code:
    BOARD = teensy31
    
    # set your Arduino tty port here
    PORT = /dev/ttyACM0
    
    # And finally, the part that brings everything together for you.
    include ../Arduino_Makefile_master/_Makefile.master
    then type make and you can see the results for your self.

    Note: This has been tested on Linux, will be tested on MacOS fairly soon, and should work on Windows if you got Cygwin installed.

  2. #2
    Junior Member
    Join Date
    Aug 2013
    Posts
    7
    Mac (10.9) has a few occurences of 'head' utility called with incompatible parameters (easily fixable) but then on my machine I get a segfault from arm-none-eabi-objdump and arm-none-eabi-c++filt (among last commands issued). Will spend some time on it.

  3. #3
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    A 40% reduction in code size. But the app blinky.cpp is tiny though dragging a big train of code with it. Such is modern computing.
    What would the reduction be for a project with, say, 50KB of application code, rather than tiny blinky.cpp plus all the fixed overhead of the large quantity of dead and n/a code?

    I guess some of this is the Arduino philosophy - no library management to help the linker omit n/a code.
    Last edited by stevech; 02-26-2014 at 04:36 PM.

  4. #4
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    No, the problem is that Paul has all the .o files linking in explicitly, instead of ld looking for what it actually needs.
    This results in alot of unused variables and code linking in.
    Please see here as to the full explanation: https://github.com/xxxajk/Arduino_Ma...ster#L696-L727

  5. #5
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Quote Originally Posted by riotwing View Post
    Mac (10.9) has a few occurences of 'head' utility called with incompatible parameters (easily fixable) but then on my machine I get a segfault from arm-none-eabi-objdump and arm-none-eabi-c++filt (among last commands issued). Will spend some time on it.
    Did you recompile your binutils?

  6. #6
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Quote Originally Posted by xxxajk View Post
    No, the problem is that ... all the .o files [are] linking in explicitly, instead of ld looking for what it actually needs.
    This results in alot of unused variables and code linking in.
    Please see here as to the full explanation: https://github.com/xxxajk/Arduino_Ma...ster#L696-L727
    Doesn't the linker automatically check to see if the .o is needed by looking at symbols/functions referenced?

  7. #7
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Quote Originally Posted by stevech View Post
    Doesn't the linker automatically check to see if the .o is needed by looking at symbols/functions referenced?
    Not if it is explicitly told to link in a .o file. Searches are done on AR files, which are libraries, not on .o files.

    The whole reason to list a file to explicitly link, is that you want the something from that to end up in the binary, because you expect to be referencing something from it, or to it.

    Example:
    The .o file contains, a bitmap of a picture, and a routine that does something with that information, or has a pointer to it.
    If you were to include it as a .o, and never reference it from your program, you will find that it is in your binary, because something referenced it.
    It doesn't see that you don't actually USE it. This is not a bug, it is a feature. How else would start up code, or main end up in the program?

    Now, if this is in an AR file...
    Since it isn't asked for to begin with, the picture and code or pointer won't end up in your program code because there is no reference to begin with.
    That is why we use libraries.

    To recap:
    Object files include code and data almost always. There are a few exceptions, but there is no need to go into those details.
    Libraries only include the minimum required pieces of code and data needed for your program. If you don't ask for something, it won't appear in your program.

  8. #8
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    2,995
    Quote Originally Posted by stevech View Post
    Doesn't the linker automatically check to see if the .o is needed by looking at symbols/functions referenced?
    Not for .o files by default. It does do this for static archives (.a files).

    Even if the linker did this, you would still get extra code if you have multiple functions in a single object file, and only a few functions are used.

    If you compile code with -ffunctions-sections and -fdata-sections, and then pass --gc-sections to the linker (usually via the option -Wl,--gc-sections when using the GCC driver), then the compiler will compile each function and global data to a different ELF section, and the linker will delete sections that have no references in the final output.

  9. #9
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Quote Originally Posted by MichaelMeissner View Post
    Not for .o files by default. It does do this for static archives (.a files).

    Even if the linker did this, you would still get extra code if you have multiple functions in a single object file, and only a few functions are used.

    If you compile code with -ffunctions-sections and -fdata-sections, and then pass --gc-sections to the linker (usually via the option -Wl,--gc-sections when using the GCC driver), then the compiler will compile each function and global data to a different ELF section, and the linker will delete sections that have no references in the final output.
    Yes, however there are a few cases within the teensy3 core code where stuff that isn't used is still actually referenced.
    The idea is to just not reference them in the first place, and let ld do the right thing.

    Edit:
    Example, Blink does not reference Serial, but this will end up in the program if you tell the IDE you want to be a serial device.
    Using an AR archive, Serial, and the buffers for it will not end up in the final output.
    Last edited by xxxajk; 02-26-2014 at 11:52 PM. Reason: Add corner case

  10. #10
    Junior Member
    Join Date
    Aug 2013
    Posts
    7
    Quote Originally Posted by xxxajk View Post
    Did you recompile your binutils?
    No actually, I just downloaded gcc-arm-embedded (to check on nanospecs and code reduction) from launchpad. I haven't spent much time on it so I can't remember if I used the toolchain from teensyduino. Will give it another go this weekend.

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,173
    Quote Originally Posted by xxxajk View Post
    No, the problem is that Paul has all the .o files linking in explicitly, instead of ld looking for what it actually needs.
    This results in alot of unused variables and code linking in.
    Yeah. Early on, sometime in August 2012, I was having trouble getting the core.a stuff to work, so I just switched to linking all the .o files to "solve" the problem. It's remained that way ever since.

    I really ought to update this in 1.19 or 1.20....

  12. #12
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Quote Originally Posted by PaulStoffregen View Post
    I really ought to update this in 1.19 or 1.20....
    Yes... it would be good to bubble this higher in the TODO list.

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,173
    Quote Originally Posted by stevech View Post
    Yes... it would be good to bubble this higher in the TODO list.
    Do you feel it should come before or after CAN bus support?

  14. #14
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Paul: All you have to do is consider the mk20dx128.o file as a crt.o...
    This is the only one to link explicitly from core, and make sure it is first in the list, and it won't matter if you redundantly include it in the AR.
    Considering it can reduce flash size, and reduces RAM usage, I think this should be before anything new, besides, the fix is very simple.

  15. #15
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Paul: One other note about doing things this way... It eliminates problems with overriding functions.
    The usual AR linking goes like this: Functions get picked from user code, then the libraries, and finally core-- you list the ARs in that order.
    This is how the normal build system works, and it makes sense... It allows user code to trump everything, and 'libraries' to trump anything in the core.
    IMHO it is one of the few things the Arduino people got right.

  16. #16
    Junior Member
    Join Date
    Aug 2013
    Posts
    7
    Quote Originally Posted by riotwing View Post
    No actually, I just downloaded gcc-arm-embedded (to check on nanospecs and code reduction) from launchpad. I haven't spent much time on it so I can't remember if I used the toolchain from teensyduino. Will give it another go this weekend.
    Ok following up I get the segfault with the toolchain installed by Teensyduino, gcc-arm-embedded doesn't have arm_cortexM4l_math.a

    Need to spend some time on it but no time until tomorrow.

  17. #17
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,173
    Quote Originally Posted by xxxajk View Post
    I think this should be before anything new, besides, the fix is very simple.
    Any fiddling with the java-based Arduino IDE build is hardly simple.

  18. #18
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    I know java... Mind if I help?

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,173
    Quote Originally Posted by xxxajk View Post
    I know java... Mind if I help?
    Just grab the Arduino IDE 1.0.5 source code, and replace the .java files with the copies in the "src" folder the installer creates in your copy of Arduino. Edit the java code and rebuild the IDE. Copy PDE.JAR from the freshly compiled IDE into the copy with Teensyduino installed and restart.

  20. #20
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Perfect! I'll either get a chance tonight or this weekend to do this.

  21. #21
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Took a quick look at the code... and, I think I can do this using the prefrences file (boards.txt) directly. :-) Details soon.

  22. #22
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Okay, the IDE does a few stupid things, formatting is total hell to look at, but I got a fix. It is all of 4 lines of code, and 2 edits to boards.
    Have to fetch, build IDE and it should work out just fine.

  23. #23
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    Here we go...

    boards.txt and Compiler.java.txt

    Had to add the txt extension for it to be accepted, but I think you can figure that out ;-)

    Enjoy your smaller output :-)

    Binary sketch size: 5,464 bytes (of a 262,144 byte maximum)
    Estimated memory use: 1,616 bytes (of a 65,536 byte maximum)
    Last edited by xxxajk; 03-01-2014 at 03:35 AM.

  24. #24
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Quote Originally Posted by xxxajk View Post
    Here we go...

    boards.txt and Compiler.java.txt

    Had to add the txt extension for it to be accepted, but I think you can figure that out ;-)

    Enjoy your smaller output :-)

    Binary sketch size: 5,464 bytes (of a 262,144 byte maximum)
    Estimated memory use: 1,616 bytes (of a 65,536 byte maximum)
    Some instructions please, for replicating what you've done... for we mindless folks?

  25. #25
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    First, get boards.txt from the above post, and decompress this file pde.zip

    Next make a backup of pde.jar and boards.txt, just in case things don't work out for you.
    Then copy the new pde.jar and boards.txt where they belong.

    On my system these files are located at
    /opt/Arduino/lib
    and
    /opt/Arduino/hardware/teensy

    Not knowing where your install is, or what operating system you use, that is the best instructions I can give you,
    If this is too much for you then wait for Paul to make a test installer for you.

Tags for this Thread

Posting Permissions

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