Omnimaga

Omnimaga => Our Projects => Ndless => Topic started by: Goplat on March 14, 2011, 06:27:45 pm

Title: Idling the CPU
Post by: Goplat on March 14, 2011, 06:27:45 pm
I noticed a thread on TI-Bank where someone said his TI-Nspire CAS drained a set of batteries by 50% in one day while testing out some programs... Power consumption is a very annoying thing in that you can't ignore it even though it's practically impossible to measure it effectively :(

I suspect that it's mainly the Nspire's 90MHz CPU that can be a power hog, so it's important to make sure we idle it properly when nothing is happening. The way to do this is with the wait-for-interrupt instruction (mcr p15, 0, SBZ, c7, c0, 4), which is executed by the idle() function in libndls. However, this instruction is only useful if the interrupt that wakes the CPU up is acknowledged. Otherwise, next time around, the interrupt controller is already asserting to the CPU that an interrupt is pending, so the instruction just returns immediately.

Presently, Ndless programs run with the CPSR I bit set on the CPU, so the OS's IRQ handler is not run, and IRQs never get acknowledged unless a program does so explicitly. I think libndls should have a delay routine that keeps the CPU idle by acknowledging timer interrupts as they come, something like this:

Code: [Select]
// Idle for n/100 seconds
void delay(int n) {
int irq_mask = *(volatile int *)0xDC000008;
*(volatile int *)0xDC00000C = ~(1 << 19); // Disable all IRQs except timer
for (; n; n--) {
asm ("mcr p15, 0, %0, c7, c0, 4" : : "r" (0)); // Wait for an interrupt to occur
*(volatile int *)0x900A0020 = 1; // Acknowledge timer interrupt at source
*(volatile int *)0xDC000028; // Make interrupt controller stop asserting nIRQ if there aren't any active IRQs left
}
*(volatile int *)0xDC000008 = irq_mask; // Re-enable disabled IRQs
return 0;
}
Title: Re: Idling the CPU
Post by: fb39ca4 on March 14, 2011, 09:50:50 pm
A function to over/underclock the CPU would also be nice, a game like block dude or ferris doesnt need 90 MHz. Even though it is simple enough already, having a function means more people are likely to use it.
Title: Re: Idling the CPU
Post by: DJ Omnimaga on March 14, 2011, 09:58:27 pm
For me batteries lasts about 2 hours O.O , but they were cheap batteries I bought in set of 12 for $1.49. It would be nice to be able to save power somehow, like during less intensive parts of games such as a RPG menu or any game that doesn't require smooth scrolling.
Title: Re: Idling the CPU
Post by: fb39ca4 on March 14, 2011, 11:39:27 pm
Exactly. If a program that uses timers to keep a constant frame rate were to calculate how much time is being taken to make each frame, it could adjust the CPU frequency accordingly, kind of like how speedstep works on computers. The only problem I could think of is it may not be good for the hardware to keep on switching frequencies.
Title: Re: Idling the CPU
Post by: DJ Omnimaga on March 14, 2011, 11:52:11 pm
Yeah that's one worry I have. I wonder if there are previous cases of dying hardware for any other kind of device due to constant frequency changes?
Title: Re: Idling the CPU
Post by: Jonius7 on March 15, 2011, 06:45:55 am
ndless uses a lot of battery life, especially when playing games on it. it had dropped to 25% on my nspire in a week

post 444 unlucky number....
Title: Re: Idling the CPU
Post by: calc84maniac on March 15, 2011, 09:52:50 am
I think ARM is supposed to handle frequency changes well. I do know that the OS frequently clocks the processor down while idle, then clocks it back up when it needs to do something.
Title: Re: Idling the CPU
Post by: NeoCrisis on March 15, 2011, 09:58:26 am
that's funny, because mine did this too!! I thought it was the battery-level component which was buggy :o but my batteries are Duracell, and they must last more than 2 months :o when i started testing games and progs such as nTris, gbc4nspire, and the whole bunch of nice projects, it went slower, and slower, and slower, so I could difficultly move the character of Pokémon... Even when CPU runs at the official 2.0 CPU (it's with 2.1 currently)
Title: Re: Idling the CPU
Post by: Goplat on March 15, 2011, 11:30:28 am
I think ARM is supposed to handle frequency changes well. I do know that the OS frequently clocks the processor down while idle, then clocks it back up when it needs to do something.
It only changes the processor speed, though, keeping the bus speed constant.

OS 1.1-2.01: 145002 when active (CPU=90MHz AHB=15MHz), 14000c when idle (CPU=15MHz AHB=15MHz)
OS 2.1: 0a1002 when active (CPU=120MHz AHB=60MHz), 0a0004 when idle (CPU=60MHz AHB=60MHz)
Title: Re: Idling the CPU
Post by: DJ Omnimaga on March 15, 2011, 03:18:58 pm
The change from 90 to 120 was an excuse to them failing at optimizing 2.1 enough to run at the same speed as the old OS at 90 MHz?
Title: Re: Idling the CPU
Post by: ExtendeD on March 19, 2011, 04:09:42 am
Sorry for this issue :(
I have updated idle() with Goplat's code. sleep() still uses idle() and is unchanged.
Programs needs to be rebuild to use the updated version.