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 package ti.sysbios.hal;
37
38 import xdc.runtime.Error;
39
40 /*!
41 * ======== Hwi ========
42 * Hardware Interrupt Manager Proxy.
43 *
44 * This module provides APIs for managing hardware interrupts.
45 * These APIs are generic across all supported targets and devices
46 * and should provide sufficient functionality for most applications.
47 *
48 * The actual implementations of the Hwi module APIs are
49 * provided by the Hwi module delegates.
50 * Additional, family-specific Hwi module APIs may also be provided by
51 * the Hwi module delegates.
52 * See the list of
53 * {@link ./../family/doc-files/delegates.html Delegate Mappings}
54 * to determine which Hwi delegate is used
55 * for your target/device.
56 *
57 * You can statically or dynamically assign functions that run when
58 * specific hardware interrupts occur. Dynamic assignment of Hwi
59 * functions to interrupts at run-time is done
60 * using the {@link #create Hwi_create} function.
61 *
62 * Interrupt routines can be written completely in C, completely in
63 * assembly, or in a mix of C and assembly. In order to support interrupt
64 * routines
65 * written completely in C, an interrupt dispatcher is provided that performs
66 * the requisite prolog and epilog for an interrupt routine.
67 *
68 * Some routines are assigned to interrupts by the other SYS/BIOS
69 * modules. For example, the
70 * {@link ti.sysbios.knl.Clock} module configures its own timer interrupt
71 * handler.
72 *
73 * @a(constraints)
74 * Since the hal Hwi module has no knowledge of the delegate Hwi
75 * module's instance definition, Hwi_construct() can NOT be properly
76 * supported.
77 *
78 * If {@link ti.sysbios.BIOS#runtimeCreatesEnabled BIOS.runtimeCreatesEnabled}
79 * is set to true, both Hwi_create() and Hwi_construct()
80 * will attempt to dynamically create (ie NOT construct) a delegate Hwi
81 * object.
82 *
83 * If {@link ti.sysbios.BIOS#runtimeCreatesEnabled BIOS.runtimeCreatesEnabled}
84 * is set to false, both Hwi_create() and Hwi_construct() will fail.
85 *
86 * @p(html)
87 * <h3> Calling Context </h3>
88 * <table border="1" cellpadding="3">
89 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
90 * </colgroup>
91 *
92 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
93 * <th> Task </th><th> Main </th><th> Startup </th></tr>
94 * <!-- -->
95 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td>
96 * <td> Y </td><td> Y </td><td> Y </td></tr>
97 * <tr><td> {@link #create} </td><td> N </td><td> N </td>
98 * <td> Y </td><td> Y </td><td> N </td></tr>
99 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td>
100 * <td> Y </td><td> Y </td><td> Y </td></tr>
101 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td>
102 * <td> Y </td><td> Y </td><td> N </td></tr>
103 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td>
104 * <td> Y </td><td> N </td><td> N </td></tr>
105 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td>
106 * <td> Y </td><td> Y </td><td> N </td></tr>
107 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td>
108 * <td> Y </td><td> Y </td><td> Y </td></tr>
109 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td>
110 * <td> Y </td><td> Y </td><td> Y </td></tr>
111 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td>
112 * <td> Y </td><td> Y </td><td> Y </td></tr>
113 * <tr><td> {@link #construct} </td><td> N </td><td> N </td>
114 * <td> Y </td><td> Y </td><td> N </td></tr>
115 * <tr><td> {@link #delete} </td><td> N </td><td> N </td>
116 * <td> Y </td><td> Y </td><td> N </td></tr>
117 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td>
118 * <td> Y </td><td> Y </td><td> N </td></tr>
119 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td>
120 * <td> Y </td><td> Y </td><td> N </td></tr>
121 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td>
122 * <td> Y </td><td> Y </td><td> N </td></tr>
123 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td>
124 * <td> Y </td><td> Y </td><td> N </td></tr>
125 * <tr><td colspan="6"> Definitions: <br />
126 * <ul>
127 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
128 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
129 * <li> <b>Task</b>: API is callable from a Task thread. </li>
130 * <li> <b>Main</b>: API is callable during any of these phases: </li>
131 * <ul>
132 * <li> In your module startup after this module is started
133 * (e.g. Hwi_Module_startupDone() returns TRUE). </li>
134 * <li> During xdc.runtime.Startup.lastFxns. </li>
135 * <li> During main().</li>
136 * <li> During BIOS.startupFxns.</li>
137 * </ul>
138 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
139 * <ul>
140 * <li> During xdc.runtime.Startup.firstFxns.</li>
141 * <li> In your module startup before this module is started
142 * (e.g. Hwi_Module_startupDone() returns FALSE).</li>
143 * </ul>
144 * </ul>
145 * </td></tr>
146 *
147 * </table>
148 * @p
149 *
150 * @a(Runtime Hwi Creation)
151 *
152 * Below is an example that configures an interrupt at runtime.
153 * Typically such code would be placed in main().
154 *
155 * @p(code)
156 * #include <xdc/runtime/Error.h>
157 * #include <ti/sysbios/hal/Hwi.h>
158 *
159 * Hwi_Handle myHwi;
160 *
161 * Int main(Int argc, char* argv[])
162 * {
163 * Hwi_Params hwiParams;
164 * Error_Block eb;
165 *
166 * Hwi_Params_init(&hwiParams);
167 * Error_init(&eb);
168 *
169 * // set the argument you want passed to your ISR function
170 * hwiParams.arg = 1;
171 *
172 * // set the event id of the peripheral assigned to this interrupt
173 * hwiParams.eventId = 10;
174 *
175 * // don't allow this interrupt to nest itself
176 * hwiParams.maskSetting = Hwi_MaskingOption_SELF;
177 *
178 * //
179 * // Configure interrupt 5 to invoke "myIsr".
180 * // Automatically enables interrupt 5 by default
181 * // set params.enableInt = FALSE if you want to control
182 * // when the interrupt is enabled using Hwi_enableInterrupt()
183 * //
184 *
185 * myHwi = Hwi_create(5, myIsr, &hwiParams, &eb);
186 *
187 * if (Error_check(&eb)) {
188 * // handle the error
189 * }
190 * }
191 *
192 * Void myIsr(UArg arg)
193 * {
194 * // this runs when interrupt #5 goes off
195 * }
196 * @p
197 *
198 * @a(Hook Functions)
199 *
200 * Sets of hook functions can be specified for the Hwi module
201 * using the configuration tool. Each set contains these hook
202 * functions:
203 * @p(blist)
204 * -Register: A function called before any statically-created Hwis
205 * are initialized at runtime. The register hook is called at boot time
206 * before main() and before interrupts are enabled.
207 * -Create: A function that is called when a Hwi is created.
208 * This includes hwis that are created statically and those
209 * created dynamically using {@link #create Hwi_create}.
210 * -Begin: A function that is called just prior to running a Hwi.
211 * -End: A function that is called just after a Hwi finishes.
212 * -Delete: A function that is called when a Hwi is deleted at
213 * run-time with {@link #delete Hwi_delete}.
214 * @p
215 *
216 * Register Function
217 *
218 * The Register function is provided to allow a hook set to store its
219 * hookset ID. This id can be passed to
220 * {@link #setHookContext Hwi_setHookContext} and
221 * {@link #getHookContext Hwi_getHookContext} to set or get
222 * hookset-specific context. The
223 * Register function must be specified if the hook implementation
224 * needs to use {@link #setHookContext Hwi_setHookContext} or
225 * {@link #getHookContext Hwi_getHookContext}.
226 * The registerFxn hook function is called during system initialization
227 * before interrupts have been enabled.
228 *
229 * @p(code)
230 * Void myRegisterFxn(Int id);
231 * @p
232 *
233 * Create and Delete Functions
234 *
235 * The create and delete functions are called whenever a Hwi is created
236 * or deleted. They are called with interrupts enabled (unless called
237 * at boot time or from main()).
238 *
239 * @p(code)
240 * Void myCreateFxn(Hwi_Handle hwi, Error_Block *eb);
241 * @p
242 *
243 * @p(code)
244 * Void myDeleteFxn(Hwi_Handle hwi);
245 * @p
246 *
247 * Begin and End Functions
248 *
249 * The beginFxn and endFxn function hooks are called with interrupts
250 * globally disabled, therefore any hook processing function will contribute
251 * to the overall system interrupt response latency. In order to minimize
252 * this impact, carefully consider the processing time spent in an Hwi
253 * beginFxn or endFxn function hook.
254 *
255 * @p(code)
256 * Void myBeginFxn(Hwi_Handle hwi);
257 * @p
258 *
259 * @p(code)
260 * Void myEndFxn(Hwi_Handle hwi);
261 * @p
262 *
263 * Hook functions can only be configured statically.
264 *
265 */
266
267 @ModuleStartup
268
269 module Hwi inherits ti.sysbios.interfaces.IHwi
270 {
271 /*!
272 * Error raised when a stack overflow (or corruption) is detected.
273 *
274 * This error is raised by kernel's stack checking function. This
275 * function checks the stacks before every task switch to make sure
276 * that reserved word at top of stack has not been modified.
277 *
278 * The stack checking logic is enabled by the {@link #checkStackFlag}
279 * configuration parameter. If this flag is set to true, the kernel will
280 * validate the stacks.
281 */
282 config Error.Id E_stackOverflow = {
283 msg: "E_stackOverflow: ISR stack overflow."
284 };
285
286 /*!
287 * Initialize ISR stack with known value for stack checking at runtime
288 *
289 * This is also useful for inspection of stack in debugger or core
290 * dump utilities for stack overflow and depth.
291 *
292 * Default is true.
293 * (see {@link #checkStackFlag}).
294 */
295 metaonly config Bool initStackFlag = true;
296
297 /*!
298 * Check for Hwi stack overrun during Idle loop.
299 *
300 * If true, then an idle function is added to the idle loop
301 * that checks for a Hwi stack overrun condition and raises
302 * an Error if one is detected.
303 *
304 * The check consists of testing the top of stack value against
305 * its initial value (see {@link #initStackFlag}). If it is no
306 * longer at this value, the assumption is that the ISR stack
307 * has been overrun. If the test fails, then the
308 * {@link #E_stackOverflow} error is raised.
309 *
310 * Runtime stack depth computation is only performed if {@link #initStackFlag} is
311 * also true.
312 *
313 * Default is true.
314 * (see {@link #initStackFlag}).
315 *
316 * To enable or disable full stack checking, you should set both this
317 * flag and the {@link ti.sysbios.knl.Task#checkStackFlag}.
318 */
319 metaonly config Bool checkStackFlag = true;
320
321 /*!
322 * ======== disable ========
323 * Globally disable interrupts.
324 *
325 * Hwi_disable globally disables hardware interrupts and returns an
326 * opaque key indicating whether interrupts were globally enabled or
327 * disabled on entry to Hwi_disable().
328 * The actual value of the key is target/device specific and is meant
329 * to be passed to Hwi_restore().
330 *
331 * Call Hwi_disable before a portion of a function that needs
332 * to run without interruption. When critical processing is complete, call
333 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
334 *
335 * Servicing of interrupts that occur while interrupts are disabled is
336 * postponed until interrupts are reenabled. However, if the same type
337 * of interrupt occurs several times while interrupts are disabled,
338 * the interrupt's function is executed only once when interrupts are
339 * reenabled.
340 *
341 * A context switch can occur when calling Hwi_enable or Hwi_restore if
342 * an enabled interrupt occurred while interrupts are disabled.
343 *
344 * Hwi_disable may be called from main(). However, since Hwi interrupts
345 * are already disabled in main(), such a call has no effect.
346 *
347 * @a(constraints)
348 * If a Task switching API such as
349 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
350 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
351 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
352 * {@link ti.sysbios.knl.Task#yield Task_yield()}
353 * is invoked which results in a context switch while
354 * interrupts are disabled, an embedded call to
355 * {@link #enable Hwi_enable} occurs
356 * on the way to the new thread context which unconditionally re-enables
357 * interrupts. Interrupts will remain enabled until a subsequent
358 * {@link #disable Hwi_disable}
359 * invocation.
360 *
361 * Swis always run with interrupts enabled.
362 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
363 * interrupts.
364 *
365 * @b(returns) opaque key for use by Hwi_restore()
366 */
367 @Macro
368 override UInt disable();
369
370 /*!
371 * ======== enable ========
372 */
373 @Macro
374 override UInt enable();
375
376 /*!
377 * ======== restore ========
378 */
379 @Macro
380 override Void restore(UInt key);
381
382 /*!
383 * ======== viewGetHandle ========
384 * @_nodoc
385 * Returns the corresponding hal Hwi handle for a delegate Hwi handle
386 *
387 * @b(returns) hal Hwi handle
388 */
389 metaonly Handle viewGetHandle(Ptr pi);
390
391 instance:
392
393 /*!
394 * ======== create ========
395 * Create a dispatched interrupt.
396 *
397 * To cause a C function to run in response to a particular system
398 * interrupt, you create a Hwi object that encapsulates information
399 * regarding the interrupt required by the Hwi module.
400 *
401 * The standard static and dynamic forms of the "create" function are
402 * supported by the ti.sysbios.hal.Hwi module.
403 * The following C code configures interrupt 5 with the "myIsr"
404 * C function.
405 *
406 * @p(code)
407 * #include <ti/sysbios/hal/Hwi>
408 *
409 * Hwi_create(5, myIsr, NULL, NULL);
410 * @p
411 *
412 * The NULL, NULL arguments are used when the default instance
413 * parameters and generic error handling is satisfactory for creating
414 * a Hwi object.
415 *
416 * A Hwi dispatcher table entry is created and filled with the
417 * function specified by the fxn parameter and the attributes
418 * specified by the params parameter.
419 *
420 * If params is NULL, the Hwi's dispatcher properties are assigned a
421 * default set of values. Otherwise, the following properties
422 * are specified by a structure of type Hwi_Params.
423 *
424 * @p(blist)
425 * - The arg element is a generic argument that is passed to the plugged
426 * function as its only parameter. The default value is 0.
427 * - The enableInt element determines whether the interrupt should be
428 * enabled in the IER by create.
429 * - The maskSetting element defines the dispatcherAutoNestingSupport
430 * behavior of the interrupt.
431 * @p
432 *
433 * Hwi_create returns a pointer to the created Hwi object.
434 *
435 * @param(intNum) interrupt number
436 * @param(hwiFxn) pointer to ISR function
437 */
438 override create(Int intNum, FuncPtr hwiFxn);
439
440 /*!
441 * ======== getHookContext ========
442 * Get hook instance's context for a Hwi.
443 *
444 * The Handle passed to this API must be the handle passed
445 * to any of the Hook functions, not the one returned by
446 * {@link #create Hwi_create}.
447 *
448 * @b(returns) hook instance's context for hwi
449 */
450 override Ptr getHookContext(Int id);
451
452 /*!
453 * ======== setHookContext ========
454 * Set hook instance's context for a Hwi.
455 *
456 * The Handle passed to this API must be the handle passed
457 * to any of the Hook functions, not the one returned by
458 * {@link #create Hwi_create}.
459 *
460 * @param(id) hook instance's ID
461 * @param(hookContext) value to write to context
462 */
463 override Void setHookContext(Int id, Ptr hookContext);
464
465 internal:
466
467
468 metaonly config UInt numHooks = 0;
469
470 /*! target/device-specific Hwi implementation. */
471 proxy HwiProxy inherits ti.sysbios.interfaces.IHwi;
472
473 struct Instance_State {
474 HwiProxy.Handle pi;
475 };
476 }