mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-02-04 06:13:00 +08:00
249 lines
8.1 KiB
XML
249 lines
8.1 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<model version="5.1.3" links="1">
|
|
<documentation>Start-stop application that demonstrates staring and stopping active objects multiple times during the runtime, as opposed to starting AOs only at the beginning.</documentation>
|
|
<!--${qpcpp}-->
|
|
<framework name="qpcpp"/>
|
|
<!--${AOs}-->
|
|
<package name="AOs" stereotype="0x02">
|
|
<!--${AOs::Launcher}-->
|
|
<class name="Launcher" superclass="qpcpp::QActive">
|
|
<!--${AOs::Launcher::inst}-->
|
|
<attribute name="inst" type="Launcher" visibility="0x00" properties="0x01">
|
|
<documentation>The only instance of the Launcher AO (Singleton pattern)</documentation>
|
|
</attribute>
|
|
<!--${AOs::Launcher::m_worker}-->
|
|
<attribute name="m_worker" type="Worker *" visibility="0x00" properties="0x00"/>
|
|
<!--${AOs::Launcher::m_te}-->
|
|
<attribute name="m_te" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Launcher::Launcher}-->
|
|
<operation name="Launcher" type="" visibility="0x00" properties="0x00">
|
|
<code> : QActive(initial),
|
|
m_worker(0),
|
|
m_te(this, TIMEOUT_SIG, 0U)</code>
|
|
</operation>
|
|
<!--${AOs::Launcher::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Launcher::SM::initial}-->
|
|
<initial target="../1">
|
|
<action>(void)e; // unused parameter
|
|
|
|
subscribe(DONE_SIG);
|
|
|
|
QS_OBJ_DICTIONARY(&Launcher::inst);
|
|
QS_OBJ_DICTIONARY(&Launcher::inst.m_te);
|
|
|
|
QS_SIG_DICTIONARY(DONE_SIG, nullptr);
|
|
QS_SIG_DICTIONARY(TIMEOUT_SIG, nullptr);</action>
|
|
<initial_glyph conn="2,2,5,1,38,6,0">
|
|
<action box="0,0,4,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Launcher::SM::inactive}-->
|
|
<state name="inactive">
|
|
<entry>m_te.armX(BSP::TICKS_PER_SEC / 5U, 0);</entry>
|
|
<exit>m_te.disarm();</exit>
|
|
<!--${AOs::Launcher::SM::inactive::TIMEOUT}-->
|
|
<tran trig="TIMEOUT" target="../../2">
|
|
<tran_glyph conn="2,22,3,1,40,14,-2">
|
|
<action box="0,-2,7,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="2,6,38,22">
|
|
<entry box="1,2,37,6"/>
|
|
<exit box="1,8,37,5"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Launcher::SM::active}-->
|
|
<state name="active">
|
|
<entry>// placement new to execute the Worker ctor
|
|
m_worker = new (&Worker::inst) Worker;
|
|
m_worker->start(
|
|
1U, // QP priority of the AO
|
|
l_workerQueueSto, // event queue storage
|
|
Q_DIM(l_workerQueueSto), // queue length [events]
|
|
l_workerStackSto, // stack storage
|
|
sizeof(l_workerStackSto)); // stack size [bytes]</entry>
|
|
<exit>m_worker->~Worker(); // explicit destructor call
|
|
m_worker = nullptr;</exit>
|
|
<!--${AOs::Launcher::SM::active::DONE}-->
|
|
<tran trig="DONE">
|
|
<action brief="wait for Worker to stop">// arm a timer for at least one tick
|
|
m_te.armX(2, 0);
|
|
// wait for Worker to stop...</action>
|
|
<tran_glyph conn="2,46,3,-1,26">
|
|
<action box="0,-2,25,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Launcher::SM::active::TIMEOUT}-->
|
|
<tran trig="TIMEOUT" target="../../1">
|
|
<tran_glyph conn="2,50,3,1,42,-34,-4">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="2,30,38,22">
|
|
<entry box="1,2,37,6"/>
|
|
<exit box="1,8,37,6"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_diagram size="46,54"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::Worker}-->
|
|
<class name="Worker" superclass="qpcpp::QActive">
|
|
<documentation>"Worker" active object that will be started, perform its job, and then stop itself.</documentation>
|
|
<!--${AOs::Worker::inst}-->
|
|
<attribute name="inst" type="Worker" visibility="0x00" properties="0x01">
|
|
<documentation>The only instance of the Worker AO (Singleton pattern)</documentation>
|
|
</attribute>
|
|
<!--${AOs::Worker::m_te}-->
|
|
<attribute name="m_te" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Worker::m_counter}-->
|
|
<attribute name="m_counter" type="uint8_t" visibility="0x00" properties="0x00">
|
|
<documentation>blink down-counter</documentation>
|
|
</attribute>
|
|
<!--${AOs::Worker::Worker}-->
|
|
<operation name="Worker" type="" visibility="0x00" properties="0x00">
|
|
<code> : QActive(&initial),
|
|
m_te(this, TIMEOUT_SIG, 0U)</code>
|
|
</operation>
|
|
<!--${AOs::Worker::~Worker}-->
|
|
<operation name="~Worker" type="" visibility="0x00" properties="0x04">
|
|
<documentation>virtual destructor</documentation>
|
|
<code>BSP::led2Off();</code>
|
|
</operation>
|
|
<!--${AOs::Worker::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Worker::SM::initial}-->
|
|
<initial target="../1/0">
|
|
<action>(void)e; // unused parameter
|
|
|
|
QS_OBJ_DICTIONARY(&Worker::inst);
|
|
QS_OBJ_DICTIONARY(&Worker::inst.m_te);</action>
|
|
<initial_glyph conn="3,2,5,1,37,24,-18">
|
|
<action box="0,0,25,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Worker::SM::active}-->
|
|
<state name="active">
|
|
<entry>m_counter = 5U; // number of blinks
|
|
m_te.armX(BSP::TICKS_PER_SEC / 5U,
|
|
BSP::TICKS_PER_SEC / 5U);</entry>
|
|
<exit>m_te.disarm();</exit>
|
|
<!--${AOs::Worker::SM::active::off}-->
|
|
<state name="off">
|
|
<!--${AOs::Worker::SM::active::off::TIMEOUT}-->
|
|
<tran trig="TIMEOUT" target="../../1">
|
|
<tran_glyph conn="4,30,3,1,20,6,-2">
|
|
<action box="0,-2,18,6"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,24,18,8"/>
|
|
</state>
|
|
<!--${AOs::Worker::SM::active::on}-->
|
|
<state name="on">
|
|
<entry>BSP::ledOn();</entry>
|
|
<exit>BSP::ledOff();</exit>
|
|
<!--${AOs::Worker::SM::active::on::TIMEOUT}-->
|
|
<tran trig="TIMEOUT">
|
|
<action>--m_counter;</action>
|
|
<!--${AOs::Worker::SM::active::on::TIMEOUT::[else]}-->
|
|
<choice target="../../../0">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="26,48,4,1,-20,-4">
|
|
<action box="0,-5,10,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Worker::SM::active::on::TIMEOUT::[m_counter==0U]}-->
|
|
<choice target="../../../../2">
|
|
<guard>m_counter == 0U</guard>
|
|
<choice_glyph conn="26,48,5,1,14,8,-4">
|
|
<action box="1,0,16,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,48,3,-1,22">
|
|
<action box="0,-2,21,4"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,34,18,16">
|
|
<entry box="1,2,16,4"/>
|
|
<exit box="1,6,16,5"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_glyph node="2,6,34,46">
|
|
<entry box="1,2,31,9"/>
|
|
<exit box="1,11,31,5"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Worker::SM::final}-->
|
|
<state name="final">
|
|
<entry>BSP::led2On();
|
|
static QEvt const doneEvt = { DONE_SIG, 0 };
|
|
QF::PUBLISH(&doneEvt, this);
|
|
stop(); // stop this active object</entry>
|
|
<state_glyph node="2,54,34,16">
|
|
<entry box="1,2,33,12"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_diagram size="42,72"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::AO_Launcher}-->
|
|
<attribute name="AO_Launcher" type="QP::QActive * const" visibility="0x00" properties="0x00">
|
|
<code>= &Launcher::inst; // opaque pointer</code>
|
|
</attribute>
|
|
</package>
|
|
<!--${.}-->
|
|
<directory name=".">
|
|
<!--${.::worker.hpp}-->
|
|
<file name="worker.hpp">
|
|
<text>#ifndef WORKER_HPP
|
|
#define WORKER_HPP
|
|
|
|
using namespace QP;
|
|
|
|
enum DPPSignals {
|
|
DONE_SIG = Q_USER_SIG, // to signal when Worker is done
|
|
// ...
|
|
MAX_PUB_SIG, // the last published signal
|
|
|
|
TIMEOUT_SIG, // for timeouts
|
|
// ...
|
|
MAX_SIG // the last signal
|
|
};
|
|
|
|
$declare${AOs::Worker}
|
|
$declare${AOs::AO_Launcher}
|
|
|
|
#endif // WORKER_HPP
|
|
</text>
|
|
</file>
|
|
<!--${.::worker.cpp}-->
|
|
<file name="worker.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "Worker.hpp"
|
|
#include "bsp.hpp"
|
|
|
|
//Q_DEFINE_THIS_FILE
|
|
|
|
$define${AOs::Worker}</text>
|
|
</file>
|
|
<!--${.::launcher.cpp}-->
|
|
<file name="launcher.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "worker.hpp"
|
|
#include "bsp.hpp"
|
|
#include <new> // for placement new
|
|
|
|
//Q_DEFINE_THIS_FILE
|
|
|
|
static QP::QEvt const *l_workerQueueSto[10];
|
|
static StackType_t l_workerStackSto[configMINIMAL_STACK_SIZE];
|
|
|
|
$declare${AOs::Launcher}
|
|
|
|
$define${AOs::AO_Launcher}
|
|
$define${AOs::Launcher}</text>
|
|
</file>
|
|
</directory>
|
|
</model>
|