I have some thoughts… (not sure what they are worth) 1) I think having a linker section for retained RAM is a good idea. Another possible option here is that .bss/.data is retained and heap is not but not sure if that distinction would be super useful. It would allow skipping of the startup code that initializes those sections without a developer having to specifically name a global variable as “retained”… I guess having some way of telling the power manager to retain some or all of the RAM (or whatever) is a good thing too...
2) I am not a big fan of the idle task/OS approach. I think having a hook to call a function is a bit more palatable. Not sure I have a good reason for that though other than it sounds simpler. 3) Being able to avoid the bootloader checks seems a big win and a must have as I suspect image verification will take a big chunk of time. 4) I wonder if this is mainly a moot point but without understanding how long it takes to bring up the system and how long devices will stay awake how can one say? It seems to me that coming out of deep sleep is a very deliberate action and that the device will end up staying awake for an amount of time that is much greater than the system init time. For example, if system init is 5 msecs and you stay awake for 5 seconds when coming out of deep sleep, how much do you end up saving? Not much… but I guess every little bit counts… Another typical case I can see is that some low power timer is active and this timer fires off at some rate. The function executed when that timer expires does some quick checks to determine if the device should wake up more fully or stay in this low power state. In these cases I would suspect RAM is retained so you dont have to worry about all this. I guess #4 was a very long-winded way to say “I think we should take the simplest approach for the deep sleep issue” :-) > On Sep 9, 2016, at 10:29 AM, Sterling Hughes <[email protected]> wrote: > > >> - (future) Provide a method to newt by which certain tasks memory can be >> linked earlier in RAM, so that for systems where RAM suspension is desired, >> a core set of system services can be located there, while other services can >> be re-initialized in a second phase. >> - This may cause some modification to the task structure to provide >> these “re-init” functions. >> > > I was specifically wondering if folks had any thoughts on this scenario. > This is the case on certain processors where you can go into ever low power > states, as you retain only certain blocks of RAM (I believe Nordic allows you > to retain down to 4K of RAM on the NRF52.) > > In terms of use-cases, I think the most common one here will be on a system > where you have the processor need to wake-up from some external operation > (e.g. button press), and you want to have system asleep until that happens. > When implementing these cases, you’ll probably also want to have some code > that comes up very quickly, and performs certain operations, prior to fully > booting the system (e.g. debouncing an I/O pin.) > > My initial thought on this was that we could locate the operating system in > that 4K of RAM, and designate a single task, which retains context to do > this. This could currently be the idle task, and the idle task can have a > restore from deep sleep hook, which was user provided. Given that the user > provided hook would likely be in a separate context from the OS, we would > dedicate a linker section to user provided retained memory so that any data > associated with the user hook could also be saved. > > Then, when the processor wants to transition to sleep mode: either through an > ISR, or some task’s context. It tells the system to transition into that > state, which triggers a saving of critical system context. When the IDLE > task comes up, it immediately calls the deep sleep hook, to determine if the > full system should reboot. If it determines the system should reboot, the > entire system then jumps to C startup and re-initializes. > > I should note that on some processors (e.g. Nordic), in these deep sleep RAM > retained states, the code begins running from the reset vector (0 in internal > flash.) Currently we locate our boot loader there, so we’ll need some other > code in the boot loader to skip image verification (if enabled), and look > into RAM for a specific pattern — if that pattern is present, restore system > operation, otherwise continue booting. > > The other option, is to skip multi-purposing the idle task, and instead add a > linker section for “retained RAM” that goes ahead of all other sections. And > then, add a hook in the C startup code that goes prior to any initialization. > In this case, that hook can run, look at the retained RAM, and perform > operations prior to system boot. This would avoid all interactions with the > RTOS itself, yet provide a standard way of having people hook into this state. > > I’m not sure which of these I like more. The OS approach seems more > complicated, but somehow feels more right. Nonetheless, I can’t really see > why running out of the idle task is that desirable, if you end up losing all > of your other task contexts. You’re really going to have to re-run system > initialization anyway (e.g. reboot) in order to get full system functionality. > > Are there any other approaches folks have seen in the past/liked? What have > people done when they’ve needed to manage these states? > > > Thanks, > > Sterling
