[PATCH v2] score: Add CPU counter support

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Feb 13 07:27:37 UTC 2014


On 2014-02-13 03:42, Chris Johns wrote:
> On 12/02/2014 11:56 pm, Sebastian Huber wrote:
>> On 2014-02-12 13:38, Chris Johns wrote:
>>> On 12/02/2014 8:27 pm, Sebastian Huber wrote:
>>>> Add a CPU counter interface to allow access to a free-running counter.
>>>> It is useful to measure short time intervals.
>>>
>>> What is meant by a short time interval and also what would a long time
>>> mean ?
>>
>> This actual time interval is CPU/BSP dependent.  The interval should at
>> least cover a system tick.
>>
>>>
>>> Is an overflow or wrap around status available and/or important ?
>>
>> A overflow of the counter register will happen on most systems.  Thus we
>> use an unsigned integer type since here modulo arithmetic is defined.
>> Also the implementation must provide the _CPU_Counter_Subtract()
>> function.  Some smaller ARM controllers have for example only 24-bit
>> timers.
>
> The examples or the generic one do not seem to handle overflows, ie the first
> sample is greater than the last. Should it do this to avoid a simple copy and
> paste error when others implement this ?

A single overflow is not a problem due to the modulo arithmetic of unsigned 
integers.  You have a problem if you want to measure time intervals greater 
than the timer period.  For the busy wait functions this is not at all since 
they simply wait longer in this case.  If you use the counter to measure worst 
case execution times of critical sections, then the timer period must be large 
enough.

>
> The documentation need to outline this and what it needs to take care of.
>
>>
>>>
>>>> This can be used for
>>>> example to enable profiling of critical low-level functions.
>>>
>>> Why use this rather than the existing
>>> rtems_clock_get_uptime_nanoseconds ?
>>>
>>> Are you looking at sub-nano second times ?
>>
>> The overhead to use rtems_clock_get_uptime_nanoseconds() is too high.
>> Also this counter should work without a clock driver and during system
>> initialization.
>>
>> Also what happens if your driver using the busy wait is initialized
>> before the clock driver, etc.?
>>
>> The step from CPU counter ticks to/from nanoseconds is explicit in this
>> API unlike to rtems_clock_get_uptime_nanoseconds().
>>
>> How do you profile the spinlock used by
>> rtems_clock_get_uptime_nanoseconds()?
>>
>
> These are all great reasons and it would be great to capture into the
> documentation. I see nothing more than what is listed here just as sentences
> rather than questions. I also think a reference to the
> rtems_clock_get_uptime_nanoseconds be provided to help guide users.

Ok.

>
>>>
>>> I would be concerned about trace data based on this unless the over
>>> was handled
>>> or interrupts are masked.
>>>
>>>>
>>>> Add two busy wait functions rtems_counter_delay_ticks() and
>>>> rtems_counter_delay_nanoseconds() implemented via the CPU counter.
>>>>
>>>
>>> How is the user protected in a portable way across different cpus ?
>>
>> Protected against what?
>>
>
> Asking to delay for a time greater than the timer overflow, warnings and
> clarifications in the doco outlining the restrictions. The intent and purpose
> is clear to you and I am guessing a little to fill in the gaps however what
> happens in 10 years time when a new user sees this.
>
>>> Is there range checking or is overflows used ?
>>
>> The range is limited by the parameter integer types.
>>
>
> And if you have a 24bit timer ?
>
>>> Are the calls re-entrant ?
>>
>> What do you mean with re-entrant here?
>>
>
> If I ask for 100 nsecs do I get that or do I get at least 100+ nsecs and/or I
> am in the delay call for 60% of the timer overflow period and get pre-empted
> and a new call is made to the delay this time for 90% of the timer overflow
> length overflowing the original call.

We have

void rtems_counter_delay_ticks( rtems_counter_ticks ticks )
{
   rtems_counter_ticks a = rtems_counter_read();
   rtems_counter_ticks delta = 0;

   do {
     rtems_counter_ticks b;

     ticks -= delta;

     b = rtems_counter_read();
     delta = rtems_counter_subtract( b, a );
     a = b;
   } while ( ticks > delta );
}

so you wait at least the time specified by ticks.  If someone interrupts you, 
then you wait longer than necessary.

>
> I feel we need more doco to help define the scope. I am not asking for the API
> or code to be made more complex as I understand the need for speed and simplicity.
>
>>>
>>>> diff --git a/doc/cpu_supplement/general.t b/doc/cpu_supplement/general.t
>>>> index cf28eef..3608705 100644
>>>> --- a/doc/cpu_supplement/general.t
>>>> +++ b/doc/cpu_supplement/general.t
>>>> @@ -341,6 +341,26 @@ _TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
>>>>   _TLS_Alignment = ALIGNOF (.tdata);
>>>>   @end example
>>>>
>>>> + at section CPU counter
>>>> +
>>>> +The CPU support must implement the CPU counter interface.  A CPU
>>>> counter is
>>>> +some free-running counter.  It ticks usually with a frequency close
>>>> to the CPU
>>>> +or system bus clock.  On some architectures the actual
>>>> implementation is board
>>>> +support package dependent.  The CPU counter is used for profiling of
>>>> low-level
>>>> +functions.  It is also used to implement two busy wait functions
>>>> + at code{rtems_counter_delay_ticks()} and
>>>> @code{rtems_counter_delay_nanoseconds()}
>>>> +which may be used in device drivers.  It may be also used as an
>>>> entropy source
>>>> +for random number generators.
>>>> +
>>>> +The CPU counter interface uses a CPU port specific unsigned integer
>>>> type
>>>> + at code{CPU_Counter_Ticks} to represent CPU counter values.  The CPU
>>>> port must
>>>> +provide the following two functions
>>>> +
>>>> + at itemize
>>>> + at item @code{_CPU_counter_Read()} to read the current CPU counter
>>>> value, and
>>>> + at item @code{_CPU_counter_Subtract()} to subtract two the CPU counter
>>>> values.
>>>> + at end itemize
>>>
>>> Is overflows handled in the maths ? I could not see it if important.
>>>
>>> Should the user be able to ask the range of the counter ?
>>
>> The only useful operation with values obtained by _CPU_counter_Read() is
>> _CPU_counter_Subtract().
>>
>
> This should be noted in the doco. Also should _CPU_counter_Subtract be
> _CPU_counter_Difference ?

Ok, I change it to _CPU_Counter_difference().


-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber at embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



More information about the devel mailing list