PowerSave Module
Jon Abbott (1421) 2651 posts |
Has any consideration been made to adding a PowerSaver Module / API to RISCOS based around WFI / WFE ? There’s possibly a few areas the CPU could be halted: OS_Byte 19, Callbacks, TaskManager. Admittedly, its a tricky one to implement due to the lack of threading in RISCOS. If HAL_Timers was shareable we could consider threading TaskManager on a high precision timer and have an Idle thread that loops around WFI. I’m going to try it in ADFFS, as there’s an obvious period after a game issues OS_Byte 19 where the CPU can be halted continually between IRQ/FIQ’s until either the physical or fake 50Hz VSync occurs and the game continues. My Pi runs really hot when playing games, although it’s spending over 50% of the CPU cycles in tight loops of a few instructions doing nothing except service IRQ’s in the background. It will be interesting to see what difference, if any, it makes. |
Steve Pampling (1551) 8170 posts |
I suppose it also opens up the possibility of a sort of suspend / resume with the machine pulling virtually zero power until, say, a keyboard event occurred. |
Jeffrey Lee (213) 6048 posts |
The Portable module is what you’re looking for, in particular Portable_Idle for WFI. OS_Byte 19 uses it, as does the Wimp (there’s some logic in there which counts the number of idle polls per second, and if it’s over a given threshold it will set the CPU speed to minimum and use Portable_Idle to sleep the CPU. Not sure offhand whether it places any additional limits on the poll rate beyond that – with a 100Hz timer IRQ, 100Hz-ish audio IRQ, and 60Hz-ish video IRQ you’d still end up with about 260 idle polls/sec), and a few other places (OS_ReadC when keyboard buffer empty, some blocking loops in filesystem code, IRQ-driven IIC transfers, etc). One place that would be nice to be able to use WFI is in HAL_CounterDelay, but that would require a fair bit of logic within the HAL to program a spare timer to generate an interrupt at the required time, and to cope with nested calls to the function. It would probably be better if this was something the OS handled, and if we had a tickless kernel design rather than relying on a 100Hz timer. There’s also scope for suspend-to-RAM functionality, but the API for that hasn’t been implemented for the current ‘PortableHAL’ version of the module (and may need some revising to work cleanly with the way RISC OS 5 does things) |
Jon Abbott (1421) 2651 posts |
What would we do without you Jeffrey! I take it from what you’ve said, the module is permanently active and already putting the Pi into WFI? Its begging for a Configuration applet to control its behaviour, particularity the threshold – or does the vaguely documented Portal_Control do that already? Is it possible to get stats so I can see how much time the CPU is idle Portable_Speed2 looks like it could provide that sort of info but doesn’t. The Cycle Counter Register obviously stops counting whilst the CPU is idle so is there some other means of counting time whilst the CPU is idle? A timer outside of the CPU perhaps? HAL_CounterDelay – Can’t it just loop on WFI under RTSupport and exit once the correct number of reentrancy calls from RTSupport occur? What about adding an Idle task that TaskManager calls when it’s run out of tasks to deal with? The Tasks window could also be extended to display how much time each process is using, where the CPU provides Cycle counters. I think back in the day, there was a Tasks replacement that used one of the IOC timers to count task time. |
Jeffrey Lee (213) 6048 posts |
Yes
Portable_Control doesn’t deal with that, no (that SWI seems to be used for turning stuff on and off more than anything else). Since it’s the Wimp that decides when the desktop is idle, the configuration settings should surely be in the Wimp, rather than in the Portable module.
If you build a copy of the Portable module with DebugSpeed set to TRUE (and DebugTimer set to 1 for the Pi) then you’ll be able to get some timing stats from Portable_Speed2 with a -1 reason code
Yes, that debug timing code in the Portable module uses a HAL timer.
I’m going to say “No” here because I have no idea what you’re talking about! If you’re talking about having HAL_CounterDelay call (or interact with) RTSupport then that would go against one of the design goals of the HAL (which is for it to be OS agnostic; having the HAL call SWIs goes against that). If you’re talking about RTSupport calling HAL_CounterDelay then that doesn’t make sense either (RTSupport doesn’t call HAL_CounterDelay or contain any blocking loops, all its scheduling is done based around TickerV) However, if HAL_CounterDelay was given a sufficiently long delay (i.e. longer than 1cs) then the HAL could conceivably check the state of the 100Hz timer and use WFI to wait until that next fires. But it would still be cleaner if this was done at a higher-level point within the OS itself.
TaskManager doesn’t call tasks. The Wimp handles all of that.
I’m fairly certain the current version of the CPU usage utility that’s in the disc image provides a view that shows CPU usage on a per-task basis (but I suspect it relies on the 100Hz monotonic timer for its calculations) |
Jon Abbott (1421) 2651 posts |
Sorry, my knowledge of RISCOS and the precise terminology I should be using has somewhat confused the conversation! I do find it somewhat frustrating that there’s a small “Elite” group of developers who know the OS inside out and give the impression that they look down on the rest of us. The Red Squirrel support response being a fine example of how not to treat your community. You’re response was the usual pro-active one only to be knocked back. Anyhow, I digress. HAL_CounterDelay – Is there an equivalent 100Hz entry point in the HAL that you could implement it, I think you’ve alluded to one.
Isn’t RTSupport part of the OS? I thought you just said above that HAL_CounterDelay’s actions needed to remain within the HAL? Are you suggesting HAL_CounterDelay trigger something in the OS that does the WFI? Or does it need to be self contained within the HAL? |
Jeffrey Lee (213) 6048 posts |
The HAL won’t be explicitly notified about 100Hz timer interrupts, but it will be implicitly notified simply because at some point the OS will call HAL_IRQSource in order to work out what IRQ has just fired. But adding extra overhead to HAL_IRQSource is a pretty nasty thing to do. There are other options (probably involving hooking into HAL_TimerIRQClear), but it wouldn’t surprise me that there are too many edge cases for this to be a suitable solution (at the moment there’s a mostly unwritten rule that timer 0 will generate interrupts at 100Hz, and that the HAL_Counter* functions should interact with timer 0 – but we should probably avoid having the HAL make too many assumptions about how the OS does things)
Yes it is. (Did you mean to say the Portable module there? That’s a part of the OS as well, obviously)
I was thinking of having the HAL issue a WFI instruction directly. Portable_Idle doesn’t really do anything special, it’s just a wrapper around the architecture-specific WFI instruction (and if a future platform did need something special, chances are the special logic would be implemented in the HAL and the Portable module would just call through to that) |
Jon Abbott (1421) 2651 posts |
I think I get you, move some of what’s in Portable into the HAL and have Portable call the HAL to sleep etc? |
Jeffrey Lee (213) 6048 posts |
Pretty much, yeah. |
Rick Murray (539) 13840 posts |
That reminds me. Ought to get the 32 bit HostFS and give Five another whirl on RedSquirrel. Been a bit out of it these last few weeks… |