Skip to content

cpu/saml21: Make Low-Power SRAM available to programs#11486

Merged
dylad merged 6 commits intoRIOT-OS:masterfrom
benpicco:saml21-lpram
Oct 1, 2019
Merged

cpu/saml21: Make Low-Power SRAM available to programs#11486
dylad merged 6 commits intoRIOT-OS:masterfrom
benpicco:saml21-lpram

Conversation

@benpicco
Copy link
Copy Markdown
Contributor

@benpicco benpicco commented May 3, 2019

Contribution description

SAML21 contains up to 8 kiB low-power SRAM that can be retained during deep sleep modes.

This adds a section for this memory in the linker script, so structures can be placed in it by giving them the __attribute__((section(".backup")))

e.g.:

static uint8_t persistent_buffer[64] __attribute__((section(".backup")));

Compile-tested only, run-tested on same54-xpro which also has 8 kiB of Backup RAM.

Testing procedure

static uint8_t persistent_buffer[64] __attribute__((section(".backup")));

int main(void) {
    /* simple check if the memory is still the same after reboot */
    if (persistent_buffer[0] != 0x23) {
            persistent_buffer[0] = 0x23;
            puts("fresh memory");
        } else {
            puts("retained memory");
    }

    /* let the RTC trigger a reset after 5s */
    struct tm time;
    rtc_get_time(&time);
    time.tm_sec += 5;
    mktime(&time);
    rtc_set_alarm(&time, NULL, NULL);

    /* this will trigger a deep sleep */
    pm_unblock(0);
    xtimer_usleep(10000);

    return 0;
}

Issues/PRs references

I'm doing the same in #11305 as SAMD5x has a very similar feature (Backup Ram instead of Low-Power SRAM but the idea is the same).

@dylad dylad self-assigned this May 4, 2019
@dylad dylad added Area: cpu Area: CPU/MCU ports Type: new feature The issue requests / The PR implemements a new feature for RIOT labels May 4, 2019
@dylad dylad added this to the Release 2019.07 milestone May 4, 2019
Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR ! This is something I wanted to do for a long time. Thanks, I'll give it a try this week.

Copy link
Copy Markdown
Contributor

@jcarrano jcarrano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a nice feature to have. The main problem now is that variables placed in .backup will not get initialized (either with a value of zeroed out) which can be quite a surprising behaviour for users. I tried it on a saml21-xpro)

Solutions, from worst to best:

  1. Leave it as is, document it.
  2. Place code in startup to unconditionally zero out the whole section. Document it.
  3. Replicate the .data and .bss scheme in LPRAM.

(2) and (3) require modifying the startup sequence, but IMO make this feature friendlier and more usable. I'll look up if there's a simple way of implementing (3).

Also, there should be a feature test available for this.

@jcarrano
Copy link
Copy Markdown
Contributor

jcarrano commented May 7, 2019

@benpicco I PR'd against your branch.

@benpicco benpicco force-pushed the saml21-lpram branch 2 times, most recently from ce8caca to 6b193bb Compare May 8, 2019 12:04
@benpicco
Copy link
Copy Markdown
Contributor Author

benpicco commented May 8, 2019

@jcarrano I've merged your branch and moved most of it to common code.
I can add definitions for stm32f4 too, but I'll have to read some data sheets first to make sure it's the same for all f4s.

@jcarrano
Copy link
Copy Markdown
Contributor

jcarrano commented May 8, 2019

I can add definitions for stm32f4 too

No need to do everything in one PR. In fact, it will go faster if we merge things little by little.

@jcarrano
Copy link
Copy Markdown
Contributor

Looks good. I'll test it as soon as I can get a saml21.

On another note - and this is a topic for another PR- I think that this approach of making the liker aware of backup memory regions is useful even when that memory is not transparently usable.

I'm referring to chips like the TM4C123. That part has 64 bytes of battery backed memory that can't be read like normal memory because it lives on a different clock domain. Even then it is still convenient to declare that region in the linker, as it allows different components of an application to claim a portion to themselves without worrying about overlap and without having resort to centrally defined mapping (like in a header).

Copy link
Copy Markdown
Contributor

@jcarrano jcarrano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the commit description it should say .backup.data instead of .backup.bss,

static uint32_t persistent_counter attribute((section(".backup.bss"))) = 1234;

@benpicco
Copy link
Copy Markdown
Contributor Author

I reworded the commit message.

@benpicco benpicco force-pushed the saml21-lpram branch 3 times, most recently from 20251aa to 565c0bd Compare June 6, 2019 15:34
@benpicco
Copy link
Copy Markdown
Contributor Author

@jcarrano ping

@jcarrano
Copy link
Copy Markdown
Contributor

@dylad, @aabadie : any of you has the device to test this. Code-wise this is fine for me, but I'd like if someone can test it.

Also, I'm dismissing my review because the issues have been addressed. I'll appove as soon as there is confirmation that it works.

@jcarrano jcarrano dismissed their stale review June 12, 2019 11:34

Changes addressed.

@dylad
Copy link
Copy Markdown
Member

dylad commented Jun 12, 2019

bad news, test doesn't work.

019-06-12 20:56:47,576 - INFO # 
2019-06-12 20:56:47,577 - INFO # Backup RAM test
2019-06-12 20:56:47,578 - INFO # 
2019-06-12 20:56:47,584 - INFO # This test will increment the counter by 1, then enter deep sleep for 1s
2019-06-12 20:56:47,585 - INFO # counter: 1

And no more output, impossible to reset or flash, I can only unplug/replug and test get stuck again. I'll try to find some times to check what happen.

Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a quick look into datasheet. Seems like LP SRAM is NOT retained in backup mode.

@benpicco benpicco force-pushed the saml21-lpram branch 4 times, most recently from fa73241 to ea011a7 Compare September 29, 2019 15:40
@benpicco benpicco requested a review from dylad September 29, 2019 16:21
Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this PR is almost good to go !
Just some comments

/* Some tools have trouble flashing MCUs in deep sleep.
* Wait a bit to make re-flashing / debugging easier.
*/
xtimer_sleep(3);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This traditional delay is troublesome because you're suppose to see the counter increments by one every second but currently this is not the case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're suppose to see the counter increments by one every second

Says who? 😉
I've added some output to clarify the delay periods.

It's really annoying when you have OpenOCD and your MCU enters deep sleep with no delay - there is no way to re-flash it. (If you're lucky you have JLink or edbg. But I'd rather save the unsuspecting Raspberry Pi GPIO users the cursing.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind keeping this delay but at least update the printf so users wont think this test is too slow ;)_

} else if (counter_noinit == counter) {
puts("WARNING: non-backup memory retained - did we really enter deep sleep?");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My personal taste would have place #ifndef CPU_BACKUP_RAM_NOT_RETAINED here so SAML21 platform doesn't display the counter before saying "aborting test". You may ignore this comment if you're fine this way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should at least once access that memory to make sure it doesn't crash & burn when doing so.

struct tm time;
rtc_get_time(&time);
time.tm_sec += SLEEP_SEC;
mktime(&time);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove this line ??

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because #11413 got merged.

@dylad dylad added CI: run tests If set, CI server will run tests on hardware for the labeled PR Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines labels Oct 1, 2019
@dylad
Copy link
Copy Markdown
Member

dylad commented Oct 1, 2019

please squash !

benpicco and others added 4 commits October 1, 2019 18:39
It is often useful to know whether the CPU was just powered on afresh
or if it was woken from a deep sleep state, e.g. by RTC or GPIO event.
Many MCUs contain some Backup or Low Power SRAM that is retained'even
in the deepest sleep modes.

In such sleep modes the MCU is essentually turned off with only the RTC
still running.
It can be woken by a GPIO or a RTC alarm. When this happens, a reset is
triggered and the normal startup routine is invoked.

This adds bss & data section for this memory in the linker script.
This allows for structures to be placed in it e.g.:

e.g.:

    static uint8_t persistent_buffer[64] __attribute__((section(".backup.bss")));
    static uint32_t persistent_counter __attribute__((section(".backup.data"))) = 1234;
SAML21 provides 2/4/8 kiB of Low Power SRAM that is retained
in backup mode.

This adds definitions to make that memory availiable to RIOT.
The test will put a device to sleep, then wake it up to see if
the backup memory was retained.
A pointer to read-only ROM data should be const.
@benpicco
Copy link
Copy Markdown
Contributor Author

benpicco commented Oct 1, 2019

squashed.

Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provided test works as expected on SAML21 and SAME54

@dylad dylad merged commit aed628f into RIOT-OS:master Oct 1, 2019
@dylad dylad added this to the Release 2019.10 milestone Oct 1, 2019
@benpicco benpicco deleted the saml21-lpram branch October 1, 2019 19:08
@benpicco
Copy link
Copy Markdown
Contributor Author

benpicco commented Oct 1, 2019

Thank you for the review and testing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants