[En-Nut-Discussion] NutGetMillis is a _very expensive_ function on Ethernut3
alainm at pobox.com
Wed Aug 20 20:00:32 CEST 2008
I will, again, give my 2c on a topic about which I am no familiarized
with Nut, but that interests me. Please don't hesitate to correct me.
If I have a CPU with an extra timer that I can program as an independant
one milisecond clock, or even a HW miliseconds counter, I would like to
have a *hardwre dependant* function to implement. And that it should be
no problem if it is *not* synchronysed with the RTC because this will
not happen in any hw that I know of (even PC).
I am stating this because I am not sure in the text bellow if this is
what you said. I just know that this is best scenario and I feel that it
"should" be possible...
Harald Kipp escreveu:
> Alain M. wrote:
>> duane ellis escreveu:
>>> Harald Kipp wrote:
>>> >> IMHO, using an array instead of a structure will be more flexible.
>>> This way we can define different indices for different targets.
>>> I do not think the ARRAY should be public, it should be 100% hidden
>>> "static to a chip/target specific C file", and the C file should
>>> implement access functions to get the clock values. Data Hiding is
>>> good. How that C file/function does its job internally is up to the
>> Specialy because it can be made in a way that gets optimyzed away by GCC.
> I didn't intend to make the cache variable public. I prefered to use an
> array instead of a structure, because it is more flexible and can be
> handled by the architecture independent part. This reduces the effort of
> porting to new platforms.
> No question that data hiding has advantages. However, it can be
> overdone. Specifically in tiny embedded systems the function call
> overhead may be significant. AFAIK, global functions are typically not
> optimized away. If, then it needs to be done by the linker. The compiler
> cannot do this.
> But calm down. ;-) There are no plans to replace the existing functions.
> I'd like to introduce two new hardware independent functions
> uint32_t NutClockGet(int idx);
> int NutClockSet(int idx, uint32_t freq);
> The idx parameter NUT_HWCLK_CPU, NUT_HWCLK_PERIPHERAL etc. which are
> platform dependent.
> For now, the second function is specified for NutClockSet(-1, 0) only,
> which means: Release cached values (freq=0) of all clocks (idx=-1).
> Later some platforms may implement the ability to set specified hardware
> clocks to specified frequencies.
> Then we still have
> uint32_t NutGetCpuClock(void);
> which is an optimized version of NutClockGet(NUT_HWCLK_CPU) and provides
> backward compatibility. If NUT_CPU_FREQ is defined, it will simply
> return NUT_CPU_FREQ;
> Otherwise NutClockGet() and NutGetCpuClock() will use the cache
> mechanism suggested by Duane. By using an array for the cache, these
> function can be moved from arch/xxx/ostimer.c to os/timer.c. Indices and
> the size of this array are defined in include/arch/<target>/timer.h.
> On the hardware dependent side there is a new function
> uint32_t NutArchClockGet(int idx);
> which reads the hardware in case of an invalid cache value.
> This way we are also able to replace constructs like
> #if defined(AT91_PLL_MAINCK)
> clk = At91GetMasterClock();
> clk = NutGetCpuClock();
> clk = NutClockGet(NUT_HWCLK_PERIPHERAL);
> or even more specific
> clk = NutClockGet(NUT_HWCLK_UART0);
> On targets with single clock support only, the indices are all the same
> #define NUT_HWCLK_CPU 0
> #define NUT_HWCLK_PERIPHERAL NUT_HWCLK_CPU
> #define NUT_HWCLK_UART0 NUT_HWCLK_PERIPHERAL
> #define NUT_HWCLK_MAX NUT_HWCLK_PERIPHERAL
> and the cache is declared as
> static uint32_t clock_cache[NUT_HWCLK_MAX + 1];
> In such cases (1 clock only) the function NutClockGet() is mapped to the
> optimized NutGetCpuClock() by
> #if NUT_HWCLK_MAX == 0
> #define NutClockGet(i) NutGetCpuClock()
> This will hopefully not add any additional code to tiny systems, where
> every byte counts. And it will provide high flexibility for coming chips
> without creating a porting nightmares.
More information about the En-Nut-Discussion