Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reserve memory for system-part1 SRAM #1742

Merged
merged 6 commits into from May 16, 2019

Conversation

@sergeuz
Copy link
Member

commented Apr 2, 2019

Problem

On the Photon, the size of the static RAM (SRAM) allocated for system-part1 is only 768 bytes, which is not enough to build Device OS with newer versions of GCC (5.4.x – 8.2.x): #1159 (comment).

The user part's SRAM is located immediately after the system-part1 SRAM, so the size of the latter region cannot be increased without breaking the backward compatibility:

Photon                                  Electron
+-------------------+ 0x20000000        +-------------------+ 0x20000000
| system-part1 SRAM |                   | system-part1 SRAM |
+-------------------+ 0x20000300        +-------------------+ 0x20000400
| user-part SRAM    |                   | user-part SRAM    |
+~~~~~~~~~~~~~~~~~~~+                   +~~~~~~~~~~~~~~~~~~~+
|                   |                   |                   |
|                   |                   | Heap              |
| Heap              |                   |                   |
|                   |                   +-------------------+ 0x2001c000
|                   |                   | system-part3 SRAM |
+-------------------+ 0x20014800        +-------------------+ 0x2001d000
| system-part2 SRAM |                   | system-part2 SRAM |
+-------------------+ 0x2001f000        +-------------------+ 0x2001f000
| Initial stack     |                   | Initial stack     |
+-------------------+ 0x20020000        +-------------------+ 0x20020000

Solution

The only viable option we have is to move the system-part1 SRAM to another location. This should be done in two steps:

  1. Make necessary changes in Device OS 1.2.0 to allow for relocation of the system-part1 SRAM in a later release.

  2. Relocate the system-part1 SRAM in Device OS 1.3.0, increase its size and make 1.2.0 a mandatory intermediate release (this can be done via our regular module dependencies mechanism).

    On the Electron, we'd also like to relocate the system-part3 SRAM and put it immediately below the relocated system-part1 SRAM in Device OS 1.3.0. This would allow us to resize SRAM regions as necessary in the scope of a single OTA update in future releases.

This PR implements the first step of the process by making module_system_part3_pre_init() on Electron and module_system_part1_pre_init() on Photon return start addresses of the corresponding SRAM regions. If the system detects that the module version of system-part3 on Electron or system-part1 on Photon is greater than or equal to 1320 it will use the start address of the corresponding SRAM region as the end address of the heap.

As a result, the memory map in Device OS 1.3.0 will look as follows:

Photon                                  Electron
+-------------------+ 0x20000000        +-------------------+ 0x20000000
| user-part SRAM    |                   | user-part SRAM    |
+~~~~~~~~~~~~~~~~~~~+                   +~~~~~~~~~~~~~~~~~~~+
|                   |                   |                   |
|                   |                   | Heap              |
| Heap              |                   |                   |
|                   |                   +-------------------+ 0x2001ba00
|                   |                   | system-part3 SRAM |
+-------------------+ 0x20014200        +-------------------+ 0x2001ca00
| system-part1 SRAM |                   | system-part1 SRAM |
+-------------------+ 0x20014800        +-------------------+ 0x2001d000
| system-part2 SRAM |                   | system-part2 SRAM |
+-------------------+ 0x2001f000        +-------------------+ 0x2001f000
| Initial stack     |                   | Initial stack     |
+-------------------+ 0x20020000        +-------------------+ 0x20020000

Steps to Test

Note: The steps below use our internal system part numbering scheme.

  1. Build and flash this PR along with the following app to a Photon and an Electron:
#include "application.h"

SYSTEM_MODE(SEMI_AUTOMATIC)

namespace {

const Serial1LogHandler logHandler(115200, LOG_LEVEL_WARN, {
    { "app", LOG_LEVEL_ALL }
});

} // namespace

void setup() {
    LOG(INFO, "Free memory: %u", (unsigned)System.freeMemory());
}

void loop() {
}
  1. Electron, Photon: Run the app and take a note of the reported free heap memory.

  2. Electron, Photon: Apply this patch (git am < patch.txt) and rebuild the firmware. The patch bumps the module versions and relocates the SRAM regions as shown on the diagram in the previous section.

  3. Electron: flash system-part3 via DFU and reset the device. Verify that the amount of free memory has decreased by exactly 1.5K. At this point, the memory map looks as follows:

Electron
+-------------------+ 0x20000000
| system-part1 SRAM |
+-------------------+ 0x20000400
| user-part SRAM    |
+~~~~~~~~~~~~~~~~~~~+
|                   |
| Heap              |
|                   |
+-------------------+ 0x2001ba00
| system-part3 SRAM |
+-------------------+ 0x2001ca00
| Unused            |
+-------------------+ 0x2001d000
| system-part2 SRAM |
+-------------------+ 0x2001f000
| Initial stack     |
+-------------------+ 0x20020000
  1. Electron, Photon: flash system-part1 via DFU and reset the device. Photon: Verify that the amount of free memory has decreased by exactly 1.5K. At this point, the memory map looks as follows:
Photon                                  Electron
+-------------------+ 0x20000000        +-------------------+ 0x20000000
| Unused            |                   | Unused            |
+-------------------+ 0x20000300        +-------------------+ 0x20000400
| user-part SRAM    |                   | user-part SRAM    |
+~~~~~~~~~~~~~~~~~~~+                   +~~~~~~~~~~~~~~~~~~~+
|                   |                   |                   |
|                   |                   | Heap              |
| Heap              |                   |                   |
|                   |                   +-------------------+ 0x2001ba00
|                   |                   | system-part3 SRAM |
+-------------------+ 0x20014200        +-------------------+ 0x2001ca00
| system-part1 SRAM |                   | system-part1 SRAM |
+-------------------+ 0x20014800        +-------------------+ 0x2001d000
| system-part2 SRAM |                   | system-part2 SRAM |
+-------------------+ 0x2001f000        +-------------------+ 0x2001f000
| Initial stack     |                   | Initial stack     |
+-------------------+ 0x20020000        +-------------------+ 0x20020000
  1. Electron, Photon: Flash system-part2 and user-part via DFU. Verify that the application reclaimed the unused space shown on the above diagram (1K on Electron and 768 bytes on Photon).

  2. Electron, Photon: Revert the patch, rebuild the firmware and flash it to the device along with the tinker application. Perform an OTA update to the patched firmware. Verify the results with particle serial inspect (the reported module versions should all be 1300).

  3. Electron, Photon: Downgrade to the original firmware OTA, flashing the modules in the reverse order. Verify the results with particle serial inspect.

References

  • [ch30182]

  • [enhancement] Reserve memory for system-part1 SRAM #1742

@sergeuz sergeuz added this to the 1.1.0-rc.1 milestone Apr 2, 2019

@sergeuz sergeuz requested review from avtolstoy and m-mcgowan Apr 2, 2019

@sergeuz

This comment has been minimized.

Copy link
Member Author

commented Apr 2, 2019

This PR also fixes various discrepancies in the linker files for Electron

@sergeuz sergeuz force-pushed the feature/reserve_part1_sram branch from 87002a8 to c968d7c Apr 3, 2019

@sergeuz sergeuz removed this from the 1.1.0-rc.1 milestone Apr 8, 2019

@technobly technobly added this to the 1.2.0-beta.1 milestone Apr 9, 2019

@sergeuz sergeuz force-pushed the feature/reserve_part1_sram branch from c968d7c to a1974e2 May 8, 2019

@technobly technobly modified the milestones: 1.2.0-beta.1, 1.2.0-rc.1 May 10, 2019

@avtolstoy
Copy link
Member

left a comment

👏

P.S. I don't know about others, but I find the diagrams slightly hard to read when the addresses don't go from bottom to the top 😏

*/
SRAM (rwx) : ORIGIN = 0x20020000-6K-10K, LENGTH = 6K
SRAM (rwx) : ORIGIN = 0x20020000-12K-4K, LENGTH = 4K

This comment has been minimized.

Copy link
@m-mcgowan

m-mcgowan May 16, 2019

Contributor

Was the length incorrect before?

This comment has been minimized.

Copy link
@sergeuz

sergeuz May 16, 2019

Author Member

Yes, it was overlapping with the system-part2 SRAM previously:

SRAM (rwx) : ORIGIN = 0x20020000 - 12K, LENGTH = 12K

user_module_sram_origin = 0x20000400;
user_module_sram_length = 0x20000 - 0x400 - 16K - 2K;
user_module_sram_length = 0x20000 - 0x400 - 12K - 4K;

This comment has been minimized.

Copy link
@m-mcgowan

m-mcgowan May 16, 2019

Contributor

rather than using repeated constants, can we introduce symbols for these?

This comment has been minimized.

Copy link
@sergeuz

sergeuz May 16, 2019

Author Member

I didn't want to overhaul the linker files in the scope of this PR. This is not the only place where we're using the same constants repeatedly, and I'd prefer to fix all such occurrences separately

@monkbroc

This comment has been minimized.

Copy link
Member

commented May 16, 2019

Does this mean that we need to add a special case to safe mode healer for the upgrade from Device OS < 1.2.0 to 1.3.0 to go through 1.2.0 first?

This was the case when upgrading Photon from < 0.7.0 to later version. It flashes 0.7.0 first, then the target version.

@sergeuz

This comment has been minimized.

Copy link
Member Author

commented May 16, 2019

Does this mean that we need to add a special case to safe mode healer for the upgrade from Device OS < 1.2.0 to 1.3.0 to go through 1.2.0 first?

AFAIK, this can be done using the Device OS' module dependencies alone by making system-part1 dependent on a specific minimum version of system-part2. We did that to switch to a compressed WiFi blob firmware in 0.8.x:

ifneq (,$(filter $(PLATFORM_ID),6 8))

@sergeuz sergeuz force-pushed the feature/reserve_part1_sram branch from d60a0a2 to fff6176 May 16, 2019

@sergeuz sergeuz merged commit 48e476f into develop May 16, 2019

1 check passed

continuous-integration/travis-ci/push The Travis CI build passed
Details

@sergeuz sergeuz deleted the feature/reserve_part1_sram branch May 16, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.