Prev: 2. Let's Play
Next: 4. Designing an Event-Driven Application
Perhaps the best place to start the explanation of the "Fly 'n' Shoot" application code is the main() function, located in the file main.c. Unless indicated otherwise in this Tutorial, you can browse the code either in the DOS version, or the Cortex-M3 version, because the application source code is identical in both. The complete main.c file is shown in Listing 3-1
(1) #include "qp_port.h" /* the QP port */ (2) #include "bsp.h" /* Board Support Package */ (3) #include "game.h" /* this application */ /* Local-scope objects -----------------------------------------------------*/ (4) static QEvent const * l_missileQueueSto[2]; /* event queue */ (5) static QEvent const * l_shipQueueSto[3]; /* event queue */ (6) static QEvent const * l_tunnelQueueSto[GAME_MINES_MAX + 5]; /* event queue */ (7) static ObjectPosEvt l_smlPoolSto[GAME_MINES_MAX + 8]; /* small-size pool */ (8) static ObjectImageEvt l_medPoolSto[GAME_MINES_MAX + 8]; /* medium-size pool */ (9) static QSubscrList l_subscrSto[MAX_PUB_SIG]; /* publish-subscribe */ /*..........................................................................*/ void main(int argc, char *argv[]) { /* explicitly invoke the active objects' ctors... */ (10) Missile_ctor(); (11) Ship_ctor(); (12) Tunnel_ctor(); (13) BSP_init(argc, argv); /* initialize the Board Support Package */ (14) QF_init(); /* initialize the framework and the underlying RT kernel */ /* initialize the event pools... */ (15) QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); (16) QF_poolInit(l_medPoolSto, sizeof(l_medPoolSto), sizeof(l_medPoolSto[0])); (17) QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); /* init publish-subscribe */ /* start the active objects... */ (18) QActive_start(AO_Missile,/* global pointer to the Missile active object */ 1, /* priority (lowest) */ l_missileQueueSto, Q_DIM(l_missileQueueSto), /* evt queue */ (void *)0, 0, /* no per-thread stack */ (QEvent *)0); /* no initialization event */ (19) QActive_start(AO_Ship, /* global pointer to the Ship active object */ 2, /* priority */ l_shipQueueSto, Q_DIM(l_shipQueueSto), /* evt queue */ (void *)0, 0, /* no per-thread stack */ (QEvent *)0); /* no initialization event */ (20) QActive_start(AO_Tunnel, /* global pointer to the Tunnel active object */ 3, /* priority */ l_tunnelQueueSto, Q_DIM(l_tunnelQueueSto), /* evt queue */ (void *)0, 0, /* no per-thread stack */ (QEvent *)0); /* no initialization event */ (21) QF_run(); /* run the QF application */ }
<qpc>\ports\80x86\dos\tcpp101\l\, and the Cortex-M3 version from the directory <qpc>\ports\cortex-m3\vanilla\iar\.
main()).BSP_init() initializes the board and is defined in the bsp.c file.a[] computed as sizeof(a)/sizeof(a[0]), which is a compile-time constant. The use of this macro simplifies the code because it allows me to eliminate many define constants that otherwise I would need to provide for the dimensions of various arrays. I can simply hard-code the dimension right in the definition of an array, which is the only place that I specify it. I then use the macro Q_DIM() whenever I need this dimension in the code.
Ship_ctor() and the pointer AO_Ship.
main(). In an embedded system, such as the Cortex-M3 board, QF_run() runs forever or till the power is removed, whichever comes first.
1.5.4