[En-Nut-Discussion] NutGetMillis is a _very expensive_ function on Ethernut3

Alain M. 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...

Thanks,
Alain

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 
>>> implementor.
>> 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();
>    #else
>      clk = NutGetCpuClock();
>    #endif
> 
> by
> 
>    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()
>    #endif
> 
> 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.
> 
> Harald
> 
> 
> 
> 
> 
> 
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> 
> 



More information about the En-Nut-Discussion mailing list