では、QPを使うとプログラムはどんな具合になるか? という実例を一つ。簡単なところでLチカのサンプルコードが記事の最後に掲載したリスト1である(ヘッダコメントは省略)。ちょっと複雑だが、まぁこの程度なら読めなくはない。ただし、ここで呼んでいるBlinky_ctor()を含むコードは、リスト1に続くリスト2の通り(ヘッダコメントは省略)。
見て頂くと分かるが、もう人間の可読性をあんまり考慮していないというか、結構読みづらいコードになっている。というのは、これはQMを使って生成したものであって、その意味でもQPを使うならMBDを利用すべきなのである。逆に言えば、従来MBDを使ってコードを開発というと、MathWorksのMATLABとEmbedded Coderを組み合わせるなんて話になりがちだが決して安価ではない。QPは、QMと組み合わせることで、このMATLAB+Embedded Coderの良い代替になり得ると考えればよい。
そういう意味では「普通の」RTOSを探しているユーザーにはまるでお薦めできないが、開発にMBDを考慮しているようなところでは、一度試してみる価値はあるのではないかと思う。QPと全ツールキットをまとめた「QP-bundle」がWindows/Linux/macOS用にそれぞれ用意されており、何しろオープンソースだから評価を始める際のコストはゼロ円で済む。あるいは、MBDの勉強用にもQPは向いているかもしれない。
#include "qpc.h" #include "blinky.h" #include "bsp.h" Q_DEFINE_THIS_FILE /*..........................................................................*/ int main(int argc, char *argv[]) { static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* storage for small pool*/ static QEvt const *blinkyQSto[10]; /* event queue storage for Blinky */ QF_init(); /* initialize the framework */ /* initialize the QS software tracing */ Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); BSP_init(); /* initialize the BSP */ /* dictionaries... */ QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); /* pause execution of the test and wait for the test script to continue */ QS_TEST_PAUSE(); /* publish-subscribe not used, no call to QF_psInit() */ /* initialize event pools... */ QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); /* start the active objects... */ Blinky_ctor(); QACTIVE_START(AO_Blinky, 1U, blinkyQSto, Q_DIM(blinkyQSto), (void *)0, 0U, (void *)0); return QF_run(); } /*--------------------------------------------------------------------------*/ void QS_onTestSetup(void) { } /*..........................................................................*/ void QS_onTestTeardown(void) { } /*..........................................................................*/ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { case 0U: { break; } default: break; } /* unused parameters... */ (void)param1; (void)param2; (void)param3; } /*..........................................................................*/ /* host callback function to "massage" the event, if necessary */ void QS_onTestEvt(QEvt *e) { #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ #else /* this test is compiled for an embedded Target system */ #endif /* unused parameters... */ (void)e; } /*..........................................................................*/ /*! callback function to output the posted QP events (not used here) */ void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { /* unused parameters... */ (void)sender; (void)recipient; (void)e; (void)status; }
#include "qpc.h" #include "blinky.h" #include "bsp.h" //Q_DEFINE_THIS_MODULE("blinky") /*************** ask QM to declare the Blinky class ******************/ /*.$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /*.${AOs::Blinky} ..........................................................*/ typedef struct { /* protected: */ QActive super; /* private: */ QTimeEvt timeEvt; } Blinky; /* protected: */ static QState Blinky_initial(Blinky * const me, void const * const par); static QState Blinky_off(Blinky * const me, QEvt const * const e); static QState Blinky_on(Blinky * const me, QEvt const * const e); /*.$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ static Blinky l_blinky; /*.$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /*. Check for the minimum required QP version */ #if (QP_VERSION < 680U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) #error qpc version 6.8.0 or higher required #endif /*.$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*.$define${AOs::AO_Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /* opaque pointer to the Blinky AO */ /*.${AOs::AO_Blinky} .......................................................*/ QActive * const AO_Blinky = &l_blinky.super; /*.$enddef${AOs::AO_Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*************** ask QM to define the Blinky class ******************/ /*.$define${AOs::Blinky_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /*.${AOs::Blinky_ctor} .....................................................*/ void Blinky_ctor(void) { Blinky *me = &l_blinky; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } /*.$enddef${AOs::Blinky_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*.$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /*.${AOs::Blinky} ..........................................................*/ /*.${AOs::Blinky::SM} ......................................................*/ static QState Blinky_initial(Blinky * const me, void const * const par) { /*.${AOs::Blinky::SM::initial} */ (void)par; /* unused parameter */ QS_OBJ_DICTIONARY(&l_blinky); QS_OBJ_DICTIONARY(&l_blinky.timeEvt); QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); QS_FUN_DICTIONARY(&Blinky_off); QS_FUN_DICTIONARY(&Blinky_on); return Q_TRAN(&Blinky_off); } /*.${AOs::Blinky::SM::off} .................................................*/ static QState Blinky_off(Blinky * const me, QEvt const * const e) { QState status_; switch (e->sig) { /*.${AOs::Blinky::SM::off} */ case Q_ENTRY_SIG: { BSP_ledOff(); status_ = Q_HANDLED(); break; } /*.${AOs::Blinky::SM::off::TIMEOUT} */ case TIMEOUT_SIG: { status_ = Q_TRAN(&Blinky_on); break; } default: { status_ = Q_SUPER(&QHsm_top); break; } } return status_; } /*.${AOs::Blinky::SM::on} ..................................................*/ static QState Blinky_on(Blinky * const me, QEvt const * const e) { QState status_; switch (e->sig) { /*.${AOs::Blinky::SM::on} */ case Q_ENTRY_SIG: { BSP_ledOn(); status_ = Q_HANDLED(); break; } /*.${AOs::Blinky::SM::on::TIMEOUT} */ case TIMEOUT_SIG: { status_ = Q_TRAN(&Blinky_off); break; } default: { status_ = Q_SUPER(&QHsm_top); break; } } return status_; } /*.$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
Copyright © ITmedia, Inc. All Rights Reserved.