Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 4:6189d844a1a2, committed 2012-09-04
- 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
--- 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