Skip to content

Investigate breaking the max sketch size limit #6681

Open
@devyte

Description

@devyte

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • I have filled out all fields below.

Platform

  • Hardware: all
  • Core Version: all relevant (2.5+)
  • Development Env: all
  • Operating System: all

Problem Description

This issue is long term.

The binary size resulting from a sketch build is currently limited to 1MB. This is a hardware limitation in the ESP because it is the max size of code mem that can be mapped from the flash.

Not only is the limitation set to 1MB, but the binary can't span a 1MB address boundary. In our case, our binary is built from two pieces: the bootloader and the sketch itself. The bootloader is loaded to address 0x0, and the sketch is loaded 4K after that (at the time of this writing), which means that our limit is actually 1MB-4KB.

The binary can actually be flashed anywhere, as long as it is fully contained within a 1MB section of the address space, so 0 to 1MB-1, 1MB to 2MB-1, etc. This works because there is a base address register that is loaded, which defines the execution space mapping.

This is issue is meant to track ideas that could work around the limitations.
Some current wild ideas:

  1. Investigate compiling with overlays
    In theory, the linker supports overlays. I don't know what this means, or if it applies to our hardware, but it's the first thing that comes to mind when dealing with a program that is larger than available memory.

  2. Investigate compiler support for bank switching.
    Compilers are known to support bank switching for RAM. Maybe it is possible to do the same for code space. If not, maybe there is something that can be done upstream on gcc side.

  3. Investigate multiple binaries.
    It may be possible to build multiple binaries, and have special mechanisms for calling functions in a different binary than the current one. Possibilities here include N-way calling (any binary to any binary), or hierarchical calling (one binary would be like the master and would call functions in other binaries, which could call in other lower binaries, etc. At simplest implementation the top would be like a master with multiple isolated stand-alone slave binaries)

3a. Wrapper functions
Wrapper functions could switch the register to the base address of the binary to access, call the relevant function, then switch the base address back before returning. At that point execution would continue normally.

3b. GCC instrumentation hooks
GCC supposedly allows hooking code to before a function gets called and code to after a function returns, and that is configurable. I don't know the specifics.

3c. Manual switching
Place the onus of switching on the user, i.e.: the user needs to switch the base address, call a function, and switch back.

In all three cases above, some compiler/linker dark magic would be needed to have the function addresses of a different binary available.

  1. Multiple applications
    The bootloader boots the sketch binary, and then the sketch is oblivious of the bootloader. It may be possible to have multiple applications that "boot each other", where each application is limited to 1MB. I think here the global RAM state would be lost when changing between them, but maybe that can be finessed somehow.
    Example:
  • app1 measures a bunch of sensors and logs into FS. Once per day, it boots into app2.
  • app2 looks at FS, starts wifi, connects to whatever, and uploads the contents of FS. Then it boots back to app1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedHelp needed from the community

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions