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