1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35 36
37
38 package ti.sysbios.knl;
39
40 import xdc.rov.ViewInfo;
41
42 import xdc.runtime.Assert;
43 import xdc.runtime.Diags;
44 import xdc.runtime.Log;
45
46 /*!
47 * ======== Clock ========
48 * System Clock Manager
49 *
50 * The System Clock Manager is responsible for all timing services in
51 * SYS/BIOS.
52 * It generates the periodic system tick. The tick period is configurable.
53 * The timeout and period for all Clock Instances and timeout values in
54 * other SYS/BIOS modules are specified in terms of Clock ticks.
55 *
56 * The Clock Manager supports two tick "modes": a periodic mode with an
57 * interrupt on each tick (TickMode_PERIODIC), and a tick suppression
58 * mode (TickMode_DYNAMIC), which reduces the number of timer interrupts to
59 * the minimum required to support the scheduled timeouts. For devices that
60 * support it (e.g., CC13xx/CC26xx devices), TickMode_DYNAMIC may be the default
61 * mode if one is not specified in the application configuration; otherwise,
62 * the default mode will be TickMode_PERIODIC. The following example shows
63 * how the tick mode can be specified in the application configuration:
64 *
65 * @p(code)
66 * var Clock = xdc.useModule('ti.sysbios.knl.Clock');
67 *
68 * // Tell the Clock module to use TickMode_PERIODIC
69 * Clock.tickMode = Clock.TickMode_PERIODIC;
70 * @p
71 *
72 * Clock objects contain functions that can be scheduled to run after a
73 * certain number of Clock ticks.
74 * Clock objects are either one-shot or periodic. Instances are started
75 * when created or they are started later using the Clock_start() function.
76 * Instances can be stopped using the Clock_stop() function. All Clock
77 * Instances are executed when they expire in the context of a software
78 * interrupt.
79 *
80 * Clock objects are placed in the Clock object service list when
81 * created/constructed and remain there until deleted/destructed.
82 * To minimize processing overhead, unused or expired Clock objects
83 * should be deleted or destructed.
84 *
85 * By default, all Clock functions run in the context of a Swi.
86 * That is, the Clock module automatically creates a Swi for
87 * its use and runs the Clock functions within that Swi.
88 * The priority of the Swi used by Clock can be changed
89 * by configuring {@link #swiPriority Clock.swiPriority}.
90 *
91 * If Swis are disabled in an application
92 * (ie {@link ti.sysbios.BIOS#swiEnabled BIOS.swiEnabled} = false),
93 * then all Clock functions are executed within the context of
94 * a Timer Hwi.
95 *
96 * The getTicks() function returns number of clock ticks since startup.
97 *
98 * By default, the Timer module defined by {@link #TimerProxy} is used to
99 * statically create a timer instance that provides a periodic 1 ms
100 * tick interrupt.
101 *
102 * If you want to use a custom configured timer for the Clock module's
103 * tick source, use the following example configuration as a guide:
104 *
105 * @p(code)
106 * var Clock = xdc.useModule('ti.sysbios.knl.Clock');
107 *
108 * // Tell the Clock module that YOU are providing the periodic interrupt
109 * Clock.tickSource = Clock.TickSource_USER;
110 *
111 * // this example uses the ti.sysbios.timers.dmtimer.Timer module
112 * var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
113 *
114 * // Change Timer 3 frequency to 24 Mhz from default if necessary
115 * Timer.intFreqs[3] = { hi:0, lo:24000000 };
116 *
117 * // create a dmtimer config parameter object
118 * var timerParams = new Timer.Params();
119 *
120 * // make sure you set the period to 1000 us (1ms)
121 * timerParams.period = 1000;
122 *
123 * // custom dmtimer config parameters here...
124 * timerParams.twer.ovf_wup_ena = 1;
125 *
126 * // Create the timer.
127 * // This example uses timer id 3.
128 * // Provide your own timer interrupt handler function.
129 * Timer.create(3, '&myTimerTick', timerParams);
130 * @p
131 *
132 * In your 'C' code, add your timer interrupt handler and have it
133 * call Clock_tick(), which will perform all of the Clock module
134 * tick duties:
135 *
136 * @p(code)
137 * #include <ti/sysbios/knl/Clock.h>
138 *
139 * Void myTimerTick(UArg arg)
140 * {
141 * Clock_tick();
142 * ...
143 * }
144 * @p
145 *
146 * @a(Note)
147 * As Clock functions execute in either a Swi or Hwi context, they
148 * are not permitted to call blocking APIs.
149
150 * Clock requires regular interrupts by an underlying timer peripheral. (If
151 * operating with TickSource_USER, Clock requires regular invocation via
152 * Clock_tick().) If the timer interrupt is inadvertently disabled Clock ticks
153 * will stop incrementing, Clock functions will not execute, and when queried
154 * Clock will report incorrect tick counts, timeouts, and ticks until timeout.
155 *
156 * Clock objects are maintained in a queue, and there may be multiple Clock
157 * objects that need to be serviced upon a given timer interrupt. Depending upon
158 * the content of the queue, and the servicing of other objects that have timed
159 * out, there will be some corresponding jitter in timing between the timer
160 * interrupt and the actual invocation of a Clock object's function.
161 *
162 * If there is a mismatch in the configured Clock tick period and the resolution
163 * of the underlying timer peripheral, by convention Clock will generate a timeout
164 * early, rather than late. For example, if the desired Clock tick period is 1
165 * millisecond, and the underlying timer is clocked at 32768Hz, the counts
166 * corresponding to 1 millisecond would be 32.678. Since an integer value must
167 * be set in the timer peripheral, a truncated value of 32 counts will be used
168 * per interrupt, resulting in an actual tick period of 0.977 msec.
169 *
170 * Clock timing services require timely servicing of the timer peripheral
171 * interrupt by the CPU, as well as timely execution of the Clock work function
172 * (typically executed as a Swi). For the case where Clock runs and sees that
173 * there have been multiple intervening timer interrupts since it was last able to
174 * process its queue, it will walk the queue multiple times to 'catch up' and
175 * resync the timeouts. If this happens the timing of execution of the missed
176 * ticks will be faster than typical. For example, if Clock finds there have been
177 * three intervening timer interrupts since it was last able to run, it will walk
178 * its queue three times rapidly to replay the missed ticks, in sequence, once for
179 * each intervening delayed tick. So if there are Clock objects that timeout on
180 * each tick increment, they will be invoked in order, but the delay between the
181 * invocation of these functions will not be a full Clock tick period; it will be
182 * much quicker, as quickly as Clock is able to repeatedly process its queue to
183 * resync to real time.
184 *
185 * Timely execution of the Clock work function is especially important for
186 * TickMode_DYNAMIC, as the timer peripheral needs to be reprogrammed on each
187 * timer peripheral interrupt. The ability of Clock to keep time sync will vary
188 * by the configured Clock tick period, the underlying timer implementation, the
189 * peripheral's count width and resolution, and the rate that the timer
190 * increments. In an extreme case, if the delay from the timer raising the
191 * interrupt to the execution of the Clock work function exceeds the rollover
192 * period of the underlying timer peripheral (e.g. a 16-bit timer running at 32kHz
193 * rolling over every 2 seconds), time sync will be lost, the next interrupt may
194 * be significantly delayed, and there will be gaps of lost Clock ticks versus
195 * real time. Some general guidelines for TickMode_DYNAMIC to maintain continuous
196 * time sync are listed below. Some implementations may be more tolerant to
197 * delays; these are conservative general limits. If these conditions cannot be
198 * met the Clock module should be configured for TickMode_PERIODIC.
199 * @p(blist)
200 * - Hardware interrupts must not be disabled too long, to exceed a Clock tick
201 * period interval.
202 * -Non-nestable hardware ISRs must not run longer than the Clock tick period
203 * interval.
204 * -No application Swi or Hwi should be allowed to run at the same or higher
205 * priority as the Clock work function, long enough to exceed the Clock tick
206 * period interval.
207 * -The total execution time of Clock functions that execute on a given tick
208 * interrupt must not exceed the Clock tick period interval.
209 * @p
210 * @a
211 *
212 * @p(html)
213 * <h3> Calling Context </h3>
214 * <table border="1" cellpadding="3">
215 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
216 * </colgroup>
217 *
218 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
219 * <th> Task </th><th> Main </th><th> Startup </th></tr>
220 * <!-- -->
221 * <tr><td> {@link #construct} </td><td> N </td><td> N </td>
222 * <td> Y </td><td> Y </td><td> N </td></tr>
223 * <tr><td> {@link #create} </td><td> N </td><td> N </td>
224 * <td> Y </td><td> Y </td><td> N </td></tr>
225 * <tr><td> {@link #delete} </td><td> N </td><td> N </td>
226 * <td> Y </td><td> Y </td><td> N </td></tr>
227 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td>
228 * <td> Y </td><td> Y </td><td> N </td></tr>
229 * <tr><td> {@link #getTicks} </td><td> Y </td><td> Y </td>
230 * <td> Y </td><td> N </td><td> N </td></tr>
231 * <tr><td> {@link #getTimerHandle} </td><td> Y </td><td> Y </td>
232 * <td> Y </td><td> Y </td><td> Y </td></tr>
233 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td>
234 * <td> Y </td><td> Y </td><td> Y </td></tr>
235 * <tr><td> {@link #tick} </td><td> Y </td><td> Y </td>
236 * <td> Y </td><td> N </td><td> N </td></tr>
237 * <tr><td> {@link #tickReconfig} </td><td> Y </td><td> Y </td>
238 * <td> Y </td><td> N </td><td> N </td></tr>
239 * <tr><td> {@link #tickStart} </td><td> Y </td><td> Y </td>
240 * <td> Y </td><td> N </td><td> N </td></tr>
241 * <tr><td> {@link #tickStop} </td><td> Y </td><td> Y </td>
242 * <td> Y </td><td> N </td><td> N </td></tr>
243 *
244 * <tr><td> {@link #getTimeout} </td><td> Y </td><td> Y </td>
245 * <td> Y </td><td> Y </td><td> N </td></tr>
246 * <tr><td> {@link #isActive} </td><td> Y </td><td> Y </td>
247 * <td> Y </td><td> Y </td><td> N </td></tr>
248 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td>
249 * <td> Y </td><td> Y </td><td> N </td></tr>
250 * <tr><td> {@link #setPeriod} </td><td> Y </td><td> Y </td>
251 * <td> Y </td><td> Y </td><td> N </td></tr>
252 * <tr><td> {@link #setTimeout} </td><td> Y </td><td> Y </td>
253 * <td> Y </td><td> Y </td><td> N </td></tr>
254 * <tr><td> {@link #start} </td><td> Y </td><td> Y </td>
255 * <td> Y </td><td> Y </td><td> N </td></tr>
256 * <tr><td> {@link #stop} </td><td> Y </td><td> Y </td>
257 * <td> Y </td><td> Y </td><td> N </td></tr>
258 * <tr><td colspan="6"> Definitions: <br />
259 * <ul>
260 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
261 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
262 * <li> <b>Task</b>: API is callable from a Task thread. </li>
263 * <li> <b>Main</b>: API is callable during any of these phases: </li>
264 * <ul>
265 * <li> In your module startup after this module is started
266 * (e.g. Clock_Module_startupDone() returns TRUE). </li>
267 * <li> During
268 * {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}. </li>
269 * <li> During main().</li>
270 * <li> During
271 * {@link ti.sysbios.BIOS#startupFxns BIOS.startupFxns}.</li>
272 * </ul>
273 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
274 * <ul>
275 * <li> During
276 * {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}.</li>
277 * <li> In your module startup before this module is started
278 * (e.g. Clock_Module_startupDone() returns FALSE).</li>
279 * </ul>
280 * </ul>
281 * </td></tr>
282 *
283 * </table>
284 * @p
285 */
286
287 @DirectCall
288
289 @ModuleStartup
290 @InstanceInitStatic
291 @InstanceFinalize
292 @Template("./Clock.xdt")
293
294
295 module Clock
296 {
297 /*!
298 * ======== TickSource ========
299 * Clock tick source
300 *
301 * @field(TickSource_TIMER) The Clock module automatically configures a
302 * a Timer instance (see {@link #TimerProxy}) to drive the Clock tick.
303 * The specific timer and its period can be controlled via
304 * {@link #timerId} and {@link #tickPeriod}.
305 *
306 * @field(TickSource_USER) The Application is responsible for calling
307 * {@link #tick Clock_tick()} periodically. Make sure {@link #tickPeriod
308 * Clock.tickPeriod} is set to the period that Clock_tick() is called.
309 *
310 * Like most other module configuration parameters, the Clock.tickPeriod
311 * config parameter value is accessible in runtime C code as
312 * "Clock_tickPeriod".
313 *
314 * @field(TickSource_NULL) The Clock module is disabled.
315 * In this case, it is an error for the application to ever call
316 * Clock_tick().
317 *
318 * @see #tickPeriod
319 * @see #timerId
320 */
321 enum TickSource {
322 TickSource_TIMER, /*! Internally configure a Timer to periodically call Clock_tick() */
323 TickSource_USER, /*! Application code calls Clock_tick() */
324 TickSource_NULL /*! The Clock module is disabled */
325 };
326
327 /*!
328 * ======== TickMode ========
329 * Clock Tick Mode
330 */
331 enum TickMode {
332 TickMode_PERIODIC, /*! Timer will interrupt every period */
333 TickMode_DYNAMIC /*! Unnecessary timer ticks will be suppressed */
334 };
335
336 /*!
337 * ======== BasicView ========
338 * @_nodoc
339 */
340 metaonly struct BasicView {
341 String label;
342 UInt32 timeout;
343 UInt period;
344 String fxn[];
345 UArg arg;
346 Bool started;
347 String tRemaining;
348 Bool periodic;
349 }
350
351 /*!
352 * ======== ModuleView ========
353 * @_nodoc
354 */
355 metaonly struct ModuleView {
356 String ticks;
357 String tickSource;
358 String tickMode;
359 String timerHandle;
360 UInt timerId;
361 UInt swiPriority;
362 UInt32 tickPeriod;
363 volatile UInt nSkip;
364 }
365
366 367 368 369
370 @Facet
371 metaonly config ViewInfo.Instance rovViewInfo =
372 ViewInfo.create({
373 viewMap: [
374 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
375 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
376 ]
377 });
378
379 /*!
380 * ======== FuncPtr ========
381 * Instance function prototype
382 */
383 typedef Void (*FuncPtr)(UArg);
384
385 /*!
386 * ======== TimerProxy ========
387 * target/device-specific Timer implementation.
388 *
389 * The Timer module used by the Clock module to
390 * create a Timer instance when Clock.tickSource_TIMER is configured.
391 *
392 * By default, a target specific Timer module is internally selected
393 * for this purpose. If the user wishes to use a different Timer module
394 * then the following configuration script will serve as an example for
395 * achieving that:
396 *
397 * @p(code)
398 * var Clock = xdc.useModule('ti.sysbios.knl.Clock');
399 *
400 * // Use a dmtimer Timer instance
401 * Clock.TimerProxy = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
402 * @p
403 *
404 */
405
406 proxy TimerProxy inherits ti.sysbios.interfaces.ITimer;
407
408 /*!
409 * ======== LW_delayed ========
410 * Logged if Clock Swi delayed by >= 1 tick
411 */
412 config Log.Event LW_delayed = {
413 mask: Diags.USER3,
414 msg: "LW_delayed: delay: %d"
415 };
416
417 /*!
418 * ======== LM_tick ========
419 * Logged in every Clock tick interrupt
420 */
421 config Log.Event LM_tick = {
422 mask: Diags.USER1 | Diags.USER2,
423 msg: "LM_tick: tick: %d"
424 };
425
426 /*!
427 * ======== LM_begin ========
428 * Logged just prior to calling each Clock function
429 */
430 config Log.Event LM_begin = {
431 mask: Diags.USER1 | Diags.USER2,
432 msg: "LM_begin: clk: 0x%x, func: 0x%x"
433 };
434
435 /*!
436 * ======== A_clockDisabled ========
437 * Asserted in Clock_create()
438 */
439 config Assert.Id A_clockDisabled = {
440 msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
441 };
442
443 /*!
444 * ======== A_badThreadType ========
445 * Asserted in Clock_create and Clock_delete
446 */
447 config Assert.Id A_badThreadType = {
448 msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
449 };
450
451 /*!
452 * @_nodoc
453 * !!! Do not delete. Required for ROM compatibility !!!
454 */
455 config UInt32 serviceMargin = 0;
456
457 /*!
458 * ======== tickSource ========
459 * Source of clock ticks
460 *
461 * If this parameter is not set to TickSource_TIMER,
462 * {@link #tickStart Clock_tickStart()},
463 * {@link #tickStop Clock_tickStop()}, and
464 * {@link #tickReconfig Clock_tickReconfig()}, have no effect.
465 *
466 * The default is TickSource_TIMER.
467 */
468 config TickSource tickSource = TickSource_TIMER;
469
470 /*!
471 * ======== tickMode ========
472 * Timer tick mode
473 *
474 * This parameter specifies the tick mode to be used by the underlying
475 * Timer.
476 *
477 * With TickMode_PERIODIC the timer will interrupt the CPU at
478 * a fixed rate, defined by the tickPeriod.
479 *
480 * With TickMode_DYNAMIC the timer can be dynamically reprogrammed by
481 * Clock, to interrupt the CPU when the next tick is actually needed for
482 * a scheduled timeout. TickMode_DYNAMIC is not supported on all devices,
483 * and may have some application constraints.
484 */
485 config TickMode tickMode;
486
487 /*!
488 * ======== timerId ========
489 * Timer Id used to create a Timer instance
490 *
491 * If {@link #tickSource Clock.tickSource} is set to TickSource_TIMER,
492 * the Clock module internally creates a
493 * static Timer instance (see {@link #TimerProxy}) that automatically calls
494 * Clock_doTick() on a periodic basis (as specified by
495 * {@link #tickPeriod tickPeriod} and {@link #periodType periodType}.)
496 *
497 * This configuration parameter allows you to control which timer is
498 * used to drive the Clock module.
499 *
500 * The default value is {@link ti.sysbios.hal.Timer#ANY Timer.ANY} (~0)
501 * and the maximum timerId possible is family and device specific.
502 */
503 config UInt timerId = ~0;
504
505 /*!
506 * ======== swiPriority ========
507 * The priority of Swi used by Clock to process its instances
508 *
509 * All Clock instances are executed in the context of a single
510 * {@link Swi}. This parameter allows you to control the priority of
511 * that Swi.
512 *
513 * The default value of this parameter is Swi.numPriorities - 1; i.e.,
514 * the maximum Swi priority.
515 *
516 * @see ti.sysbios.knl.Swi#numPriorities
517 */
518 metaonly config UInt swiPriority;
519
520 /*!
521 * ======== tickPeriod ========
522 * Tick period specified in microseconds
523 *
524 * Default value is family dependent. For example, Linux systems often
525 * only support a minimum period of 10000 us and multiples of 10000 us.
526 * TI platforms have a default of 1000 us.
527 *
528 * Like most other module configuration parameters, the Clock.tickPeriod
529 * config parameter value is accessible in runtime C code as
530 * "Clock_tickPeriod".
531 */
532
533 config UInt32 tickPeriod;
534
535 /*!
536 * @_nodoc
537 * ======== stopCheckNext ========
538 * Boolean to control whether a check is made upon each Clock_stop() call
539 * to determine if the Clock object being stopped is due to timeout on the
540 * next scheduled tick. If this feature is enabled, and the timeout
541 * coincides with the next scheduled tick, then a special 'trigger' Clock
542 * will be started to force a reschedule of the next tick, as soon as
543 * possible. This feature is only applicable for Clock.TickMode_DYNAMIC.
544 *
545 * For most use cases it is most efficient to simply stop
546 * a Clock object, and then let the next scheduled tick occur naturally.
547 * But some low power application use cases (that routinely stop the next
548 * expiring Clock object) can benefit by scheduling an immediate tick, to
549 * suppress the next scheduled tick. The default value for most
550 * targets is 'false', for cc26xx/cc13xx it is 'true'. The default is
551 * established in Clock.xs, if the application has not explicitly
552 * specified a value.
553 */
554 metaonly config Bool stopCheckNext;
555
556 /*!
557 * ======== getTicks ========
558 * Time in Clock ticks
559 *
560 * The value returned will wrap back to zero after it reaches the max
561 * value that can be stored in 32 bits.
562 *
563 * @b(returns) time in clock ticks
564 */
565 UInt32 getTicks();
566
567 /*!
568 * @_nodoc
569 * ======== getTimerHandle ========
570 * Get timer Handle
571 *
572 * Used when it is necessary to change family
573 * specific options for the timer and its Hwi Object.
574 *
575 * @b(returns) Timer Handle
576 */
577 TimerProxy.Handle getTimerHandle();
578
579 /*!
580 * @_nodoc
581 * ======== setTicks ========
582 * Set the internal Clock tick counter
583 *
584 * Used internally by Power modules. Only applicable for
585 * Clock.TickMode_PERIODIC
586 */
587 Void setTicks(UInt32 ticks);
588
589 /*!
590 * ======== tickStop ========
591 * Stop clock for reconfiguration
592 *
593 * This function is used to stop the timer used for generation of
594 * clock ticks. It is used along with Clock_tickStart() and
595 * Clock_tickReconfig() to allow reconfiguration of timer at runtime.
596 *
597 * Stopping the timer may not be supported for some types of timers, and
598 * is not supported for Clock.TickMode_DYNAMIC; in these cases, this
599 * this function call will have no effect.
600 *
601 * @a(constraints)
602 * This function is non-reentrant and appropriate locks must be used to
603 * protect against re-entrancy.
604 */
605 Void tickStop();
606
607 /*!
608 * ======== tickReconfig ========
609 * Reconfigure clock for new cpu frequency
610 *
611 * This function uses the new cpu frequency to reconfigure the timer used
612 * for generation of clock ticks such that tick period is
613 * accurate. This function is used along with Clock_tickStop() and
614 * Clock_tickStart() to allow reconfiguration of timer at runtime.
615 *
616 * Reconfiguration may not be supported for some types of timers, and is
617 * not supported for Clock.TickMode_DYNAMIC; in these cases, this
618 * this function call will have no effect, and will return false.
619 *
620 * When calling Clock_tickReconfig outside of main(), you must also call
621 * Clock_tickStop and Clock_tickStart to stop and restart the timer.
622 * Use the following call sequence:
623 *
624 * @p(code)
625 * // disable interrupts if an interrupt could lead to
626 * // another call to Clock_tickReconfig or if interrupt
627 * // processing relies on having a running timer
628 * Hwi_disable() or Swi_disable();
629 * BIOS_setCpuFreq(&freq);
630 * Clock_tickStop();
631 * Clock_tickReconfig();
632 * Clock_tickStart();
633 * Hwi_restore() or Swi_enable()
634 * @p
635 *
636 * When calling Clock_tickReconfig from main(), the timer has not yet
637 * been started because the timer is started as part of BIOS_start().
638 * As a result, you can use the following simplified call sequence
639 * in main():
640 *
641 * @p(code)
642 * BIOS_setCpuFrequency(Types.FreqHz *freq);
643 * Clock_tickReconfig(Void);
644 * @p
645 *
646 * The return value is false if the timer cannot support the new
647 * frequency
648 *
649 * @b(returns) true if successful
650 *
651 * @a(constraints)
652 * This function is non-reentrant and appropriate locks must be used to
653 * protect against re-entrancy.
654 */
655 Bool tickReconfig();
656
657 /*!
658 * ======== tickStart ========
659 * Start clock after reconfiguration
660 *
661 * This function starts the timer used for generation of clock ticks
662 * It is used along with Clock_tickStop() and Clock_tickReconfig() to
663 * allow reconfiguration of timer at runtime. The new timer configuration
664 * reflects changes caused by a call to reconfig().
665 *
666 * Reconfiguration and restart of a timer may not be supported for some
667 * types of timers, and is not supported for Clock.TickMode_DYNAMIC; in
668 * these cases, this function call will have no effect.
669 *
670 * @a(constraints)
671 * This function is non-reentrant and appropriate locks must be used to
672 * protect against re-entrancy.
673 */
674 Void tickStart();
675
676 /*!
677 * ======== tick ========
678 * Advance Clock time by one tick
679 *
680 * After incrementing a global tick counter, this function posts a Swi
681 * that processes the clock instances.
682 *
683 * This function is automatically called by a timer ISR when
684 * {@link #tickSource} is set to {@link #TickSource_TIMER}.
685 *
686 * When {@link #tickSource} is set to
687 * {@link #TickSource_USER}, Clock_tick() must be called by the
688 * application. Usually, this is done within a user defined {@link ti.sysbios.hal.Hwi Hwi},
689 * {@link Swi}, or {@link Task}.
690 *
691 * Note that this function is not re-entrant. The application is
692 * responsible for ensuring that invocations of this function are
693 * serialized: either only one thread in the system ever calls this
694 * function or all calls are "wrapped" by an appropriate mutex.
695 *
696 * @see #tickSource
697 */
698 Void tick();
699
700 /*!
701 * @_nodoc
702 * ======== workFunc ========
703 * Clock Q service routine
704 *
705 * @param(arg0) Unused. required to match Swi.FuncPtr
706 * @param(arg1) Unused. required to match Swi.FuncPtr
707 */
708
709 Void workFunc(UArg arg0, UArg arg1);
710
711 /*!
712 * @_nodoc
713 * ======== workFuncDynamic ========
714 * Clock Q service routine for TickMode_DYNAMIC
715 *
716 * @param(arg0) Unused. required to match Swi.FuncPtr
717 * @param(arg1) Unused. required to match Swi.FuncPtr
718 */
719 Void workFuncDynamic(UArg arg0, UArg arg1);
720
721 /*!
722 * @_nodoc
723 * ======= logTick ========
724 * Log the LD_tick from within Clock module scope
725 */
726 Void logTick();
727
728 /*!
729 * @_nodoc
730 * ======== getCompletedTicks ========
731 * Get the number of Clock ticks that have completed
732 *
733 * Returns the number of ticks completed, to the point where
734 * the underlying Timer interrupt has been serviced.
735 *
736 * Used by some TimestampProviders
737 *
738 * @b(returns) time in clock ticks
739 */
740 UInt32 getCompletedTicks();
741
742 /*!
743 * @_nodoc
744 * ======== getTickPeriod ========
745 * Get the Clock tick period in timer counts
746 *
747 * The period is in units returned by the underlying Timer.
748 *
749 * Used by some TimestampProviders
750 *
751 * @b(returns) period in timer counts
752 */
753 UInt32 getTickPeriod();
754
755 /*!
756 * @_nodoc
757 * ======== getTicksUntilInterrupt ========
758 * Get the number of Clock tick periods expected to expire between now
759 * and the next interrupt from the timer peripheral
760 *
761 * Used internally by Power modules.
762 *
763 * @b(returns) count in ticks
764 */
765 UInt32 getTicksUntilInterrupt();
766
767 /*!
768 * @_nodoc
769 * ======== getTicksUntilTimeout ========
770 * Get the number of Clock tick periods between now and the next
771 * active Clock object timeout.
772 *
773 * Used internally by Power modules.
774 *
775 * @a(constraints)
776 * Must be called with interrupts disabled. Only applicable for
777 * Clock.TickSource_TIMER.
778 *
779 * @b(returns) count in ticks
780 */
781 UInt32 getTicksUntilTimeout();
782
783 /*!
784 * @_nodoc
785 * ======= walkQueueDynamic ========
786 * Walk Clock's work queue for TickMode_DYNAMIC
787 */
788 UInt32 walkQueueDynamic(Bool service, UInt32 tick);
789
790 /*!
791 * @_nodoc
792 * ======= walkQueuePeriodic ========
793 * Walk Clock's work queue for TickMode_PERIODIC
794 */
795 UInt32 walkQueuePeriodic();
796
797 /*!
798 * @_nodoc
799 * ======= scheduleNextTick ========
800 * Reprogram Clock's Timer for earliest required tick
801 */
802 Void scheduleNextTick(UInt32 deltaTicks, UInt32 absTick);
803
804 instance:
805
806 /*!
807 * ======== create ========
808 * Creates a Clock Instance
809 *
810 * The first argument is the function that gets called when the timeout
811 * expires.
812 *
813 * The 'timeout' argument is used to specify the startup timeout for
814 * both one-shot and periodic Clock instances (in Clock ticks). This
815 * timeout is applied when the Clock instance is started. For periodic
816 * instances, the configured Clock function will be called initially
817 * after an interval equal to the timeout, and will be subsequently
818 * called at the rate specified by the {@link #period} parameter. For
819 * one-shot instances (where the {@link #period} parameter is 0), once
820 * the Clock instance is started (with {@link #start Clock_start()} or
821 * automatically if {@link #startFlag} is true) the configured Clock
822 * function will be called once after an interval equal to the timeout.
823 *
824 * When instances are created they are placed upon a linked list managed
825 * by the Clock module. For this reason, instances cannot be created
826 * from either Hwi or Swi context.
827 *
828 * By default, all Clock functions run in the context of a Swi.
829 * That is, the Clock module automatically creates a Swi for
830 * its use and runs the Clock functions within that Swi.
831 * The priority of the Swi used by Clock can be changed
832 * by configuring {@link #swiPriority Clock.swiPriority}.
833 *
834 * If Swis are disabled in an application
835 * (ie {@link ti.sysbios.BIOS#swiEnabled BIOS.swiEnabled} = false),
836 * then all Clock functions are executed within the context of
837 * a Timer Hwi.
838 *
839 * @a(constraint)
840 * @p(blist)
841 * As Clock functions execute in either a Swi or Hwi context, they
842 * are not permitted to call blocking APIs.
843 * @p
844 * @a
845 *
846 * @param(clockFxn) Function that runs upon timeout
847 * @param(timeout) One-shot timeout or initial start delay (in clock
848 * ticks)
849 */
850 create(FuncPtr clockFxn, UInt timeout);
851
852
853
854 /*!
855 * ======== startFlag ========
856 * Start immediately after instance is created
857 *
858 * When this flag is set to false, the user will have to call
859 * Clock_start() to start the instance.
860 *
861 * When set to true, both statically created Clock objects and Clock
862 * objects created in main() are started at the end of main() when the
863 * user calls BIOS_start(). Dynamically created Clock objects created
864 * after main() (ie within a task) will be started immediately.
865 *
866 * The default setting for this parameter is false.
867 *
868 * The configured Clock function will be called initially after an
869 * interval equal to the 'timeout' argument for both one-shot and
870 * periodic Clock objects.
871 *
872 * Periodic Clock objects will subsequently be called at the rate
873 * specified by the {@link #period} parameter.
874 *
875 */
876 config Bool startFlag = false;
877
878 /*!
879 * ======== period ========
880 * Period of this instance (in clock ticks)
881 *
882 * This parameter is used to set the subsequent timeout interval (in
883 * Clock ticks) for periodic instances.
884 *
885 * The default value of this parameter is 0, which indicates this is
886 * a one-shot Clock object.
887 *
888 * A non zero value for this parameter specifies that the Clock
889 * object is to be called periodically, and also specifies the
890 * rate (in Clock ticks) that the Clock function will be called
891 * AFTER the initial 'timeout' argument period.
892 *
893 * For one-shot Clock instances, this parameter must be set to zero.
894 */
895 config UInt32 period = 0;
896
897 /*!
898 * ======== arg ========
899 * Uninterpreted argument passed to instance function
900 *
901 * The default is null.
902 */
903 config UArg arg = null;
904
905 /*!
906 * @_nodoc
907 * ======== addI ========
908 * Lightweight One-Shot Clock create for internal SYS/BIOS timeout APIs
909 * Does NOT start the timeout (ie requires Clock_startI() to be called)
910 * Does NOT assume Hwis are disabled
911 */
912 Void addI(FuncPtr clockFxn, UInt32 timeout, UArg arg);
913
914 /*!
915 * @_nodoc
916 * ======== initI ========
917 * Lightweight One-Shot Clock create for internal SYS/BIOS timeout APIs
918 * Does NOT start the timeout (ie requires Clock_startI() to be called)
919 * Does NOT assume Hwis are disabled
920 * Does NOT add Clock object to Clock Q.
921 */
922 Void initI(FuncPtr clockFxn, UInt32 timeout, UArg arg);
923
924 /*!
925 * @_nodoc
926 * ======== enqueueI ========
927 * Add Clock object to Clock Q.
928 * Assumes Hwis are disabled
929 */
930 Void enqueueI();
931
932 /*!
933 * @_nodoc
934 * ======== removeI ========
935 * Lightweight Clock delete for internal SYS/BIOS timeout APIs
936 * Assumes Hwis are disabled
937 */
938 Void removeI();
939
940 /*!
941 * ======== start ========
942 * Start instance
943 *
944 * The {@link #timeout} and {@link #period} values set during create()
945 * or by calling Clock_setTimeout() and Clock_setPeriod() are used and
946 * the expiry is recomputed.
947 * Note that for periodic instances, the first expiry is
948 * computed using the timeout specified. All subsequent expiries use the
949 * period value.
950 *
951 * @a(constraints)
952 * The timeout of an instance cannot be zero.
953 *
954 * @a(constraints)
955 * When using a very fast Clock tick period it may not always be possible
956 * to start a Clock object with maximum timeout (0xFFFFFFFF). This limit
957 * applies when Clock_start() is called while Clock is in-process of
958 * servicing its timeout queue (called by another ISR, by a higher-priority
959 * Swi, or within a Clock function). In this situation the timeout of the
960 * newly-started object may occur in the near future rather than in the
961 * far future. For one-shot objects there will be a single early timeout;
962 * for periodic objects there will be an early timeout, but the next
963 * timeout will occur correctly offset from the first timeout. This
964 * condition is due to a Clock tick count wrap, and only occurs when there
965 * is a very fast Clock tick period such that there are virtual Clock tick
966 * period increments between the last timer interrupt to the invocation of
967 * Clock_start(). For example, if the Clock tick period is 10 usec, and if
968 * the Clock tick count is 0x10000005 when the interrupt occurs, and if
969 * there are 3 intervening tick periods (30 usec) before the call to
970 * Clock_start(), then the future timeout will be computed as
971 * 0x10000005 + 3 + 0xFFFFFFFF = 0x10000007, only 2 ticks in the future.
972 * In this case, the maximum timeout should be limited to 0xFFFFFFFD to
973 * achieve the maximum delay since the last timer interrupt.
974 */
975 Void start();
976
977 /*!
978 * @_nodoc
979 * ======== startI ========
980 * Internal start function which assumes Hwis disabled
981 */
982 Void startI();
983
984 /*!
985 * ======== stop ========
986 * Stop instance
987 */
988 Void stop();
989
990 /*!
991 * ======== setPeriod ========
992 * Set periodic interval
993 *
994 * @param(period) periodic interval in Clock ticks
995 *
996 * @a(constraints)
997 * Cannot change period of instance that has been started.
998 */
999 Void setPeriod(UInt32 period);
1000
1001 /*!
1002 * ======== setTimeout ========
1003 * Set the initial timeout
1004 *
1005 * @param(timeout) initial timeout in Clock ticks
1006 *
1007 * @a(constraints)
1008 * Cannot change the initial timeout of instance that has been started.
1009 */
1010 Void setTimeout(UInt32 timeout);
1011
1012 /*!
1013 * ======== setFunc ========
1014 * Overwrite Clock function and arg
1015 *
1016 * Replaces a Clock object's clockFxn function originally
1017 * provided in {@link #create}.
1018 *
1019 * @param(clockFxn) function of type FuncPtr
1020 * @param(arg) argument to clockFxn
1021 *
1022 * @a(constraints)
1023 * Cannot change function and arg of Clock object that has been started.
1024 */
1025 Void setFunc(FuncPtr fxn, UArg arg);
1026
1027 /*!
1028 * ======== getPeriod ========
1029 * Get period of instance
1030 *
1031 * Returns the period of an instance.
1032 *
1033 * @b(returns) returns periodic interval in Clock ticks
1034 */
1035 UInt32 getPeriod();
1036
1037 /*!
1038 * ======== getTimeout ========
1039 * Get timeout of instance
1040 *
1041 * Returns the remaining time if the instance is active; if the instance
1042 * is not active, returns zero.
1043 *
1044 * @b(returns) returns timeout in clock ticks
1045 */
1046 UInt32 getTimeout();
1047
1048 /*!
1049 * ======== isActive ========
1050 * Determine if Clock object is currently active (ie running)
1051 *
1052 * Returns TRUE if Clock object is currently active
1053 *
1054 * @b(returns) returns active state
1055 */
1056 Bool isActive();
1057
1058 internal:
1059
1060 1061 1062 1063
1064 metaonly config Bool timerSupportsDynamic = false;
1065
1066 1067 1068 1069 1070
1071 config Void (*doTickFunc)(UArg);
1072
1073 /*!
1074 * ======== doTick ========
1075 * Function called by the timer interrupt handler
1076 *
1077 * @param(arg) Unused. Required to match signature of Hwi.FuncPtr
1078 */
1079
1080 Void doTick(UArg arg);
1081
1082 1083 1084 1085
1086 config Clock.Handle triggerClock;
1087
1088 1089 1090 1091
1092 Void triggerFunc(UArg arg);
1093
1094 1095 1096
1097 struct Instance_State {
1098 Queue.Elem elem;
1099 UInt32 timeout;
1100 UInt32 currTimeout;
1101 UInt32 period;
1102 volatile Bool active;
1103 FuncPtr fxn;
1104 UArg arg;
1105
1106 1107 1108 1109 1110 1111 1112
1113 UInt32 timeoutTicks;
1114 };
1115
1116 1117 1118
1119 struct Module_State {
1120 volatile UInt32 ticks;
1121 UInt swiCount;
1122 TimerProxy.Handle timer;
1123
1124 Queue.Object clockQ;
1125 Swi.Handle swi;
1126 volatile UInt numTickSkip;
1127 UInt32 nextScheduledTick;
1128 UInt32 maxSkippable;
1129 Bool inWorkFunc;
1130 volatile Bool startDuringWorkFunc;
1131 Bool ticking;
1132 };
1133 }