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 import ti.sysbios.hal.Timer;
47
48 /*!
49 * ======== Clock ========
50 * System Clock Manager
51 *
52 * The System Clock Manager is responsible for all timing services in
53 * SYS/BIOS.
54 * It generates the periodic system tick. The tick period is configurable.
55 * The timeout and period for all Clock Instances and timeout values in
56 * other SYS/BIOS modules are specified in terms of Clock ticks.
57 *
58 * The Clock Manager supports two tick "modes": a periodic mode with an
59 * interrupt on each tick (TickMode_PERIODIC), and a tick suppression
60 * mode (TickMode_DYNAMIC), which reduces the number of timer interrupts to
61 * the minimum required to support the scheduled timeouts. For devices that
62 * support it (e.g., MSP430 devices), TickMode_DYNAMIC will be the default
63 * mode if one is not specified in the application configuration; otherwise,
64 * the default mode will be TickMode_PERIODIC. The following example shows
65 * how the tick mode can be specified in the application configuration:
66 *
67 * @p(code)
68 * var Clock = xdc.useModule('ti.sysbios.knl.Clock');
69 *
70 * // Tell the Clock module to use TickMode_PERIODIC
71 * Clock.tickMode = Clock.TickMode_PERIODIC;
72 * @p
73 *
74 * Clock Instances are functions that can be scheduled to run after a
75 * certain number of Clock ticks.
76 * Clock instances are either one-shot or periodic. Instances are started
77 * when created or they are started later using the Clock_start()function.
78 * Instances can be stopped using the Clock_stop() function. All Clock
79 * Instances are executed when they expire in the context of a software
80 * interrupt.
81 *
82 * Clock objects are placed in the Clock object service list when
83 * created/constructed and remain there until deleted/destructed.
84 * To minimize processing overhead, unused or expired Clock objects
85 * should be deleted or destructed.
86 *
87 * The getTicks() function returns number of clock ticks since startup.
88 *
89 * By default, the Clock module statically configures a
90 * {@link ti.sysbios.hal.Timer}
91 * timer instance to provide the periodic 1 ms tick interrupt. If you
92 * want to use a custom configured timer for the Clock module's tick source,
93 * use the following example configuration as a guide:
94 *
95 * @p(code)
96 * var Clock = xdc.useModule('ti.sysbios.knl.Clock');
97 *
98 * // Tell the Clock module that YOU are providing the periodic interrupt
99 * Clock.tickSource = Clock.TickSource_USER;
100 *
101 * // this example uses the ti.sysbios.timers.dmtimer.Timer module
102 * var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
103 *
104 * // create a dmtimer config parameter object
105 * var timerParams = new Timer.Params();
106 *
107 * // make sure you set the period to 1000 us (1ms)
108 * timerParams.period = 1000;
109 *
110 * // custom dmtimer config parameters here...
111 * timerParams.twer.ovf_wup_ena = 1;
112 *
113 * // Create the timer.
114 * // This example uses timer id 3.
115 * // The timer interrupt handler must be set to 'Clock.tick'.
116 * Timer.create(3, Clock.tick, timerParams);
117 * @p
118 *
119 * @p(html)
120 * <h3> Calling Context </h3>
121 * <table border="1" cellpadding="3">
122 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
123 * </colgroup>
124 *
125 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
126 * <th> Task </th><th> Main </th><th> Startup </th></tr>
127 * <!-- -->
128 * <tr><td> {@link #construct} </td><td> N </td><td> N </td>
129 * <td> Y </td><td> Y </td><td> N </td></tr>
130 * <tr><td> {@link #create} </td><td> N </td><td> N </td>
131 * <td> Y </td><td> Y </td><td> N </td></tr>
132 * <tr><td> {@link #delete} </td><td> N </td><td> N </td>
133 * <td> Y </td><td> Y </td><td> N </td></tr>
134 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td>
135 * <td> Y </td><td> Y </td><td> N </td></tr>
136 * <tr><td> {@link #getTicks} </td><td> Y </td><td> Y </td>
137 * <td> Y </td><td> N </td><td> N </td></tr>
138 * <tr><td> {@link #getTimeout} </td><td> Y </td><td> Y </td>
139 * <td> Y </td><td> Y </td><td> N </td></tr>
140 * <tr><td> {@link #getTimerHandle} </td><td> Y </td><td> Y </td>
141 * <td> Y </td><td> Y </td><td> Y </td></tr>
142 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td>
143 * <td> Y </td><td> Y </td><td> Y </td></tr>
144 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td>
145 * <td> Y </td><td> Y </td><td> N </td></tr>
146 * <tr><td> {@link #setPeriod} </td><td> Y </td><td> Y </td>
147 * <td> Y </td><td> Y </td><td> N </td></tr>
148 * <tr><td> {@link #setTimeout} </td><td> Y </td><td> Y </td>
149 * <td> Y </td><td> Y </td><td> N </td></tr>
150 * <tr><td> {@link #start} </td><td> Y </td><td> Y </td>
151 * <td> Y </td><td> Y </td><td> N </td></tr>
152 * <tr><td> {@link #stop} </td><td> Y </td><td> Y </td>
153 * <td> Y </td><td> Y </td><td> N </td></tr>
154 * <tr><td> {@link #tick} </td><td> Y </td><td> Y </td>
155 * <td> Y </td><td> N </td><td> N </td></tr>
156 * <tr><td> {@link #tickReconfig} </td><td> Y </td><td> Y </td>
157 * <td> Y </td><td> N </td><td> N </td></tr>
158 * <tr><td> {@link #tickStart} </td><td> Y </td><td> Y </td>
159 * <td> Y </td><td> N </td><td> N </td></tr>
160 * <tr><td> {@link #tickStop} </td><td> Y </td><td> Y </td>
161 * <td> Y </td><td> N </td><td> N </td></tr>
162 * <tr><td colspan="6"> Definitions: <br />
163 * <ul>
164 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
165 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
166 * <li> <b>Task</b>: API is callable from a Task thread. </li>
167 * <li> <b>Main</b>: API is callable during any of these phases: </li>
168 * <ul>
169 * <li> In your module startup after this module is started
170 * (e.g. Clock_Module_startupDone() returns TRUE). </li>
171 * <li> During
172 * {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}. </li>
173 * <li> During main().</li>
174 * <li> During
175 * {@link ti.sysbios.BIOS#startupFxns BIOS.startupFxns}.</li>
176 * </ul>
177 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
178 * <ul>
179 * <li> During
180 * {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}.</li>
181 * <li> In your module startup before this module is started
182 * (e.g. Clock_Module_startupDone() returns FALSE).</li>
183 * </ul>
184 * </ul>
185 * </td></tr>
186 *
187 * </table>
188 * @p
189 */
190
191 @ModuleStartup
192 @InstanceInitStatic
193 @InstanceFinalize
194 @Template("./Clock.xdt")
195
196 module Clock
197 {
198 /*!
199 * ======== TickSource ========
200 * Clock tick source
201 *
202 * @field(TickSource_TIMER) {@link #tick Clock_tick()} is called
203 * automatically from within a {@link ti.sysbios.hal.Timer} ISR. The
204 * specific timer and its period can be controlled via {@link #timerId}
205 * and {@link tickPeriod}.
206 *
207 * @field(TickSource_USER) {@link #tick Clock_tick()} must be explicitly
208 * called by the user's application.
209 *
210 * @field(TickSource_NULL) {@link #tick Clock_tick()} is never called.
211 * In this case, it is an error for the application to ever call
212 * Clock_tick().
213 *
214 * @see #tickPeriod
215 * @see #timerId
216 */
217 enum TickSource {
218 TickSource_TIMER, /*! Use Timer to automatically call Clock_tick() */
219 TickSource_USER, /*! Application explicitly calls Clock_tick() */
220 TickSource_NULL /*! Clock_tick() is never called */
221 };
222
223 /*!
224 * ======== TickMode ========
225 * Clock Tick Mode
226 */
227 enum TickMode {
228 TickMode_PERIODIC, /*! Timer will interrupt every period */
229 TickMode_DYNAMIC /*! Unnecessary timer ticks can be suppressed */
230 };
231
232 /*!
233 * ======== BasicView ========
234 * @_nodoc
235 */
236 metaonly struct BasicView {
237 String label;
238 UInt32 timeout;
239 UInt period;
240 String fxn[];
241 UArg arg;
242 Bool started;
243 String tRemaining;
244 Bool periodic;
245 }
246
247 /*!
248 * ======== ModuleView ========
249 * @_nodoc
250 */
251 metaonly struct ModuleView {
252 String ticks;
253 String tickSource;
254 String tickMode;
255 String timerHandle;
256 UInt timerId;
257 UInt swiPriority;
258 UInt32 tickPeriod;
259 volatile UInt nSkip;
260 }
261
262 263 264 265
266 @Facet
267 metaonly config ViewInfo.Instance rovViewInfo =
268 ViewInfo.create({
269 viewMap: [
270 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
271 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
272 ]
273 });
274
275 /*!
276 * ======== FuncPtr ========
277 * Instance function prototype
278 */
279 typedef Void (*FuncPtr)(UArg);
280
281 /*!
282 * ======== LW_delayed ========
283 * Logged if Clock Swi delayed by >= 1 tick
284 */
285 config Log.Event LW_delayed = {
286 mask: Diags.USER3,
287 msg: "LW_delayed: delay: %d"
288 };
289
290 /*!
291 * ======== LM_tick ========
292 * Logged in every Clock tick interrupt
293 */
294 config Log.Event LM_tick = {
295 mask: Diags.USER1 | Diags.USER2,
296 msg: "LM_tick: tick: %d"
297 };
298
299 /*!
300 * ======== LM_begin ========
301 * Logged just prior to calling each Clock function
302 */
303 config Log.Event LM_begin = {
304 mask: Diags.USER1 | Diags.USER2,
305 msg: "LM_begin: clk: 0x%x, func: 0x%x"
306 };
307
308 /*!
309 * ======== A_clockDisabled ========
310 * Asserted in Clock_create()
311 */
312 config Assert.Id A_clockDisabled = {
313 msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
314 };
315
316 /*!
317 * ======== A_badThreadType ========
318 * Asserted in Clock_create and Clock_delete
319 */
320 config Assert.Id A_badThreadType = {
321 msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
322 };
323
324 /*!
325 * ======== tickSource ========
326 * Source of clock ticks
327 *
328 * If this parameter is not set to TickSource_TIMER,
329 * {@link #tickStart Clock_tickStart()},
330 * {@link #tickStop Clock_tickStop()}, and
331 * {@link #tickReconfig Clock_tickReconfig()}, have no effect.
332 *
333 * The default is TickSource_TIMER.
334 */
335 config TickSource tickSource = TickSource_TIMER;
336
337 /*!
338 * ======== tickMode ========
339 * Timer tick mode
340 *
341 * This parameter specifies the tick mode to be used by the underlying
342 * Timer. With TickMode_PERIODIC the timer will interrupt the CPU at
343 * a fixed rate, defined by the tickPeriod. With TickMode_DYNAMIC the
344 * timer can be dynamically reprogrammed by Clock, to interrupt the CPU
345 * when the next tick is actually needed for a scheduled timeout.
346 */
347 config TickMode tickMode;
348
349 /*!
350 * ======== timerId ========
351 * Timer Id used to create a Timer instance
352 *
353 * If {@link #tickSource Clock.tickSource} is set to TickSource_TIMER,
354 * the Clock module automatically creates a
355 * {@link ti.sysbios.hal.Timer#create instance} that automatically calls
356 * Clock_doTick() on a periodic basis (as specified by
357 * {@link #tickPeriod tickPeriod} and {@link #periodType periodType}.)
358 *
359 * This configuration parameter allows you to control which timer is
360 * used to drive the Clock module.
361 *
362 * The default value is {@link ti.sysbios.hal.Timer#ANY Timer.ANY} (~0)
363 * and the maximum timerId possible is family and device specific.
364 *
365 * @see ti.sysbios.hal.Timer
366 */
367 config UInt timerId = ~0;
368
369 /*!
370 * ======== swiPriority ========
371 * The priority of Swi used by Clock to process its instances
372 *
373 * All Clock instances are executed in the context of a single
374 * {@link Swi}. This parameter allows you to control the priority of
375 * that Swi.
376 *
377 * The default value of this parameter is Swi.numPriorities - 1; i.e.,
378 * the maximum Swi priority.
379 *
380 * @see ti.sysbios.knl.Swi#numPriorities
381 */
382 metaonly config UInt swiPriority;
383
384 /*!
385 * ======== tickPeriod ========
386 * Tick period specified in microseconds
387 *
388 * Default value is family dependent. For example, Linux systems often
389 * only support a minimum period of 10000 us and multiples of 10000 us.
390 * TI platforms have a default of 1000 us.
391 */
392 config UInt32 tickPeriod;
393
394 /*!
395 * ======== getTicks ========
396 * Time in Clock ticks
397 *
398 * The value returned will wrap back to zero after it reaches the max
399 * value that can be stored in 32 bits.
400 *
401 * @b(returns) time in clock ticks
402 */
403 @DirectCall
404 UInt32 getTicks();
405
406 /*!
407 * ======== getTimerHandle ========
408 * Get timer Handle
409 *
410 * Used when is it necessary to change family
411 * specific options for the timer and its Hwi Object.
412 *
413 * @b(returns) Timer Handle
414 */
415 @DirectCall
416 ti.sysbios.hal.Timer.Handle getTimerHandle();
417
418 /*!
419 * ======== tickStop ========
420 * Stop clock for reconfiguration
421 *
422 * This function is used to stop the timer used for generation of
423 * clock ticks. It is used along with Clock_tickStart() and
424 * Clock_tickReconfig() to allow reconfiguration of timer at runtime.
425 *
426 * @a(constraints)
427 * This function is non-reentrant and appropriate locks must be used to
428 * protect against re-entrancy.
429 */
430 @DirectCall
431 Void tickStop();
432
433 /*!
434 * ======== tickReconfig ========
435 * Reconfigure clock for new cpu frequency
436 *
437 * This function uses the new cpu frequency to reconfigure the timer used
438 * for generation of clock ticks such that tick period is
439 * accurate. This function is used along with Clock_tickStop() and
440 * Clock_tickStart() to allow reconfiguration of timer at runtime.
441 *
442 * When calling Clock_tickReconfig outside of main(), you must also call
443 * Clock_tickStop and Clock_tickStart to stop and restart the timer.
444 * Use the following call sequence:
445 *
446 * @p(code)
447 * // disable interrupts if an interrupt could lead to
448 * // another call to Clock_tickReconfig or if interrupt
449 * // processing relies on having a running timer
450 * Hwi_disable() or Swi_disable();
451 * BIOS_setCpuFrequency(Types.FreqHz *freq);
452 * Clock_tickStop();
453 * Clock_tickReconfig();
454 * Clock_tickStart();
455 * Hwi_restore() or Swi_enable()
456 * @p
457 *
458 * When calling Clock_tickReconfig from main(), the timer has not yet
459 * been started because the timer is started as part of BIOS_start().
460 * As a result, you can use the following simplified call sequence
461 * in main():
462 *
463 * @p(code)
464 * BIOS_setCpuFrequency(Types.FreqHz *freq);
465 * Clock_tickReconfig(Void);
466 * @p
467 *
468 * The return value is false if the timer cannot support the new
469 * frequency
470 *
471 * @b(returns) true if successful
472 *
473 * @a(constraints)
474 * This function is non-reentrant and appropriate locks must be used to
475 * protect against re-entrancy.
476 */
477 @DirectCall
478 Bool tickReconfig();
479
480 /*!
481 * ======== tickStart ========
482 * Start clock after reconfiguration
483 *
484 * This function starts the timer used for generation of clock ticks
485 * It is used along with Clock_tickStop() and Clock_tickReconfig() to
486 * allow reconfiguration of timer at runtime. The new timer configuration
487 * reflects changes caused by a call to reconfig().
488 *
489 * @a(constraints)
490 * This function is non-reentrant and appropriate locks must be used to
491 * protect against re-entrancy.
492 */
493 @DirectCall
494 Void tickStart();
495
496 /*!
497 * ======== tick ========
498 * Advance Clock time by one tick
499 *
500 * After incrementing a global tick counter, this function posts a Swi
501 * that processes the clock instances.
502 *
503 * This function is automatically called by a timer ISR when
504 * {@link #tickSource} is set to {@link #TickSource_TIMER}.
505 *
506 * When {@link #tickSource} is set to
507 * {@link #TickSource_USER}, Clock_tick() must be called by the
508 * application. Usually, this is done within a user defined {@link Hwi},
509 * {@link Swi}, or {@link Task}.
510 *
511 * Note that this function is not re-entrant. The application is
512 * responsible for ensuring that invocations of this function are
513 * serialized: either only one thread in the system ever calls this
514 * function or all calls are "wrapped" by an appropriate mutex.
515 *
516 * @see #tickSource
517 */
518 @DirectCall
519 Void tick();
520
521 /*!
522 * @_nodoc
523 * ======== workFunc ========
524 * Clock Q service routine
525 *
526 * @param(arg0) Unused. required to match Swi.FuncPtr
527 * @param(arg1) Unused. required to match Swi.FuncPtr
528 */
529 @DirectCall
530 Void workFunc(UArg arg0, UArg arg1);
531
532 /*!
533 * @_nodoc
534 * ======== workFuncDynamic ========
535 * Clock Q service routine for TickMode_DYNAMIC
536 *
537 * @param(arg0) Unused. required to match Swi.FuncPtr
538 * @param(arg1) Unused. required to match Swi.FuncPtr
539 */
540 @DirectCall
541 Void workFuncDynamic(UArg arg0, UArg arg1);
542
543 /*!
544 * @_nodoc
545 * ======= logTick ========
546 * Log the LD_tick from within Clock module scope
547 */
548 @DirectCall
549 Void logTick();
550
551 /*!
552 * @_nodoc
553 * ======== getCompletedTicks ========
554 * Get the number of Clock ticks that have completed
555 *
556 * Retuns the number of ticks completed, to the point where
557 * the underlying Timer interrupt has been serviced.
558 *
559 * @b(returns) time in clock ticks
560 */
561 @DirectCall
562 UInt32 getCompletedTicks();
563
564 /*!
565 * @_nodoc
566 * ======== getTickPeriod ========
567 * Get the Clock tick period
568 *
569 * The period is in units returned by the underlying Timer.
570 *
571 * @b(returns) period in timer counts
572 */
573 @DirectCall
574 UInt32 getTickPeriod();
575
576 /*!
577 * @_nodoc
578 * ======= setupTimerToSkipTicks ========
579 * Reprogram Clock's Timer to suppress unnecessary tick interrupts
580 */
581 @DirectCall
582 Void setupTimerToSkipTicks(UInt skips);
583
584 instance:
585
586 /*!
587 * ======== create ========
588 * Creates a Clock Instance
589 *
590 * The first argument is the function that gets called when the timeout
591 * expires.
592 *
593 * The 'timeout' argument is used to specify the initial timeout
594 * for both one-shot and periodic Clock instances (in Clock ticks).
595 *
596 * The {@link #period} parameter is used to set the subsequent timeout
597 * interval (in Clock ticks) for periodic instances.
598 *
599 * For one-shot instances, the period parameter must be set to zero.
600 *
601 * When instances are created they are placed upon a linked list managed
602 * by the Clock module. For this reason, instances cannot be created
603 * from either Hwi or Swi context.
604 *
605 * @param(clockFxn) Function that runs upon timeout
606 * @param(timeout) One-shot timeout or initial start delay (in clock
607 * ticks)
608 */
609 @DirectCall
610 create(FuncPtr clockFxn, UInt timeout);
611
612 /*!
613 * ======== startFlag ========
614 * Start immediately after instance is created
615 *
616 * When this flag is set to false, the user will have to call
617 * Clock_start() to start the instance.
618 *
619 * When set to true, both statically created Clock objects and Clock
620 * objects created in main() are started at the end of main() when the
621 * user calls BIOS_start(). Dynamically created Clock objects created
622 * after main() (ie within a task) will be started immediately.
623 *
624 * The default setting for this parameter is false.
625 *
626 * The configured Clock function will be called initially after an
627 * interval equal to the 'timeout' argument for both one-shot and
628 * periodic Clock objects.
629 *
630 * Periodic Clock objects will subsequently be called at the rate
631 * specified by the {@link #period} parameter.
632 *
633 */
634 config Bool startFlag = false;
635
636 /*!
637 * ======== period ========
638 * Period of this instance (in clock ticks)
639 *
640 * The default value of this parameter is 0, which indicates this is
641 * a one-shot Clock object.
642 *
643 * A non zero value for this parameter specifies that the Clock
644 * object is to be called periodically, and also specifies the
645 * rate (in Clock ticks) that the Clock function will be called
646 * AFTER the initial 'timeout' argument period.
647 *
648 * For one-shot Clock instances, this parameter must be set to zero.
649 */
650 config UInt period = 0;
651
652 /*!
653 * ======== arg ========
654 * Uninterpreted argument passed to instance function
655 *
656 * The default is null.
657 */
658 config UArg arg = null;
659
660 /*!
661 * ======== start ========
662 * Start instance
663 *
664 * The {@link #timeout} and {@link #period} values set during create()
665 * or by calling Clock_setTimeout() and Clock_setPeriod() are used and
666 * the expiry is recomputed.
667 * Note that for periodic instances, the first expiry is
668 * computed using the timeout specified. All subsequent expiries use the
669 * period value.
670 *
671 * @a(constraints)
672 * Timeout of instance cannot be zero
673 */
674 @DirectCall
675 Void start();
676
677 /*!
678 * @_nodoc
679 * ======== startI ========
680 * Internal start function which assumes Hwis disabled
681 */
682 @DirectCall
683 Void startI();
684
685 /*!
686 * ======== stop ========
687 * Stop instance
688 */
689 @DirectCall
690 Void stop();
691
692 /*!
693 * ======== setPeriod ========
694 * Set periodic interval
695 *
696 * @param(period) periodic interval in Clock ticks
697 *
698 * @a(constraints)
699 * Cannot change period of instance that has been started.
700 */
701 @DirectCall
702 Void setPeriod(UInt period);
703
704 /*!
705 * ======== setTimeout ========
706 * Set the initial timeout
707 *
708 * @param(timeout) initial timeout in Clock ticks
709 *
710 * @a(constraints)
711 * Cannot change the initial timeout of instance that has been started.
712 */
713 @DirectCall
714 Void setTimeout(UInt timeout);
715
716 /*!
717 * ======== setFunc ========
718 * Overwrite Clock function and arg
719 *
720 * Replaces a Clock object's clockFxn function originally
721 * provided in {@link #create}.
722 *
723 * @param(clockFxn) function of type FuncPtr
724 * @param(arg) argument to clockFxn
725 *
726 * @a(constraints)
727 * Cannot change function and arg of Clock object that has been started.
728 */
729 @DirectCall
730 Void setFunc(FuncPtr fxn, UArg arg);
731
732 /*!
733 * ======== getPeriod ========
734 * Get period of instance
735 *
736 * Returns the period of an instance.
737 *
738 * @b(returns) returns periodic interval in Clock ticks
739 */
740 @DirectCall
741 UInt getPeriod();
742
743 /*!
744 * ======== getTimeout ========
745 * Get timeout of instance
746 *
747 * Returns the remaining time if instance has been started.
748 *
749 * @b(returns) returns timeout in clock ticks
750 */
751 @DirectCall
752 UInt getTimeout();
753
754 internal:
755
756 /*!
757 * ======== doTick ========
758 * Function called by the timer interrupt handler
759 *
760 * @param(arg) Unused. Required to match signature of Hwi.FuncPtr
761 */
762 Void doTick(UArg arg);
763
764 765 766
767 struct Instance_State {
768 Queue.Elem elem;
769 UInt32 timeout;
770 UInt32 currTimeout;
771 UInt32 period;
772 volatile Bool active;
773 FuncPtr fxn;
774 UArg arg;
775 };
776
777 778 779
780 struct Module_State {
781 volatile UInt32 ticks;
782 UInt swiCount;
783 Timer.Handle timer;
784 Void (*doTickFunc)(UArg);
785
786 Queue.Object clockQ;
787 Swi.Handle swi;
788 UInt32 periodCounts;
789 volatile UInt numTickSkip;
790 UInt skipsWorkFunc;
791 Bool inWorkFunc;
792 };
793 }
794 795 796 797
798