source: svn/trunk/newcon3bcm2_21bu/magnum/basemodules/kni/linuxuser/bkni.h @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 34.1 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2010, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bkni.h $
11 * $brcm_Revision: Hydra_Software_Devel/40 $
12 * $brcm_Date: 3/16/10 4:17p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/basemodules/kni/generic/bkni.h $
19 *
20 * Hydra_Software_Devel/40   3/16/10 4:17p erickson
21 * SW3548-2837: add BKNI_DEBUG_CS_TIMING feature, default off
22 *
23 * Hydra_Software_Devel/39   4/14/09 11:51a erickson
24 * PR53778: default BKNI_TRACK_MALLOCS for linux user mode only
25 *
26 * Hydra_Software_Devel/38   4/14/09 9:11a erickson
27 * PR53778: default BKNI_TRACK_MALLOCS on for linux in debug mode
28 *
29 * Hydra_Software_Devel/37   4/9/09 1:35p vsilyaev
30 * PR 53778: Keep a history of free'ed objects for better debug facilities
31 *
32 * Hydra_Software_Devel/36   4/2/09 11:28a erickson
33 * PR53778: extend BKNI_TRACK_MALLOCS to events and mutexes
34 *
35 * Hydra_Software_Devel/35   1/29/09 8:12p vsilyaev
36 * PR 42495: Improved tracking of memory allocation
37 *
38 * Hydra_Software_Devel/34   12/29/08 1:01p erickson
39 * PR50742: fix spelling of BKNI_AssertIsrContext
40 *
41 * Hydra_Software_Devel/33   9/18/08 3:23p erickson
42 * PR46838: merge
43 *
44 * Hydra_Software_Devel/PR46838/1   9/17/08 4:55p dyzhang
45 * PR46838: fix compiling warning with BKNI_TRACK_MALLOCS on.
46 *
47 * Hydra_Software_Devel/32   8/21/08 4:43p vsilyaev
48 * PR 32280: Added BKNI_ASSERT_ISR_CONTEXT
49 *
50 * Hydra_Software_Devel/31   5/7/08 10:54a erickson
51 * PR42495: add BKNI_TRACK_MALLOCS feature, defaulted off
52 *
53 * Hydra_Software_Devel/30   9/11/06 4:13p erickson
54 * PR21941: 23976
55 *
56 * Hydra_Software_Devel/29   4/28/04 12:14p vsilyaev
57 * PR 9698: Created _isr aliases for ISR safe functions.
58 *
59 * Hydra_Software_Devel/28   4/8/03 4:47p erickson
60 * BKNI_ResetEvent now returns void
61 * Split BKNI_AcquireMutex into Acquire and TryAcquire
62 *
63 * Hydra_Software_Devel/27   4/4/03 12:22p erickson
64 * updated docs
65 *
66 * Hydra_Software_Devel/26   4/4/03 11:53a erickson
67 * updated docs
68 *
69 * Hydra_Software_Devel/25   4/4/03 11:34a erickson
70 * updated docs
71 *
72 * Hydra_Software_Devel/24   4/4/03 11:27a erickson
73 * updated documentation
74 *
75 * Hydra_Software_Devel/23   4/3/03 6:13p erickson
76 * some pre 0.9 api rework
77 *
78 * Hydra_Software_Devel/22   4/3/03 3:57p erickson
79 * documentation updates
80 *
81 * Hydra_Software_Devel/21   4/1/03 7:02p erickson
82 * updated comments
83 *
84 * Hydra_Software_Devel/20   4/1/03 5:21p vsilyaev
85 * Change timeout type in Sleep and Delay from [signed[ int to unsigned.
86 *
87 * Hydra_Software_Devel/19   3/31/03 3:40p erickson
88 * added BKNI_ResetEvent
89 *
90 * Hydra_Software_Devel/18   3/28/03 6:53p erickson
91 * updated comments
92 *
93 * Hydra_Software_Devel/17   3/28/03 12:36p erickson
94 * updated WaitForEvent documentation
95 *
96 * Hydra_Software_Devel/16   3/25/03 11:45a erickson
97 * Removed implementation notes
98 *
99 * Hydra_Software_Devel/15   3/24/03 2:10p erickson
100 * updated comments
101 *
102 * Hydra_Software_Devel/14   3/24/03 11:38a erickson
103 * reworked docs
104 *
105 * Hydra_Software_Devel/13   3/17/03 4:09p erickson
106 * kernel interface doc changes
107 *
108 * Hydra_Software_Devel/12   3/12/03 3:49p erickson
109 * updated tests and got linuxkernel working with them
110 *
111 * Hydra_Software_Devel/11   3/12/03 12:04p erickson
112 * updated return codes, comments
113 *
114 * Hydra_Software_Devel/10   3/11/03 6:59p erickson
115 * changed kernelinterface from using object ptrs to handles
116 *
117 * Hydra_Software_Devel/9   3/10/03 8:28p vsilyaev
118 * Added support for the tagged kernet interface API.
119 *
120 * Hydra_Software_Devel/8   3/10/03 6:36p vsilyaev
121 * Uses extern "C" { } brackets.
122 *
123 * Hydra_Software_Devel/7   3/10/03 4:55p erickson
124 * using standard bkni.h
125 * no longer includes STD_INC include path
126 *
127 * Hydra_Software_Devel/6   3/10/03 2:44p vsilyaev
128 * Function without parameters should have prototype (void).
129 * Include bkni_imp.h at the end.
130 *
131 * Hydra_Software_Devel/4   3/10/03 2:29p erickson
132 * updated docs
133 *
134 * Hydra_Software_Devel/3   3/6/03 6:27p erickson
135 * rework KNI api
136 *
137 * Hydra_Software_Devel/2   3/6/03 10:07a erickson
138 * updated documentation
139 *
140 * Hydra_Software_Devel/1   3/5/03 5:16p erickson
141 * Initial kernelinterface work
142 *
143 ***************************************************************************/
144#ifndef BKNI_H__
145#define BKNI_H__
146
147#ifdef __cplusplus
148extern "C" {
149#endif
150
151/*====================== Module Overview ===========================
152
153---++++ *Summary:*
154
155The Kernel Interface is the set of operating system and standard C library functions
156required by the Magnum architecture which is portable across all software
157and hardware platforms which Broadcom uses.
158
159
160---++++ *Requirements:*
161
162*Portable* - every function must work on every platform in the same well-defined way.
163Some error conditions cannot or should not be standardized, therefore we also include
164usage rules (see BKNI_EnterCriticalSection for an example.)
165Every platform implementationmust be regularly checked with compliance tests.
166
167*Safe* - Because of the inherent dangers of multitasking,
168each kernel interface implementation must ensure there are no race conditions within the
169implementation.
170The API must also be simple and explicit in order to help developers avoid race
171conditions in their code.
172
173*Minimal* - The number of functions should be just enough to allow us to implement the Magnum
174architecture. Platform-dependent code should make use of platform-specific functions.
175
176
177---++++ *Files:*
178
179The kernel interface is divided into three sections:
180
181*bkni.h* is the single-task kernel interface. It is used by code which follows the single-task
182model of execution specified in ThreadSafe.
183
184*bkni_multi.h* is the multi-tasking kernel interface. It is used by code which follows
185the multi-task model of execution specified in ThreadSafe. bkni_multi.h also includes
186bkni.h.
187
188*bkni_metrics.h* is the metrics interface. It must not be called by Magnum code, but
189provides system monitoring and debugging to platform-specific code.
190
191
192<nopublish>
193---++++ *Summary of Changes:*
194
195New naming convention.
196
197Replaced structures with opaque handles.
198
199Init and Uninit functions.
200
201Replaced semaphores with mutexes.While a semaphore can be configured as a mutex, it can
202easily be misconfigured and introduce race conditions. The combination of a mutex and an event
203is simple and sufficient.
204
205Removed sprintf and vsprintf because they introduce possible buffer overruns. snprintf
206and vsnprintf are sufficient.
207
208Memory map functionality (MmuMap and UnmmuMap) was moved to the MemoryManager.
209
210Removed debug macros (DBGMSG) and data types (WORD, HANDLE, etc.).
211</nopublish>
212
213
214---++++ *Interrupt Safety:*
215
216The following functions can be called from an ISR or a critical section:
217
218    * BKNI_Memset, BKNI_Memcpy, BKNI_Memcmp, BKNI_Memchr, BKNI_Memmove
219    * BKNI_Printf, BKNI_Vprintf
220    * BKNI_Delay
221    * BKNI_SetEvent
222    * BKNI_WaitForEvent, but only with a timeout of zero.
223
224All other functions are not callable from either an ISR or critical section.
225*****************************************************************************/
226
227/***************************************************************************
228Summary:
229    Event handle created by BKNI_CreateEvent.
230****************************************************************************/
231typedef struct BKNI_EventObj *BKNI_EventHandle;
232
233/***************************************************************************
234Summary:
235    Initialize the kernel interface before use.
236
237Description:
238    The system must call BKNI_Init() before making any other kernel interface call.
239    Magnum code cannot call BKNI_Init().
240
241    The BKNI_Init call should reset the metrics interface. See BKNI_Metrics_Reset.
242
243Returns:
244    BERR_SUCCESS - The kernel interface successfully initialized.
245    BERR_OS_ERROR - Initialization failed.
246****************************************************************************/
247BERR_Code BKNI_Init(void);
248
249
250/***************************************************************************
251Summary:
252    Uninitialize the kernel interface after use.
253
254Description:
255    Cleans up the kernel interface. No kernel interface calls can be made after this,
256    except BKNI_Init().
257    Magnum code cannot call BKNI_Uninit().
258
259Returns:
260    <none>
261****************************************************************************/
262void BKNI_Uninit(void);
263
264
265/***************************************************************************
266Summary:
267    Set byte array to a value.
268
269Description:
270    Copies the value of ch (converted to an unsigned char) into each of the first n
271    characters of the memory pointed to by mem.
272
273    Can be called from an interrupt-context.
274
275Input:
276    mem - memory to be set
277    ch - 8 bit value to be copied into memory
278    n - number of bytes to be copied into memory
279
280Returns:
281    The value of mem
282****************************************************************************/
283void *BKNI_Memset(void *mem, int ch, size_t n);
284
285
286/***************************************************************************
287Summary:
288    Copy non-overlapping memory.
289
290Description:
291    Copies n characters from the object pointed to by src into the object pointed
292    to by dest.
293
294    If copying takes place between objects that overlap, the
295    behavior is undefined. Use BKNI_Memmove instead.
296
297    Can be called from an interrupt-context.
298
299Input:
300    dest - the destination byte array
301    src - the source byte array
302    n - number of bytes to copy
303
304Returns:
305    The value of dest
306****************************************************************************/
307void *BKNI_Memcpy(void *dest, const void *src, size_t n);
308
309
310/***************************************************************************
311Summary:
312    Compare two blocks of memory.
313
314Description:
315    Compares the first n characters of the object pointed to by s1 to the first n
316    characters of the object pointed to by s2.
317
318    Can be called from an interrupt-context.
319
320Returns:
321    An integer greater than, equal to, or less than zero, accordingly as the object
322    pointed to by s1 is greater than, equal to, or less than the object pointed to by s2.
323****************************************************************************/
324int BKNI_Memcmp(
325    const void *s1,     /* byte array to be compared */
326    const void *s2,     /* byte array to be compared */
327    size_t n            /* maximum number of bytes to be compared */
328    );
329
330
331/***************************************************************************
332Summary:
333    Find a byte in a block of memory.
334
335Description:
336    Locates the first occurrence of ch (converted to an unsigned char) in the initial n
337    characters (each interpreted as unsigned char) of the object pointed to by mem.
338
339    Can be called from an interrupt-context.
340
341Input:
342    mem - byte array to be searched
343    ch - 8 bit value to be searched for
344    n - maximum number of bytes to be searched
345
346Returns:
347    A pointer to the located character, or a null pointer if the character does not
348    occur in the object.
349****************************************************************************/
350void *BKNI_Memchr(const void *mem, int ch, size_t n);
351
352
353/***************************************************************************
354Summary:
355    Copy potentially overlapping memory.
356
357Description:
358    Copies n characters from the object pointed to by src into the object pointed
359    to by dest. Copying takes place as if the n characters from the object pointed
360    to by src are first copied into a temporary array of n characters that does
361    not overlap the objects pointed to by dest and src, and then the n characters
362    from the temporary array are copied into the object pointed to by dest.
363
364    If the memory does not overlap, BKNI_Memcpy is preferred.
365
366    Can be called from an interrupt-context.
367
368Returns:
369    The value of dest
370****************************************************************************/
371void *BKNI_Memmove(
372    void *dest,         /* destination byte array */
373    const void *src,    /* source byte array */
374    size_t n            /* number of bytes to copy */
375    );
376
377
378/***************************************************************************
379Summary:
380    Print characters to the console.
381
382Description:
383    Although printing to the console is very important for development, it cannot
384    and should not be guaranteed to actually print in all contexts.
385    It is valid for the system developer to eliminate all BKNI_Printf output in
386    release builds or if the context demands it (e.g. interrupt context).
387
388    You should use BKNI_Printf instead of
389    DebugInterface when you explicity want to print information to a console
390    regardless of debug state (e.g. BXPT_PrintStatus, BPSI_PrintPsiInformation).
391    BKNI_Printf is also used by the generic DebugInterface implementation.
392
393    We only guarantee a subset of ANSI C format specifiers. These include:
394
395    * %d  - int in decimal form
396    * %u  - unsigned int in decimal form
397    * %ld - long in decimal form
398    * %lu - unsigned long in decimal form
399    * %x  - unsigned int in lowercase hex form
400    * %lx - unsigned long in lowercase hex form
401    * %X  - unsigned int in uppercase hex form
402    * %lX - unsigned long in uppercase hex form
403    * %c  - an int argument converted to unsigned char
404    * %s  - string
405    * \n  - newline
406    * \t  - tab
407    * %%  - % character
408    * %03d - Zero padding of integers, where '3' and 'd' are only examples. This can be applied to any of the preceding numeric format specifiers (not %c or %s).
409    * Pass-through of non-control characters.
410
411    Beyond these, we do not guarantee the output format.
412
413    For BKNI_Printf and BKNI_Vprintf, other ANSI C format specifiers
414    may be used, and platforms should try to make sure that any combination of formats
415    and parameters will not cause a system crash.
416
417    When calling BKNI_Snprint and BKNI_Vsnprintf, Magnum code must only use the
418    guaranteed format specifiers if the results must always be the same on all platforms.
419
420    BKNI_Printf can be called from an interrupt-context.
421
422Returns:
423    >=0 is success. It is the number of characters transmitted.
424    <0 is failure, either in encoding or in outputing.
425****************************************************************************/
426int BKNI_Printf(
427    const char *fmt, /* format string */
428    ...                 /* variable arguments */
429    );
430
431
432/***************************************************************************
433Summary:
434    Print characters to a null-terminated string.
435
436Description:
437    See BKNI_Printf for a description of the format specifiers supported.
438
439    Can be called from an interrupt-context.
440
441Returns:
442    If the output is not truncated, it returns the number of characters printed, not
443    including the trailing null byte.
444
445    If the output is truncated, it should try to return the number
446    of characters that would have been printed had the size of memory been large
447    enough. However, this result is not required and no Magnum code should
448    depend on this result.
449****************************************************************************/
450int BKNI_Snprintf(
451    char *s,            /* destination string */
452    size_t n,           /* size of memory that can be used. It should include
453                            space for the trailing null byte. */
454    const char *fmt,    /* format string */
455    ...                 /* variable arguments */
456    );
457
458
459/***************************************************************************
460Summary:
461    Print characters to the console using a variable argument list.
462
463Description:
464    Equivalent to BKNI_Printf, with the variable argument list replaced by the va_list
465    parameter. va_list must initialized by the va_start macro (and possibly
466    subsequent va_arg calls). The BKNI_Vprintf function does not invoke the va_end macro.
467
468    The value of the va_list parameter may be modified and so it is indeterminate upon return.
469
470    See BKNI_Printf for a description of the format specifiers supported.
471
472    Can be called from an interrupt-context.
473
474Input:
475    fmt - See BKNI_Printf
476    va_list - See StandardTypes and stdarg.h
477
478Returns:
479    >=0 is success. It is the number of characters transmitted.
480    <0 is failure, either in encoding or in outputing.
481****************************************************************************/
482int BKNI_Vprintf(const char *fmt, va_list ap);
483
484
485/***************************************************************************
486Summary:
487    Print characters to a null-terminated string using a variable argument list.
488
489Description:
490    See BKNI_Printf for a description of the format specifiers supported.
491    See BKNI_Vprintf for a description of the va_list parameter.
492
493    Can be called from an interrupt-context.
494
495Input:
496    s - memory to print into
497    n - size of memory that can be used. It should include space for the trailing null byte.
498    fmt - See BKNI_Printf
499    va_list - See StandardTypes and stdarg.h
500
501Returns:
502    If the output is not truncated, it returns the number of characters printed, not
503    including the trailing null byte.
504
505    If the output is truncated, it should try to return the number
506    of characters that would have been printed had the size of memory been large
507    enough. However, this result is not required and no Magnum code should
508    depend on this result.
509****************************************************************************/
510int BKNI_Vsnprintf(char *s, size_t n, const char *fmt, va_list ap);
511
512
513/***************************************************************************
514Summary:
515    Busy sleep.
516
517Description:
518    BKNI_Delay is a busy sleep which guarantees you will delay for at least the specified
519    number of microseconds. It does not call the scheduler, therefore the Delay is able to be
520    less than the system clock time. This consumes CPU time, so it should be used for only
521    short sleeps and only when BKNI_Sleep cannot be used.
522
523    Be aware that on a preemptive system, any task can be interrupted and the scheduler can
524    run, and so there is no guarantee of maximum delay time. If you have maximum time
525    constraints, you should be using an interrupt.
526
527    Can be called from an interrupt-context.
528
529Input:
530    microsec - minimum number of microseconds to delay
531
532Returns:
533    <none>
534****************************************************************************/
535void BKNI_Delay(unsigned int microsec);
536
537/**
538BKNI_TRACK_MALLOCS is a simple way to track BKNI_Malloc memory leaks and bad BKNI_Frees.
539It can also help find the location of bad BKNI_EventHandle and BKNI_MutexHandle instances.
540**/
541#ifndef BKNI_TRACK_MALLOCS
542#if defined(LINUX) && !defined(__KERNEL__) && BDBG_DEBUG_BUILD
543#define BKNI_TRACK_MALLOCS 1
544#else
545#define BKNI_TRACK_MALLOCS 0
546#endif
547#endif
548
549/**
550BKNI_DEBUG_CS_TIMING can find critical sections which execute too long. This might happen because
551of poorly written code or context switching on an overly busy system or a system with misconfigured
552real-time threads.
553**/
554#ifndef BKNI_DEBUG_CS_TIMING
555#define BKNI_DEBUG_CS_TIMING 0
556#endif
557
558/***************************************************************************
559Summary:
560    Allocate system memory.
561
562Description:
563    Allocates space for an object whose size is specified by size and whose
564    value is indeterminate.
565
566    System memory is usually managed by an operating system. It differs
567    from memory managed by a MemoryManager in that it is not
568    guaranteed to be physically continuous and you cannot request alignment.
569
570    Passing a size of 0 is not allowed and leads to undefined behavior.
571
572    The caller is responsible to also call BKNI_Free to free the memory
573    when done. Memory that is not explicitly freed
574    may or may not remain allocated beyond the life-cycle of a particular
575    application.
576
577Returns:
578    NULL - Memory could not be allocated
579    Non-NULL - Memory was allocated
580****************************************************************************/
581#if BKNI_TRACK_MALLOCS
582#define BKNI_Malloc(size) BKNI_Malloc_tagged(size, __FILE__, __LINE__)
583
584void *BKNI_Malloc_tagged(
585    size_t size,
586    const char *file,
587    unsigned line
588    );
589#else
590void *BKNI_Malloc(
591    size_t size             /* Number of bytes to allocate */
592    );
593#endif
594
595/***************************************************************************
596Summary:
597    Dellocate system memory.
598
599Description:
600    Causes the memory pointed to by mem to be deallocated, that is, made available for
601    further allocation.
602
603    The following scenarios are not allowed and lead to undefined behavior:
604
605    * Passing a pointer which was not returned by an earlier BKNI_Malloc call
606    * Passing a pointer which was already freed
607    * Passing NULL
608
609Returns:
610    <none>
611****************************************************************************/
612#if BKNI_TRACK_MALLOCS
613#define BKNI_Free(mem) BKNI_Free_tagged(mem, __FILE__, __LINE__)
614
615void BKNI_Free_tagged(
616    void *mem,          /* Pointer to memory allocated by BKNI_Malloc */
617    const char *file,
618    unsigned line
619    );
620#else
621void BKNI_Free(
622    void *mem           /* Pointer to memory allocated by BKNI_Malloc */
623    );
624#endif
625
626#if BKNI_TRACK_MALLOCS
627/***************************************************************************
628Summary:
629Print all current mallocs
630****************************************************************************/
631void BKNI_DumpMallocs(void);
632#endif
633
634/***************************************************************************
635Summary:
636    Yield the current task to the scheduler.
637
638Description:
639    BKNI_Sleep is a sheduler sleep which guarantees you will delay for at least the
640    specified number of milliseconds. It puts the process to sleep and allows the scheduler
641    to run. The minimum sleep time is dependent on the system clock time. If you need
642    a minimum time which is less that the system clock time, you'll need to use BKNI_Delay.
643
644    Actual sleep time is dependent on the scheduler but will be at least as long as
645    the value specified by the millisec parameter.
646
647    A sleep value of 0 should cause the scheduler to execute. This may or may not result in
648    any delay.
649
650    BKNI_Sleep cannot be called from an interrupt context. Use BKNI_Delay instead.
651
652Returns:
653    BERR_SUCCESS - The system slept for at least the specified number of milliseconds.
654    BERR_OS_ERROR - The sleep was interrupted before the specified time.
655****************************************************************************/
656BERR_Code BKNI_Sleep(
657    unsigned int millisec   /* minimum number of milliseconds to sleep */
658    );
659
660
661/***************************************************************************
662Summary:
663    Create an event used by one task to signal another task.
664
665Description:
666    Note that there is no 'name' parameter in BKNI_CreateEvent. We do not support named
667    events because they are essentially global variables that can lead to unwanted behavior.
668    Passing in a name for debugging purposes might lead to someone to think we
669    support named events.
670
671    The event is created in an unsignalled state.
672
673Input:
674    event - point to an event handle which will be initialized.
675
676Returns:
677    BERR_SUCCESS - The event is allocated and initialized.
678    BERR_OS_ERROR - The event could not be allocated or initialized.
679****************************************************************************/
680#if BKNI_TRACK_MALLOCS
681#define BKNI_CreateEvent(event) BKNI_CreateEvent_tagged(event, __FILE__, __LINE__)
682
683BERR_Code BKNI_CreateEvent_tagged(
684    BKNI_EventHandle *event,
685    const char *file,
686    int line
687    );
688#else
689BERR_Code BKNI_CreateEvent(BKNI_EventHandle *event);
690#endif
691
692
693/***************************************************************************
694Summary:
695    Destroy an event.
696
697Description:
698    If any signal is pending, it is lost.
699
700Input:
701    event - event initialized by BKNI_CreateEvent
702****************************************************************************/
703#if BKNI_TRACK_MALLOCS
704#define BKNI_DestroyEvent(event) BKNI_DestroyEvent_tagged(event, __FILE__, __LINE__)
705
706void BKNI_DestroyEvent_tagged(
707    BKNI_EventHandle event,
708    const char *file,
709    int line
710    );
711#else
712void BKNI_DestroyEvent(BKNI_EventHandle event);
713#endif
714
715/***************************************************************************
716Summary:
717    Wait until an event is signalled by BKNI_SetEvent.
718
719Description:
720    Suspends execution of the current task until the event specified by the event parameter
721    becomes signalled. The task should be blocked by the scheduler, resulting in no wasted
722    CPU time.
723
724    This function fails if the event does not become signalled within
725    the period specified by the timeoutMsec parameter. A timeout of zero instructs this
726    function to fail immediately if the event is not signalled. A timeout value of
727    BKNI_INFINTE (defined in bkni_multi.h) causes this function not to return until successful.
728
729    BKNI_WaitForEvent can be called from a single-task module only if that module follows
730    the rules specified under PortingInterface interrupt handling.
731    For this reason, BKNI_INFINITE is defined in bkni_multi.h. An event
732    that blocks for a less-than-infinite time can be considered as an interruptible
733    sleep. See PortingInterface for a description of interrupt handling in a single-threaded
734    module.
735
736    A single BKNI_WaitForEvent call will consume all pending signals.
737
738    However, if multiple tasks call BKNI_WaitForEvent for the same event, it is only
739    guaranteed that at least one will be woken up with the next BKNI_SetEvent call. Some platforms
740    may wake up one, others may wake up all. To avoid problems, Magnum code
741    should only wait on a particular event from a single task.
742
743    BKNI_WaitForEvent can be called from an interrupt context, but only if timeoutMsec
744    is 0. In this case, it checks if the event has been set, and does not block if it
745    has not. Calling BKNI_WaitForEvent from an interrupt context with a non-zero timeout
746    leads to undefined behavior.
747
748Returns:
749    BERR_SUCCESS - An event happened and was consumed.
750    BERR_TIMEOUT - Either the timeout was 0 and no event was already pending, or the timeout expired before an event happened.
751    BERR_OS_ERROR - The system interruped the wait and an event did not happen.
752****************************************************************************/
753BERR_Code BKNI_WaitForEvent(BKNI_EventHandle event, int timeoutMsec);
754
755
756/***************************************************************************
757Summary:
758    Signal an event which causes BKNI_WaitForEvent to return.
759
760Description:
761    Causes the event specified by the event parameter to become signalled. At least one
762    task waiting on the event becomes unblocked.
763
764    If no task is waiting on this event, the signal is remembered and the next call
765    to BKNI_WaitForEvent will succeed immediately.
766
767    BKNI_SetEvent may be called from an interrupt context.
768
769See Also:
770    See BKNI_WaitForEvent for more details and usage rules.
771****************************************************************************/
772void BKNI_SetEvent(BKNI_EventHandle event);
773
774
775/***************************************************************************
776Summary:
777Reset an event so that there are no signals pending.
778
779Description:
780In certain cases it is necessary to reset an event in order to avoid a race condition.
781Consider the following code:
782
783<verbatim>
784    foo() {
785        SetHardware();
786        err = BKNI_WaitForEvent(event, timeout);
787        if (err)
788            return err;
789        return AcquireData();
790    }
791
792    interrupt() {
793     BKNI_SetEvent(event);
794    }
795</verbatim>
796
797And now consider the following execution sequence:
798
799<verbatim>
800    foo() called
801        setHardware() called
802        BKNI_WaitForEvent() called
803        BKNI_WaitForEvent times out and foo returns an error.
804
805    Interrupt happens and BKNI_SetEvent called
806
807    foo() called again
808        setHardware() called
809        BKNI_WaitForEvent() called
810        --> BKNI_WaitForEvent returns BERR_SUCCESS from the old interrupt
811        AcquireData() is called before it should be.
812</verbatim>
813
814In order to avoid this problem, BKNI_ResetEvent must be called before setting or
815resetting hardware. Be careful that there is not a race condition between
816BKNI_ResetEvent and the actual resetting of hardware. If you cannot disable
817the particular interrupt, you need to use a critical section.
818
819<verbatim>
820    foo() {
821        BKNI_EnterCriticalSection();
822        BKNI_ResetEvent(event);
823        SetHardware();
824        BKNI_LeaveCriticalSection();
825        err = BKNI_WaitForEvent(event, timeout);
826        if (err)
827            return err;
828        return AcquireData();
829    }
830</verbatim>
831
832A simple implementation of BKNI_ResetEvent is to call BKNI_WaitForEvent with a timeout
833of 0. For some platforms, there may be a more optimal implementation.
834
835Returns:
836    <none>
837****************************************************************************/
838void BKNI_ResetEvent(BKNI_EventHandle event);
839
840
841/***************************************************************************
842Summary:
843    Cause the application or system to abort immediately if possible.
844    On platforms that support it, the system state should be captured.
845
846Description:
847    This is called from a failed BDBG_ASSERT() (see DebugInterface).
848
849    Can be called from an interrupt-context.
850
851    There is no required behavior for this function. It can be completely
852    empty. There is no need to print an error message from inside BKNI_Fail
853    because the DebugInterface will have printed something before calling
854    it.
855
856See Also:
857    DebugInterface, BDBG_ASSERT
858****************************************************************************/
859void BKNI_Fail(void);
860
861
862/***************************************************************************
863Summary:
864    Create a Magnum critical section which protects against concurrent execution by
865    another Magnum critical section or Magnum ISR (interrupt service routine).
866
867Description:
868    A Magnum critical section is defined as a block of code between a BKNI_EnterCriticalSection
869    call and a BKNI_LeaveCriticalSection call or any code inside a Magnum ISR (distinguished with an _isr suffix).
870    Be aware that a Magnum critical section may not mean the same thing as an operating system's critical
871    section. Typically, operating system critical sections mean that interrupts are disabled and
872    no context switch is possible.
873    A Magnum critical section may or may not mean this, depending on the implementation of KNI.
874
875    Magnum critical sections cannot be preempted by other Magnum critical sections.
876    This includes both interrupts and context switching. But it only applies to Magnum code, not
877    to code outside of Magnum. While there are many ways these rules can be implemented in a system, the recommended
878    approach is as following:
879    * If your system executes Magnum-isr code in interrupt context, Magnum critical sections must be implemented by disabling interrupts.
880    * If your system executes Magnum-isr code in task context, Magnum critical sections must be implemented with a global mutex.
881
882    Be aware that on task-context only systems, critical sections may not prevent the scheduler
883    from time-slicing and executing non-critical section code concurrently with the
884    critical section.
885
886    Critical sections are also used to protect concurrent access to a register shared
887    with another module. Ideally, there are no registers shared between disconnected
888    software modules, but sometimes this is unavoidable.
889
890    Magnum code cannot nest critical sections. Calling BKNI_EnterCriticalSection from
891    inside a critical section is not allowed and leads to undefined behavior.
892    Possible results include deadlock or undetected race conditions.
893
894    A platform implementation might chose to allow BKNI_EnterCriticalSection to nest
895    because of platform-specific considerations.
896
897See Also:
898    BKNI_LeaveCriticalSection, Magnum InterruptSafe rules
899****************************************************************************/
900#if BKNI_DEBUG_CS_TIMING
901#define BKNI_EnterCriticalSection() BKNI_EnterCriticalSection_tagged(__FILE__, __LINE__)
902void BKNI_EnterCriticalSection_tagged(
903    const char *file,
904    unsigned line
905    );
906#else
907void BKNI_EnterCriticalSection(void);
908#endif
909
910/***************************************************************************
911Summary:
912    Leave a critical section.
913
914Description:
915    Calling BKNI_LeaveCriticalSection when you are not in a critical section
916    is not allowed and leads to undefined behavior.
917
918See Also:
919    BKNI_EnterCriticalSection, Magnum InterruptSafe rules
920****************************************************************************/
921#if BKNI_DEBUG_CS_TIMING
922#define BKNI_LeaveCriticalSection() BKNI_LeaveCriticalSection_tagged(__FILE__, __LINE__)
923void BKNI_LeaveCriticalSection_tagged(
924    const char *file,
925    unsigned line
926    );
927#else
928void BKNI_LeaveCriticalSection(void);
929#endif
930
931/***************************************************************************
932Summary:
933    Verifies a critical section.
934
935Description:
936    Assert that code is running in interrupt context, either from an ISR
937    or inside critical section
938
939See Also:
940    BKNI_EnterCriticalSection, Magnum InterruptSafe rules
941****************************************************************************/
942#ifdef BDBG_DEBUG_BUILD
943#define BKNI_ASSERT_ISR_CONTEXT() BKNI_AssertIsrContext(__FILE__, __LINE__)
944#else
945#define BKNI_ASSERT_ISR_CONTEXT() (void)0
946#endif
947void BKNI_AssertIsrContext(const char *filename, unsigned lineno);
948
949
950/* lines below provides aliases for functions safe to call from the interrupt handler */
951#define BKNI_Memset_isr BKNI_Memset
952#define BKNI_Memcpy_isr BKNI_Memcpy
953#define BKNI_Memcmp_isr BKNI_Memcmp
954#define BKNI_Memchr_isr BKNI_Memchr
955#define BKNI_Memmove_isr BKNI_Memmove
956#define BKNI_Delay_isr BKNI_Delay
957#define BKNI_SetEvent_isr BKNI_SetEvent
958
959typedef struct BKNI_MallocEntryInfo {
960    const void *mem;
961    size_t size;
962    const char *malloc_file;
963    unsigned malloc_line;
964    bool alive; /* sets to true if block is still allocated */
965    const char *free_file;
966    unsigned free_line;
967} BKNI_MallocEntryInfo;
968
969/* Called from DBG, and should only be used for the debug purposes */
970BERR_Code BKNI_GetMallocEntryInfo(
971    const void *memory, /* pointer memory allocated by BKNI_Malloc */
972    BKNI_MallocEntryInfo *info
973    );
974
975#define BKNI_GetTrackMallocEntry_isr BKNI_GetTrackMallocEntry
976
977#ifdef __cplusplus
978}
979#endif
980
981#endif /* BKNI_H__ */
Note: See TracBrowser for help on using the repository browser.