Simple "Blinky" example for the QP active object framework
Fork of qp_dpp by
philo.cpp@4:6189d844a1a2, 2012-09-04 (annotated)
- Committer:
- QL
- Date:
- Tue Sep 04 22:41:20 2012 +0000
- Revision:
- 4:6189d844a1a2
- Parent:
- 3:81ceb3127876
updated for QP 4.5.02
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
QL | 0:efb9ac8d1a88 | 1 | ////////////////////////////////////////////////////////////////////////////// |
QL | 4:6189d844a1a2 | 2 | // Model: dpp.qm |
QL | 4:6189d844a1a2 | 3 | // File: ././philo.cpp |
QL | 0:efb9ac8d1a88 | 4 | // |
QL | 4:6189d844a1a2 | 5 | // This file has been generated automatically by QP Modeler (QM). |
QL | 4:6189d844a1a2 | 6 | // DO NOT EDIT THIS FILE MANUALLY. |
QL | 0:efb9ac8d1a88 | 7 | // |
QL | 4:6189d844a1a2 | 8 | // Please visit www.state-machine.com/qm for more information. |
QL | 0:efb9ac8d1a88 | 9 | ////////////////////////////////////////////////////////////////////////////// |
QL | 0:efb9ac8d1a88 | 10 | #include "qp_port.h" |
QL | 0:efb9ac8d1a88 | 11 | #include "dpp.h" |
QL | 0:efb9ac8d1a88 | 12 | #include "bsp.h" |
QL | 0:efb9ac8d1a88 | 13 | |
QL | 4:6189d844a1a2 | 14 | namespace DPP { |
QL | 4:6189d844a1a2 | 15 | |
QL | 0:efb9ac8d1a88 | 16 | Q_DEFINE_THIS_FILE |
QL | 0:efb9ac8d1a88 | 17 | |
QL | 0:efb9ac8d1a88 | 18 | // Active object class ------------------------------------------------------- |
QL | 4:6189d844a1a2 | 19 | // @(/2/0) ................................................................... |
QL | 4:6189d844a1a2 | 20 | class Philo : public QP::QActive { |
QL | 0:efb9ac8d1a88 | 21 | private: |
QL | 4:6189d844a1a2 | 22 | QP::QTimeEvt m_timeEvt; |
QL | 0:efb9ac8d1a88 | 23 | |
QL | 0:efb9ac8d1a88 | 24 | public: |
QL | 0:efb9ac8d1a88 | 25 | Philo(); |
QL | 0:efb9ac8d1a88 | 26 | |
QL | 4:6189d844a1a2 | 27 | protected: |
QL | 4:6189d844a1a2 | 28 | static QP::QState initial(Philo * const me, QP::QEvt const * const e); |
QL | 4:6189d844a1a2 | 29 | static QP::QState thinking(Philo * const me, QP::QEvt const * const e); |
QL | 4:6189d844a1a2 | 30 | static QP::QState hungry(Philo * const me, QP::QEvt const * const e); |
QL | 4:6189d844a1a2 | 31 | static QP::QState eating(Philo * const me, QP::QEvt const * const e); |
QL | 0:efb9ac8d1a88 | 32 | }; |
QL | 0:efb9ac8d1a88 | 33 | |
QL | 0:efb9ac8d1a88 | 34 | // Local objects ------------------------------------------------------------- |
QL | 4:6189d844a1a2 | 35 | static Philo l_philo[N_PHILO]; // storage for all Philos |
QL | 0:efb9ac8d1a88 | 36 | |
QL | 4:6189d844a1a2 | 37 | // helper function to provide a randomized think time for Philos |
QL | 4:6189d844a1a2 | 38 | inline QP::QTimeEvtCtr think_time() { |
QL | 4:6189d844a1a2 | 39 | return static_cast<QP::QTimeEvtCtr>((BSP_random() % BSP_TICKS_PER_SEC) |
QL | 4:6189d844a1a2 | 40 | + (BSP_TICKS_PER_SEC/2U)); |
QL | 4:6189d844a1a2 | 41 | } |
QL | 3:81ceb3127876 | 42 | |
QL | 4:6189d844a1a2 | 43 | // helper function to provide a randomized eat time for Philos |
QL | 4:6189d844a1a2 | 44 | inline QP::QTimeEvtCtr eat_time() { |
QL | 4:6189d844a1a2 | 45 | return static_cast<QP::QTimeEvtCtr>((BSP_random() % BSP_TICKS_PER_SEC) |
QL | 4:6189d844a1a2 | 46 | + BSP_TICKS_PER_SEC); |
QL | 4:6189d844a1a2 | 47 | } |
QL | 0:efb9ac8d1a88 | 48 | |
QL | 4:6189d844a1a2 | 49 | // helper function to provide the ID of Philo "me" |
QL | 4:6189d844a1a2 | 50 | inline uint8_t PHILO_ID(Philo const * const me) { |
QL | 4:6189d844a1a2 | 51 | return static_cast<uint8_t>(me - l_philo); |
QL | 4:6189d844a1a2 | 52 | } |
QL | 4:6189d844a1a2 | 53 | |
QL | 4:6189d844a1a2 | 54 | enum InternalSignals { // internal signals |
QL | 0:efb9ac8d1a88 | 55 | TIMEOUT_SIG = MAX_SIG |
QL | 0:efb9ac8d1a88 | 56 | }; |
QL | 4:6189d844a1a2 | 57 | |
QL | 0:efb9ac8d1a88 | 58 | // Global objects ------------------------------------------------------------ |
QL | 4:6189d844a1a2 | 59 | QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO |
QL | 0:efb9ac8d1a88 | 60 | &l_philo[0], |
QL | 0:efb9ac8d1a88 | 61 | &l_philo[1], |
QL | 0:efb9ac8d1a88 | 62 | &l_philo[2], |
QL | 0:efb9ac8d1a88 | 63 | &l_philo[3], |
QL | 0:efb9ac8d1a88 | 64 | &l_philo[4] |
QL | 0:efb9ac8d1a88 | 65 | }; |
QL | 0:efb9ac8d1a88 | 66 | |
QL | 4:6189d844a1a2 | 67 | // Philo definition ---------------------------------------------------------- |
QL | 4:6189d844a1a2 | 68 | // @(/2/0) ................................................................... |
QL | 4:6189d844a1a2 | 69 | // @(/2/0/1) ................................................................. |
QL | 4:6189d844a1a2 | 70 | Philo::Philo() |
QL | 4:6189d844a1a2 | 71 | : QActive(Q_STATE_CAST(&Philo::initial)), |
QL | 4:6189d844a1a2 | 72 | m_timeEvt(TIMEOUT_SIG) |
QL | 4:6189d844a1a2 | 73 | { |
QL | 4:6189d844a1a2 | 74 | } |
QL | 4:6189d844a1a2 | 75 | |
QL | 4:6189d844a1a2 | 76 | // @(/2/0/2) ................................................................. |
QL | 4:6189d844a1a2 | 77 | // @(/2/0/2/0) |
QL | 4:6189d844a1a2 | 78 | QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) { |
QL | 4:6189d844a1a2 | 79 | static bool registered = false; // starts off with 0, per C-standard |
QL | 4:6189d844a1a2 | 80 | (void)e; // suppress the compiler warning about unused parameter |
QL | 0:efb9ac8d1a88 | 81 | if (!registered) { |
QL | 4:6189d844a1a2 | 82 | registered = true; |
QL | 4:6189d844a1a2 | 83 | |
QL | 0:efb9ac8d1a88 | 84 | QS_OBJ_DICTIONARY(&l_philo[0]); |
QL | 0:efb9ac8d1a88 | 85 | QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); |
QL | 0:efb9ac8d1a88 | 86 | QS_OBJ_DICTIONARY(&l_philo[1]); |
QL | 0:efb9ac8d1a88 | 87 | QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); |
QL | 0:efb9ac8d1a88 | 88 | QS_OBJ_DICTIONARY(&l_philo[2]); |
QL | 0:efb9ac8d1a88 | 89 | QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); |
QL | 0:efb9ac8d1a88 | 90 | QS_OBJ_DICTIONARY(&l_philo[3]); |
QL | 0:efb9ac8d1a88 | 91 | QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); |
QL | 0:efb9ac8d1a88 | 92 | QS_OBJ_DICTIONARY(&l_philo[4]); |
QL | 0:efb9ac8d1a88 | 93 | QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); |
QL | 0:efb9ac8d1a88 | 94 | |
QL | 0:efb9ac8d1a88 | 95 | QS_FUN_DICTIONARY(&Philo::initial); |
QL | 0:efb9ac8d1a88 | 96 | QS_FUN_DICTIONARY(&Philo::thinking); |
QL | 0:efb9ac8d1a88 | 97 | QS_FUN_DICTIONARY(&Philo::hungry); |
QL | 0:efb9ac8d1a88 | 98 | QS_FUN_DICTIONARY(&Philo::eating); |
QL | 0:efb9ac8d1a88 | 99 | } |
QL | 4:6189d844a1a2 | 100 | QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos |
QL | 4:6189d844a1a2 | 101 | QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos |
QL | 0:efb9ac8d1a88 | 102 | |
QL | 0:efb9ac8d1a88 | 103 | me->subscribe(EAT_SIG); |
QL | 0:efb9ac8d1a88 | 104 | return Q_TRAN(&Philo::thinking); |
QL | 0:efb9ac8d1a88 | 105 | } |
QL | 4:6189d844a1a2 | 106 | // @(/2/0/2/1) ............................................................... |
QL | 4:6189d844a1a2 | 107 | QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) { |
QL | 4:6189d844a1a2 | 108 | QP::QState status; |
QL | 0:efb9ac8d1a88 | 109 | switch (e->sig) { |
QL | 4:6189d844a1a2 | 110 | // @(/2/0/2/1) |
QL | 0:efb9ac8d1a88 | 111 | case Q_ENTRY_SIG: { |
QL | 4:6189d844a1a2 | 112 | me->m_timeEvt.postIn(me, think_time()); |
QL | 4:6189d844a1a2 | 113 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 114 | break; |
QL | 0:efb9ac8d1a88 | 115 | } |
QL | 4:6189d844a1a2 | 116 | // @(/2/0/2/1) |
QL | 4:6189d844a1a2 | 117 | case Q_EXIT_SIG: { |
QL | 4:6189d844a1a2 | 118 | (void)me->m_timeEvt.disarm(); |
QL | 4:6189d844a1a2 | 119 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 120 | break; |
QL | 4:6189d844a1a2 | 121 | } |
QL | 4:6189d844a1a2 | 122 | // @(/2/0/2/1/0) |
QL | 0:efb9ac8d1a88 | 123 | case TIMEOUT_SIG: { |
QL | 4:6189d844a1a2 | 124 | status = Q_TRAN(&Philo::hungry); |
QL | 4:6189d844a1a2 | 125 | break; |
QL | 0:efb9ac8d1a88 | 126 | } |
QL | 4:6189d844a1a2 | 127 | // @(/2/0/2/1/1) |
QL | 4:6189d844a1a2 | 128 | case EAT_SIG: // intentionally fall through |
QL | 0:efb9ac8d1a88 | 129 | case DONE_SIG: { |
QL | 4:6189d844a1a2 | 130 | /* EAT or DONE must be for other Philos than this one */ |
QL | 4:6189d844a1a2 | 131 | Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); |
QL | 4:6189d844a1a2 | 132 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 133 | break; |
QL | 4:6189d844a1a2 | 134 | } |
QL | 4:6189d844a1a2 | 135 | default: { |
QL | 4:6189d844a1a2 | 136 | status = Q_SUPER(&QHsm::top); |
QL | 4:6189d844a1a2 | 137 | break; |
QL | 0:efb9ac8d1a88 | 138 | } |
QL | 0:efb9ac8d1a88 | 139 | } |
QL | 4:6189d844a1a2 | 140 | return status; |
QL | 0:efb9ac8d1a88 | 141 | } |
QL | 4:6189d844a1a2 | 142 | // @(/2/0/2/2) ............................................................... |
QL | 4:6189d844a1a2 | 143 | QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) { |
QL | 4:6189d844a1a2 | 144 | QP::QState status; |
QL | 0:efb9ac8d1a88 | 145 | switch (e->sig) { |
QL | 4:6189d844a1a2 | 146 | // @(/2/0/2/2) |
QL | 0:efb9ac8d1a88 | 147 | case Q_ENTRY_SIG: { |
QL | 0:efb9ac8d1a88 | 148 | TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); |
QL | 0:efb9ac8d1a88 | 149 | pe->philoNum = PHILO_ID(me); |
QL | 3:81ceb3127876 | 150 | AO_Table->POST(pe, me); |
QL | 4:6189d844a1a2 | 151 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 152 | break; |
QL | 0:efb9ac8d1a88 | 153 | } |
QL | 4:6189d844a1a2 | 154 | // @(/2/0/2/2/0) |
QL | 0:efb9ac8d1a88 | 155 | case EAT_SIG: { |
QL | 4:6189d844a1a2 | 156 | // @(/2/0/2/2/0/0) |
QL | 4:6189d844a1a2 | 157 | if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { |
QL | 4:6189d844a1a2 | 158 | status = Q_TRAN(&Philo::eating); |
QL | 4:6189d844a1a2 | 159 | } |
QL | 4:6189d844a1a2 | 160 | else { |
QL | 4:6189d844a1a2 | 161 | status = Q_UNHANDLED(); |
QL | 0:efb9ac8d1a88 | 162 | } |
QL | 0:efb9ac8d1a88 | 163 | break; |
QL | 0:efb9ac8d1a88 | 164 | } |
QL | 4:6189d844a1a2 | 165 | // @(/2/0/2/2/1) |
QL | 0:efb9ac8d1a88 | 166 | case DONE_SIG: { |
QL | 4:6189d844a1a2 | 167 | /* DONE must be for other Philos than this one */ |
QL | 4:6189d844a1a2 | 168 | Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); |
QL | 4:6189d844a1a2 | 169 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 170 | break; |
QL | 4:6189d844a1a2 | 171 | } |
QL | 4:6189d844a1a2 | 172 | default: { |
QL | 4:6189d844a1a2 | 173 | status = Q_SUPER(&QHsm::top); |
QL | 4:6189d844a1a2 | 174 | break; |
QL | 0:efb9ac8d1a88 | 175 | } |
QL | 0:efb9ac8d1a88 | 176 | } |
QL | 4:6189d844a1a2 | 177 | return status; |
QL | 0:efb9ac8d1a88 | 178 | } |
QL | 4:6189d844a1a2 | 179 | // @(/2/0/2/3) ............................................................... |
QL | 4:6189d844a1a2 | 180 | QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) { |
QL | 4:6189d844a1a2 | 181 | QP::QState status; |
QL | 0:efb9ac8d1a88 | 182 | switch (e->sig) { |
QL | 4:6189d844a1a2 | 183 | // @(/2/0/2/3) |
QL | 0:efb9ac8d1a88 | 184 | case Q_ENTRY_SIG: { |
QL | 4:6189d844a1a2 | 185 | me->m_timeEvt.postIn(me, eat_time()); |
QL | 4:6189d844a1a2 | 186 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 187 | break; |
QL | 0:efb9ac8d1a88 | 188 | } |
QL | 4:6189d844a1a2 | 189 | // @(/2/0/2/3) |
QL | 0:efb9ac8d1a88 | 190 | case Q_EXIT_SIG: { |
QL | 0:efb9ac8d1a88 | 191 | TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); |
QL | 0:efb9ac8d1a88 | 192 | pe->philoNum = PHILO_ID(me); |
QL | 4:6189d844a1a2 | 193 | QP::QF::PUBLISH(pe, me); |
QL | 4:6189d844a1a2 | 194 | (void)me->m_timeEvt.disarm(); |
QL | 4:6189d844a1a2 | 195 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 196 | break; |
QL | 0:efb9ac8d1a88 | 197 | } |
QL | 4:6189d844a1a2 | 198 | // @(/2/0/2/3/0) |
QL | 0:efb9ac8d1a88 | 199 | case TIMEOUT_SIG: { |
QL | 4:6189d844a1a2 | 200 | status = Q_TRAN(&Philo::thinking); |
QL | 4:6189d844a1a2 | 201 | break; |
QL | 0:efb9ac8d1a88 | 202 | } |
QL | 4:6189d844a1a2 | 203 | // @(/2/0/2/3/1) |
QL | 4:6189d844a1a2 | 204 | case EAT_SIG: // intentionally fall through |
QL | 0:efb9ac8d1a88 | 205 | case DONE_SIG: { |
QL | 4:6189d844a1a2 | 206 | /* EAT or DONE must be for other Philos than this one */ |
QL | 4:6189d844a1a2 | 207 | Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); |
QL | 4:6189d844a1a2 | 208 | status = Q_HANDLED(); |
QL | 4:6189d844a1a2 | 209 | break; |
QL | 4:6189d844a1a2 | 210 | } |
QL | 4:6189d844a1a2 | 211 | default: { |
QL | 4:6189d844a1a2 | 212 | status = Q_SUPER(&QHsm::top); |
QL | 4:6189d844a1a2 | 213 | break; |
QL | 0:efb9ac8d1a88 | 214 | } |
QL | 0:efb9ac8d1a88 | 215 | } |
QL | 4:6189d844a1a2 | 216 | return status; |
QL | 0:efb9ac8d1a88 | 217 | } |
QL | 4:6189d844a1a2 | 218 | |
QL | 4:6189d844a1a2 | 219 | |
QL | 4:6189d844a1a2 | 220 | } // namespace DPP |