Hallo,
Ich probiere gerade QM (QP Modeler) aus.
(http://www.state-machine.com/qm) und finde das Programm bis jetzt 100x
besser als IAR visualSTATE (zumindest für das was ich damit machen
will).
Ich habe als teil eines Projekts eine Statemachine von Hand programmiert
und die ist inzwischen mit ca. 2000 Zeilen Code etwas unübersichtlich
geworden und deswegen schaue ich jetzt nach Programmen um die mir das
modifizieren/warten der Statemachine vereinfachen.
Der Editor von QM funktioniert super und der Quellcode den es generiert
ist im Gegensatz zu IAR visualSTATE auch verständlich und in ein Projekt
integrierbar.
hier der Quelltext den QM aus der Statemachine im Anhang generiert:
1 | /* $(LEDS::Switch) .........................................................*/
|
2 | typedef struct SwitchTag
|
3 | {
|
4 | /* protected: */
|
5 | QFsm super;
|
6 | } Switch;
|
7 |
|
8 | /* protected: */
|
9 | QState Switch_initial(Switch *me, QEvent const *e);
|
10 | QState Switch_AN(Switch *me, QEvent const *e);
|
11 | QState Switch_AUS(Switch *me, QEvent const *e);
|
12 | QState Switch_BLINKEN(Switch *me, QEvent const *e);
|
13 |
|
14 | /* $(LEDS::Switch) .........................................................*/
|
15 | /* $(LEDS::Switch::Statechart) .............................................*/
|
16 | /* @(/1/0/0/0) */
|
17 | QState Switch_initial(Switch *me, QEvent const *e)
|
18 | {
|
19 | return Q_TRAN(&Switch_AN);
|
20 | }
|
21 | /* $(LEDS::Switch::Statechart::AN) .........................................*/
|
22 | QState Switch_AN(Switch *me, QEvent const *e)
|
23 | {
|
24 | switch (e->sig)
|
25 | {
|
26 | case Q_ENTRY_SIG: {
|
27 | SET_BIT( PORTA , BIT1 );
|
28 | return Q_HANDLED();
|
29 | }
|
30 | case SWITCH_SIG: {
|
31 | return Q_TRAN(&Switch_AUS);
|
32 | }
|
33 | }
|
34 | return Q_IGNORED();
|
35 | }
|
36 | /* $(LEDS::Switch::Statechart::AUS) ........................................*/
|
37 | QState Switch_AUS(Switch *me, QEvent const *e)
|
38 | {
|
39 | switch (e->sig)
|
40 | {
|
41 | case Q_ENTRY_SIG: {
|
42 | CLR_BIT( PORTA , BIT1 );
|
43 | return Q_HANDLED();
|
44 | }
|
45 | case SWITCH_SIG: {
|
46 | return Q_TRAN(&Switch_BLINKEN);
|
47 | }
|
48 | }
|
49 | return Q_IGNORED();
|
50 | }
|
51 | /* $(LEDS::Switch::Statechart::BLINKEN) ....................................*/
|
52 | QState Switch_BLINKEN(Switch *me, QEvent const *e)
|
53 | {
|
54 | switch (e->sig)
|
55 | {
|
56 | case Q_ENTRY_SIG: {
|
57 | TOG_BIT( PORTA , BIT1 );
|
58 | return Q_HANDLED();
|
59 | }
|
60 | case SWITCH_SIG: {
|
61 | return Q_TRAN(&Switch_AN);
|
62 | }
|
63 | case TICK_SIG: {
|
64 | return Q_TRAN(&Switch_BLINKEN);
|
65 | }
|
66 | }
|
67 | return Q_IGNORED();
|
68 | }
|
allerdings würde mir ein Quelltext der ungefähr so aufgebaut ist besser
gefallen:
1 | typedef enum
|
2 | {
|
3 | Initial
|
4 | AN
|
5 | AUS
|
6 | BLINKEN
|
7 | }STATE_DEFINITIONS
|
8 |
|
9 | static STATE_DEFINITIONS en_States = Initial;
|
10 |
|
11 | void SWITCH(void)
|
12 | {
|
13 | switch (en_States)
|
14 | {
|
15 | case AN:
|
16 | en_States = AUS;
|
17 | CLR_BIT( PORTA , BIT1 );
|
18 | break;
|
19 |
|
20 | case AUS:
|
21 | en_States = BLINKEN;
|
22 | TOG_BIT( PORTA , BIT1 );
|
23 | break;
|
24 |
|
25 | case BLINKEN:
|
26 | en_States = AN;
|
27 | SET_BIT( PORTA , BIT1 );
|
28 | break;
|
29 | }
|
30 | }
|
31 |
|
32 | void TICK(void)
|
33 | {
|
34 | switch (en_States)
|
35 | {
|
36 | case AN:
|
37 | case AUS:
|
38 | //do nothing
|
39 | break;
|
40 |
|
41 | case BLINKEN:
|
42 | //stay in this State
|
43 | TOG_BIT( PORTA , BIT1 );
|
44 | break;
|
45 | }
|
46 | }
|
kennt vielleicht jemand Tools die Statemachines so umsetzen oder kann
man QM vielleicht so konfigurieren?