Simple "Blinky" example for the QP active object framework
Fork of qp_dpp by
Revision 7:80bbc7a6c78c, committed 2014-10-12
- Comitter:
- QL
- Date:
- Sun Oct 12 18:56:53 2014 +0000
- Parent:
- 6:88e2e4d0b573
- Commit message:
- Simple "Blinky" example for the QP active object framework
Changed in this revision
diff -r 88e2e4d0b573 -r 80bbc7a6c78c blinky.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/blinky.cpp Sun Oct 12 18:56:53 2014 +0000 @@ -0,0 +1,139 @@ +//**************************************************************************** +// Model: blinky.qm +// File: ./blinky.cpp +// +// This code has been generated by QM tool (see state-machine.com/qm). +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// 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. +// +// 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. +//**************************************************************************** +//${.::blinky.cpp} ........................................................... +#include "qp_port.h" +#include "blinky.h" +#include "bsp.h" + +Q_DEFINE_THIS_FILE + + + +//${AOs::BlinkClass} ......................................................... +class BlinkClass : public QP::QActive { +private: + QP::QTimeEvt m_timeEvt; + +public: + BlinkClass(); + +protected: + static QP::QState initial(BlinkClass * const me, QP::QEvt const * const e); + static QP::QState led_on(BlinkClass * const me, QP::QEvt const * const e); + static QP::QState led_off(BlinkClass * const me, QP::QEvt const * const e); +}; + + + + + +static BlinkClass l_blinky; + +QP::QActive * const AO_Blinky = &l_blinky; + + + + +//${AOs::BlinkClass} ......................................................... +//${AOs::BlinkClass::BlinkClass} ............................................. +BlinkClass::BlinkClass() + : QActive(Q_STATE_CAST(&BlinkClass::initial)) , + m_timeEvt(TIMEOUT_SIG){ +} + +//${AOs::BlinkClass::SM} ..................................................... +QP::QState BlinkClass::initial(BlinkClass * const me, QP::QEvt const * const e) { + // ${AOs::BlinkClass::SM::initial} + // Make sure it only happens once + static bool registered = false; + + // Stop compiler warning + (void)e; + + // Add objects and signals to the kernal dictionary for QSPY + if (!registered) { + registered = true; + + QS_OBJ_DICTIONARY(&l_blinky); + QS_OBJ_DICTIONARY(&l_blinky.m_timeEvt); + + QS_FUN_DICTIONARY(&BlinkClass::initial); + QS_FUN_DICTIONARY(&BlinkClass::led_on); + QS_FUN_DICTIONARY(&BlinkClass::led_off); + } + + QS_SIG_DICTIONARY(TIMEOUT_SIG, me); + return Q_TRAN(&led_on); +} +//${AOs::BlinkClass::SM::led_on} ............................................. +QP::QState BlinkClass::led_on(BlinkClass * const me, QP::QEvt const * const e) { + QP::QState status_; + switch (e->sig) { + // ${AOs::BlinkClass::SM::led_on} + case Q_ENTRY_SIG: { + BSP_ledOn(); + me->m_timeEvt.postEvery(me, BSP_TICKS_PER_SEC / 2); + status_ = Q_HANDLED(); + break; + } + // ${AOs::BlinkClass::SM::led_on} + case Q_EXIT_SIG: { + (void)me->m_timeEvt.disarm(); + status_ = Q_HANDLED(); + break; + } + // ${AOs::BlinkClass::SM::led_on::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&led_off); + break; + } + default: { + status_ = Q_SUPER(&QP::QHsm::top); + break; + } + } + return status_; +} +//${AOs::BlinkClass::SM::led_off} ............................................ +QP::QState BlinkClass::led_off(BlinkClass * const me, QP::QEvt const * const e) { + QP::QState status_; + switch (e->sig) { + // ${AOs::BlinkClass::SM::led_off} + case Q_ENTRY_SIG: { + BSP_ledOff(); + me->m_timeEvt.postEvery(me, BSP_TICKS_PER_SEC / 2); + status_ = Q_HANDLED(); + break; + } + // ${AOs::BlinkClass::SM::led_off} + case Q_EXIT_SIG: { + (void)me->m_timeEvt.disarm(); + status_ = Q_HANDLED(); + break; + } + // ${AOs::BlinkClass::SM::led_off::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&led_on); + break; + } + default: { + status_ = Q_SUPER(&QP::QHsm::top); + break; + } + } + return status_; +}
diff -r 88e2e4d0b573 -r 80bbc7a6c78c blinky.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/blinky.h Sun Oct 12 18:56:53 2014 +0000 @@ -0,0 +1,13 @@ +#ifndef blinky_h +#define blinky_h + +enum BlinkySignals { + TIMEOUT_SIG = QP::Q_USER_SIG, + MAX_PUB_SIG, // the last published signal + + MAX_SIG // the last signal +}; + +extern QP::QActive * const AO_Blinky; + +#endif // blinky_h
diff -r 88e2e4d0b573 -r 80bbc7a6c78c bsp.cpp --- a/bsp.cpp Wed Sep 05 14:03:05 2012 +0000 +++ b/bsp.cpp Sun Oct 12 18:56:53 2014 +0000 @@ -1,39 +1,5 @@ -////////////////////////////////////////////////////////////////////////////// -// 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 "blinky.h" #include "bsp.h" #include "LPC17xx.h" #ifdef Q_SPY @@ -41,8 +7,6 @@ #endif ////////////////////////////////////////////////////////////////////////////// -namespace DPP { - Q_DEFINE_THIS_FILE enum ISR_Priorities { // ISR priorities starting from the highest urgency @@ -52,8 +16,6 @@ }; // 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) @@ -67,10 +29,6 @@ #define QSPY_BAUD_RATE 115200U - enum AppRecords { // application-specific trace records - PHILO_STAT = QP::QS_USER - }; - Serial l_qspy(USBTX, USBRX); #endif @@ -98,7 +56,7 @@ // 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(); @@ -109,38 +67,12 @@ (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_ledOn(void) { + LED_PORT->FIOSET = LED1_BIT; } //............................................................................ -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; +void BSP_ledOff(void) { + LED_PORT->FIOCLR = LED1_BIT; } //............................................................................ @@ -155,19 +87,17 @@ } } -} // 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); + (void)SysTick_Config(SystemCoreClock / 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_SetPriority(SysTick_IRQn, SYSTICK_PRIO); + NVIC_SetPriority(EINT0_IRQn, GPIOPORTA_PRIO); NVIC_EnableIRQ(EINT0_IRQn); } @@ -207,7 +137,7 @@ // 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/ + // http://mbed.org/users/simon/notebook/interface-powerdown/ // __WFI(); #endif @@ -244,7 +174,7 @@ // 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/ + // http://mbed.org/users/simon/notebook/interface-powerdown/ // __WFI(); QF_INT_ENABLE();
diff -r 88e2e4d0b573 -r 80bbc7a6c78c bsp.h --- a/bsp.h Wed Sep 05 14:03:05 2012 +0000 +++ b/bsp.h Sun Oct 12 18:56:53 2014 +0000 @@ -1,55 +1,11 @@ -////////////////////////////////////////////////////////////////////////////// -// 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 +void BSP_ledOn(void); +void BSP_ledOff(void); #endif // bsp_h
diff -r 88e2e4d0b573 -r 80bbc7a6c78c dpp.h --- a/dpp.h Wed Sep 05 14:03:05 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// Model: dpp.qm -// File: ././dpp.h -// -// This file has been generated automatically by QP Modeler (QM). -// DO NOT EDIT THIS FILE MANUALLY. -// -// Please visit www.state-machine.com/qm for more information. -////////////////////////////////////////////////////////////////////////////// -#ifndef dpp_h -#define dpp_h - -namespace DPP { - -enum DPPSignals { - 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 direclty to Table from hungry Philo - MAX_SIG // the last signal -}; - -// @(/1/0) ................................................................... -class TableEvt : public QP::QEvt { -public: - uint8_t philoNum; -}; - -// number of philosophers -#define N_PHILO ((uint8_t)5) - -extern QP::QActive * const AO_Philo[N_PHILO]; -extern QP::QActive * const AO_Table; - -} // namespace DPP - -#endif // dpp_h
diff -r 88e2e4d0b573 -r 80bbc7a6c78c main.cpp --- a/main.cpp Wed Sep 05 14:03:05 2012 +0000 +++ b/main.cpp Sun Oct 12 18:56:53 2014 +0000 @@ -1,81 +1,27 @@ -////////////////////////////////////////////////////////////////////////////// -// Product: DPP example -// 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-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 "blinky.h" #include "bsp.h" -namespace DPP { - //............................................................................ -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 +int main(void) { + static QP::QEvt const *blinkyQueueSto[5]; + //static QP::QSubscrList subscrSto[MAX_PUB_SIG]; + //static QF_MPOOL_EL(QP::QEvt) smlPoolSto[10]; // small pool QP::QF::init(); // initialize the framework and the underlying RT kernel BSP_init(); // initialize the BSP - - // 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]); - - QP::QF::psInit(&subscrSto[0], Q_DIM(subscrSto)); // init publish-subscribe + + //QP::QF::psInit(&subscrSto[0], Q_DIM(subscrSto)); // init publish-subscribe // initialize event pools... - QP::QF::poolInit(&smlPoolSto[0], sizeof(smlPoolSto), - sizeof(smlPoolSto[0])); + //QP::QF::poolInit(&smlPoolSto[0], sizeof(smlPoolSto), + // sizeof(smlPoolSto[0])); // start the active objects... - 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(static_cast<uint8_t>(N_PHILO + 1U), - &tableQueueSto[0], Q_DIM(tableQueueSto), + AO_Blinky->start(1U, + &blinkyQueueSto[0], Q_DIM(blinkyQueueSto), static_cast<void *>(0), 0U); - return QP::QF::run(); // run the QF application } - -} // namespace DPP
diff -r 88e2e4d0b573 -r 80bbc7a6c78c mbed.bld --- a/mbed.bld Wed Sep 05 14:03:05 2012 +0000 +++ b/mbed.bld Sun Oct 12 18:56:53 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/9a9732ce53a1 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1 \ No newline at end of file
diff -r 88e2e4d0b573 -r 80bbc7a6c78c philo.cpp --- a/philo.cpp Wed Sep 05 14:03:05 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// Model: dpp.qm -// File: ././philo.cpp -// -// This file has been generated automatically by QP Modeler (QM). -// DO NOT EDIT THIS FILE MANUALLY. -// -// 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 ------------------------------------------------------- -// @(/2/0) ................................................................... -class Philo : public QP::QActive { -private: - QP::QTimeEvt m_timeEvt; - -public: - Philo(); - -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 - -// 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 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); -} - -// 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 ------------------------------------------------------------ -QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO - &l_philo[0], - &l_philo[1], - &l_philo[2], - &l_philo[3], - &l_philo[4] -}; - -// 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]); - QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); - - QS_FUN_DICTIONARY(&Philo::initial); - QS_FUN_DICTIONARY(&Philo::thinking); - QS_FUN_DICTIONARY(&Philo::hungry); - QS_FUN_DICTIONARY(&Philo::eating); - } - 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); -} -// @(/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()); - 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: { - status = Q_TRAN(&Philo::hungry); - break; - } - // @(/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(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm::top); - break; - } - } - return status; -} -// @(/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); - status = Q_HANDLED(); - break; - } - // @(/2/0/2/2/0) - case EAT_SIG: { - // @(/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(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm::top); - break; - } - } - return status; -} -// @(/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()); - status = Q_HANDLED(); - break; - } - // @(/2/0/2/3) - case Q_EXIT_SIG: { - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); - QP::QF::PUBLISH(pe, me); - (void)me->m_timeEvt.disarm(); - status = Q_HANDLED(); - break; - } - // @(/2/0/2/3/0) - case TIMEOUT_SIG: { - status = Q_TRAN(&Philo::thinking); - break; - } - // @(/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(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm::top); - break; - } - } - return status; -} - - -} // namespace DPP
diff -r 88e2e4d0b573 -r 80bbc7a6c78c table.cpp --- a/table.cpp Wed Sep 05 14:03:05 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,283 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// Model: dpp.qm -// File: ././table.cpp -// -// This file has been generated automatically by QP Modeler (QM). -// DO NOT EDIT THIS FILE MANUALLY. -// -// 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 ------------------------------------------------------- -// @(/2/1) ................................................................... -class Table : public QP::QActive { -private: - uint8_t m_fork[N_PHILO]; - bool m_isHungry[N_PHILO]; - -public: - Table(); - -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); -}; - -// 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; // the single instance of the Table active object - -// Global-scope objects ------------------------------------------------------ -QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer - -//............................................................................ -// @(/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] = false; - } -} - -// @(/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(&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, (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 - - 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); -} -// @(/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: { - 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, 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] = USED; - me->m_fork[n] = USED; - TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; - QP::QF::PUBLISH(pe, me); - BSP_displayPhilStat(n, EATING); - status = Q_HANDLED(); - } - // @(/2/1/3/1/2/0/1) - else { - me->m_isHungry[n] = true; - status = Q_HANDLED(); - } - break; - } - // @(/2/1/3/1/2/1) - 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; - m = RIGHT(n); // check the right neighbor - - if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) { - 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; - 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 - if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { - 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; - QP::QF::PUBLISH(pe, me); - BSP_displayPhilStat(m, EATING); - } - status = Q_HANDLED(); - break; - } - // @(/2/1/3/1/2/2) - case EAT_SIG: { - Q_ERROR(); - status = Q_HANDLED(); - break; - } - // @(/2/1/3/1/2/3) - case PAUSE_SIG: { - status = Q_TRAN(&Table::paused); - break; - } - default: { - status = Q_SUPER(&Table::active); - break; - } - } - 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