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., MSP430 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 (for example, for MSP430,
422 * see a description on this wiki page:
423 * https://processors.wiki.ti.com/index.php/SYS/BIOS_for_the_MSP430#Clock_Tick_Suppression).
424 */
425 config TickMode tickMode;
426
427 /*!
428 * ======== timerId ========
429 * Timer Id used to create a Timer instance
430 *
431 * If {@link #tickSource Clock.tickSource} is set to TickSource_TIMER,
432 * the Clock module internally creates a
433 * static Timer instance (see {@link #TimerProxy}) that automatically calls
434 * Clock_doTick() on a periodic basis (as specified by
435 * {@link #tickPeriod tickPeriod} and {@link #periodType periodType}.)
436 *
437 * This configuration parameter allows you to control which timer is
438 * used to drive the Clock module.
439 *
440 * The default value is {@link ti.sysbios.hal.Timer#ANY Timer.ANY} (~0)
441 * and the maximum timerId possible is family and device specific.
442 */
443 config UInt timerId = ~0;
444
445 /*!
446 * ======== swiPriority ========
447 * The priority of Swi used by Clock to process its instances
448 *
449 * All Clock instances are executed in the context of a single
450 * {@link Swi}. This parameter allows you to control the priority of
451 * that Swi.
452 *
453 * The default value of this parameter is Swi.numPriorities - 1; i.e.,
454 * the maximum Swi priority.
455 *
456 * @see ti.sysbios.knl.Swi#numPriorities
457 */
458 metaonly config UInt swiPriority;
459
460 /*!
461 * ======== tickPeriod ========
462 * Tick period specified in microseconds
463 *
464 * Default value is family dependent. For example, Linux systems often
465 * only support a minimum period of 10000 us and multiples of 10000 us.
466 * TI platforms have a default of 1000 us.
467 *
468 * Like most other module configuration parameters, the Clock.tickPeriod
469 * config parameter value is accessible in runtime C code as
470 * "Clock_tickPeriod".
471 */
472 config UInt32 tickPeriod;
473
474 /*!
475 * @_nodoc
476 * ======== stopCheckNext ========
477 * Boolean to control whether a check is made upon each Clock_stop() call
478 * to determine if the Clock object being stopped is due to timeout on the
479 * next scheduled tick. If this feature is enabled, and the timeout
480 * coincides with the next scheduled tick, then a special 'trigger' Clock
481 * will be started to force a reschedule of the next tick, as soon as
482 * possible. This feature is only applicable for Clock.TickMode_DYNAMIC.
483 *
484 * For most use cases it is most efficient to simply stop
485 * a Clock object, and then let the next scheduled tick occur naturally.
486 * But some low power application use cases (that routinely stop the next
487 * expiring Clock object) can benefit by scheduling an immediate tick, to
488 * suppress the next scheduled tick. The default value for most
489 * targets is 'false', for cc26xx/cc13xx it is 'true'. The default is
490 * established in Clock.xs, if the application has not explicitly
491 * specified a value.
492 */
493 metaonly config Bool stopCheckNext;
494
495 /*!
496 * ======== getTicks ========
497 * Time in Clock ticks
498 *
499 * The value returned will wrap back to zero after it reaches the max
500 * value that can be stored in 32 bits.
501 *
502 * @b(returns) time in clock ticks
503 */
504 UInt32 getTicks();
505
506 /*!
507 * @_nodoc
508 * ======== getTimerHandle ========
509 * Get timer Handle
510 *
511 * Used when it is necessary to change family
512 * specific options for the timer and its Hwi Object.
513 *
514 * @b(returns) Timer Handle
515 */
516 TimerProxy.Handle getTimerHandle();
517
518 /*!
519 * @_nodoc
520 * ======== setTicks ========
521 * Set the internal Clock tick counter
522 *
523 * Used internally by Power modules.
524 */
525 Void setTicks(UInt32 ticks);
526
527 /*!
528 * ======== tickStop ========
529 * Stop clock for reconfiguration
530 *
531 * This function is used to stop the timer used for generation of
532 * clock ticks. It is used along with Clock_tickStart() and
533 * Clock_tickReconfig() to allow reconfiguration of timer at runtime.
534 *
535 * Stopping the timer may not be supported for some types of timers, and
536 * is not supported for Clock.TickMode_DYNAMIC; in these cases, this
537 * this function call will have no effect.
538 *
539 * @a(constraints)
540 * This function is non-reentrant and appropriate locks must be used to
541 * protect against re-entrancy.
542 */
543 Void tickStop();
544
545 /*!
546 * ======== tickReconfig ========
547 * Reconfigure clock for new cpu frequency
548 *
549 * This function uses the new cpu frequency to reconfigure the timer used
550 * for generation of clock ticks such that tick period is
551 * accurate. This function is used along with Clock_tickStop() and
552 * Clock_tickStart() to allow reconfiguration of timer at runtime.
553 *
554 * Reconfiguration may not be supported for some types of timers, and is
555 * not supported for Clock.TickMode_DYNAMIC; in these cases, this
556 * this function call will have no effect, and will return false.
557 *
558 * When calling Clock_tickReconfig outside of main(), you must also call
559 * Clock_tickStop and Clock_tickStart to stop and restart the timer.
560 * Use the following call sequence:
561 *
562 * @p(code)
563 * // disable interrupts if an interrupt could lead to
564 * // another call to Clock_tickReconfig or if interrupt
565 * // processing relies on having a running timer
566 * Hwi_disable() or Swi_disable();
567 * BIOS_setCpuFreq(&freq);
568 * Clock_tickStop();
569 * Clock_tickReconfig();
570 * Clock_tickStart();
571 * Hwi_restore() or Swi_enable()
572 * @p
573 *
574 * When calling Clock_tickReconfig from main(), the timer has not yet
575 * been started because the timer is started as part of BIOS_start().
576 * As a result, you can use the following simplified call sequence
577 * in main():
578 *
579 * @p(code)
580 * BIOS_setCpuFrequency(Types.FreqHz *freq);
581 * Clock_tickReconfig(Void);
582 * @p
583 *
584 * The return value is false if the timer cannot support the new
585 * frequency
586 *
587 * @b(returns) true if successful
588 *
589 * @a(constraints)
590 * This function is non-reentrant and appropriate locks must be used to
591 * protect against re-entrancy.
592 */
593 Bool tickReconfig();
594
595 /*!
596 * ======== tickStart ========
597 * Start clock after reconfiguration
598 *
599 * This function starts the timer used for generation of clock ticks
600 * It is used along with Clock_tickStop() and Clock_tickReconfig() to
601 * allow reconfiguration of timer at runtime. The new timer configuration
602 * reflects changes caused by a call to reconfig().
603 *
604 * Reconfiguration and restart of a timer may not be supported for some
605 * types of timers, and is not supported for Clock.TickMode_DYNAMIC; in
606 * these cases, this function call will have no effect.
607 *
608 * @a(constraints)
609 * This function is non-reentrant and appropriate locks must be used to
610 * protect against re-entrancy.
611 */
612 Void tickStart();
613
614 /*!
615 * ======== tick ========
616 * Advance Clock time by one tick
617 *
618 * After incrementing a global tick counter, this function posts a Swi
619 * that processes the clock instances.
620 *
621 * This function is automatically called by a timer ISR when
622 * {@link #tickSource} is set to {@link #TickSource_TIMER}.
623 *
624 * When {@link #tickSource} is set to
625 * {@link #TickSource_USER}, Clock_tick() must be called by the
626 * application. Usually, this is done within a user defined {@link ti.sysbios.hal.Hwi Hwi},
627 * {@link Swi}, or {@link Task}.
628 *
629 * Note that this function is not re-entrant. The application is
630 * responsible for ensuring that invocations of this function are
631 * serialized: either only one thread in the system ever calls this
632 * function or all calls are "wrapped" by an appropriate mutex.
633 *
634 * @see #tickSource
635 */
636 Void tick();
637
638 /*!
639 * @_nodoc
640 * ======== workFunc ========
641 * Clock Q service routine
642 *
643 * @param(arg0) Unused. required to match Swi.FuncPtr
644 * @param(arg1) Unused. required to match Swi.FuncPtr
645 */
646 Void workFunc(UArg arg0, UArg arg1);
647
648 /*!
649 * @_nodoc
650 * ======== workFuncDynamic ========
651 * Clock Q service routine for TickMode_DYNAMIC
652 *
653 * @param(arg0) Unused. required to match Swi.FuncPtr
654 * @param(arg1) Unused. required to match Swi.FuncPtr
655 */
656 Void workFuncDynamic(UArg arg0, UArg arg1);
657
658 /*!
659 * @_nodoc
660 * ======= logTick ========
661 * Log the LD_tick from within Clock module scope
662 */
663 Void logTick();
664
665 /*!
666 * @_nodoc
667 * ======== getCompletedTicks ========
668 * Get the number of Clock ticks that have completed
669 *
670 * Returns the number of ticks completed, to the point where
671 * the underlying Timer interrupt has been serviced.
672 *
673 * Used by some TimestampProviders
674 *
675 * @b(returns) time in clock ticks
676 */
677 UInt32 getCompletedTicks();
678
679 /*!
680 * @_nodoc
681 * ======== getTickPeriod ========
682 * Get the Clock tick period in timer counts
683 *
684 * The period is in units returned by the underlying Timer.
685 *
686 * Used by some TimestampProviders
687 *
688 * @b(returns) period in timer counts
689 */
690 UInt32 getTickPeriod();
691
692 /*!
693 * @_nodoc
694 * ======== getTicksUntilInterrupt ========
695 * Get the number of Clock tick periods expected to expire between now
696 * and the next interrupt from the timer peripheral
697 *
698 * Used internally by Power modules.
699 *
700 * @b(returns) count in ticks
701 */
702 UInt32 getTicksUntilInterrupt();
703
704 /*!
705 * @_nodoc
706 * ======== getTicksUntilTimeout ========
707 * Get the number of Clock tick periods between now and the next
708 * active Clock object timeout.
709 *
710 * Used internally by Power modules.
711 *
712 * @a(constraints)
713 * Must be called with interrupts disabled. Only applicable for
714 * Clock.TickSource_TIMER.
715 *
716 * @b(returns) count in ticks
717 */
718 UInt32 getTicksUntilTimeout();
719
720 /*!
721 * @_nodoc
722 * ======= walkQueueDynamic ========
723 * Walk Clock's work queue for TickMode_DYNAMIC
724 */
725 UInt32 walkQueueDynamic(Bool service, UInt32 tick);
726
727 /*!
728 * @_nodoc
729 * ======= walkQueuePeriodic ========
730 * Walk Clock's work queue for TickMode_PERIODIC
731 */
732 UInt32 walkQueuePeriodic();
733
734 /*!
735 * @_nodoc
736 * ======= scheduleNextTick ========
737 * Reprogram Clock's Timer for earliest required tick
738 */
739 Void scheduleNextTick(UInt32 deltaTicks, UInt32 absTick);
740
741 instance:
742
743 /*!
744 * ======== create ========
745 * Creates a Clock Instance
746 *
747 * The first argument is the function that gets called when the timeout
748 * expires.
749 *
750 * The 'timeout' argument is used to specify the startup timeout for
751 * both one-shot and periodic Clock instances (in Clock ticks). This
752 * timeout is applied when the Clock instance is started. For periodic
753 * instances, the configured Clock function will be called initially
754 * after an interval equal to the timeout, and will be subsequently
755 * called at the rate specified by the {@link #period} parameter. For
756 * one-shot instances (where the {@link #period} parameter is 0), once
757 * the Clock instance is started (with {@link #start Clock_start()} or
758 * automatically if {@link #startFlag} is true) the configured Clock
759 * function will be called once after an interval equal to the timeout.
760 *
761 * When instances are created they are placed upon a linked list managed
762 * by the Clock module. For this reason, instances cannot be created
763 * from either Hwi or Swi context.
764 *
765 * By default, all Clock functions run in the context of a Swi.
766 * That is, the Clock module automatically creates a Swi for
767 * its use and runs the Clock functions within that Swi.
768 * The priority of the Swi used by Clock can be changed
769 * by configuring {@link #swiPriority Clock.swiPriority}.
770 *
771 * If Swis are disabled in an application
772 * (ie {@link ti.sysbios.BIOS#swiEnabled BIOS.swiEnabled} = false),
773 * then all Clock functions are executed within the context of
774 * a Timer Hwi.
775 *
776 * @a(constraint)
777 * @p(blist)
778 * As Clock functions execute in either a Swi or Hwi context, they
779 * are not permitted to call blocking APIs.
780 * @p
781 * @a
782 *
783 * @param(clockFxn) Function that runs upon timeout
784 * @param(timeout) One-shot timeout or initial start delay (in clock
785 * ticks)
786 */
787 create(FuncPtr clockFxn, UInt timeout);
788
789 /*!
790 * ======== startFlag ========
791 * Start immediately after instance is created
792 *
793 * When this flag is set to false, the user will have to call
794 * Clock_start() to start the instance.
795 *
796 * When set to true, both statically created Clock objects and Clock
797 * objects created in main() are started at the end of main() when the
798 * user calls BIOS_start(). Dynamically created Clock objects created
799 * after main() (ie within a task) will be started immediately.
800 *
801 * The default setting for this parameter is false.
802 *
803 * The configured Clock function will be called initially after an
804 * interval equal to the 'timeout' argument for both one-shot and
805 * periodic Clock objects.
806 *
807 * Periodic Clock objects will subsequently be called at the rate
808 * specified by the {@link #period} parameter.
809 *
810 */
811 config Bool startFlag = false;
812
813 /*!
814 * ======== period ========
815 * Period of this instance (in clock ticks)
816 *
817 * This parameter is used to set the subsequent timeout interval (in
818 * Clock ticks) for periodic instances.
819 *
820 * The default value of this parameter is 0, which indicates this is
821 * a one-shot Clock object.
822 *
823 * A non zero value for this parameter specifies that the Clock
824 * object is to be called periodically, and also specifies the
825 * rate (in Clock ticks) that the Clock function will be called
826 * AFTER the initial 'timeout' argument period.
827 *
828 * For one-shot Clock instances, this parameter must be set to zero.
829 */
830 config UInt32 period = 0;
831
832 /*!
833 * ======== arg ========
834 * Uninterpreted argument passed to instance function
835 *
836 * The default is null.
837 */
838 config UArg arg = null;
839
840 /*!
841 * @_nodoc
842 * ======== addI ========
843 * Lightweight One-Shot Clock create for internal SYS/BIOS timeout APIs
844 * Does NOT start the timeout (ie requires Clock_startI() to be called)
845 * Does NOT assume Hwis are disabled
846 */
847 Void addI(FuncPtr clockFxn, UInt32 timeout, UArg arg);
848
849 /*!
850 * @_nodoc
851 * ======== removeI ========
852 * Lightweight Clock delete for internal SYS/BIOS timeout APIs
853 * Assumes Hwis are disabled
854 */
855 Void removeI();
856
857 /*!
858 * ======== start ========
859 * Start instance
860 *
861 * The {@link #timeout} and {@link #period} values set during create()
862 * or by calling Clock_setTimeout() and Clock_setPeriod() are used and
863 * the expiry is recomputed.
864 * Note that for periodic instances, the first expiry is
865 * computed using the timeout specified. All subsequent expiries use the
866 * period value.
867 *
868 * @a(constraints)
869 * Timeout of instance cannot be zero
870 */
871 Void start();
872
873 /*!
874 * @_nodoc
875 * ======== startI ========
876 * Internal start function which assumes Hwis disabled
877 */
878 Void startI();
879
880 /*!
881 * ======== stop ========
882 * Stop instance
883 */
884 Void stop();
885
886 /*!
887 * ======== setPeriod ========
888 * Set periodic interval
889 *
890 * @param(period) periodic interval in Clock ticks
891 *
892 * @a(constraints)
893 * Cannot change period of instance that has been started.
894 */
895 Void setPeriod(UInt32 period);
896
897 /*!
898 * ======== setTimeout ========
899 * Set the initial timeout
900 *
901 * @param(timeout) initial timeout in Clock ticks
902 *
903 * @a(constraints)
904 * Cannot change the initial timeout of instance that has been started.
905 */
906 Void setTimeout(UInt32 timeout);
907
908 /*!
909 * ======== setFunc ========
910 * Overwrite Clock function and arg
911 *
912 * Replaces a Clock object's clockFxn function originally
913 * provided in {@link #create}.
914 *
915 * @param(clockFxn) function of type FuncPtr
916 * @param(arg) argument to clockFxn
917 *
918 * @a(constraints)
919 * Cannot change function and arg of Clock object that has been started.
920 */
921 Void setFunc(FuncPtr fxn, UArg arg);
922
923 /*!
924 * ======== getPeriod ========
925 * Get period of instance
926 *
927 * Returns the period of an instance.
928 *
929 * @b(returns) returns periodic interval in Clock ticks
930 */
931 UInt32 getPeriod();
932
933 /*!
934 * ======== getTimeout ========
935 * Get timeout of instance
936 *
937 * Returns the remaining time if instance has been started.
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 Bool startDuringWorkFunc;
1016 Bool ticking;
1017 };
1018 }