This TEP proposes a Timer design that supports common timingrequirements both in precision and width across common hardwareconfigurations. This TEP focuses on aligning the Timer abstractionwith the three-layer Hardware Abstraction Architecture (HAA).
Most microcontrollers offer a rich timer system, with features like:
The interested reader can refer to Appendix A for a brief overview ofthe timer hardware on some current TinyOS platforms.
TinyOS does not attempt to capture all this diversity in aplatform-independent fashion. Instead, following the principles of theHAA[_tep2], each microcontroller should expose all this functionalityvia components and interfaces at the HPL and, where appropriate, HAL levels.However, two aspects of timers are sufficiently common and important that they should be made available in a well-defined way: measuring time,and triggering (possibly repeating) events at specific times. The restof this TEP specifies:
This TEP ends with appendices documenting, as an example, the mica2timer subsystem implementation.
Before presenting the interfaces (2.2), we start with a generaldiscussion of the issues of precision, width and accuracy intimer interfaces (2.1).
Three fundamental properties of timers are precision, width andaccuracy.
Examples of precision are millisecond, a cycle of a 32kHz clock, andmicroseconds. All precisions presented in this TEP are in "binary"units with respect to one second. That is, one second contains 1024binary milliseconds, 32768 32kHz ticks, or 1048576 microseconds.This TEP emphasizes millisecond and 32kHz tick precisions whilereasonably accommodating other precisions. The use of "binary" unitsis motivated by the common availability of hardware clocks driven by a 32768Hz crystal.
Examples of widths are 8-bit, 16-bit, 32-bit, and 64-bit. The widthfor timer interfaces and components SHOULD be 32-bits. This TEPemphasizes 32-bit widths while reasonably accommodating other widths -a particular platform may have good reasons not to expose a 32-bitinterface.
Accuracy reflects how closely a component conforms to the precision itclaims to provide. Accuracy is affected by issues such as clock drift (muchhigher for internal vs crystal oscillators) and hardware limitations. As anexample of hardware limitations, a mica2 clocked at 7.37MHz cannot offer anexact binary microsecond timer -- the closest it can come is 7.37MHz/8. Ratherthan introduce a plethora of precisions, we believe it is often best topick the existing precision closest to what can be provided, along withappropriate documentation. However, the accuracy MUST remain reasonable:for instance, it would be inappropriate to claim that a millisecond timeris a 32kHz timer.
This TEP parameterizes all interfaces by precision and someinterfaces by width. This intentionally makes similar timerinterfaces with different precision or width mutually incompatible.It also allows user code to clearly express and understand theprecision and width for a given timer interface. Accuracy is notreflected in the interface type.
Precision is expressed as a dummy type -- TMilli, T32khz, andTMicro -- written in the standard Timer.h header like this:
typedef struct { int notUsed; } TMilli; // 1024 ticks per secondtypedef struct { int notUsed; } T32khz; // 32768 ticks per secondtypedef struct { int notUsed; } TMicro; // 1048576 ticks per second
Note that the precision names are expressed as either frequency orperiod, whichever is convenient.
This TEP proposes these timer interfaces:
interface Counter< precision_tag, size_type >interface Alarm< precision_tag, size_type >interface BusyWait< precision_tag, size_type >interface LocalTime< precision_tag >interface Timer< precision_tag >
The LocalTime and Timer interfaces are used primarily by userapplications and use a fixed width of 32-bits. The Alarm, BusyWait,and Counter interfaces are used by the TinyOS timer system andadvanced user components.
The Counter interface returns the current time and provides commandsand an event for managing overflow conditions. These overflowcommands and events are necessary for properly deriving larger widthCounters from smaller widths.
interface Counter<precision_tag,size_type>{ async command size_type get(); async command bool isOverflowPending(); async command void clearOverflow(); async event void overflow();}
Alarm components are extensions of Counters that signal an eventwhen their compare register detects the alarm time has been hit.All commands and events of the Alarm interface are asynchronous (orin "interrupt context"). The Alarm interface provides a set of"basic" commands for common usage and provides a set of "extended"commands for advanced use.
interface Alarm<precision_tag,size_type>{ // basic interface async command void start( size_type dt ); async command void stop(); async event void fired(); // extended interface async command bool isRunning(); async command void startAt( size_type t0, size_type dt ); async command size_type getNow(); async command size_type getAlarm();}
startAt(t0,dt)
cancel any previously running alarm and set to fire at time t1 =t0+dt. This form allows a delay to be anchored to some time t0 takenbefore the invocation of startAt. The timer subsystem uses this forminternally, to be able to use of the full width of an alarm while alsodetecting when a short alarm elapses prematurely(过早地).
The time t0 is always assumed to be in the past. A value of t0numerically greater than the current time (returned by getNow())represents a time from before the last wraparound.
The BusyWait interface allows for very short synchronous delays.BusyWait should be used sparingly and when an Alarm would not bereasonably efficient or accurate. The BusyWait interface replacesthe TOSH_uwait macro from TinyOS 1.x.
BusyWait blocks for no less than the specified amount of time. Noexplicit upper bound is imposed on the enacted delay, though it isexpected that the underlying implementation spins in a busy loop untilthe specified amount of time has elapsed.
interface BusyWait<precision_tag,size_type>{ async command void wait( size_type dt );}
The LocalTime interface exposes a 32-bit counter without overflowutilities. This is primarily for application code that does notcare about overflow conditions.
interface LocalTime<precision_tag>{ async command uint32_t get();}
All commands and events of the Timer interface are synchronous (orin "task context"). The Timer interface provides a set of "basic"commands for common usage and provides a set of "extended" commandsfor advanced use. The Timer interface allows for periodic events.
interface Timer<precision_tag>{ // basic interface command void startPeriodic( uint32_t dt ); command void startOneShot( uint32_t dt ); command void stop(); event void fired(); // extended interface command bool isRunning(); command bool isOneShot(); command void startPeriodicAt( uint32_t t0, uint32_t dt ); command void startOneShotAt( uint32_t t0, uint32_t dt ); command uint32_t getNow(); command uint32_t gett0(); command uint32_t getdt();}
cancel any previously running timer and set to fire at time t1 =t0+dt. The timer will fire periodically every dt time units untilstopped.
As with alarms, the time t0 is always assumed to be in the past. Avalue of t0 numerically greater than the current time (returned bygetNow()) represents a time from before the last wraparound.
cancel any previously running timer and set to fire at time t1 =t0+dt. The timer will fire once then stop.
t0 is as in startPeriodicAt.
Platforms SHOULD expose their relevant timing capabilities usingstandard Alarm and Counter interfaces. The design pattern presentedhere defines a component naming convention to allow platformindependent access to particular Alarms and Counters if they existand to cause compile errors if they do not.
A platform specific hardware timer with precision ${P} and width${W} SHOULD be exposed as these two conventional Counter and Alarmcomponents:
configuration Counter${P}${W}C{ provides interface Counter< T${P}, uint${W}_t >;}generic configuration Alarm${P}${W}C(){ provides interface Alarm< T${P}, uint${W}_t >;}
Instantiating an Alarm${P}${W}C component provides a new and independentAlarm. If the platform presents a limited number of Alarm resources,then allocating more Alarms in an application than are available for theplatform SHOULD produce a compile-time error. See Appendices B and Cfor an example of how to make allocatable Alarms that are eachimplemented on independent hardware timers.
For example, if a platform has an 8-bit 32kHz counter and three8-bit 32kHz alarms, then the Counter and Alarm interfaces for${P}=32khz and ${W}=16 are:
configuration Counter32khz8C{ provides interface Counter< T32khz, uint8_t >;}generic configuration Alarm32khz8C(){ provides interface Alarm< T32khz, uint8_t >;}
This pattern MAY be used to define components for the platform thatare mutually incompatible in a single application. Incompatiblecomponents SHOULD produce compile-time errors when compiledtogether.
The following component MUST be provided on all platforms
HilTimerMilliCBusyWaitMicroC
Both of these components use "binary" units, i.e., 1/1024s forHilTimerMilliC and 1/1048576s for BusyWaitMicroC. Components usingother precisions (e.g., regular, non-binary milliseconds) MAY also beprovided.
configuration HilTimerMilliC{ provides interface Init; provides interface Timer<TMilli> as TimerMilli[ uint8_t num ]; provides interface LocalTime<TMilli>;}
A new timer is allocated using unique(UQ_TIMER_MILLI) to obtain anew unique timer number. This timer number is used to index theTimerMilli parameterised interface. UQ_TIMER_MILLI is defined inTimer.h. HilTimerMilliC is used by the LocalTimeMilliC component and theTimerMilliC generic component, both found in tos/system/
configuration BusyWaitMicroC{ provides interface BusyWait<TMicro,uint16_t>;}
BusyWaitMicroC allows applications to busy-wait for a number ofmicroseconds. Its use should be restricted to situations where thedelay is small and setting a timer or alarm would be impractical,inefficient or insufficiently precise.
A number of platform independent generic components are provided tohelp implementers and advanced users of the TinyOS timer system:
Appendices B and C show how these can be used to help implementthe timer HAL and HIL.
AlarmToTimerC converts a 32-bit Alarm to a Timer.
generic component AlarmToTimerC( typedef precision_tag ){ provides interface Timer<precision_tag>; uses interface Alarm<precision_tag,uint32_t>;}
BusyWaitCounterC uses a Counter to block until a specified amount oftime elapses.
generic component BusyWaitC( typedef precision_tag, typedef size_type @integer() ){ provides interface BusyWait<precision_tag,size_type>; uses interface Counter<precision_tag,size_type>;}
CounterToLocalTimeC converts from a 32-bit Counter to LocalTime.
generic component CounterToLocalTimeC( precision_tag ){ provides interface LocalTime<precision_tag>; uses interface Counter<precision_tag,uint32_t>;}
TransformAlarmC decreases precision and/or widens an Alarm. Analready widened Counter component is used to help.
generic component TransformAlarmC( typedef to_precision_tag, typedef to_size_type @integer(), typedef from_precision_tag, typedef from_size_type @integer(), uint8_t bit_shift_right ){ provides interface Alarm<to_precision_tag,to_size_type> as Alarm; uses interface Counter<to_precision_tag,to_size_type> as Counter; uses interface Alarm<from_precision_tag,from_size_type> as AlarmFrom;}
to_precision_tag and to_size_type describe the final precision andfinal width for the provided Alarm. from_precision_tag andfrom_size_type describe the precision and width for the sourceAlarmFrom. bit_shift_right describes the bit-shift necessary toconvert from the used precision to the provided precision.
For instance to convert from an Alarm<T32khz,uint16_t> to anAlarm<TMilli,uint32_t>, the following TransformAlarmC would becreated:
new TransformAlarmC( TMilli, uint32_t, T32khz, uint16_t, 5 )
It is the exclusive responsibility of the developer usingTransformAlarmC to ensure that all five of its arguments are selfconsistent. No compile errors are generated if the parameterspassed to TransformAlarmC are inconsistent.
TransformCounterC decreases precision and/or widens a Counter.
generic component TransformCounterC( typedef to_precision_tag, typedef to_size_type @integer(), typedef from_precision_tag, typedef from_size_type @integer(), uint8_t bit_shift_right, typedef upper_count_type @integer() ){ provides interface Counter<to_precision_tag,to_size_type> as Counter; uses interface Counter<from_precision_tag,from_size_type> as CounterFrom;}
to_precision_tag and to_size_type describe the final precision andfinal width for the provided Counter. from_precision_tag andfrom_size_type describe the precision and width for the sourceCounterFrom. bit_shift_right describes the bit-shift necessary toconvert from the used precision to the provided precision.upper_count_type describes the numeric type used to store theadditional counter bits. upper_count_type MUST be a type with widthgreater than or equal to the additional bits in to_size_type plusbit_shift_right.
For instance to convert from a Counter<T32khz,uint16_t> to aCounter<TMilli,uint32_t>, the following TransformCounterC would becreated:
new TransformCounterC( TMilli, uint32_t, T32khz, uint16_t, 5, uint32_t )
VirtualizeTimerC uses a single Timer to create up to 255 virtualtimers.
generic component VirtualizeTimerC( typedef precision_tag, int max_timers ){ provides interface Init; provides interface Timer<precision_tag> as Timer[ uint8_t num ]; uses interface Timer<precision_tag> as TimerFrom;}
The definition of the HIL interfaces are found in tinyos-2.x/tos/lib/timer:
- Alarm.nc
- BusyWait.nc
- Counter.nc
- LocalTime.nc
- Timer.h defines precision tags and strings for unique()
- Timer.nc
The implementation of the utility components are also found intinyos-2.x/tos/lib/timer:
- AlarmToTimerC.nc
- BusyWaitCounterC.nc
- CounterToLocalTimeC.nc
- TransformAlarmC.nc
- TransformCounterC.nc
- VirtualizeAlarmC.nc
- VirtualizeTimerC.nc
The implementation of timers for the MSP430 is intinyos-2.x/tos/chips/msp430/timer:
- Alarm32khz16C.nc is generic and provides a new Alarm<T32khz,uint16_t>
- Alarm32khz32C.nc is generic and provides a new Alarm<T32khz,uint32_t>
- AlarmMilli16C.nc is generic and provides a new Alarm<TMilli,uint16_t>
- AlarmMilli32C.nc is generic and provides a new Alarm<TMilli,uint32_t>
- BusyWait32khzC.nc provides BusyWait<T32khz,uint16_t>
- BusyWaitMicroC.nc provides BusyWait<TMicro,uint16_t>
- Counter32khz16C.nc provides Counter<T32khz,uint16_t>
- Counter32khz32C.nc provides Counter<T32khz,uint32_t>
- CounterMilli16C.nc provides Counter<TMilli,uint16_t>
- CounterMilli32C.nc provides Counter<TMilli,uint32_t>
- GpioCaptureC.nc
- HilTimerMilliC.nc provides LocalTime<TMilli> and Timer<TMilli> as TimerMilli[uint8_t num]
- Msp430AlarmC.nc is generic and converts an MSP430 timer to a 16-bit Alarm
- Msp430Capture.nc HPL interface definition for MSP430 timer captures
- Msp430ClockC.nc exposes MSP430 hardware clock initialization
- Msp430ClockInit.nc HPL interface definition for hardware clock initialization
- Msp430ClockP.nc implements MSP430 hardware clock initialization andcalibration and startup
- Msp430Compare.nc HPL interface definition for MSP430 timer compares
- Msp430Counter32khzC.nc provides Counter<T32khz,uint16_t> based onMSP430 TimerB
- Msp430CounterC.nc is generic and converts an Msp430Timer to a Counter
- Msp430CounterMicroC.nc provides Counter<TMicro,uint16_t> based onMSP430 TimerA
- Msp430Timer.h defines additional MSP430 timer bitmasks and structs
- Msp430Timer.nc HPL interface definition
- Msp430Timer32khzC.nc is generic and allocates a new 32khz hardware timer
- Msp430Timer32khzMapC.nc exposes the MSP430 hardware timers as aparameterized interface allocatable using Msp430Timer32khzC
- Msp430TimerC.nc exposes the MSP430 hardware timers
- Msp430TimerCapComP.nc is generic and implements the HPL for MSP430capture/compare special function registers
- Msp430TimerCommonP.nc maps the MSP430 timer interrupts to Msp430TimerEvents
- Msp430TimerControl.nc HPL interface definition
- Msp430TimerEvent.nc HPL interface definition
- Msp430TimerP.nc is generic and implements the HPL for MSP430 timerspecial function registers
Implementation of timers for the ATmega128 and PXA27x may be found intinyos-2.x/tos/chips/atm128/timer andtinyos-2.x/tos/chips/pxa27x/timer respectively.
- Atmega128
- Two 8-bit timers, each allowing
- 7 prescaler values (division by different powers of 2)
- Timer 0 can use an external 32768Hz crystal
- One compare register, with many compare actions (changeoutput pin, clear counter, generate interrupt, etc)
- Two 16-bit timers, each with
- 5 prescaler values
- External and software clocking options
- Three compare registers (again with many actions)
- Input capture
- MSP430
- Two 16-bit timers with
- One with three compare registers
- One with eight compare registers
- Each from distinct clock source
- Each with limited prescalers
- Intel PXA27x
- One fixed rate (3.25MHz) 32-bit timer with
- 4 compare registers
- Watchdog functionality
- 8 variable rate 32-bit timers with
- 1 associated compare register each
- Individually selectable rates: 1/32768s, 1ms, 1s, 1us
- Individually selectable sources: (32.768 external osc,13 Mhz internal clock)
- Periodic & one-shot capability
- Two external sync events
The Atmega128 exposes its four timers through a common set of interfaces:
- HplTimer<width> - get/set current time, overflow event, control, init
- HplCompare<width> - get/set compare time, fired event, control
- HplCapture<width> - get/set capture time, captured event, control, config
Parameterising these interfaces by width allows reusing the same interfacesfor the 8 and 16-bit timers. This simplifies building reusable higher levelcomponents which are independent of timer width.
interface HplAtm128Timer<timer_size>{ /// Timer value register: Direct access async command timer_size get(); async command void set( timer_size t ); /// Interrupt signals async event void overflow(); //<! Signalled on overflow interrupt /// Interrupt flag utilites: Bit level set/clr async command void reset(); //<! Clear the overflow interrupt flag async command void start(); //<! Enable the overflow interrupt async command void stop(); //<! Turn off overflow interrupts async command bool test(); //<! Did overflow interrupt occur? async command bool isOn(); //<! Is overflow interrupt on? /// Clock initialization interface async command void off(); //<! Turn off the clock async command void setScale( uint8_t scale); //<! Turn on the clock async command uint8_t getScale(); //<! Get prescaler setting}interface HplAtm128Compare<size_type>{ /// Compare value register: Direct access async command size_type get(); async command void set(size_type t); /// Interrupt signals async event void fired(); //<! Signalled on compare interrupt /// Interrupt flag utilites: Bit level set/clr async command void reset(); //<! Clear the compare interrupt flag async command void start(); //<! Enable the compare interrupt async command void stop(); //<! Turn off comparee interrupts async command bool test(); //<! Did compare interrupt occur? async command bool isOn(); //<! Is compare interrupt on?}interface HplAtm128Capture<size_type>{ /// Capture value register: Direct access async command size_type get(); async command void set(size_type t); /// Interrupt signals async event void captured(size_type t); //<! Signalled on capture int /// Interrupt flag utilites: Bit level set/clr async command void reset(); //<! Clear the capture interrupt flag async command void start(); //<! Enable the capture interrupt async command void stop(); //<! Turn off capture interrupts async command bool test(); //<! Did capture interrupt occur? async command bool isOn(); //<! Is capture interrupt on? async command void setEdge(bool up); //<! True = detect rising edge}
These interfaces are provided by four components, corresponding to eachhardware timer: HplAtm128Timer0AsyncC, and HplAtm128Timer0C throughHplAtm128Timer3C. Timers 1 and 3 have three compare registers, so offera parameterised HplAtm128Compare interface:
configuration HplAtm128Timer1C{ provides { // 16-bit Timers interface HplAtm128Timer<uint16_t> as Timer; interface HplAtm128TimerCtrl16 as TimerCtrl; interface HplAtm128Capture<uint16_t> as Capture; interface HplAtm128Compare<uint16_t> as Compare[uint8_t id]; }}...
where the id corresponds to the compare register number. The parameterisedinterface is only connected for id equal to 0, 1 or 2. Attempts to useanother value cause a compile-time error. This is achieved as follows (codefrom the implementation of HplAtm128Timer1C)
Compare[0] = HplAtm128Timer1P.CompareA; Compare[1] = HplAtm128Timer1P.CompareB;Compare[2] = HplAtm128Timer1P.CompareC;
The Atmega128 chip components do not define a HAL, as the timerconfiguration choices (frequencies, use of input capture or compare output,etc) are platform-specific. Instead, it provides a few generic componentsfor converting the HPL interfaces into platform-independent interfaces.These generic components include appropriate configuration parameters(e.g., prescaler values):
generic module Atm128AlarmC(typedef frequency_tag, typedef timer_size @integer(), uint8_t prescaler, int mindt){ provides interface Init; provides interface Alarm<frequency_tag, timer_size> as Alarm; uses interface HplTimer<timer_size>; uses interface HplCompare<timer_size>;} ...generic module Atm128CounterC(typedef frequency_tag, typedef timer_size @integer()){ provides interface Counter<frequency_tag,timer_size> as Counter; uses interface HplTimer<timer_size> as Timer;} ...
As a result of issues arising from using timer 0 in asynchronous mode,the HAL also offers the following component:
generic configuration Atm128AlarmAsyncC(typedef precision, int divider) { provides { interface Init @atleastonce(); interface Alarm<precision, uint32_t>; interface Counter<precision, uint32_t>; }}...
which builds a 32-bit alarm and timer over timer 0. divider is usedto initialise the timer0 scaling factor.
Members of the mica family (mica2, mica2dot, micaz) use the Atmega128microprocessor and have external crystals at 4 or 7.37MHz. Additionally,they can be run from an internal oscillator at 1, 2, 4, or 8 MHz. Theinternal oscillator is less precise, but allows for much faster startupfrom power-down and power-save modes (6 clocks vs 16000 clocks). Finally,power consumption is lower at the lower frequencies.
The mica family members support operation at all these frequencies viaa MHZ preprocessor symbol, which can be defined to 1, 2, 4, or 8.If undefined, it defaults to a platform-dependent value (4 for mica2dot,8 for mica2 and micaz).
The mica family configures its four timers in part based on the valueof this MHZ symbol:
Timer 0: uses Atm128AlarmAsyncC to divide the external 32768Hz crystalby 32, creating a 32-bit alarm and counter. This alarm and counter isused to build HilTimerMilliC, using the AlarmToTimerC,VirtualizeTimerC and CounterToLocalTimeC utility components.
Timing accuracy is as good as the external crystal.
Timer 1: the 16-bit hardware timer 1 is set to run at 1MHz if possible.However, the set of dividers for timer 1 is limited to 1, 8,64, 256 and 1024. So, when clocked at 2 or 4MHz, a divider of 1 isselected and timer 1 runs at 2 or 4MHz. To reflect this fact, the HAL components exposing timer 1 are named CounterOne16C andAlarmOne16C (rather than the CounterMicro16C AlarmMicro16Cas suggested in Section 3).
32-bit microsecond Counters and Alarms, named CounterMicro32C andAlarmMicro32C, are created from CounterOne16C andAlarmOne16C using the TransformAlarmC and TransformCounterC utility components.
Three compare registers are available on timer1, so up to three instancesof AlarmOne16C and/or AlarmMicro32C can be created. The timingaccuracy depends on how the mote is clocked:
Timer 2: this timer is not currently exposed by the HAL.
Timer 3: the 16-bit hardware timer 3 is set to run at a rate close to32768Hz, if possible. As with timer 1, the limited set of dividers makesthis impossible at some clock frequencies, so the 16-bit timer 3 HALcomponents are named CounterThree16C and AlarmThree16C. As with timer 1, the rate of timer 3 is adjusted in software tobuild 32-bit counter and 32-bit alarms, giving componentsCounter32khz32C and Alarm32khz32C. As with timer 1, three compareregisters, hence up to three instances of Alarm32khz32C and/orAlarmThree16C are available.
At 1, 2, 4 and 8MHz, Counter32khz32C and Alarm32khz32C runat 31.25kHz (plus clock rate inaccuracy). At 7.37MHz, they run at~28.8kHz.
The automatic allocation of compare registers to alarms (andcorresponding compile-time error when too many compare registers areused) is achieved as follows. The implementations of AlarmOne16Cand AlarmThree16C use the Atm128AlarmC generic component andwire it, using unique, to one of the compare registers offered byHplAtm128Timer1C and HplAtm128Timer3C:
generic configuration AlarmOne16C(){ provides interface Alarm<TOne, uint16_t>;}implementation{ components HplAtm128Timer1C, InitOneP, new Atm128AlarmC(TOne, uint16_t, 3) as NAlarm; Alarm = NAlarm; NAlarm.HplAtm128Timer -> HplAtm128Timer1C.Timer; NAlarm.HplAtm128Compare -> HplAtm128Timer1C.Compare[unique(UQ_TIMER1_COMPARE)];}
On the fourth creation of an AlarmOne16C, unique(UQ_TIMER1_COMPARE)will return 3, causing a compile-time error as discussed in Appendix B(HplAtm128Timer1C's Compare interface is only defined for valuesfrom 0 to 2).
When an Atmega128 is in any power-saving mode, hardware timers 1, 2 and 3stop counting. The default Atmega128 power management will enter thesepower-saving modes even when timers 1 and 3 are enabled, so time asmeasured by timers 1 and 3 does not represent real time. However, if anyalarms built on timers 1 or 3 are active, the Atmega128 power managementwill not enter power-saving modes.
The mica family HIL components are built as follows:
Finally, the mica family motes measure their clock rate at boot time, basedon the external 32768Hz crystal. The results of this clock rate measurementare made available via the cyclesPerJiffy command of theAtm128Calibrate interface of the MeasureClockC component. Thiscommand reports the number of cycles per 1/32768s. Please see this interfacedefinition for other useful commands for more accurate timing.
联系客服