Dining Philosophers Problem (DPP) example for the QP active object framework. Demonstrates: event-driven programming, hierarchical state machines in C++, modeling and graphical state machine design, code generation, preemptive multitasking, software tracing, power saving mode, direct event posting, publish-subscribe. More information available in the [[/users/QL/notebook|Quantum Leaps Notebook pages]]. See also [[http://www.state-machine.com|state-machine.com]].

Dependencies:   mbed qp

Files at this revision

API Documentation at this revision

Comitter:
QL
Date:
Tue Sep 04 22:41:20 2012 +0000
Parent:
3:81ceb3127876
Child:
5:15aad9bccbbd
Commit message:
updated for QP 4.5.02

Changed in this revision

bsp.cpp Show annotated file Show diff for this revision Revisions of this file
bsp.h Show annotated file Show diff for this revision Revisions of this file
dpp.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
philo.cpp Show annotated file Show diff for this revision Revisions of this file
qp.lib Show annotated file Show diff for this revision Revisions of this file
qp_config.h Show annotated file Show diff for this revision Revisions of this file
table.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/bsp.cpp	Mon Sep 26 02:21:01 2011 +0000
+++ b/bsp.cpp	Tue Sep 04 22:41:20 2012 +0000
@@ -1,265 +1,340 @@
-//////////////////////////////////////////////////////////////////////////////
-// Product: BSP for "Dining Philosophers Problem" example, QK kernel
-// Last Updated for Version: 4.2.04
-// Date of the Last Update:  Sep 25, 2011
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
-//
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
-//
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
-//////////////////////////////////////////////////////////////////////////////
-#include "qp_port.h"
-#include "dpp.h"
-#include "bsp.h"
-#include "LPC17xx.h"
-
-Q_DEFINE_THIS_FILE
-
-// Local-scope objects -------------------------------------------------------
-enum ISR_Priorities {      // ISR priorities starting from the highest urgency
-    GPIOPORTA_PRIO,
-    SYSTICK_PRIO,
-    // ...
-};
-
-#define LED_PORT      LPC_GPIO1
-#define LED1_BIT     (1U << 18)
-#define LED2_BIT     (1U << 20)
-#define LED3_BIT     (1U << 21)
-#define LED4_BIT     (1U << 23)
-
-#ifdef Q_SPY
-    #include "mbed.h"             // mbed is used only for the built-in serial
-
-    QSTimeCtr l_tickTime;
-    QSTimeCtr l_tickPeriod;
-    static uint8_t l_SysTick_Handler;
-
-    #define QSPY_BAUD_RATE          115200
-
-    enum AppRecords {                    // application-specific trace records
-        PHILO_STAT = QS_USER
-    };
-
-    Serial l_qspy(USBTX, USBRX);
-#endif
-
-//............................................................................
-extern "C" void SysTick_Handler(void) {
-    QK_ISR_ENTRY();                // inform the QK kernel of entering the ISR
-
-#ifdef Q_SPY
-    uint32_t volatile dummy = SysTick->CTRL; // clear the COUNTFLAG in SysTick
-    l_tickTime += l_tickPeriod;              // account for the clock rollover
-#endif
-
-    QF::TICK(&l_SysTick_Handler);             // process all armed time events
-
-    QK_ISR_EXIT();                  // inform the QK kernel of exiting the ISR
-}
-
-//............................................................................
-void BSP_init(void) {
-    SystemInit();                            // initialize the clocking system
-
-                                                     // set LED port to output
-    LED_PORT->FIODIR |= (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
-    
-                                                             // clear the LEDs
-    LED_PORT->FIOCLR  = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
-
-    if (QS_INIT((void *)0) == 0) {       // initialize the QS software tracing
-        Q_ERROR();
-    }
-    QS_OBJ_DICTIONARY(&l_SysTick_Handler);
-}
-//............................................................................
-void BSP_displyPhilStat(uint8_t n, char const *stat) {
-                            // represent LEDs in a const array for convenience
-    static uint32_t const led[] = { LED1_BIT, LED2_BIT, LED3_BIT, LED4_BIT };
-    if (n < 3) {
-        if (stat[0] == 'e') {
-            LED_PORT->FIOSET = led[n];
-        }
-        else {
-            LED_PORT->FIOCLR = led[n];
-        }
-    }
-    
-    QS_BEGIN(PHILO_STAT, AO_Philo[n])     // application-specific record begin
-        QS_U8(1, n);                                     // Philosopher number
-        QS_STR(stat);                                    // Philosopher status
-    QS_END()
-}
-//............................................................................
-void BSP_busyDelay(void) {
-    uint32_t volatile i = 10;
-    while (i-- > 0UL) {                                      // busy-wait loop
-    }
-}
-
-//............................................................................
-void QF::onStartup(void) {
-                 // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate
-    SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
-
-                          // set priorities of all interrupts in the system...
-    NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO);
-    NVIC_SetPriority(EINT0_IRQn,   GPIOPORTA_PRIO);
-
-    NVIC_EnableIRQ(EINT0_IRQn);
-}
-//............................................................................
-void QF::onCleanup(void) {
-}
-//............................................................................
-void QK::onIdle(void) {
-
-    QF_INT_LOCK(dummy);
-    LED_PORT->FIOSET = LED4_BIT;                           // turn the LED4 on
-    __NOP();                        // delay a bit to see some light intensity
-    __NOP();
-    __NOP();
-    __NOP();
-    LED_PORT->FIOCLR = LED4_BIT;                          // turn the LED4 off
-    QF_INT_UNLOCK(dummy);
-
-#ifdef Q_SPY
-    if (l_qspy.writeable()) {
-        QF_INT_LOCK(dummy);
-        uint16_t b = QS::getByte();
-        QF_INT_UNLOCK(dummy);
-        if (b != QS_EOD) {
-            l_qspy.putc((uint8_t)b);
-        }
-    }
-#else    
-    // Put the CPU and peripherals to the low-power mode. You might need to
-    // customize the clock management for your application, see the datasheet
-    // for your particular Cortex-M3 MCU.
-    //
-    // Specifially for the mbed board, see the articles:
-    // * "Power Management" http://mbed.org/cookbook/Power-Management; and
-    // * "Interface Powerdown" at 
-    //   http://mbed.org/users/simon/notebook/interface-powerdown/
-    // 
-    __WFI();
-#endif
-}
-
-//............................................................................
-void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) {
-    (void)file;                                      // avoid compiler warning
-    (void)line;                                      // avoid compiler warning
-    QF_INT_LOCK(dummy);          // make sure that all interrupts are disabled
-                                                          // light up all LEDs
-    LED_PORT->FIOSET = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
-
-    for (;;) {          // NOTE: replace the loop with reset for final version
-    }
-}
-
-//----------------------------------------------------------------------------
-#ifdef Q_SPY
-//............................................................................
-uint8_t QS::onStartup(void const *arg) {
-    static uint8_t qsBuf[6*256];                     // buffer for Quantum Spy
-    initBuf(qsBuf, sizeof(qsBuf));
-    
-    l_qspy.baud(QSPY_BAUD_RATE);
-    
-    l_tickPeriod = SystemCoreClock / BSP_TICKS_PER_SEC;
-    l_tickTime   = l_tickPeriod;             // to start the timestamp at zero
-
-                                                    // setup the QS filters...
-    QS_FILTER_ON(QS_ALL_RECORDS);
-
-//    QS_FILTER_OFF(QS_QEP_STATE_EMPTY);
-//    QS_FILTER_OFF(QS_QEP_STATE_ENTRY);
-//    QS_FILTER_OFF(QS_QEP_STATE_EXIT);
-//    QS_FILTER_OFF(QS_QEP_STATE_INIT);
-//    QS_FILTER_OFF(QS_QEP_INIT_TRAN);
-//    QS_FILTER_OFF(QS_QEP_INTERN_TRAN);
-//    QS_FILTER_OFF(QS_QEP_TRAN);
-//    QS_FILTER_OFF(QS_QEP_IGNORED);
-
-    QS_FILTER_OFF(QS_QF_ACTIVE_ADD);
-    QS_FILTER_OFF(QS_QF_ACTIVE_REMOVE);
-    QS_FILTER_OFF(QS_QF_ACTIVE_SUBSCRIBE);
-    QS_FILTER_OFF(QS_QF_ACTIVE_UNSUBSCRIBE);
-    QS_FILTER_OFF(QS_QF_ACTIVE_POST_FIFO);
-    QS_FILTER_OFF(QS_QF_ACTIVE_POST_LIFO);
-    QS_FILTER_OFF(QS_QF_ACTIVE_GET);
-    QS_FILTER_OFF(QS_QF_ACTIVE_GET_LAST);
-    QS_FILTER_OFF(QS_QF_EQUEUE_INIT);
-    QS_FILTER_OFF(QS_QF_EQUEUE_POST_FIFO);
-    QS_FILTER_OFF(QS_QF_EQUEUE_POST_LIFO);
-    QS_FILTER_OFF(QS_QF_EQUEUE_GET);
-    QS_FILTER_OFF(QS_QF_EQUEUE_GET_LAST);
-    QS_FILTER_OFF(QS_QF_MPOOL_INIT);
-    QS_FILTER_OFF(QS_QF_MPOOL_GET);
-    QS_FILTER_OFF(QS_QF_MPOOL_PUT);
-    QS_FILTER_OFF(QS_QF_PUBLISH);
-    QS_FILTER_OFF(QS_QF_NEW);
-    QS_FILTER_OFF(QS_QF_GC_ATTEMPT);
-    QS_FILTER_OFF(QS_QF_GC);
-//    QS_FILTER_OFF(QS_QF_TICK);
-    QS_FILTER_OFF(QS_QF_TIMEEVT_ARM);
-    QS_FILTER_OFF(QS_QF_TIMEEVT_AUTO_DISARM);
-    QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM_ATTEMPT);
-    QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM);
-    QS_FILTER_OFF(QS_QF_TIMEEVT_REARM);
-    QS_FILTER_OFF(QS_QF_TIMEEVT_POST);
-    QS_FILTER_OFF(QS_QF_INT_LOCK);
-    QS_FILTER_OFF(QS_QF_INT_UNLOCK);
-    QS_FILTER_OFF(QS_QF_ISR_ENTRY);
-    QS_FILTER_OFF(QS_QF_ISR_EXIT);
-
-//    QS_FILTER_OFF(QS_QK_MUTEX_LOCK);
-//    QS_FILTER_OFF(QS_QK_MUTEX_UNLOCK);
-//    QS_FILTER_OFF(QS_QK_SCHEDULE);
-
-    return (uint8_t)1;                                       // return success
-}
-//............................................................................
-void QS::onCleanup(void) {
-}
-//............................................................................
-QSTimeCtr QS::onGetTime(void) {              // invoked with interrupts locked
-    if ((SysTick->CTRL & 0x00000100) == 0) {              // COUNTFLAG no set?
-        return l_tickTime - (QSTimeCtr)SysTick->VAL;
-    }
-    else {        // the rollover occured, but the SysTick_ISR did not run yet
-        return l_tickTime + l_tickPeriod - (QSTimeCtr)SysTick->VAL;
-    }
-}
-//............................................................................
-void QS::onFlush(void) {
-    uint16_t b;
-    QF_INT_LOCK(dummy);
-    while ((b = QS::getByte()) != QS_EOD) {
-        while (!l_qspy.writeable()) {    // wait until serial port is writable
-        }
-        l_qspy.putc((uint8_t)b);
-    }
-    QF_INT_UNLOCK(dummy);
-}
-#endif                                                                // Q_SPY
-//----------------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////////
+// Product: DPP example, configurable Vanilla/QK kernel
+// Last Updated for Version: 4.5.02
+// Date of the Last Update:  Sep 04, 2012
+//
+//                    Q u a n t u m     L e a P s
+//                    ---------------------------
+//                    innovating embedded systems
+//
+// Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
+//
+// This program is open source software: you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Alternatively, this program may be distributed and modified under the
+// terms of Quantum Leaps commercial licenses, which expressly supersede
+// the GNU General Public License and are specifically designed for
+// licensees interested in retaining the proprietary status of their code.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// Contact information:
+// Quantum Leaps Web sites: http://www.quantum-leaps.com
+//                          http://www.state-machine.com
+// e-mail:                  info@quantum-leaps.com
+//////////////////////////////////////////////////////////////////////////////
+#include "qp_port.h"
+#include "dpp.h"
+#include "bsp.h"
+#include "LPC17xx.h"
+#ifdef Q_SPY
+    #include "mbed.h"             // mbed is used only for the built-in serial
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+namespace DPP {
+
+Q_DEFINE_THIS_FILE
+
+enum ISR_Priorities {      // ISR priorities starting from the highest urgency
+    GPIOPORTA_PRIO,
+    SYSTICK_PRIO
+    // ...
+};
+
+// Local-scope objects -------------------------------------------------------
+static uint32_t l_rnd;                                          // random seed
+
+#define LED_PORT      LPC_GPIO1
+#define LED1_BIT     (1U << 18)
+#define LED2_BIT     (1U << 20)
+#define LED3_BIT     (1U << 21)
+#define LED4_BIT     (1U << 23)
+
+#ifdef Q_SPY
+    QP::QSTimeCtr l_tickTime;
+    QP::QSTimeCtr l_tickPeriod;
+    static uint8_t l_SysTick_Handler;
+
+    #define QSPY_BAUD_RATE  115200U
+
+    enum AppRecords {                    // application-specific trace records
+        PHILO_STAT = QP::QS_USER
+    };
+
+    Serial l_qspy(USBTX, USBRX);
+#endif
+
+//............................................................................
+extern "C" void SysTick_Handler(void) {
+    QK_ISR_ENTRY();                // inform the QK kernel of entering the ISR
+
+#ifdef Q_SPY
+    uint32_t volatile dummy = SysTick->CTRL; // clear the COUNTFLAG in SysTick
+    l_tickTime += l_tickPeriod;              // account for the clock rollover
+#endif
+
+    QP::QF::TICK(&l_SysTick_Handler);         // process all armed time events
+
+    QK_ISR_EXIT();                  // inform the QK kernel of exiting the ISR
+}
+
+//............................................................................
+void BSP_init(void) {
+    // set the system clock as specified in lm3s_config.h (20MHz from PLL)
+    SystemInit();
+
+                                                     // set LED port to output
+    LED_PORT->FIODIR |= (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
+    
+                                                             // clear the LEDs
+    LED_PORT->FIOCLR  = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
+
+                                      // initialize the QS software tracing...
+    Q_ALLEGE(QS_INIT(static_cast<void *>(0)));
+    QS_RESET();
+    QS_OBJ_DICTIONARY(&l_SysTick_Handler);
+}
+//............................................................................
+void BSP_terminate(int16_t const result) {
+    (void)result;
+}
+//............................................................................
+void BSP_displayPhilStat(uint8_t const n, char_t const * const stat) {
+                            // represent LEDs in a const array for convenience
+    static uint32_t const led[] = { LED1_BIT, LED2_BIT, LED3_BIT, LED4_BIT };
+    if (n < 3) {
+        if (stat[0] == 'e') {
+            LED_PORT->FIOSET = led[n];
+        }
+        else {
+            LED_PORT->FIOCLR = led[n];
+        }
+    }
+    
+    QS_BEGIN(PHILO_STAT, AO_Philo[n])     // application-specific record begin
+        QS_U8(1U, n);                                    // Philosopher number
+        QS_STR(stat);                                    // Philosopher status
+    QS_END()
+}
+//............................................................................
+void BSP_displayPaused(uint8_t const paused) {
+    (void)paused;
+}
+//............................................................................
+uint32_t BSP_random(void) {     // a very cheap pseudo-random-number generator
+    // "Super-Duper" Linear Congruential Generator (LCG)
+    // LCG(2^32, 3*7*11*13*23, 0, seed)
+    //
+    l_rnd = l_rnd * (3U*7U*11U*13U*23U);
+    return l_rnd >> 8;
+}
+//............................................................................
+void BSP_randomSeed(uint32_t const seed) {
+    l_rnd = seed;
+}
+
+//............................................................................
+extern "C" void Q_onAssert(char_t const * const file, int_t const line) {
+    (void)file;                                      // avoid compiler warning
+    (void)line;                                      // avoid compiler warning
+    QF_INT_DISABLE();            // make sure that all interrupts are disabled
+                                                          // light up all LEDs
+    LED_PORT->FIOSET = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT);
+
+    for (;;) {          // NOTE: replace the loop with reset for final version
+    }
+}
+
+}                                                             // namespace DPP
+//////////////////////////////////////////////////////////////////////////////
+
+namespace QP {
+
+//............................................................................
+void QF::onStartup(void) {
+                 // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate
+    (void)SysTick_Config(SystemCoreClock / DPP::BSP_TICKS_PER_SEC);
+
+                          // set priorities of all interrupts in the system...
+    NVIC_SetPriority(SysTick_IRQn, DPP::SYSTICK_PRIO);
+    NVIC_SetPriority(EINT0_IRQn,   DPP::GPIOPORTA_PRIO);
+
+    NVIC_EnableIRQ(EINT0_IRQn);
+}
+//............................................................................
+void QF::onCleanup(void) {
+}
+//............................................................................
+#ifdef QK_PREEMPTIVE
+
+void QK::onIdle(void) {
+
+    QF_INT_DISABLE();
+    LED_PORT->FIOSET = LED4_BIT;                           // turn the LED4 on
+    __NOP();                        // delay a bit to see some light intensity
+    __NOP();
+    __NOP();
+    __NOP();
+    LED_PORT->FIOCLR = LED4_BIT;                          // turn the LED4 off
+    QF_INT_ENABLE();
+
+#ifdef Q_SPY
+    if (DPP::l_qspy.writeable()) {
+    
+        QF_INT_DISABLE();
+        uint16_t b = QS::getByte();
+        QF_INT_ENABLE();
+
+        if (b != QS_EOD) {
+            DPP::l_qspy.putc((uint8_t)b);
+        }
+    }
+#else    
+    // Put the CPU and peripherals to the low-power mode. You might need to
+    // customize the clock management for your application, see the datasheet
+    // for your particular Cortex-M3 MCU.
+    //
+    // Specifially for the mbed board, see the articles:
+    // * "Power Management" http://mbed.org/cookbook/Power-Management; and
+    // * "Interface Powerdown" at 
+    //   http://mbed.org/users/simon/notebook/interface-powerdown/
+    // 
+    __WFI();
+#endif
+}
+
+#else                                         // non-preemptive Vanilla kernel
+
+void QF::onIdle(void) {               // NOTE: called with interrupts DISABLED
+
+    LED_PORT->FIOSET = LED4_BIT;                           // turn the LED4 on
+    __NOP();                        // delay a bit to see some light intensity
+    __NOP();
+    __NOP();
+    __NOP();
+    LED_PORT->FIOCLR = LED4_BIT;                          // turn the LED4 off
+
+#ifdef Q_SPY
+    QF_INT_ENABLE();
+    if (DPP::l_qspy.writeable()) {
+    
+        QF_INT_DISABLE();
+        uint16_t b = QS::getByte();
+        QF_INT_ENABLE();
+
+        if (b != QS_EOD) {
+            DPP::l_qspy.putc((uint8_t)b);
+        }
+    }
+#else    
+    // Put the CPU and peripherals to the low-power mode. You might need to
+    // customize the clock management for your application, see the datasheet
+    // for your particular Cortex-M3 MCU.
+    //
+    // Specifially for the mbed board, see the articles:
+    // * "Power Management" http://mbed.org/cookbook/Power-Management; and
+    // * "Interface Powerdown" at 
+    //   http://mbed.org/users/simon/notebook/interface-powerdown/
+    // 
+    __WFI();
+    QF_INT_ENABLE();
+#endif
+}
+
+#endif                                                        // QK_PREEMPTIVE
+
+//----------------------------------------------------------------------------
+#ifdef Q_SPY
+//............................................................................
+bool QS::onStartup(void const *arg) {
+    static uint8_t qsBuf[6*256];                     // buffer for Quantum Spy
+    initBuf(qsBuf, sizeof(qsBuf));
+    
+    DPP::l_qspy.baud(QSPY_BAUD_RATE);
+    
+    DPP::l_tickPeriod = SystemCoreClock / DPP::BSP_TICKS_PER_SEC;
+    DPP::l_tickTime   = DPP::l_tickPeriod;   // to start the timestamp at zero
+
+                                                    // setup the QS filters...
+    QS_FILTER_ON(QS_ALL_RECORDS);
+
+//    QS_FILTER_OFF(QS_QEP_STATE_EMPTY);
+//    QS_FILTER_OFF(QS_QEP_STATE_ENTRY);
+//    QS_FILTER_OFF(QS_QEP_STATE_EXIT);
+//    QS_FILTER_OFF(QS_QEP_STATE_INIT);
+//    QS_FILTER_OFF(QS_QEP_INIT_TRAN);
+//    QS_FILTER_OFF(QS_QEP_INTERN_TRAN);
+//    QS_FILTER_OFF(QS_QEP_TRAN);
+//    QS_FILTER_OFF(QS_QEP_IGNORED);
+
+//    QS_FILTER_OFF(QS_QF_ACTIVE_ADD);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_REMOVE);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_SUBSCRIBE);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_UNSUBSCRIBE);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_POST_FIFO);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_POST_LIFO);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_GET);
+//    QS_FILTER_OFF(QS_QF_ACTIVE_GET_LAST);
+//    QS_FILTER_OFF(QS_QF_EQUEUE_INIT);
+//    QS_FILTER_OFF(QS_QF_EQUEUE_POST_FIFO);
+//    QS_FILTER_OFF(QS_QF_EQUEUE_POST_LIFO);
+//    QS_FILTER_OFF(QS_QF_EQUEUE_GET);
+//    QS_FILTER_OFF(QS_QF_EQUEUE_GET_LAST);
+//    QS_FILTER_OFF(QS_QF_MPOOL_INIT);
+//    QS_FILTER_OFF(QS_QF_MPOOL_GET);
+//    QS_FILTER_OFF(QS_QF_MPOOL_PUT);
+//    QS_FILTER_OFF(QS_QF_PUBLISH);
+//    QS_FILTER_OFF(QS_QF_NEW);
+//    QS_FILTER_OFF(QS_QF_GC_ATTEMPT);
+//    QS_FILTER_OFF(QS_QF_GC);
+//    QS_FILTER_OFF(QS_QF_TICK);
+//    QS_FILTER_OFF(QS_QF_TIMEEVT_ARM);
+//    QS_FILTER_OFF(QS_QF_TIMEEVT_AUTO_DISARM);
+//    QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM_ATTEMPT);
+//    QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM);
+//    QS_FILTER_OFF(QS_QF_TIMEEVT_REARM);
+//    QS_FILTER_OFF(QS_QF_TIMEEVT_POST);
+    QS_FILTER_OFF(QS_QF_CRIT_ENTRY);
+    QS_FILTER_OFF(QS_QF_CRIT_EXIT);
+    QS_FILTER_OFF(QS_QF_ISR_ENTRY);
+    QS_FILTER_OFF(QS_QF_ISR_EXIT);
+
+    return true;                                             // return success
+}
+//............................................................................
+void QS::onCleanup(void) {
+}
+//............................................................................
+QSTimeCtr QS::onGetTime(void) {              // invoked with interrupts locked
+    if ((SysTick->CTRL & 0x00000100U) == 0U) {            // COUNTFLAG no set?
+        return DPP::l_tickTime - (QSTimeCtr)SysTick->VAL;
+    }
+    else {        // the rollover occured, but the SysTick_ISR did not run yet
+        return DPP::l_tickTime + DPP::l_tickPeriod - (QSTimeCtr)SysTick->VAL;
+    }
+}
+//............................................................................
+void QS::onFlush(void) {
+    uint16_t b;
+    QF_INT_DISABLE();
+    while ((b = QS::getByte()) != QS_EOD) {
+        while (!DPP::l_qspy.writeable()) {    // wait until serial is writable
+        }
+        DPP::l_qspy.putc((uint8_t)b);
+    }
+    QF_INT_ENABLE();
+}
+#endif                                                                // Q_SPY
+//----------------------------------------------------------------------------
+
+}                                                              // namespace QP
--- a/bsp.h	Mon Sep 26 02:21:01 2011 +0000
+++ b/bsp.h	Tue Sep 04 22:41:20 2012 +0000
@@ -1,39 +1,56 @@
-//////////////////////////////////////////////////////////////////////////////
-// Product: DPP example, Board Support Package
-// Last Updated for Version: 4.0.01
-// Date of the Last Update:  Jul 29, 2008
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2008 Quantum Leaps, LLC. All rights reserved.
-//
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
-//
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
-//////////////////////////////////////////////////////////////////////////////
-#ifndef bsp_h
-#define bsp_h
-                                                // System clock tick rate [Hz]
-#define BSP_TICKS_PER_SEC 100
-
-void BSP_init(void);
-void BSP_displyPhilStat(uint8_t n, char const *stat);
-void BSP_busyDelay(void);             // to artificially extend RTC processing
-
-#endif                                                                // bsp_h
-
-
+//////////////////////////////////////////////////////////////////////////////
+// Product: DPP example, Board Support Package
+// Last Updated for Version: 4.5.02
+// Date of the Last Update:  Aug 09, 2012
+//
+//                    Q u a n t u m     L e a P s
+//                    ---------------------------
+//                    innovating embedded systems
+//
+// Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
+//
+// This program is open source software: you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Alternatively, this program may be distributed and modified under the
+// terms of Quantum Leaps commercial licenses, which expressly supersede
+// the GNU General Public License and are specifically designed for
+// licensees interested in retaining the proprietary status of their code.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// Contact information:
+// Quantum Leaps Web sites: http://www.quantum-leaps.com
+//                          http://www.state-machine.com
+// e-mail:                  info@quantum-leaps.com
+//////////////////////////////////////////////////////////////////////////////
+#ifndef bsp_h
+#define bsp_h
+                                                // System clock tick rate [Hz]
+namespace DPP {
+
+uint32_t const BSP_TICKS_PER_SEC = static_cast<uint32_t>(50);
+uint32_t const BSP_SCREEN_WIDTH  = static_cast<uint32_t>(96);
+uint32_t const BSP_SCREEN_HEIGHT = static_cast<uint32_t>(16);
+
+void BSP_init(void);
+void BSP_displayPaused(uint8_t const paused);
+void BSP_displayPhilStat(uint8_t const n, char_t const *stat);
+void BSP_terminate(int16_t const result);
+
+void BSP_randomSeed(uint32_t const seed);                       // random seed
+uint32_t BSP_random(void);                          // pseudo-random generator
+
+}                                                             // namespace DPP
+
+#endif                                                                // bsp_h
+
+
--- a/dpp.h	Mon Sep 26 02:21:01 2011 +0000
+++ b/dpp.h	Tue Sep 04 22:41:20 2012 +0000
@@ -1,50 +1,40 @@
 //////////////////////////////////////////////////////////////////////////////
-// Product: DPP example
-// Last Updated for Version: 4.0.00
-// Date of the Last Update:  Apr 07, 2008
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2008 Quantum Leaps, LLC. All rights reserved.
+// Model: dpp.qm
+// File:  ././dpp.h
 //
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
+// This file has been generated automatically by QP Modeler (QM).
+// DO NOT EDIT THIS FILE MANUALLY.
 //
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
+// Please visit www.state-machine.com/qm for more information.
 //////////////////////////////////////////////////////////////////////////////
 #ifndef dpp_h
 #define dpp_h
 
+namespace DPP {
+
 enum DPPSignals {
-   EAT_SIG = Q_USER_SIG,        // published by Table to let a philosopher eat
-   DONE_SIG,                      // published by Philosopher when done eating
-   TERMINATE_SIG,             // published by BSP to terminate the application
-   MAX_PUB_SIG,                                   // the last published signal
+    EAT_SIG = QP::Q_USER_SIG, // published by Table to let a philosopher eat
+    DONE_SIG,                 // published by Philosopher when done eating
+    PAUSE_SIG,                // published by BSP to pause the application
+    TERMINATE_SIG,            // published by BSP to terminate the application
+    MAX_PUB_SIG,              // the last published signal
 
-   HUNGRY_SIG,                      // posted from hungry Philosopher to Table
-   MAX_SIG                                                  // the last signal
+    HUNGRY_SIG,               // posted direclty to Table from hungry Philo
+    MAX_SIG                   // the last signal
 };
 
-struct TableEvt : public QEvent {
-    uint8_t philoNum;                                    // philosopher number
+// @(/1/0) ...................................................................
+class TableEvt : public QP::QEvt {
+public:
+    uint8_t philoNum;
 };
 
-enum { N_PHILO = 5 };                                // number of philosophers
+// number of philosophers
+#define N_PHILO ((uint8_t)5)
 
-extern QActive * const AO_Philo[N_PHILO];     // "opaque" pointers to Philo AO
-extern QActive * const AO_Table;              // "opaque" pointer  to Table AO
+extern QP::QActive * const AO_Philo[N_PHILO];
+extern QP::QActive * const AO_Table;
 
-#endif                                                                // dpp_h
+}                             // namespace DPP
+
+#endif                        // dpp_h
--- a/main.cpp	Mon Sep 26 02:21:01 2011 +0000
+++ b/main.cpp	Tue Sep 04 22:41:20 2012 +0000
@@ -1,78 +1,81 @@
 //////////////////////////////////////////////////////////////////////////////
 // Product: DPP example
-// Last Updated for Version: 4.2.00
-// Date of the Last Update:  Jul 23, 2011
+// Last Updated for Version: 4.5.02
+// Date of the Last Update:  Aug 11, 2012
 //
 //                    Q u a n t u m     L e a P s
 //                    ---------------------------
 //                    innovating embedded systems
 //
-// Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
+// Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
+//
+// This program is open source software: you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
 //
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
+// Alternatively, this program may be distributed and modified under the
+// terms of Quantum Leaps commercial licenses, which expressly supersede
+// the GNU General Public License and are specifically designed for
+// licensees interested in retaining the proprietary status of their code.
 //
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
 //
 // Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
+// Quantum Leaps Web sites: http://www.quantum-leaps.com
+//                          http://www.state-machine.com
 // e-mail:                  info@quantum-leaps.com
 //////////////////////////////////////////////////////////////////////////////
 #include "qp_port.h"
 #include "dpp.h"
 #include "bsp.h"
 
-// Local-scope objects -------------------------------------------------------
-static QEvent const *l_tableQueueSto[N_PHILO];
-static QEvent const *l_philoQueueSto[N_PHILO][N_PHILO];
-static QSubscrList   l_subscrSto[MAX_PUB_SIG];
-
-static union SmallEvents {
-    void   *e0;                                          // minimum event size
-    uint8_t e1[sizeof(TableEvt)];
-    // ... other event types to go into this pool
-} l_smlPoolSto[2*N_PHILO];                 // storage for the small event pool
+namespace DPP {
 
 //............................................................................
-int main() {
+extern "C" int_t main(void) {
+    static QP::QEvt const *tableQueueSto[N_PHILO];
+    static QP::QEvt const *philoQueueSto[N_PHILO][N_PHILO];
+    static QP::QSubscrList   subscrSto[MAX_PUB_SIG];
+    static QF_MPOOL_EL(TableEvt) smlPoolSto[2U*N_PHILO];         // small pool
+
+    QP::QF::init();   // initialize the framework and the underlying RT kernel
 
     BSP_init();                                          // initialize the BSP
 
-    QF::init();       // initialize the framework and the underlying RT kernel
+                                                     // object dictionaries...
+    QS_OBJ_DICTIONARY(smlPoolSto);
+    QS_OBJ_DICTIONARY(tableQueueSto);
+    QS_OBJ_DICTIONARY(philoQueueSto[0]);
+    QS_OBJ_DICTIONARY(philoQueueSto[1]);
+    QS_OBJ_DICTIONARY(philoQueueSto[2]);
+    QS_OBJ_DICTIONARY(philoQueueSto[3]);
+    QS_OBJ_DICTIONARY(philoQueueSto[4]);
 
-                                                     // object dictionaries...
-    QS_OBJ_DICTIONARY(l_smlPoolSto);
-    QS_OBJ_DICTIONARY(l_tableQueueSto);
-    QS_OBJ_DICTIONARY(l_philoQueueSto[0]);
-    QS_OBJ_DICTIONARY(l_philoQueueSto[1]);
-    QS_OBJ_DICTIONARY(l_philoQueueSto[2]);
-    QS_OBJ_DICTIONARY(l_philoQueueSto[3]);
-    QS_OBJ_DICTIONARY(l_philoQueueSto[4]);
-
-    QF::psInit(l_subscrSto, Q_DIM(l_subscrSto));     // init publish-subscribe
+    QP::QF::psInit(&subscrSto[0], Q_DIM(subscrSto)); // init publish-subscribe
 
                                                   // initialize event pools...
-    QF::poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0]));
+    QP::QF::poolInit(&smlPoolSto[0], sizeof(smlPoolSto),
+                                     sizeof(smlPoolSto[0]));
 
                                                 // start the active objects...
-    uint8_t n;
-    for (n = 0; n < N_PHILO; ++n) {
-        AO_Philo[n]->start((uint8_t)(n + 1),
-                           l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]),
-                           (void *)0, 0, (QEvent *)0);
+    for (uint8_t n = 0U; n < N_PHILO; ++n) {
+        AO_Philo[n]->start(static_cast<uint8_t>(n + 1U),
+                           &philoQueueSto[n][0], Q_DIM(philoQueueSto[n]),
+                           static_cast<void *>(0), 0U);
     }
-    AO_Table->start((uint8_t)(N_PHILO + 1),
-                    l_tableQueueSto, Q_DIM(l_tableQueueSto),
-                    (void *)0, 0, (QEvent *)0);
+    AO_Table->start(static_cast<uint8_t>(N_PHILO + 1U),
+                    &tableQueueSto[0], Q_DIM(tableQueueSto),
+                    static_cast<void *>(0), 0U);
+
 
-    QF::run();                                       // run the QF application
+    return QP::QF::run();                            // run the QF application
+}
 
-    return 0;
-}
+}                                                             // namespace DPP
--- a/mbed.bld	Mon Sep 26 02:21:01 2011 +0000
+++ b/mbed.bld	Tue Sep 04 22:41:20 2012 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/9a9732ce53a1
+http://mbed.org/users/mbed_official/code/mbed/builds/9a9732ce53a1
\ No newline at end of file
--- a/philo.cpp	Mon Sep 26 02:21:01 2011 +0000
+++ b/philo.cpp	Tue Sep 04 22:41:20 2012 +0000
@@ -1,65 +1,62 @@
 //////////////////////////////////////////////////////////////////////////////
-// Product: DPP example
-// Last Updated for Version: 4.2.00
-// Date of the Last Update:  Jul 15, 2011
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
+// Model: dpp.qm
+// File:  ././philo.cpp
 //
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
+// This file has been generated automatically by QP Modeler (QM).
+// DO NOT EDIT THIS FILE MANUALLY.
 //
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
+// Please visit www.state-machine.com/qm for more information.
 //////////////////////////////////////////////////////////////////////////////
 #include "qp_port.h"
 #include "dpp.h"
 #include "bsp.h"
 
+namespace DPP {
+
 Q_DEFINE_THIS_FILE
 
 // Active object class -------------------------------------------------------
-class Philo : public QActive {
+// @(/2/0) ...................................................................
+class Philo : public QP::QActive {
 private:
-    QTimeEvt m_timeEvt;                       // to timeout thinking or eating
+    QP::QTimeEvt m_timeEvt;
 
 public:
     Philo();
 
-private:
-    static QState initial (Philo *me, QEvent const *e);
-    static QState thinking(Philo *me, QEvent const *e);
-    static QState hungry  (Philo *me, QEvent const *e);
-    static QState eating  (Philo *me, QEvent const *e);
+protected:
+    static QP::QState initial(Philo * const me, QP::QEvt const * const e);
+    static QP::QState thinking(Philo * const me, QP::QEvt const * const e);
+    static QP::QState hungry(Philo * const me, QP::QEvt const * const e);
+    static QP::QState eating(Philo * const me, QP::QEvt const * const e);
 };
 
 // Local objects -------------------------------------------------------------
-static Philo l_philo[N_PHILO];                       // storage for all Philos
+static Philo l_philo[N_PHILO];   // storage for all Philos
 
-#define THINK_TIME  (BSP_TICKS_PER_SEC/2)
-#define EAT_TIME    (BSP_TICKS_PER_SEC/5)
+// helper function to provide a randomized think time for Philos
+inline QP::QTimeEvtCtr think_time() {
+    return static_cast<QP::QTimeEvtCtr>((BSP_random() % BSP_TICKS_PER_SEC)
+                                        + (BSP_TICKS_PER_SEC/2U));
+}
 
-                              // helper macro to provide the ID of Philo "me_"
-#define PHILO_ID(me_)    ((uint8_t)((me_) - l_philo))
+// helper function to provide a randomized eat time for Philos
+inline QP::QTimeEvtCtr eat_time() {
+    return static_cast<QP::QTimeEvtCtr>((BSP_random() % BSP_TICKS_PER_SEC)
+                                        + BSP_TICKS_PER_SEC);
+}
 
-enum InternalSignals {                                     // internal signals
+// helper function to provide the ID of Philo "me"
+inline uint8_t PHILO_ID(Philo const * const me) {
+    return static_cast<uint8_t>(me - l_philo);
+}
+
+enum InternalSignals {           // internal signals
     TIMEOUT_SIG = MAX_SIG
 };
+
 // Global objects ------------------------------------------------------------
-QActive * const AO_Philo[N_PHILO] = {        // "opaque" pointers to Philo AOs
+QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO
     &l_philo[0],
     &l_philo[1],
     &l_philo[2],
@@ -67,15 +64,23 @@
     &l_philo[4]
 };
 
-//............................................................................
-Philo::Philo()
-    : QActive((QStateHandler)&Philo::initial),
-      m_timeEvt(TIMEOUT_SIG)
-{}
-//............................................................................
-QState Philo::initial(Philo *me, QEvent const *) {
-    static uint8_t registered;            // starts off with 0, per C-standard
+// Philo definition ----------------------------------------------------------
+// @(/2/0) ...................................................................
+// @(/2/0/1) .................................................................
+Philo::Philo() 
+  : QActive(Q_STATE_CAST(&Philo::initial)),
+    m_timeEvt(TIMEOUT_SIG)
+{
+}
+
+// @(/2/0/2) .................................................................
+// @(/2/0/2/0)
+QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) {
+    static bool registered = false; // starts off with 0, per C-standard
+    (void)e; // suppress the compiler warning about unused parameter
     if (!registered) {
+        registered = true;
+
         QS_OBJ_DICTIONARY(&l_philo[0]);
         QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt);
         QS_OBJ_DICTIONARY(&l_philo[1]);
@@ -91,80 +96,125 @@
         QS_FUN_DICTIONARY(&Philo::thinking);
         QS_FUN_DICTIONARY(&Philo::hungry);
         QS_FUN_DICTIONARY(&Philo::eating);
-
-        registered = (uint8_t)1;
     }
-    QS_SIG_DICTIONARY(HUNGRY_SIG, me);               // signal for each Philos
-    QS_SIG_DICTIONARY(TIMEOUT_SIG, me);              // signal for each Philos
+    QS_SIG_DICTIONARY(HUNGRY_SIG, me);  // signal for each Philos
+    QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos
 
     me->subscribe(EAT_SIG);
-
     return Q_TRAN(&Philo::thinking);
 }
-//............................................................................
-QState Philo::thinking(Philo *me, QEvent const *e) {
+// @(/2/0/2/1) ...............................................................
+QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) {
+    QP::QState status;
     switch (e->sig) {
+        // @(/2/0/2/1)
         case Q_ENTRY_SIG: {
-            me->m_timeEvt.postIn(me, THINK_TIME);
-            return Q_HANDLED();
+            me->m_timeEvt.postIn(me, think_time());
+            status = Q_HANDLED();
+            break;
         }
+        // @(/2/0/2/1)
+        case Q_EXIT_SIG: {
+            (void)me->m_timeEvt.disarm();
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/0/2/1/0)
         case TIMEOUT_SIG: {
-            return Q_TRAN(&Philo::hungry);
+            status = Q_TRAN(&Philo::hungry);
+            break;
         }
-        case EAT_SIG:                            // intentionally fall-through
+        // @(/2/0/2/1/1)
+        case EAT_SIG: // intentionally fall through
         case DONE_SIG: {
-                         // EAT or DONE must be for other Philos than this one
-            Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me));
-            return Q_HANDLED();
+            /* EAT or DONE must be for other Philos than this one */
+            Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
+            status = Q_HANDLED();
+            break;
+        }
+        default: {
+            status = Q_SUPER(&QHsm::top);
+            break;
         }
     }
-    return Q_SUPER(&QHsm::top);
+    return status;
 }
-//............................................................................
-QState Philo::hungry(Philo *me, QEvent const *e) {
+// @(/2/0/2/2) ...............................................................
+QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) {
+    QP::QState status;
     switch (e->sig) {
+        // @(/2/0/2/2)
         case Q_ENTRY_SIG: {
             TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
             pe->philoNum = PHILO_ID(me);
             AO_Table->POST(pe, me);
-            return Q_HANDLED();
+            status = Q_HANDLED();
+            break;
         }
+        // @(/2/0/2/2/0)
         case EAT_SIG: {
-            if (((TableEvt *)e)->philoNum == PHILO_ID(me)) {
-                return Q_TRAN(&Philo::eating);
+            // @(/2/0/2/2/0/0)
+            if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) {
+                status = Q_TRAN(&Philo::eating);
+            }
+            else {
+                status = Q_UNHANDLED();
             }
             break;
         }
+        // @(/2/0/2/2/1)
         case DONE_SIG: {
-                                // DONE must be for other Philos than this one
-            Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me));
-            return Q_HANDLED();
+            /* DONE must be for other Philos than this one */
+            Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
+            status = Q_HANDLED();
+            break;
+        }
+        default: {
+            status = Q_SUPER(&QHsm::top);
+            break;
         }
     }
-    return Q_SUPER(&QHsm::top);
+    return status;
 }
-//............................................................................
-QState Philo::eating(Philo *me, QEvent const *e) {
+// @(/2/0/2/3) ...............................................................
+QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) {
+    QP::QState status;
     switch (e->sig) {
+        // @(/2/0/2/3)
         case Q_ENTRY_SIG: {
-            me->m_timeEvt.postIn(me, EAT_TIME);
-            return Q_HANDLED();
+            me->m_timeEvt.postIn(me, eat_time());
+            status = Q_HANDLED();
+            break;
         }
+        // @(/2/0/2/3)
         case Q_EXIT_SIG: {
             TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
             pe->philoNum = PHILO_ID(me);
-            QF::PUBLISH(pe, me);
-            return Q_HANDLED();
+            QP::QF::PUBLISH(pe, me);
+            (void)me->m_timeEvt.disarm();
+            status = Q_HANDLED();
+            break;
         }
+        // @(/2/0/2/3/0)
         case TIMEOUT_SIG: {
-            return Q_TRAN(&Philo::thinking);
+            status = Q_TRAN(&Philo::thinking);
+            break;
         }
-        case EAT_SIG:                            // intentionally fall-through
+        // @(/2/0/2/3/1)
+        case EAT_SIG: // intentionally fall through
         case DONE_SIG: {
-                         // EAT or DONE must be for other Philos than this one
-            Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me));
-            return Q_HANDLED();
+            /* EAT or DONE must be for other Philos than this one */
+            Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
+            status = Q_HANDLED();
+            break;
+        }
+        default: {
+            status = Q_SUPER(&QHsm::top);
+            break;
         }
     }
-    return Q_SUPER(&QHsm::top);
+    return status;
 }
+
+
+}                                                             // namespace DPP
--- a/qp.lib	Mon Sep 26 02:21:01 2011 +0000
+++ b/qp.lib	Tue Sep 04 22:41:20 2012 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/QL/code/qp/#bf92d3a6625e
+http://mbed.org/users/QL/code/qp/#ca2e6010d9e2
--- a/qp_config.h	Mon Sep 26 02:21:01 2011 +0000
+++ b/qp_config.h	Tue Sep 04 22:41:20 2012 +0000
@@ -1,40 +1,47 @@
-//////////////////////////////////////////////////////////////////////////////
-// Product: QP-mbed configuration file
-// Last Updated for Version: 4.2.04
-// Date of the Last Update:  Sep 25, 2011
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
-//
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
-//
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
-//////////////////////////////////////////////////////////////////////////////
-#ifndef qp_config_h
-#define qp_config_h
-
-// enable the Q-SPY software tracing instrumentation
-#define Q_SPY
-
-// enable preemptive QK kernel
-#define QK_PREEMPTIVE
-
-// The maximum number of active objects in the application (could be up to 63)
-#define QF_MAX_ACTIVE      16
-
-#endif                                                          // qp_config_h
+//////////////////////////////////////////////////////////////////////////////
+// Product: QP-mbed configuration file
+// Last Updated for Version: 4.5.02
+// Date of the Last Update: Sep 04, 2012
+//
+//                    Q u a n t u m     L e a P s
+//                    ---------------------------
+//                    innovating embedded systems
+//
+// Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
+//
+// This program is open source software: you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Alternatively, this program may be distributed and modified under the
+// terms of Quantum Leaps commercial licenses, which expressly supersede
+// the GNU General Public License and are specifically designed for
+// licensees interested in retaining the proprietary status of their code.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// Contact information:
+// Quantum Leaps Web sites: http://www.quantum-leaps.com
+//                          http://www.state-machine.com
+// e-mail:                  info@quantum-leaps.com
+//////////////////////////////////////////////////////////////////////////////
+#ifndef qp_config_h
+#define qp_config_h
+
+// enable the Q-SPY software tracing instrumentation
+//#define Q_SPY
+
+// enable preemptive QK kernel
+//#define QK_PREEMPTIVE
+
+// The maximum number of active objects in the application (could be up to 63)
+#define QF_MAX_ACTIVE      16
+
+#endif                                                          // qp_config_h
--- a/table.cpp	Mon Sep 26 02:21:01 2011 +0000
+++ b/table.cpp	Tue Sep 04 22:41:20 2012 +0000
@@ -1,148 +1,283 @@
 //////////////////////////////////////////////////////////////////////////////
-// Product: DPP example
-// Last Updated for Version: 4.2.00
-// Date of the Last Update:  Jul 15, 2011
-//
-//                    Q u a n t u m     L e a P s
-//                    ---------------------------
-//                    innovating embedded systems
-//
-// Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
+// Model: dpp.qm
+// File:  ././table.cpp
 //
-// This software may be distributed and modified under the terms of the GNU
-// General Public License version 2 (GPL) as published by the Free Software
-// Foundation and appearing in the file GPL.TXT included in the packaging of
-// this file. Please note that GPL Section 2[b] requires that all works based
-// on this software must also be made publicly available under the terms of
-// the GPL ("Copyleft").
+// This file has been generated automatically by QP Modeler (QM).
+// DO NOT EDIT THIS FILE MANUALLY.
 //
-// Alternatively, this software may be distributed and modified under the
-// terms of Quantum Leaps commercial licenses, which expressly supersede
-// the GPL and are specifically designed for licensees interested in
-// retaining the proprietary status of their code.
-//
-// Contact information:
-// Quantum Leaps Web site:  http://www.quantum-leaps.com
-// e-mail:                  info@quantum-leaps.com
+// Please visit www.state-machine.com/qm for more information.
 //////////////////////////////////////////////////////////////////////////////
 #include "qp_port.h"
 #include "dpp.h"
 #include "bsp.h"
 
+namespace DPP {
+
 Q_DEFINE_THIS_FILE
 
 // Active object class -------------------------------------------------------
-class Table : public QActive {
+// @(/2/1) ...................................................................
+class Table : public QP::QActive {
 private:
     uint8_t m_fork[N_PHILO];
-    uint8_t m_isHungry[N_PHILO];
+    bool m_isHungry[N_PHILO];
 
 public:
     Table();
 
-private:
-    static QState initial(Table *me, QEvent const *e);
-    static QState serving(Table *me, QEvent const *e);
+protected:
+    static QP::QState initial(Table * const me, QP::QEvt const * const e);
+    static QP::QState active(Table * const me, QP::QEvt const * const e);
+    static QP::QState serving(Table * const me, QP::QEvt const * const e);
+    static QP::QState paused(Table * const me, QP::QEvt const * const e);
 };
 
-#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1)) % N_PHILO))
-#define LEFT(n_)  ((uint8_t)(((n_) + 1) % N_PHILO))
-enum ForkState { FREE, USED };
+// helper function to provide the RIGHT neighbour of a Philo[n]
+inline uint8_t RIGHT(uint8_t const n) {
+    return static_cast<uint8_t>((n + (N_PHILO - 1U)) % N_PHILO);
+}
+
+// helper function to provide the LEFT neighbour of a Philo[n]
+inline uint8_t LEFT(uint8_t const n) {
+    return static_cast<uint8_t>((n + 1U) % N_PHILO);
+}
+
+static uint8_t const FREE = static_cast<uint8_t>(0);
+static uint8_t const USED = static_cast<uint8_t>(1);
+
+static char_t const * const THINKING = &"thinking"[0];
+static char_t const * const HUNGRY   = &"hungry  "[0];
+static char_t const * const EATING   = &"eating  "[0];
 
 // Local objects -------------------------------------------------------------
-static Table l_table;                                    // local Table object
+static Table l_table; // the single instance of the Table active object
 
-// Public-scope objects ------------------------------------------------------
-QActive * const AO_Table = &l_table;                    // "opaque" AO pointer
+// Global-scope objects ------------------------------------------------------
+QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer
 
 //............................................................................
-Table::Table() : QActive((QStateHandler)&Table::initial) {
-    uint8_t n;
-    for (n = 0; n < N_PHILO; ++n) {
+// @(/2/1) ...................................................................
+// @(/2/1/2) .................................................................
+Table::Table() 
+  : QActive(Q_STATE_CAST(&Table::initial))
+{
+    for (uint8_t n = 0U; n < N_PHILO; ++n) {
         m_fork[n] = FREE;
-        m_isHungry[n] = 0;
+        m_isHungry[n] = false;
     }
 }
-//............................................................................
-QState Table::initial(Table *me, QEvent const *) {
+
+// @(/2/1/3) .................................................................
+// @(/2/1/3/0)
+QP::QState Table::initial(Table * const me, QP::QEvt const * const e) {
+    (void)e; // suppress the compiler warning about unused parameter
 
     QS_OBJ_DICTIONARY(&l_table);
-    QS_FUN_DICTIONARY(&QHsm::top);
+    QS_FUN_DICTIONARY(&QP::QHsm::top);
     QS_FUN_DICTIONARY(&Table::initial);
+    QS_FUN_DICTIONARY(&Table::active);
     QS_FUN_DICTIONARY(&Table::serving);
+    QS_FUN_DICTIONARY(&Table::paused);
 
-    QS_SIG_DICTIONARY(DONE_SIG,      0);                     // global signals
-    QS_SIG_DICTIONARY(EAT_SIG,       0);
-    QS_SIG_DICTIONARY(TERMINATE_SIG, 0);
+    QS_SIG_DICTIONARY(DONE_SIG,      (void *)0); // global signals
+    QS_SIG_DICTIONARY(EAT_SIG,       (void *)0);
+    QS_SIG_DICTIONARY(PAUSE_SIG,     (void *)0);
+    QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
 
-    QS_SIG_DICTIONARY(HUNGRY_SIG,    me);             // signal just for Table
+    QS_SIG_DICTIONARY(HUNGRY_SIG,    me); // signal just for Table
 
     me->subscribe(DONE_SIG);
+    me->subscribe(PAUSE_SIG);
     me->subscribe(TERMINATE_SIG);
 
+    for (uint8_t n = 0U; n < N_PHILO; ++n) {
+        me->m_fork[n] = FREE;
+        me->m_isHungry[n] = false;
+        BSP_displayPhilStat(n, THINKING);
+    }
     return Q_TRAN(&Table::serving);
 }
-//............................................................................
-QState Table::serving(Table *me, QEvent const *e) {
-    uint8_t n, m;
-    TableEvt *pe;
-
+// @(/2/1/3/1) ...............................................................
+QP::QState Table::active(Table * const me, QP::QEvt const * const e) {
+    QP::QState status;
     switch (e->sig) {
+        // @(/2/1/3/1/0)
+        case TERMINATE_SIG: {
+            BSP_terminate(0);
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/1/3/1/1)
+        case EAT_SIG: {
+            Q_ERROR();
+            status = Q_HANDLED();
+            break;
+        }
+        default: {
+            status = Q_SUPER(&QHsm::top);
+            break;
+        }
+    }
+    return status;
+}
+// @(/2/1/3/1/2) .............................................................
+QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
+    QP::QState status;
+    switch (e->sig) {
+        // @(/2/1/3/1/2)
+        case Q_ENTRY_SIG: {
+            for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat...
+                if (me->m_isHungry[n]
+                    && (me->m_fork[LEFT(n)] == FREE)
+                    && (me->m_fork[n] == FREE))
+                {
+                    me->m_fork[LEFT(n)] = USED;
+                    me->m_fork[n] = USED;
+                    TableEvt *te = Q_NEW(TableEvt, EAT_SIG);
+                    te->philoNum = n;
+                    QP::QF::PUBLISH(te, me);
+                    me->m_isHungry[n] = false;
+                    BSP_displayPhilStat(n, EATING);
+                }
+            }
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/1/3/1/2/0)
         case HUNGRY_SIG: {
-            n = ((TableEvt const *)e)->philoNum;
-                         // phil ID must be in range and he must be not hungry
+            uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
+            // phil ID must be in range and he must be not hungry
             Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
 
-            BSP_displyPhilStat(n, "hungry  ");
-            m = LEFT(n);
+            BSP_displayPhilStat(n, HUNGRY);
+            uint8_t m = LEFT(n);
+            // @(/2/1/3/1/2/0/0)
             if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) {
-                me->m_fork[m] = me->m_fork[n] = USED;
-                pe = Q_NEW(TableEvt, EAT_SIG);
+                me->m_fork[m] = USED;
+                me->m_fork[n] = USED;
+                TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
                 pe->philoNum = n;
-                QF::PUBLISH(pe, me);
-                BSP_displyPhilStat(n, "eating  ");
+                QP::QF::PUBLISH(pe, me);
+                BSP_displayPhilStat(n, EATING);
+                status = Q_HANDLED();
             }
+            // @(/2/1/3/1/2/0/1)
             else {
-                me->m_isHungry[n] = 1;
+                me->m_isHungry[n] = true;
+                status = Q_HANDLED();
             }
-            return Q_HANDLED();
+            break;
         }
+        // @(/2/1/3/1/2/1)
         case DONE_SIG: {
-            n = ((TableEvt const *)e)->philoNum;
-                         // phil ID must be in range and he must be not hungry
+            uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
+            // phil ID must be in range and he must be not hungry
             Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
 
-            BSP_displyPhilStat(n, "thinking");
-            m = LEFT(n);
-                                         // both forks of Phil[n] must be used
+            BSP_displayPhilStat(n, THINKING);
+            uint8_t m = LEFT(n);
+            // both forks of Phil[n] must be used
             Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
 
-            me->m_fork[m] = me->m_fork[n] = FREE;
-            m = RIGHT(n);                          // check the right neighbor
+            me->m_fork[m] = FREE;
+            me->m_fork[n] = FREE;
+            m = RIGHT(n); // check the right neighbor
+
             if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) {
-                me->m_fork[n] = me->m_fork[m] = USED;
-                me->m_isHungry[m] = 0;
-                pe = Q_NEW(TableEvt, EAT_SIG);
+                me->m_fork[n] = USED;
+                me->m_fork[m] = USED;
+                me->m_isHungry[m] = false;
+                TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
                 pe->philoNum = m;
-                QF::PUBLISH(pe, me);
-                BSP_displyPhilStat(m, "eating  ");
+                QP::QF::PUBLISH(pe, me);
+                BSP_displayPhilStat(m, EATING);
             }
-            m = LEFT(n);                            // check the left neighbor
-            n = LEFT(m);                     // left fork of the left neighbor
+            m = LEFT(n); // check the left neighbor
+            n = LEFT(m); // left fork of the left neighbor
             if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) {
-                me->m_fork[m] = me->m_fork[n] = USED;
-                me->m_isHungry[m] = 0;
-                pe = Q_NEW(TableEvt, EAT_SIG);
+                me->m_fork[m] = USED;
+                me->m_fork[n] = USED;
+                me->m_isHungry[m] = false;
+                TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
                 pe->philoNum = m;
-                QF::PUBLISH(pe, me);
-                BSP_displyPhilStat(m, "eating  ");
+                QP::QF::PUBLISH(pe, me);
+                BSP_displayPhilStat(m, EATING);
             }
-            return Q_HANDLED();
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/1/3/1/2/2)
+        case EAT_SIG: {
+            Q_ERROR();
+            status = Q_HANDLED();
+            break;
         }
-        case TERMINATE_SIG: {
-            QF::stop();
-            return Q_HANDLED();
+        // @(/2/1/3/1/2/3)
+        case PAUSE_SIG: {
+            status = Q_TRAN(&Table::paused);
+            break;
+        }
+        default: {
+            status = Q_SUPER(&Table::active);
+            break;
         }
     }
-    return Q_SUPER(&QHsm::top);
+    return status;
 }
+// @(/2/1/3/1/3) .............................................................
+QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
+    QP::QState status;
+    switch (e->sig) {
+        // @(/2/1/3/1/3)
+        case Q_ENTRY_SIG: {
+            BSP_displayPaused(1U);
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/1/3/1/3)
+        case Q_EXIT_SIG: {
+            BSP_displayPaused(0U);
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/1/3/1/3/0)
+        case PAUSE_SIG: {
+            status = Q_TRAN(&Table::serving);
+            break;
+        }
+        // @(/2/1/3/1/3/1)
+        case HUNGRY_SIG: {
+            uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
+            // philo ID must be in range and he must be not hungry
+            Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
+            me->m_isHungry[n] = true;
+            BSP_displayPhilStat(n, HUNGRY);
+            status = Q_HANDLED();
+            break;
+        }
+        // @(/2/1/3/1/3/2)
+        case DONE_SIG: {
+            uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
+            // phil ID must be in range and he must be not hungry
+            Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
+
+            BSP_displayPhilStat(n, THINKING);
+            uint8_t m = LEFT(n);
+            /* both forks of Phil[n] must be used */
+            Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
+
+            me->m_fork[m] = FREE;
+            me->m_fork[n] = FREE;
+            status = Q_HANDLED();
+            break;
+        }
+        default: {
+            status = Q_SUPER(&Table::active);
+            break;
+        }
+    }
+    return status;
+}
+
+
+}                                                             // namespace DPP