Imported Upstream version 2.9.0
[debian/cc1111] / support / regression / tests / bug1938300.c
1 /*
2     bug 1938300
3 */
4
5 #include <testfwk.h>
6
7 #if (defined PORT_HOST) || defined (SDCC_STACK_AUTO)
8
9 /*****************************************************************************
10 * Product; Jongle Reconfigurable USB hardware
11 * Last Updated for Version;
12 * Date of the Last Update;
13 *
14 *                    Q u a n t u m     L e a P s
15 *                    ---------------------------
16 *                    innovating embedded systems
17 *
18 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
19 *
20 * This software may be distributed and modified under the terms of the GNU
21 * General Public License version 2 (GPL) as published by the Free Software
22 * Foundation and appearing in the file GPL.TXT included in the packaging of
23 * this file. Please note that GPL Section 2[b] requires that all works based
24 * on this software must also be made publicly available under the terms of
25 * the GPL ("Copyleft").
26 *
27 * Alternatively, this software may be distributed and modified under the
28 * terms of Quantum Leaps commercial licenses, which expressly supersede
29 * the GPL and are specifically designed for licensees interested in
30 * retaining the proprietary status of their code.
31 *
32 * Contact information;
33 * Quantum Leaps Web site;  http;//www.quantum-leaps.com
34 * e-mail;                  info@quantum-leaps.com
35 *****************************************************************************/
36 #ifndef qpn_port_h
37 #define qpn_port_h
38
39 /* #include "ezusbfx2.h" */
40
41 #define NEAR  near
42 #define IDATA idata
43 #define XDATA xdata
44 #define CODE  code
45 #define SFR_T sfr
46 #define BIT_T bit
47
48 #define QF_ISR_NEST
49 /* #define Q_ROM_VAR               CODE */
50 /* #define Q_ROM_PTR(X)            (X) */
51 #define Q_REENTRANT             /* __reentrant */
52 #define Q_ROM                   CODE
53 #define Q_PARAM_SIZE            0
54 #define QF_TIMEEVT_CTR_SIZE     2
55 #define Q_NFSM
56 /*#define QF_FSM_ACTIVE*/
57 #define QF_MAX_ACTIVE           4
58 #define QF_TIMEEVT_CTR_SIZE     2
59
60                                 /* interrupt locking policy for task level */
61 #define QF_INT_LOCK()           EA = 0
62 #define QF_INT_UNLOCK()         EA = 1
63
64 #define __disable_interrupt()   EA = 0
65 #define __enable_interrupt()    EA = 1
66
67                             /* interrupt locking policy for interrupt level */
68 /* #define QF_ISR_NEST */                    /* nesting of ISRs not allowed */
69
70 /*#include <intrinsics.h>  * contains prototypes for the intrinsic functions */
71 #include <stdint.h>    /* Exact-width integer types. WG14/N843 C99 Standard */
72
73 #endif                                                        /* qpn_port_h */
74
75
76
77 /*****************************************************************************
78 * Product; QEP-nano public interface
79 * Last Updated for Version; 3.4.01
80 * Date of the Last Update;  Sep 24, 2007
81 *
82 *                    Q u a n t u m     L e a P s
83 *                    ---------------------------
84 *                    innovating embedded systems
85 *
86 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
87 *
88 * This software may be distributed and modified under the terms of the GNU
89 * General Public License version 2 (GPL) as published by the Free Software
90 * Foundation and appearing in the file GPL.TXT included in the packaging of
91 * this file. Please note that GPL Section 2[b] requires that all works based
92 * on this software must also be made publicly available under the terms of
93 * the GPL ("Copyleft").
94 *
95 * Alternatively, this software may be distributed and modified under the
96 * terms of Quantum Leaps commercial licenses, which expressly supersede
97 * the GPL and are specifically designed for licensees interested in
98 * retaining the proprietary status of their code.
99 *
100 * Contact information;
101 * Quantum Leaps Web site;  http;//www.quantum-leaps.com
102 * e-mail;                  info@quantum-leaps.com
103 *****************************************************************************/
104 #ifndef qepn_h
105 #define qepn_h
106
107 /** \ingroup qepn qfn qkn
108 * \file qepn.h
109 * \brief Public QEP-nano interface.
110 *
111 * This header file must be included in all modules that use QP-nano.
112 * Typically, this header file is included indirectly through the
113 * header file qpn_port.h.
114 */
115
116 #ifndef Q_ROM             /* if NOT defined, provide the default definition */
117
118     /** \brief Macro to specify compiler-specific directive for placing a
119     * constant object in ROM.
120     *
121     * Many compilers for 8-bit Harvard-architecture MCUs provide non-stanard
122     * extensions to support placement of objects in different memories.
123     * In order to conserve the precious RAM, QP-nano uses the Q_ROM macro for
124     * all constant objects that can be allocated in ROM.
125     *
126     * To override the following empty definition, you need to define the
127     * Q_ROM macro in the qpn_port.h header file. Some examples of valid
128     * Q_ROM macro definitions are; __code (IAR 8051 compiler), code (Keil
129     * 8051 compiler), PROGMEM (gcc for AVR), __flash (IAR for AVR).
130     */
131     #define Q_ROM
132 #endif
133 #ifndef Q_ROM_VAR         /* if NOT defined, provide the default definition */
134
135     /** \brief Macro to specify compiler-specific directive for accessing a
136     * constant object in ROM.
137     *
138     * Many compilers for 8-bit MCUs provide different size pointers for
139     * accessing objects in various memories. Constant objects allocated
140     * in ROM (see #Q_ROM macro) often mandate the use of specific-size
141     * pointers (e.g., far pointers) to get access to ROM objects. The
142     * macro Q_ROM_VAR specifies the kind of the pointer to be used to access
143     * the ROM objects.
144     *
145     * To override the following empty definition, you need to define the
146     * Q_ROM_VAR macro in the qpn_port.h header file. An example of valid
147     * Q_ROM_VAR macro definition is; __far (Freescale HC(S)08 compiler).
148     */
149     #define Q_ROM_VAR
150 #endif
151 #ifndef Q_REENTRANT       /* if NOT defined, provide the default definition */
152
153     /** \brief Macro to specify compiler-specific directive for generating
154     * reentrant function.
155     *
156     * Some compilers for 8-bit MCUs provide, most notably the Keil C51
157     * compiler for 8051, don't generate ANSI-C compliant reentrant functions
158     * by default, due to the limited hardware architecture. These compilers
159     * allow to dedicate specific functions to be reentrant with a special
160     * extended keyword (such as "reentrant" for Keil C51). The macro
161     * Q_REENTRANT is defined to nothing by default, to work with ANSI-C
162     * compiliant compilers, but can be defined to "reentrant" to work with
163     * Keil C51 and perhpas other compilers.
164     */
165     #define Q_REENTRANT
166 #endif
167
168 /****************************************************************************/
169 /** helper macro to calculate static dimension of a 1-dim array \a array_ */
170 #define Q_DIM(array_) (sizeof(array_) / sizeof(array_[0]))
171
172 /****************************************************************************/
173 /** \brief get the current QP version number string
174 *
175 * \return version of the QP as a constant 6-character string of the form
176 * x.y.zz, where x is a 1-digit major version number, y is a 1-digit minor
177 * version number, and zz is a 2-digit release number.
178 */
179 char const Q_ROM * Q_ROM_VAR QP_getVersion(void);
180
181 /** \brief Scalar type describing the signal of an event.
182 */
183 typedef uint8_t QSignal;
184
185 /****************************************************************************/
186 #ifndef Q_PARAM_SIZE
187     /** \brief macro to define the size of event parameter.
188     * Valid values 0, 1, 2, or 4; default 0
189     */
190     #define Q_PARAM_SIZE 0
191 #endif
192 #if (Q_PARAM_SIZE == 0)
193 #elif (Q_PARAM_SIZE == 1)
194
195     /** \brief type of the event parameter.
196     *
197     * This typedef is configurable via the preprocessor switch #Q_PARAM_SIZE.
198     * The other possible values of this type are as follows; \n
199     * none when (Q_PARAM_SIZE == 0); \n
200     * uint8_t when (Q_PARAM_SIZE == 1); \n
201     * uint16_t when (Q_PARAM_SIZE == 2); and \n
202     * uint32_t when (Q_PARAM_SIZE == 4).
203     */
204     typedef uint8_t QParam;
205 #elif (Q_PARAM_SIZE == 2)
206     typedef uint16_t QParam;
207 #elif (Q_PARAM_SIZE == 4)
208     typedef uint32_t QParam;
209 #else
210     #error "Q_PARAM_SIZE defined incorrectly, expected 0, 1, 2, or 4"
211 #endif
212
213 /** \brief Event structure.
214 *
215 * QEvent represents events, optionally with a single scalar parameter.
216 * \sa Q_PARAM_SIZE
217 * \sa ;;QParam
218 */
219 typedef struct QEventTag {
220     QSignal sig;                                   /**< signal of the event */
221
222 #if (Q_PARAM_SIZE != 0)
223     QParam par;                          /**< scalar parameter of the event */
224 #endif
225 } QEvent;
226
227 /****************************************************************************/
228 /** \brief QP reserved signals */
229 enum QReservedSignals {
230     Q_ENTRY_SIG = 1,                   /**< signal for coding entry actions */
231     Q_EXIT_SIG,                         /**< signal for coding exit actions */
232     Q_INIT_SIG,           /**< signal for coding nested initial transitions */
233     Q_TIMEOUT_SIG,                          /**< signal used by time events */
234     Q_USER_SIG      /**< first signal that can be used in user applications */
235 };
236
237 /****************************************************************************/
238 struct QFsmTag;                                      /* forward declaration */
239
240         /** \brief the signature of non-hierarchical state handler function */
241 typedef void (*QState)(NEAR struct QFsmTag *me);
242
243 /** \brief Finite State Machine.
244 *
245 * QFsm represents a traditional non-hierarchical Finite State Machine (FSM)
246 * without state hierarchy, but with entry/exit actions.
247 *
248 * \note QFsm is not intended to be instantiated directly, but rather serves
249 * as the base structure for derivation of state machines in the application
250 * code.
251 *
252 * The following example illustrates how to derive a state machine structure
253 * from QFsm. Please note that the QFsm member super_ is defined as the FIRST
254 * member of the derived struct.
255 * \include qepn_qfsm.c
256 *
257 * \sa \ref derivation
258 */
259 typedef struct QFsmTag {
260     QState state;            /**< current active state of the FSM (private) */
261     QEvent evt;       /**< currently processed event in the FSM (protected) */
262 } QFsm;
263
264 /** \brief macro to access the signal of the current event of a state machine
265 *
266 * \sa ;;QFsm ;;QHsm
267 */
268 #define Q_SIG(me_)  (((QFsm *)(me_))->evt.sig)
269
270 #if (Q_PARAM_SIZE != 0)
271 /** \brief macro to access the parameter of the current event of
272 * a state machine
273 *
274 * \sa ;;QFsm ;;QHsm Q_PARAM_SIZE
275 */
276 #define Q_PAR(me_)  (((QFsm *)(me_))->evt.par)
277 #endif
278
279 #ifndef Q_NFSM
280
281 /** \brief State machine constructor.
282 *
283 * \param me_ pointer the state machine structure derived from ;;QHsm.
284 * \param initial_ is the pointer to the initial state of the state machine.
285 * \note Must be called only ONCE before taking the initial transition
286 * with QFsm_init() and dispatching any events via QFsm_dispatch().
287 */
288 #define QFsm_ctor(me_, initial_) do { \
289     ((QFsm *)me_)->state = (QState)(initial_); \
290     Q_SIG(me_) = (QSignal)Q_INIT_SIG; \
291 } while (0)
292
293 /** \brief Initializes a FSM
294 *
295 * Takes the top-most initial transition in a FSM.
296 * \param me is the pointer the state machine structure derived from ;;FHsm.
297 *
298 * \note Must be called only ONCE after QFsm_ctor() and before any calls
299 * to QFsm_dispatch().
300 */
301 void QFsm_init(NEAR QFsm *me);
302
303 /** \brief Dispatches an event to a FSM
304 *
305 * Processes one event at a time in Run-to-Completion fashion. The argument
306 * \a me is the pointer the state machine structure derived from ;;QFsm.
307 *
308 * \note Must be called after QFsm_init().
309 */
310 void QFsm_dispatch(NEAR QFsm *me) Q_REENTRANT;
311
312 /* protected methods */
313
314 /** \brief Returns current active state of a FSM.
315 *
316 * \note this is a protected function to be used only inside state handler
317 * functions.
318 */
319 #define QFsm_getState(me_)  ((QState const)((QFsm *)(me_))->state)
320
321 #endif                                                            /* Q_NFSM */
322
323 /** \brief Designates a target for an initial or regular transition.
324 *
325 * Q_TRAN() can be used both in the FSMs and HSMs;
326 *
327 * \include qepn_qtran.c
328 */
329 #define Q_TRAN(target_) do { \
330     ((QFsm *)me)->state = (QState)(target_); \
331     ((QFsm *)me)->evt.sig = (QSignal)0; \
332 } while (0)
333
334 /****************************************************************************/
335 #ifndef Q_NHSM
336
337 struct QHsmTag;                                      /* forward declaration */
338
339                  /** \brief the signature of state handler function for HSM */
340 typedef QState (*QHsmState)(NEAR struct QHsmTag *me);
341
342   /** \brief a name for the return type from the HSM state handler function */
343 typedef QState QSTATE;
344
345 /** \brief a Hierarchical State Machine.
346 *
347 * QHsm represents a Hierarchical Finite State Machine (HSM). QHsm
348 * extends the capabilities of a basic FSM with state hierarchy.
349 *
350 * \note QHsm is not intended to be instantiated directly, but rather serves
351 * as the base structure for derivation of state machines in the application
352 * code.
353 *
354 * The following example illustrates how to derive a state machine structure
355 * from QHsm. Please note that the QHsm member super_ is defined as the FIRST
356 * member of the derived struct.
357 * \include qepn_qhsm.c
358 *
359 * \sa \ref derivation
360 */
361 typedef struct QHsmTag {
362     QHsmState state;         /**< current active state of the HSM (private) */
363     QEvent evt;       /**< currently processed event in the HSM (protected) */
364 } QHsm;
365
366 /* public methods */
367 /** \brief State machine constructor.
368 *
369 * \param me_ pointer the state machine structure derived from ;;QHsm.
370 * \param initial_ is the pointer to the initial state of the state machine.
371 * \note Must be called only ONCE before taking the initial transition
372 * with QHsm_init() and dispatching any events via QHsm_dispatch().
373 */
374 #define QHsm_ctor(me_, initial_) do { \
375     ((QHsm *)me_)->state  = (QHsmState)(initial_); \
376     Q_SIG(me_) = (QSignal)Q_INIT_SIG; \
377 } while (0)
378
379 /** \brief Initializes a HSM.
380 *
381 * Takes the top-most initial transition in a HSM.
382 * \param me is the pointer the state machine structure derived from ;;QHsm.
383 *
384 * \note Must be called only ONCE after QHsm_ctor() and before any calls
385 * to QHsm_dispatch().
386 */
387 void QHsm_init(NEAR QHsm *me);
388
389 /** \brief Dispatches an event to a HSM
390 *
391 * Processes one event at a time in Run-to-Completion fashion.
392 * \param me is the pointer the state machine structure derived from ;;QHsm.
393 *
394 * \note Must be called repetitively for each event after QHsm_init().
395 */
396 void QHsm_dispatch(NEAR QHsm *me) Q_REENTRANT;
397
398 /* protected methods... */
399
400 /** \brief The top-state.
401 *
402 * QHsm_top() is the ultimate root of state hierarchy in all HSMs derived
403 * from ;;QHsm. This state handler always returns (QSTATE)0, which means
404 * that it "handles" all events.
405 *
406 * \sa Example of the QCalc_on() state handler for Q_INIT().
407 */
408 QSTATE QHsm_top(NEAR QHsm *me) Q_REENTRANT;
409
410 /** \return the current active state of the \a me_ state machine  */
411 #define QHsm_getState(me_)  ((QHsmState const)((QHsm *)(me_))->state)
412
413 #endif                                                            /* Q_NHSM */
414
415
416 /****************************************************************************/
417 /*  DEPRECATED  DEPRECATED  DEPRECATED  DEPRECATED  DEPRECATED  DEPRECATED  */
418
419 /* If QPN compatibility level not defined or the level is lower than v3.4    */
420 #if (!defined(QPN_COMP_LEVEL) || (QPN_COMP_LEVEL < 34))
421
422 /** signal for coding the top-most initial transition (deprecated) */
423 #define Q_TOP_INIT_SIG      Q_INIT_SIG
424
425 /** \brief Designates a target for an initial transition.
426 *
427 * \note DEPRECATED
428 * \sa Q_TRAN()
429 */
430 #define Q_INIT(target_)     Q_TRAN(target_)
431
432 /** \brief Returns current active state of a FSM.
433 *
434 * \note DEPRECATED
435 * \sa QFsm_getState()
436 */
437 #define QFsm_getState_(me_) QFsm_getState(me_)
438
439 /** \brief Returns current active state of a HSM.
440 *
441 * \note DEPRECATED
442 * \sa QHsm_getState()
443 */
444 #define QHsm_getState_(me_) QHsm_getState(me_)
445
446 #endif                                               /* QPN_COMP_LEVEL < 34 */
447
448
449 #endif                                                            /* qepn_h */
450
451
452
453 /*****************************************************************************
454 * Product; QF-nano public interface
455 * Last Updated for Version; 3.4.01
456 * Date of the Last Update;  Sep 18, 2007
457 *
458 *                    Q u a n t u m     L e a P s
459 *                    ---------------------------
460 *                    innovating embedded systems
461 *
462 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
463 *
464 * This software may be distributed and modified under the terms of the GNU
465 * General Public License version 2 (GPL) as published by the Free Software
466 * Foundation and appearing in the file GPL.TXT included in the packaging of
467 * this file. Please note that GPL Section 2[b] requires that all works based
468 * on this software must also be made publicly available under the terms of
469 * the GPL ("Copyleft").
470 *
471 * Alternatively, this software may be distributed and modified under the
472 * terms of Quantum Leaps commercial licenses, which expressly supersede
473 * the GPL and are specifically designed for licensees interested in
474 * retaining the proprietary status of their code.
475 *
476 * Contact information;
477 * Quantum Leaps Web site;  http;//www.quantum-leaps.com
478 * e-mail;                  info@quantum-leaps.com
479 *****************************************************************************/
480 #ifndef qfn_h
481 #define qfn_h
482
483 /** \ingroup qepn qfn qkn
484 * \file qfn.h
485 * \brief Public QF-nano interface.
486 *
487 * This header file must be included in all modules that use QP-nano.
488 * Typically, this header file is included indirectly through the
489 * header file qpn_port.h.
490 */
491
492 #ifndef QF_TIMEEVT_CTR_SIZE
493     /** \brief macro to override the default QTimeEvtCtr size.
494     * Valid values 0, 1, 2, or 4; default 0
495     */
496     #define QF_TIMEEVT_CTR_SIZE 0
497 #endif
498 #if (QF_TIMEEVT_CTR_SIZE == 0)
499 #elif (QF_TIMEEVT_CTR_SIZE == 1)
500     typedef uint8_t QTimeEvtCtr;
501 #elif (QF_TIMEEVT_CTR_SIZE == 2)
502     /** \brief type of the Time Event counter, which determines the dynamic
503     * range of the time delays measured in clock ticks.
504     *
505     * This typedef is configurable via the preprocessor switch
506     * #QF_TIMEEVT_CTR_SIZE. The other possible values of this type are
507     * as follows; \n
508     * none when (QF_TIMEEVT_CTR_SIZE not defined or == 0), \n
509     * uint8_t when (QF_TIMEEVT_CTR_SIZE == 1); \n
510     * uint16_t when (QF_TIMEEVT_CTR_SIZE == 2); and \n
511     * uint32_t when (QF_TIMEEVT_CTR_SIZE == 4).
512     */
513     typedef uint16_t QTimeEvtCtr;
514 #elif (QF_TIMEEVT_CTR_SIZE == 4)
515     typedef uint32_t QTimeEvtCtr;
516 #else
517     #error "QF_TIMER_SIZE defined incorrectly, expected 1, 2, or 4"
518 #endif
519
520 /** \brief Active Object struct
521 *
522 * QActive is the base structure for derivation of active objects. Active
523 * objects in QF-nano are encapsulated tasks (each embedding a state machine
524 * and an event queue) that communicate with one another asynchronously by
525 * sending and receiving events. Within an active object, events are
526 * processed sequentially in a run-to-completion (RTC) fashion, while QF
527 * encapsulates all the details of thread-safe event exchange and queuing.
528 *
529 * \note ;;QActive is not intended to be instantiated directly, but rather
530 * serves as the base structure for derivation of active objects in the
531 * application code.
532 *
533 * The following example illustrates how to derive an active object from
534 * QActive. Please note that the QActive member super_ is defined as the
535 * FIRST member of the derived struct.
536 * \include qfn_qactive.c
537 *
538 * \sa ;;QActiveTag for the description of the data members \n \ref derivation
539 */
540 typedef struct QActiveTag {
541
542 #if (!defined(QF_FSM_ACTIVE) && !defined(Q_NHSM))
543     QHsm super;                 /**< derives from the ;;QHsm base structure */
544 #else
545     QFsm super;                 /**< derives from the ;;QFsm base structure */
546 #endif
547
548     /** \brief offset to where next event will be inserted into the buffer
549     */
550     uint8_t head;
551
552     /** \brief offset of where next event will be extracted from the buffer
553     */
554     uint8_t tail;
555
556     /** \brief number of events currently present in the ring buffer
557     */
558     uint8_t nUsed;
559
560 #if (QF_TIMEEVT_CTR_SIZE != 0)
561     /** \brief Time Event tick counter for the active object
562     */
563     QTimeEvtCtr tickCtr;
564 #endif
565 } QActive;
566
567 #if (!defined(QF_FSM_ACTIVE) && !defined(Q_NHSM))
568     /** \brief Active object constructor.
569     *
570     * \param me_ pointer the active object structure derived from ;;QActive.
571     * \param initial_ is the pointer to the initial state of the active
572     * object.
573     * \note Must be called exactly ONCE for each active object
574     * in the application before calling QF_run().
575     */
576     #define QActive_ctor(me_, initial_) do { \
577         QHsm_ctor(me_, initial_); \
578         ((QActive *)(me_))->nUsed = (uint8_t)0; \
579     } while (0)
580 #else
581     #define QActive_ctor(me_, initial_) do { \
582         QFsm_ctor(me_, initial_); \
583         ((QActive *)(me_))->nUsed = (uint8_t)0; \
584     } while (0)
585 #endif
586
587
588 #if (Q_PARAM_SIZE != 0)
589     /** \brief Posts an event \a e directly to the event queue of the acitve
590     * object \a prio using the First-In-First-Out (FIFO) policy. This
591     * function briefly locks and unlocks interrupts to protect the
592     * queue integrity.
593     *
594     * Direct event posting is the only asynchronous communication method
595     * available in QF-nano. The following example illustrates how the
596     * Ped active object posts directly the PED_WAITING event to the PELICAN
597     * crossing active object.
598     * \include qfn_post.c
599     *
600     * \note The producer of the event (Ped in this case) must only "know"
601     * the recipient's priority (Pelican), but the specific definition of
602     * the Pelican structure is not required.
603     *
604     * \note Direct event posting should not be confused with direct event
605     * dispatching. In contrast to asynchronous event posting through event
606     * queues, direct event dispatching is synchronous. Direct event
607     * dispatching occurs when you call QHsm_dispatch(), or QFsm_dispatch()
608     * function.
609     */
610     void QF_post(uint8_t prio, QSignal sig, QParam par) Q_REENTRANT;
611
612     /** \brief Posts an event \a e directly to the event queue of the acitve
613     * object \a prio using the First-In-First-Out (FIFO) policy. This
614     * function does NOT lock/unlock interrupts and is intended only
615     * to be used inside critical sections (such as inside ISRs that cannot
616     * nest).
617     *
618     * \sa QF_post()
619     */
620     void QF_postISR(uint8_t prio, QSignal sig, QParam par) Q_REENTRANT;
621 #else
622     void QF_post(uint8_t prio, QSignal sig) Q_REENTRANT;
623     void QF_postISR(uint8_t prio, QSignal sig) Q_REENTRANT;
624 #endif
625
626 /****************************************************************************/
627 /** \brief QActive Control Block
628 *
629 * QActiveCB represents the constant information that the QF-nano needs
630 * to manage the active object. QActiveCB objects are grouped in the
631 * array QF_active[], which typically can be placed in ROM.
632 *
633 * The following example illustrates how to allocate and initialize the
634 * QActive control blocks in the array QF_active[].
635 * \include qfn_main.c
636 */
637 typedef struct QActiveCBTag {
638     QActive *act;        /**< \brief pointer to the active object structure */
639     QEvent *queue;            /**< \brief pointer to the event queue buffer */
640     uint8_t end;                  /**< \brief the length of the ring buffer */
641 } QActiveCB;
642
643 #if (QF_TIMEEVT_CTR_SIZE != 0)
644
645 #if (QF_TIMEEVT_CTR_SIZE > 1)
646
647 /** \brief Arm a one-shot time event for direct event posting.
648 *
649 * Arms a time event \a me to fire in \a tout clock ticks
650 * (one-shot time event). The timeout signal Q_TIMEOUT_SIG gets directly
651 * posted (using the FIFO policy) into the event queue of the active object
652 * \a me.
653 *
654 * After posting, the time event gets automatically disarmed and can be reused.
655 *
656 * A one-shot time event can be disarmed at any time by calling the
657 * QActive_disarm() function. Also, a one-shot time event can be re-armed
658 * to fire in a different number of clock ticks by calling QActive_arm() again.
659 *
660 * The following example shows how to arm a one-shot time event from a state
661 * machine of an active object;
662 * \include qfn_arm.c
663 */
664 void QActive_arm(NEAR QActive *me, QTimeEvtCtr tout) Q_REENTRANT;
665
666 /** \brief Disarm a time event.
667 *
668 * The time event \a me gets disarmed and can be reused.
669 */
670 void QActive_disarm(NEAR QActive *me) Q_REENTRANT;
671
672 #else                                   /* QF_TIMEEVT_CTR_SIZE must be == 1 */
673
674 /** \brief Arm a one-shot time event for direct event posting.
675 *
676 * Arms a time event \param me_ to fire in \param tout_ clock ticks
677 * (one-shot time event). The timeout signal Q_TIMEOUT_SIG gets directly
678 * posted (using the FIFO policy) into the event queue of the active object
679 * \param me_.
680 *
681 * After posting, the time event gets automatically disarmed and can be reused.
682 *
683 * A one-shot time event can be disarmed at any time by calling the
684 * QActive_disarm() function. Also, a one-shot time event can be re-armed
685 * to fire in a different number of clock ticks by calling QActive_arm() again.
686 *
687 * The following example shows how to arm a one-shot time event from a state
688 * machine of an active object;
689 * \include qfn_arm.c
690 */
691 #define QActive_arm(me_, tout_) ((me_)->tickCtr = (QTimeEvtCtr)(tout_))
692
693 /** \brief Disarm a time event.
694 *
695 * The time event \param me_ gets disarmed and can be reused.
696 */
697 #define QActive_disarm(me_)     ((me_)->tickCtr = (QTimeEvtCtr)0)
698
699 #endif                                           /* QF_TIMEEVT_CTR_SIZE > 1 */
700
701 /** \brief Processes all armed time events at every clock tick.
702 *
703 * This function must be called periodically from a time-tick ISR or from
704 * the highest-priority task so that QF can manage the timeout events.
705 *
706 * \note The QF_tick() function is not reentrant meaning that it must run to
707 * completion before it is called again. Also, QF_tick() assumes that it
708 * never will get preempted by a task, which is always the case when it is
709 * called from an ISR or the highest-priority task.
710 *
711 * The following example illustrates the call to QF_tick();
712 * \include qfn_tick.c
713 */
714 void QF_tick(void);
715
716 #endif                                        /* (QF_TIMEEVT_CTR_SIZE != 0) */
717
718 /* protected methods ...*/
719
720 /** \brief QF initialization.
721 *
722 * This function initializes QF and must be called exactly once before any
723 * other QF function. In QF-nano this function is defined in the BSP.
724 */
725 void QF_init(void);
726
727 /** \brief Starts the interrupts and initializes other critical resources
728 * that might interact with the QF application.
729 *
730 * QF_start() is called from QF_run(), right before starting the non-preemptive
731 * multitasking in the background loop.
732 *
733 * \note This function is strongly platform-dependent and is not implemented
734 * in the QF, but either in the QF port or in the Board Support Package (BSP)
735 * for the given application.
736 *
737 * \sa QF initialization example for ;;QActiveCB.
738 */
739 void QF_start(void);
740
741 /** \brief Transfers control to QF to run the application.
742 *
743 * QF_run() implemetns the simple non-preemptive scheduler. QF_run() must be
744 * called from your startup code after you initialize the QF and define at
745 * least one active object control block in QF_active[].
746 *
747 * \note When the Quantum Kernel (QK) is used as the underlying real-time
748 * kernel for the QF, all platfrom dependencies are handled in the QK, so
749 * no porting of QF is necessary. In other words, you only need to recompile
750 * the QF platform-independent code with the compiler for your platform, but
751 * you don't need to provide any platform-specific implementation (so, no
752 * qf_port.c file is necessary). Moreover, QK implements the function QF_run()
753 * in a platform-independent way, in the modile qk.c.
754 */
755 void QF_run(void);
756
757 #ifndef QK_PREEMPTIVE
758     /** \brief QF idle callback (customized in BSPs for QF)
759     *
760     * QF_onIdle() is called by the non-preemptive scheduler built into QF-nano
761     * when the QF-nano detects that no events are available for active objects
762     * (the idle condition). This callback gives the application an opportunity
763     * to enter a power-saving CPU mode, or perform some other idle processing.
764     *
765     * \note QF_onIdle() is invoked with interrupts LOCKED because the idle
766     * condition can be asynchronously changed at any time by an interrupt.
767     * QF_onIdle() MUST unlock the interrupts internally, but not before
768     * putting the CPU into the low-power mode. (Ideally, unlocking interrupts
769     * and low-power mode should happen atomically). At the very least, the
770     * function MUST unlock interrupts, otherwise interrups will be locked
771     * permanently.
772     *
773     * \note QF_onIdle() is not used in the PREEMPTIVE configuration. When
774     * QK_PREEMPTIVE macro is defined, the preemptive kernel QK-nano is used
775     * instead of the non-preemptive QF-nano scheduler. QK-nano uses a
776     * different idle callback \sa QK_onIdle().
777     */
778 void QF_onIdle(void);
779 #endif
780
781 /** \brief Exits the QF application and returns control to the OS/Kernel.
782 *
783 * This function exits the framework. After calling this function, QF is no
784 * longer in control of the application. The typical use of this method is
785 * for exiting the QF application to return back to the operating system
786 * or for handling fatal errors that require resetting the system.
787 *
788 * This function is strongly platform-dependent and is not implemented in
789 * QF-nano, but either in the QF port or in the Board Support Package (BSP)
790 * for the given application. Some QF ports might not require implementing
791 * QF_exit() at all, because many embedded application don't have anything
792 * to exit to.
793 */
794 void QF_exit(void);
795
796                                            /** active object control blocks */
797 extern QActiveCB const Q_ROM Q_ROM_VAR QF_active[];
798
799                                            /** the number of control blocks */
800 extern uint8_t   const Q_ROM Q_ROM_VAR QF_activeNum;
801
802 /** \brief Ready set of QF-nano.
803 *
804 * The QF-nano ready set keeps track of active objects that are ready to run.
805 * The ready set represents each active object as a bit, with the bits
806 * assigned according to priorities of the active objects. The bit is set
807 * if the corresponding active object is ready to run (i.e., has one or
808 * more events in its event queue) and zero if the event queue is empty.
809 * The QF-nano ready set is one byte-wide, which corresponds to 8 active
810 * objects maximum.
811 */
812 extern uint8_t volatile QF_readySet_;
813
814 #endif                                                             /* qfn_h */
815
816
817
818 /*****************************************************************************
819 * Product; QP-nano
820 * Last Updated for Version; 3.4.00
821 * Date of the Last Update;  Aug 20, 2007
822 *
823 *                    Q u a n t u m     L e a P s
824 *                    ---------------------------
825 *                    innovating embedded systems
826 *
827 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
828 *
829 * This software may be distributed and modified under the terms of the GNU
830 * General Public License version 2 (GPL) as published by the Free Software
831 * Foundation and appearing in the file GPL.TXT included in the packaging of
832 * this file. Please note that GPL Section 2[b] requires that all works based
833 * on this software must also be made publicly available under the terms of
834 * the GPL ("Copyleft").
835 *
836 * Alternatively, this software may be distributed and modified under the
837 * terms of Quantum Leaps commercial licenses, which expressly supersede
838 * the GPL and are specifically designed for licensees interested in
839 * retaining the proprietary status of their code.
840 *
841 * Contact information;
842 * Quantum Leaps Web site;  http;//www.quantum-leaps.com
843 * e-mail;                  info@quantum-leaps.com
844 *****************************************************************************/
845 #ifndef qassert_h
846 #define qassert_h
847
848 /** \ingroup qepn qfn
849 * \file qassert.h
850 * \brief Customizable assertions.
851 *
852 * Defines customizable and memory-efficient assertions applicable to
853 * embedded systems. This header file can be used in C, C++, and mixed C/C++
854 * programs.
855 *
856 * \note The preprocessor switch Q_NASSERT disables checking assertions.
857 * In particular macros \ref Q_ASSERT, \ref Q_REQUIRE, \ref Q_ENSURE,
858 * \ref Q_INVARIANT, and \ref Q_ERROR do NOT evaluate the test condition
859 * passed as the argument to these macros. One notable exception is the
860 * macro \ref Q_ALLEGE, that still evaluates the test condition, but does
861 * not report assertion failures when the switch Q_NASSERT is defined.
862 */
863 #ifdef Q_NASSERT          /* Q_NASSERT defined--assertion checking disabled */
864
865     #define Q_DEFINE_THIS_FILE
866     #define Q_DEFINE_THIS_MODULE(name_)
867     #define Q_ASSERT(ignore_)  ((void)0)
868     #define Q_ALLEGE(test_)    ((void)(test_))
869     #define Q_ERROR()          ((void)0)
870
871 #else                  /* Q_NASSERT not defined--assertion checking enabled */
872
873     #ifdef __cplusplus
874         extern "C" {
875     #endif
876
877     /** callback invoked in case the condition passed to \ref Q_ASSERT,
878     * \ref Q_REQUIRE, \ref Q_ENSURE, \ref Q_ERROR, or \ref Q_ALLEGE
879     * evaluates to FALSE.
880     *
881     * \param file file name where the assertion failed
882     * \param line line number at which the assertion failed
883     */
884     /*lint -sem(Q_assert_handler, r_no)    Q_assert_handler() never returns */
885     void Q_assert_handler(char const Q_ROM * const Q_ROM_VAR file, int line);
886
887     #ifdef __cplusplus
888         }
889     #endif
890
891     /** Place this macro at the top of each C/C++ module to define the file
892     * name string using __FILE__ (NOTE; __FILE__ might contain lengthy path
893     * name). This file name will be used in reporting assertions in this file.
894     */
895     #define Q_DEFINE_THIS_FILE \
896         static char const Q_ROM Q_ROM_VAR l_this_file[] = __FILE__;
897
898     /** Place this macro at the top of each C/C++ module to define the module
899     * name as the argument \a name_. This file name will be used in reporting
900     * assertions in this file.
901     */
902     #define Q_DEFINE_THIS_MODULE(name_) \
903         static char const Q_ROM Q_ROM_VAR l_this_file[] = #name_;
904
905     /** General purpose assertion that makes sure the \a test_ argument is
906     * TRUE. Calls the Q_assert_handler() callback if the \a test_ evaluates
907     * to FALSE.
908     * \note the \a test_ is NOT evaluated if assertions are
909     * disabled with the Q_NASSERT switch.
910     */
911     #define Q_ASSERT(test_) \
912         if (test_) { \
913         } \
914         else (Q_assert_handler(l_this_file, __LINE__))
915
916     /** General purpose assertion that ALWAYS evaluates the \a test_
917     * argument and calls the Q_assert_handler() callback if the \a test_
918     * evaluates to FALSE.
919     * \note the \a test_ argument IS always evaluated even when assertions are
920     * disabled with the Q_NASSERT macro. When the Q_NASSERT macro is
921     * defined, the Q_assert_handler() callback is NOT called, even if the
922     * \a test_ evaluates to FALSE.
923     */
924     #define Q_ALLEGE(test_)    Q_ASSERT(test_)
925
926     /** Assertion that always calls the Q_assert_handler() callback if
927     * ever executed.
928     * \note can be disabled with the Q_NASSERT switch.
929     */
930     #define Q_ERROR() \
931         (Q_assert_handler(l_this_file, __LINE__))
932
933 #endif                                                           /* NASSERT */
934
935 /** Assertion that checks for a precondition. This macro is equivalent to
936 * \ref Q_ASSERT, except the name provides a better documentation of the
937 * intention of this assertion.
938 */
939 #define Q_REQUIRE(test_)   Q_ASSERT(test_)
940
941 /** Assertion that checks for a postcondition. This macro is equivalent to
942 * \ref Q_ASSERT, except the name provides a better documentation of the
943 * intention of this assertion.
944 */
945 #define Q_ENSURE(test_)    Q_ASSERT(test_)
946
947 /** Assertion that checks for an invariant. This macro is equivalent to
948 * \ref Q_ASSERT, except the name provides a better documentation of the
949 * intention of this assertion.
950 */
951 #define Q_INVARIANT(test_) Q_ASSERT(test_)
952
953 /** Compile-time assertion exploits the fact that in C/C++ a dimension of
954  * an array must be non-zero. The following declaration causes a compilation
955  * error if the compile-time expression (\a test_) is not TRUE. The assertion
956  * has no runtime side effects.
957  */
958 #define Q_ASSERT_COMPILE(test_) \
959     extern char Q_assert_compile[(test_)]
960
961 #endif                                                         /* qassert_h */
962
963
964
965 /*****************************************************************************
966 * Product; QEP-nano implemenation
967 * Last Updated for Version; 3.4.01
968 * Date of the Last Update;  Sep 18, 2007
969 *
970 *                    Q u a n t u m     L e a P s
971 *                    ---------------------------
972 *                    innovating embedded systems
973 *
974 * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
975 *
976 * This software may be distributed and modified under the terms of the GNU
977 * General Public License version 2 (GPL) as published by the Free Software
978 * Foundation and appearing in the file GPL.TXT included in the packaging of
979 * this file. Please note that GPL Section 2[b] requires that all works based
980 * on this software must also be made publicly available under the terms of
981 * the GPL ("Copyleft").
982 *
983 * Alternatively, this software may be distributed and modified under the
984 * terms of Quantum Leaps commercial licenses, which expressly supersede
985 * the GPL and are specifically designed for licensees interested in
986 * retaining the proprietary status of their code.
987 *
988 * Contact information;
989 * Quantum Leaps Web site;  http;//www.quantum-leaps.com
990 * e-mail;                  info@quantum-leaps.com
991 *****************************************************************************/
992
993 Q_DEFINE_THIS_MODULE(qepn)
994
995 /** \ingroup qepn qfn
996 * \file qepn.c
997 * QEP-nano implementation.
998 */
999
1000 /** empty signal for internal use only */
1001 #define QEP_EMPTY_SIG        0
1002
1003 /** maximum depth of state nesting (including the top level), must be >= 2 */
1004 #define QEP_MAX_NEST_DEPTH   5
1005
1006 #ifndef Q_NHSM
1007 /*..........................................................................*/
1008 void QHsm_dispatch(NEAR QHsm *me) Q_REENTRANT {
1009     QHsmState path[QEP_MAX_NEST_DEPTH];
1010     QHsmState s;
1011     QHsmState t = me->state;
1012
1013     path[1] = t;    /* save the current state in case a transition is taken */
1014
1015     do {                             /* process the event hierarchically... */
1016         s = t;
1017         t = (QHsmState)((*s)(me));                /* invoke state handler s */
1018     } while (t != (QHsmState)0);
1019
1020     if (me->evt.sig == (QSignal)0) {                   /* transition taken? */
1021         QHsmState src = s;                  /* the source of the transition */
1022         int8_t ip = (int8_t)(-1);            /* transition entry path index */
1023         int8_t iq;                    /* helper transition entry path index */
1024
1025         path[0] = me->state;                          /* save the new state */
1026         me->state = path[1];                   /* restore the current state */
1027
1028                       /* exit current state to the transition source src... */
1029         for (s = path[1]; s != src; ) {
1030             Q_SIG(me) = (QSignal)Q_EXIT_SIG;
1031             t = (QHsmState)(*s)(me);                /* find superstate of s */
1032             if (t != (QHsmState)0) {               /* exit action unhandled */
1033                 s = t;                            /* t points to superstate */
1034             }
1035             else {                                   /* exit action handled */
1036                 Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1037                 s = (QHsmState)(*s)(me);            /* find superstate of s */
1038             }
1039         }
1040
1041         t = path[0];                            /* target of the transition */
1042
1043         if (src == t) {    /* (a) check source==target (transition to self) */
1044             Q_SIG(me) = (QSignal)Q_EXIT_SIG;
1045             (void)(*src)(me);                            /* exit the source */
1046             ip = (int8_t)0;                             /* enter the target */
1047         }
1048         else {
1049             Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1050             t = (QHsmState)(*t)(me);           /* find superstate of target */
1051             if (src == t) {              /* (b) check source==target->super */
1052                 ip = (int8_t)0;                         /* enter the target */
1053             }
1054             else {
1055                 Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1056                 s = (QHsmState)(*src)(me);        /* find superstate of src */
1057                 if (s == t) {     /* (c) check source->super==target->super */
1058                     Q_SIG(me) = (QSignal)Q_EXIT_SIG;
1059                     (void)(*src)(me);                    /* exit the source */
1060                     ip = (int8_t)0;                     /* enter the target */
1061                 }
1062                 else {
1063                     if (s == path[0]) {  /* (d) check source->super==target */
1064                         Q_SIG(me) = (QSignal)Q_EXIT_SIG;
1065                         (void)(*src)(me);                /* exit the source */
1066                     }
1067                     else { /* (e) check rest of source==target->super->super..
1068                             * and store the entry path along the way
1069                             */
1070                         iq = (int8_t)0;      /* indicate that LCA not found */
1071                         ip = (int8_t)1;  /* enter target and its superstate */
1072                         path[1] = t;       /* save the superstate of target */
1073                         Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1074                         t = (QHsmState)(*t)(me);    /* find superstate of t */
1075                         while (t != (QHsmState)0) {
1076                             path[++ip] = t;         /* store the entry path */
1077                             if (t == src) {            /* is it the source? */
1078                                 iq = (int8_t)1;  /* indicate that LCA found */
1079                                             /* entry path must not overflow */
1080                                 Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH);
1081                                 --ip;            /* do not enter the source */
1082                                 t = (QHsmState)0;     /* terminate the loop */
1083                             }
1084                             else {   /* it is not the source, keep going up */
1085                                 Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1086                                 t = (QHsmState)(*t)(me); /* superstate of t */
1087                             }
1088                         }
1089                         if (iq == (int8_t)0) {    /* the LCA not found yet? */
1090
1091                                             /* entry path must not overflow */
1092                             Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH);
1093
1094                             Q_SIG(me) = (QSignal)Q_EXIT_SIG;
1095                             (void)(*src)(me);            /* exit the source */
1096
1097                                 /* (f) check the rest of source->super
1098                                  *                  == target->super->super...
1099                                  */
1100                             iq = ip;
1101                             do {
1102                                 if (s == path[iq]) {    /* is this the LCA? */
1103                                     t = s;    /* indicate that LCA is found */
1104                                     ip = (int8_t)(iq - 1);/*do not enter LCA*/
1105                                     iq = (int8_t)(-1);/* terminate the loop */
1106                                 }
1107                                 else {
1108                                     --iq; /* try lower superstate of target */
1109                                 }
1110                             } while (iq >= (int8_t)0);
1111
1112                             if (t == (QHsmState)0) {  /* LCA not found yet? */
1113                                     /* (g) check each source->super->...
1114                                      * for each target->super...
1115                                      */
1116                                 do {
1117                                     Q_SIG(me) = (QSignal)Q_EXIT_SIG;
1118                                     t = (QHsmState)(*s)(me);      /* exit s */
1119                                     if (t != (QHsmState)0) {  /* unhandled? */
1120                                         s = t;    /* t points to super of s */
1121                                     }
1122                                     else {           /* exit action handled */
1123                                         Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1124                                         s = (QHsmState)(*s)(me);/*super of s*/
1125                                     }
1126                                     iq = ip;
1127                                     do {
1128                                         if (s == path[iq]) {/* is this LCA? */
1129                                                         /* do not enter LCA */
1130                                             ip = (int8_t)(iq - 1);
1131                                             iq = (int8_t)(-1);/*break inner */
1132                                             s = (QHsmState)0; /*break outer */
1133                                         }
1134                                         else {
1135                                             --iq;
1136                                         }
1137                                     } while (iq >= (int8_t)0);
1138                                 } while (s != (QHsmState)0);
1139                             }
1140                         }
1141                     }
1142                 }
1143             }
1144         }
1145                     /* retrace the entry path in reverse (desired) order... */
1146         for (; ip >= (int8_t)0; --ip) {
1147             Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
1148             (void)(*path[ip])(me);                        /* enter path[ip] */
1149         }
1150         s = path[0];                      /* stick the target into register */
1151         me->state = s;                          /* update the current state */
1152
1153                                       /* drill into the target hierarchy... */
1154         Q_SIG(me) = (QSignal)Q_INIT_SIG;
1155         while ((*s)(me) == (QState)0) {
1156             t = me->state;
1157             path[0] = t;
1158             ip = (int8_t)0;
1159             Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1160             t = (QHsmState)(*t)(me);                /* find superstate of t */
1161             while (t != s) {
1162                 ++ip;
1163                 path[ip] = t;
1164                 Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
1165                 t = (QHsmState)(*t)(me);            /* find superstate of t */
1166             }
1167                                             /* entry path must not overflow */
1168             Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH);
1169
1170             do {    /* retrace the entry path in reverse (correct) order... */
1171                 Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
1172                 (void)(*path[ip])(me);                    /* enter path[ip] */
1173                 --ip;
1174             } while (ip >= (int8_t)0);
1175             s = me->state;
1176             Q_SIG(me) = (QSignal)Q_INIT_SIG;
1177         }
1178     }
1179 }
1180
1181 void Q_assert_handler(char const Q_ROM * const Q_ROM_VAR file, int line)
1182 {
1183     file;
1184     line;
1185 }
1186
1187 #endif                                                            /* Q_NHSM */
1188
1189 #endif //(defined PORT_HOST) || defined (SDCC_STACK_AUTO)
1190
1191 void
1192 testDummy(void)
1193 {
1194 }