... | ... | @@ -84,6 +84,26 @@ enum ExampleTopics : uint8_t |
|
|
Then we can define the MyHSM class and its states, which are identified by the two methods `state_S1`, `state_S2` (which is a super-state) and `state_S3` (which is a sub-state of `state_S2`).
|
|
|
|
|
|
```cpp
|
|
|
#pragma once
|
|
|
|
|
|
#include "events/HSM.h"
|
|
|
#include "events/EventBroker.h"
|
|
|
|
|
|
#define sEventBroker Singleton<EventBroker>::getInstance()
|
|
|
|
|
|
namespace Boardcore {
|
|
|
|
|
|
enum ExampleEvents : uint8_t
|
|
|
{
|
|
|
EV_1 = EV_FIRST_CUSTOM,
|
|
|
EV_2
|
|
|
};
|
|
|
|
|
|
enum ExampleTopics : uint8_t
|
|
|
{
|
|
|
TOPIC_1
|
|
|
};
|
|
|
|
|
|
class MyHSM : public HSM<MyHSM>
|
|
|
{
|
|
|
public:
|
... | ... | @@ -93,20 +113,22 @@ public: |
|
|
last_event(0)
|
|
|
{
|
|
|
// make this object to subscribe to TOPIC_1
|
|
|
sEventBroker->subscribe(this, TOPIC_1);
|
|
|
sEventBroker.subscribe(this, TOPIC_1);
|
|
|
}
|
|
|
|
|
|
~MyHSM()
|
|
|
{
|
|
|
// unsubscribe from all the topics this object was subscribed to
|
|
|
sEventBroker->unsubscribe(this);
|
|
|
sEventBroker.unsubscribe(this);
|
|
|
}
|
|
|
|
|
|
State state_initialization(const Event& ev)
|
|
|
{ // this is just a ficticious state
|
|
|
// that automatically triggers a transition
|
|
|
// to the HSM initial state
|
|
|
UNUSED(ev);
|
|
|
// Common.h defined UNUSED(x) for (void)(x),
|
|
|
// but Common.h was replaced by miosix.h
|
|
|
(void)(ev);
|
|
|
return transition(&MyHSM::state_S1);
|
|
|
}
|
|
|
|
... | ... | @@ -114,7 +136,7 @@ public: |
|
|
{
|
|
|
State ret_state = HANDLED;
|
|
|
|
|
|
switch (ev.sig)
|
|
|
switch (ev)
|
|
|
{
|
|
|
case EV_INIT:
|
|
|
case EV_ENTRY:
|
... | ... | @@ -137,12 +159,12 @@ public: |
|
|
}
|
|
|
default:
|
|
|
{
|
|
|
ret_state = tran_super(&MyHSM::Hsm_top); // no parent state
|
|
|
ret_state = tranSuper(&MyHSM::state_top); // no parent state
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
last_event = ev.sig;
|
|
|
last_event = ev;
|
|
|
|
|
|
return ret_state;
|
|
|
}
|
... | ... | @@ -151,7 +173,7 @@ public: |
|
|
{
|
|
|
State ret_state = HANDLED;
|
|
|
|
|
|
switch (ev.sig)
|
|
|
switch (ev)
|
|
|
{
|
|
|
case EV_INIT:
|
|
|
{
|
... | ... | @@ -173,12 +195,12 @@ public: |
|
|
}
|
|
|
default:
|
|
|
{
|
|
|
ret_state = tran_super(&MyHSM::Hsm_top); // no parent state
|
|
|
ret_state = tranSuper(&MyHSM::state_top); // no parent state
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
last_event = ev.sig;
|
|
|
last_event = ev;
|
|
|
|
|
|
return ret_state;
|
|
|
}
|
... | ... | @@ -187,7 +209,7 @@ public: |
|
|
{
|
|
|
State ret_state = HANDLED;
|
|
|
|
|
|
switch (ev.sig)
|
|
|
switch (ev)
|
|
|
{
|
|
|
case EV_INIT:
|
|
|
case EV_ENTRY:
|
... | ... | @@ -204,12 +226,12 @@ public: |
|
|
}
|
|
|
default:
|
|
|
{
|
|
|
ret_state = tran_super(&MyHSM::state_S2); // try with parent state S2
|
|
|
ret_state = tranSuper(&MyHSM::state_S2); // try with parent state S2
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
last_event = ev.sig;
|
|
|
last_event = ev;
|
|
|
|
|
|
return ret_state;
|
|
|
}
|
... | ... | @@ -217,53 +239,59 @@ public: |
|
|
private:
|
|
|
uint8_t last_event;
|
|
|
};
|
|
|
|
|
|
} //namespace Boardcore
|
|
|
```
|
|
|
|
|
|
#### test-hsm.cpp
|
|
|
|
|
|
```cpp
|
|
|
#include <Common.h>
|
|
|
#include "MyHSM.h"
|
|
|
#include <miosix.h>
|
|
|
#include "events/MyHSM.h"
|
|
|
|
|
|
#define broker Singleton<EventBroker>::getInstance()
|
|
|
|
|
|
using namespace miosix;
|
|
|
using namespace Boardcore;
|
|
|
|
|
|
int main()
|
|
|
{
|
|
|
EventBroker* broker = EventBroker::getInstance(); // singleton object
|
|
|
broker->start();
|
|
|
broker.start();
|
|
|
|
|
|
MyHSM hsm;
|
|
|
|
|
|
if (hsm.start())
|
|
|
{
|
|
|
// trigger self-loop on state S1
|
|
|
broker->post(Event{EV_1}, TOPIC_1);
|
|
|
broker.post(Event{EV_1}, TOPIC_1);
|
|
|
Thread::sleep(100);
|
|
|
|
|
|
// trigger transition to state S2
|
|
|
// which in turn will automatically
|
|
|
// start from state S3 (the first sub-state)
|
|
|
broker->post(Event{EV_2}, TOPIC_1);
|
|
|
broker.post(Event{EV_2}, TOPIC_1);
|
|
|
Thread::sleep(100);
|
|
|
|
|
|
// trigger self-loop on state S3
|
|
|
broker->post(Event{EV_2}, TOPIC_1);
|
|
|
broker.post(Event{EV_2}, TOPIC_1);
|
|
|
Thread::sleep(100);
|
|
|
|
|
|
// the parent state S2 handles the event
|
|
|
// and triggers transition to state S1
|
|
|
broker->post(Event{EV_1}, TOPIC_1);
|
|
|
broker.post(Event{EV_1}, TOPIC_1);
|
|
|
Thread::sleep(100);
|
|
|
|
|
|
hsm.stop();
|
|
|
broker->stop();
|
|
|
broker.stop();
|
|
|
}
|
|
|
else {
|
|
|
TRACE("Failed to start MyHSM\n");
|
|
|
}
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
```
|
|
|
#### Output
|
|
|
```
|
... | ... | |