[ECOS] Changing CPU clock frequency on the fly

Bart Veer bartv@ecoscentric.com
Wed Jan 28 15:58:00 GMT 2004

>>>>> "Nelu" == Gratian Crisan <nelu@iv.ro> writes:

    Nelu> Hi,
    Nelu> we are running eCos on a custom board based on AT91FR40162 ARM cpu from Atmel. 
    Nelu> (we use eCos target: eb40a). 
    Nelu> 	I am trying to do dynamic frequency management, mainly for power management 
    Nelu> reasons. The board has a programable oscillator with an output frequency 
    Nelu> ranging from 1KHz to 68MHz. 
    Nelu> 	Browsing trough eCos mailing lists I've stumbled upon an email in which Gary 
    Nelu> Thomas wrote that eCos isn't set up for this and it may not be a good idea.
    Nelu> My question is: what are the main reasons why this may not be a good idea?
    Nelu> What needs to be changed in order to implement dynamic frequency management in 
    Nelu> eCos. So far I've dug up the following things that need recalculation/setup:
    Nelu> - flash wait states (EBI wait states);
    Nelu> - recalculate main heartbeat CYGNUM_HAL_RTC_PERIOD to keep it at 100Hz;
    Nelu> - setup the serials to account for CPU clock frequency change;

This sort of thing is possible, see
Most of eCos does not care whether the processor is running at 1MHz or
1GHz, as long as there are enough cpu cycles to meet the application's
requirements. However you do have to be careful about a few things.

First, you have to check all the hardware being used to see how they
might be affected. You have already identified the flash and the
serial ports, there may be other devices as well. This sort of thing
depends entirely on the hardware and what bits of it are actually used
by your application.

Second, clock interrupts should happen at a constant rate (typically a
100 Hz) irrespective of the cpu frequency. These clock interrupts are
what tell eCos how much time has elapsed, so they are used for e.g.
TCP/IP timeouts. You will want to look at the HAL_CLOCK_INITIALIZE(),
HAL_CLOCK_READ() and especially HAL_CLOCK_RESET() macros appropriate
for your platform, and how these are used by the kernel's clock.cxx
module. At a guess, inside HAL_CLOCK_RESET() you'll want to scale the
period argument to compensate for a reduced cpu frequency.

Note that I think Gary's message was referring to changing the clock
interrupt frequency rather than the cpu frequency. I agree with him
that this is a bad idea, eCos is not designed to cope with that sort
of thing.

Third, you may want to be careful about exactly when you change the
cpu frequency. If you drop from 68MHz to say 10MHz halfway between
clock interrupts and don't adjust the interrupt clock, you are
introducing drift. Either manipulate the hardware timer that generates
clock interrupts at the same time as you change the cpu frequency, or
look at changing the cpu frequency in e.g. a kernel alarm function
which will be called shortly after a clock interrupt and do another
RESET() in there.

Finally there may be code which "knows" about the cpu speed,
especially inside device drivers. For example if the driver must wait
n microseconds between touching two hardware registers, that will
usually be implemented by either a spinning loop or an invocation of
HAL_DELAY_US(). For such small delays you cannot use higher-level
functionality like kernel alarms. Usually it will not matter much if
the cpu is running slower than expected, you are just giving the
hardware some extra time to settle down. However some drivers may be
more sensitive to exact timing. I suggest looking through the various
drivers used for your platform, there may be some obvious code that
will need tweaking.


Bart Veer                       eCos Configuration Architect
http://www.ecoscentric.com/     The eCos and RedBoot experts

Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

More information about the Ecos-discuss mailing list