diff --git a/CodeTutorials/300-FSM/00-Zustandsbasierte_Systeme.pdf b/CodeTutorials/300-FSM/00-Zustandsbasierte_Systeme.pdf new file mode 100644 index 0000000..61fb7e1 Binary files /dev/null and b/CodeTutorials/300-FSM/00-Zustandsbasierte_Systeme.pdf differ diff --git a/CodeTutorials/300-FSM/10-Statecharts(Marwedel).pdf b/CodeTutorials/300-FSM/10-Statecharts(Marwedel).pdf new file mode 100644 index 0000000..81d6b7e Binary files /dev/null and b/CodeTutorials/300-FSM/10-Statecharts(Marwedel).pdf differ diff --git a/CodeTutorials/300-FSM/20-Harel_Statecharts.pdf b/CodeTutorials/300-FSM/20-Harel_Statecharts.pdf new file mode 100644 index 0000000..8879160 Binary files /dev/null and b/CodeTutorials/300-FSM/20-Harel_Statecharts.pdf differ diff --git a/CodeTutorials/320-FSM_Realisierung/00-FSM-Realisierung.pdf b/CodeTutorials/320-FSM_Realisierung/00-FSM-Realisierung.pdf new file mode 100644 index 0000000..eea281d Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/00-FSM-Realisierung.pdf differ diff --git a/CodeTutorials/320-FSM_Realisierung/10-FSM-Realisierung.pdf b/CodeTutorials/320-FSM_Realisierung/10-FSM-Realisierung.pdf new file mode 100644 index 0000000..8beb42d Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/10-FSM-Realisierung.pdf differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counter.c b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counter.c new file mode 100644 index 0000000..34867eb --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counter.c @@ -0,0 +1,31 @@ +// +// counter.c +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2019 +// + +#include "counter.h" + +static int countValue; + +void cnt_init(int val) +{ + countValue = val; +} + +void cnt_count(int step) +{ + countValue += step; +} + +int cnt_getCounter() +{ + return countValue; +} + +void cnt_setCounter(int val) +{ + countValue = val; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counter.h b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counter.h new file mode 100644 index 0000000..7c4b9a9 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counter.h @@ -0,0 +1,24 @@ +// +// counter.h +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2019 +// + +#ifndef COUNTER_H__ +#define COUNTER_H__ + +void cnt_init(int val); +// initializes counter to val + +void cnt_count(int step); +// counts the counter up (step>0) or down (step<0) by step + +int cnt_getCounter(); +// returns the counter value + +void cnt_setCounter(int val); +// sets the counter to val + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterCtrl.c b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterCtrl.c new file mode 100644 index 0000000..53f1288 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterCtrl.c @@ -0,0 +1,91 @@ +// +// counterCtrl.c +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2019 +// + +#include +#include "counterCtrl.h" +#include "counter.h" + +typedef enum {idleState, // idle state + countUpState, // counting up at each count event + countDownState} // counting down at each count event + State; + +static State currentState = idleState; // holds the current state of the FSM + +void cnt_ctrlInit(int initValue) +{ + currentState = idleState; + cnt_init(initValue); +} + + +void cnt_ctrlProcess(cnt_Event e) +{ + switch (currentState) + { + case idleState: + printf("State: idleState\n"); + if (cnt_evUp == e) + { + // actions + printf("State: idleState, counter = %d\n", cnt_getCounter()); + // state transition + printf("Changing to State: countUpState\n"); + currentState = countUpState; + } + else if (cnt_evDown == e) + { + // actions + printf("State: idleState, counter = %d\n", cnt_getCounter()); + // state transition + printf("Changing to State: countDownState\n"); + currentState = countDownState; + } + break; + + case countUpState: + printf("State: countUpState\n"); + if (cnt_evCount == e) + { + // actions + cnt_count(1); + printf("State: countUpState, counter = %d\n", cnt_getCounter()); + // state transition + } + else if (cnt_evStop == e) + { + // actions + // state transition + printf("Changing to State: idleState\n"); + currentState = idleState; + } + break; + + case countDownState: + printf("State: countDownState\n"); + if (cnt_evCount == e) + { + // actions + cnt_count(-1); + printf("State: countDownState, counter = %d\n", cnt_getCounter()); + // state transition + } + else if (cnt_evStop == e) + { + // actions + // state transition + printf("Changing to State: idleState\n"); + currentState = idleState; + } + break; + + default: + break; + } +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterCtrl.h b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterCtrl.h new file mode 100644 index 0000000..e369bef --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterCtrl.h @@ -0,0 +1,25 @@ +// +// counterCtrl.h +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2019 +// + +#ifndef COUNTERCTRL_H__ +#define COUNTERCTRL_H__ + +typedef enum {cnt_evUp, // count upwards + cnt_evDown, // count downwards + cnt_evCount, // count (up or down) + cnt_evStop} // stop counting + cnt_Event; + +void cnt_ctrlInit(int initValue); +// initializes counter FSM + +void cnt_ctrlProcess(cnt_Event e); +// changes the state of the FSM based on the event 'e' +// starts the actions + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest new file mode 100644 index 0000000..f9aa282 Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest.c b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest.c new file mode 100644 index 0000000..7d5d327 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest.c @@ -0,0 +1,53 @@ +// +// counterTest.c +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2019 +// + +#include +#include "counterCtrl.h" + +int main(void) +{ + char answer; + + cnt_ctrlInit(0); + + do + { + printf("\n-------------------------------------------\n"); + printf(" u Count up\n"); + printf(" d Count down\n"); + printf(" c Count\n"); + printf(" s Stop counting\n"); + printf(" q Quit\n"); + + printf("\nPlease press key: "); + scanf("%c", &answer); + getchar(); // nach scanf() ist noch ein '\n' im Inputbuffer: auslesen und wegwerfen + printf("\n"); + + switch (answer) + { + case 'u': + cnt_ctrlProcess(cnt_evUp); + break; + case 'd': + cnt_ctrlProcess(cnt_evDown); + break; + case 'c': + cnt_ctrlProcess(cnt_evCount); + break; + case 's': + cnt_ctrlProcess(cnt_evStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest.c~ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest.c~ new file mode 100644 index 0000000..a3a2611 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/counterTest.c~ @@ -0,0 +1,53 @@ +// +// counterTest.c +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2014 +// + +#include +#include "counterCtrl.h" + +int main(void) +{ + char answer; + + cntCtrlInit(0); + + do + { + printf("\n-------------------------------------------\n"); + printf(" u Count up\n"); + printf(" d Count down\n"); + printf(" c Count\n"); + printf(" s Stop counting\n"); + printf(" q Quit\n"); + + printf("\nPlease press key: "); + scanf("%c", &answer); +// getchar(); // nach scanf() ist noch ein '\n' im Inputbuffer: auslesen und wegwerfen + printf("\n"); + + switch (answer) + { + case 'u': + cntCtrlProcess(cntEvUp); + break; + case 'd': + cntCtrlProcess(cntEvDown); + break; + case 'c': + cntCtrlProcess(cntEvCount); + break; + case 's': + cntCtrlProcess(cntEvStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/makefile b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/makefile new file mode 100644 index 0000000..6818838 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_C/makefile @@ -0,0 +1,29 @@ +# +# Makefile fuer Counter-Programm +# File: makefile +# Reto Bonderer, 24.11.2010 +# +CC = gcc +LINK = gcc +# '-pedantic' sorgt dafuer, dass gcc streng arbeitet +#CFLAGS = -c -pedantic +#LFLAGS = -pedantic +CFLAGS = -c -Wall +LFLAGS = -Wall +OBJS = counter.o counterCtrl.o counterTest.o +EXE = counterTest + +$(EXE): $(OBJS) + $(LINK) $(LFLAGS) -o $(EXE) $(OBJS) + +counterTest.o: counterTest.c counterCtrl.h + $(CC) $(CFLAGS) counterTest.c + +counter.o: counter.c counter.h + $(CC) $(CFLAGS) counter.c + +counterCtrl.o: counterCtrl.c counterCtrl.h counter.h + $(CC) $(CFLAGS) counterCtrl.c + +clean: + rm -f $(EXE) $(OBJS) diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/Counter.cpp b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/Counter.cpp new file mode 100644 index 0000000..2054287 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/Counter.cpp @@ -0,0 +1,28 @@ +// +// Counter.cpp +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include "Counter.h" + +Counter::Counter(int val): countValue(val) +{ +} + +void Counter::count(int step) +{ + countValue += step; +} + +int Counter::getCounter() const +{ + return countValue; +} + +void Counter::setCounter(int val) +{ + countValue = val; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/Counter.h b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/Counter.h new file mode 100644 index 0000000..a00c2b7 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/Counter.h @@ -0,0 +1,29 @@ +// +// Counter.h +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTER_H__ +#define COUNTER_H__ + +class Counter +{ + public: + Counter(int val = 0); + + void count(int step); + // counts the counter up (step>0) or down (step<0) by step + + int getCounter() const; + // returns the counter value + + void setCounter(int val); + // sets the counter to val + private: + int countValue; +}; + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/CounterCtrl.cpp b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/CounterCtrl.cpp new file mode 100644 index 0000000..679258c --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/CounterCtrl.cpp @@ -0,0 +1,84 @@ +// +// CounterCtrl.cpp +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include +#include "CounterCtrl.h" +#include "Counter.h" +using namespace std; + +CounterCtrl::CounterCtrl(int initValue) : + currentState(idleState), + myCounter(initValue) +{ +} + +void CounterCtrl::process(Event e) +{ + switch (currentState) + { + case idleState: + cout << "State: idleState" << endl; + if (evUp == e) + { + // actions + cout << "State: idleState, counter = " << myCounter.getCounter() << endl; + // state transition + cout << "Changing to State: countUpState" << endl; + currentState = countUpState; + } + else if (evDown == e) + { + // actions + cout << "State: idleState, counter = " << myCounter.getCounter() << endl; + // state transition + cout << "Changing to State: countDownState" << endl; + currentState = countDownState; + } + break; + + case countUpState: + cout << "State: countUpState" << endl; + if (evCount == e) + { + // actions + myCounter.count(1); + cout << "State: countUpState, counter = " << myCounter.getCounter() << endl; + // state transition + } + else if (evStop == e) + { + // actions + // state transition + cout << "Changing to State: idleState" << endl; + currentState = idleState; + } + break; + + case countDownState: + cout << "State: countDownState" << endl; + if (evCount == e) + { + // actions + myCounter.count(-1); + cout << "State: countDownState, counter = " << myCounter.getCounter() << endl; + // state transition + } + else if (evStop == e) + { + // actions + // state transition + cout << "Changing to State: idleState" << endl; + currentState = idleState; + } + break; + + default: + break; + } +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/CounterCtrl.h b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/CounterCtrl.h new file mode 100644 index 0000000..4ad29c8 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/CounterCtrl.h @@ -0,0 +1,33 @@ +// +// CounterCtrl.h +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTERCTRL_H__ +#define COUNTERCTRL_H__ +#include "Counter.h" + +class CounterCtrl +{ + public: + enum Event{evUp, // count upwards + evDown, // count downwards + evCount, // count (up or down) + evStop}; // stop counting + CounterCtrl(int initValue = 0); + void process(Event e); + // changes the state of the FSM based on the event 'e' + // starts the actions + + private: + enum State{idleState, // idle state + countUpState, // counting up at each count event + countDownState}; // counting down at each count event + + State currentState; // holds the current state of the FSM + Counter myCounter; +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest new file mode 100644 index 0000000..d210c9b Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest.cpp b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest.cpp new file mode 100644 index 0000000..ac3ba85 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest.cpp @@ -0,0 +1,52 @@ +// +// counterTest.cpp +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#include +#include "CounterCtrl.h" +using namespace std; + +int main(void) +{ + char answer; + CounterCtrl myFsm(0); // initValue of counter == 0 + + do + { + cout << endl << "-------------------------------------------" << endl; + cout << " u Count up" << endl; + cout << " d Count down" << endl; + cout << " c Count" << endl; + cout << " s Stop counting" << endl; + cout << " q Quit" << endl; + + cout << endl << "Please press key: "; + cin >> answer; + cout << endl; + + switch (answer) + { + case 'u': + myFsm.process(CounterCtrl::evUp); + break; + case 'd': + myFsm.process(CounterCtrl::evDown); + break; + case 'c': + myFsm.process(CounterCtrl::evCount); + break; + case 's': + myFsm.process(CounterCtrl::evStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest.exe b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest.exe new file mode 100644 index 0000000..a5ebdaa Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/counterTest.exe differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/makefile b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/makefile new file mode 100644 index 0000000..2bea153 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Ctrl_Cpp/makefile @@ -0,0 +1,26 @@ +# +# Makefile fuer Counter-Programm +# File: makefile +# Reto Bonderer, 23.10.2018 +# +CC = g++ +LINK = g++ +CFLAGS = -c -Wall +LFLAGS = -Wall +OBJS = Counter.o CounterCtrl.o counterTest.o +EXE = counterTest + +$(EXE): $(OBJS) + $(LINK) $(LFLAGS) -o $(EXE) $(OBJS) + +counterTest.o: counterTest.cpp CounterCtrl.h + $(CC) $(CFLAGS) counterTest.cpp + +Counter.o: Counter.cpp Counter.h + $(CC) $(CFLAGS) Counter.cpp + +CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h Counter.h + $(CC) $(CFLAGS) CounterCtrl.cpp + +clean: + rm -f $(EXE) $(OBJS) diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/Counter.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern/Counter.cpp new file mode 100644 index 0000000..2054287 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/Counter.cpp @@ -0,0 +1,28 @@ +// +// Counter.cpp +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include "Counter.h" + +Counter::Counter(int val): countValue(val) +{ +} + +void Counter::count(int step) +{ + countValue += step; +} + +int Counter::getCounter() const +{ + return countValue; +} + +void Counter::setCounter(int val) +{ + countValue = val; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/Counter.h b/CodeTutorials/320-FSM_Realisierung/src/Pattern/Counter.h new file mode 100644 index 0000000..0823cd7 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/Counter.h @@ -0,0 +1,29 @@ +// +// Counter.h +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTER_H__ +#define COUNTER_H__ + +class Counter +{ + public: + Counter(int val=0); + + void count(int step); + // counts the counter up (step>0) or down (step<0) by step + + int getCounter() const; + // returns the counter value + + void setCounter(int val); + // sets the counter to val + private: + int countValue; +}; + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterCtrl.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterCtrl.cpp new file mode 100644 index 0000000..bc6915f --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterCtrl.cpp @@ -0,0 +1,22 @@ +// +// CounterCtrl.cpp +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// CounterCtrl is the Context class in the State pattern +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#include "CounterCtrl.h" +#include "CounterState.h" + +CounterCtrl::CounterCtrl(int initValue): + entity(initValue), + pState(IdleState::getInstance()) // initial state +{ +} + +void CounterCtrl::process(Event e) +{ // delegates all requests to CounterState + pState = pState->handle(entity, e); +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterCtrl.h b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterCtrl.h new file mode 100644 index 0000000..6840ee5 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterCtrl.h @@ -0,0 +1,31 @@ +// +// CounterCtrl.h +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#ifndef COUNTERCTRL_H__ +#define COUNTERCTRL_H__ +#include "Counter.h" + +class CounterState; // forward declaration + +class CounterCtrl +// this is the 'Context' class of the State pattern +{ + public: + enum Event{evUp, // count upwards + evDown, // count downwards + evCount, // count (up or down) + evStop}; // stop counting + CounterCtrl(int initValue = 0); + void process(Event e); + // changes the state of the FSM based on the event 'e' + + private: + Counter entity; + CounterState* pState; // holds the current state +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterState.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterState.cpp new file mode 100644 index 0000000..b52f7fa --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterState.cpp @@ -0,0 +1,102 @@ +// +// CounterState.cpp +// +// implements all states of an up/down-Counter +// this file contains all classes of the state machine. +// it may make sense to have separate files for each state +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#include +#include "CounterState.h" +using namespace std; + + +// class CounterState +CounterState* CounterState::changeState(Counter& entity, CounterState* pnewState) +{ + return pnewState; +} + +// class IdleState +IdleState IdleState::instance; +IdleState* IdleState::getInstance() +{ + return &instance; +} + +CounterState* IdleState::handle(Counter& entity, CounterCtrl::Event e) +{ + cout << "State: idleState" << endl; + if (CounterCtrl::evUp == e) + { + // transition actions + cout << "counter = " << entity.getCounter() << endl; + // state transition + return changeState(entity, CountUpState::getInstance()); + } + else if (CounterCtrl::evDown == e) + { + // transition actions + cout << "counter = " << entity.getCounter() << endl; + // state transition + return changeState(entity, CountDownState::getInstance()); + } + return this; +} + +// class CountUpState +CountUpState CountUpState::instance; +CountUpState* CountUpState::getInstance() +{ + return &instance; +} + +CounterState* CountUpState::handle(Counter& entity, CounterCtrl::Event e) +{ + cout << "State: countUpState" << endl; + if (CounterCtrl::evCount == e) + { + // transition actions + entity.count(1); + cout << "counter = " << entity.getCounter() << endl; + // state transition + return changeState(entity, CountUpState::getInstance()); + } + else if (CounterCtrl::evStop == e) + { + // transition actions + // state transition + return changeState(entity, IdleState::getInstance()); + } + return this; +} + + +// class CountDownState +CountDownState CountDownState::instance; +CountDownState* CountDownState::getInstance() +{ + return &instance; +} + +CounterState* CountDownState::handle(Counter& entity, CounterCtrl::Event e) +{ + cout << "State: countDownState" << endl; + if (CounterCtrl::evCount == e) + { + // transition actions + entity.count(-1); + cout << "counter = " << entity.getCounter() << endl; + // state transition + return changeState(entity, CountDownState::getInstance()); + } + else if (CounterCtrl::evStop == e) + { + // transition actions + // state transition + return changeState(entity, IdleState::getInstance()); + } + return this; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterState.h b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterState.h new file mode 100644 index 0000000..0728f21 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/CounterState.h @@ -0,0 +1,53 @@ +// +// CounterState.h +// +// implements an up/down-Counter +// this file contains all classes of the state machine +// it may make sense to have separate files for each state +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, 21.10.2017 +// + +#ifndef COUNTERSTATE_H__ +#define COUNTERSTATE_H__ +#include "CounterCtrl.h" // Events are defined here + +class CounterState // abstract base class +{ + public: + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e) = 0; + // returns new state + protected: // only inherited classes may use these member functions + CounterState* changeState(Counter& entity, CounterState* pnewState); +}; + +class IdleState : public CounterState // it's a singleton +{ + public: + static IdleState* getInstance(); + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e); + private: + IdleState() {}; + static IdleState instance; +}; + +class CountUpState : public CounterState // it's a singleton +{ + public: + static CountUpState* getInstance(); + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e); + private: + CountUpState() {}; + static CountUpState instance; +}; + +class CountDownState : public CounterState // it's a singleton +{ + public: + static CountDownState* getInstance(); + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e); + private: + CountDownState() {}; + static CountDownState instance; +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/counterTest.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern/counterTest.cpp new file mode 100644 index 0000000..db2baba --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/counterTest.cpp @@ -0,0 +1,52 @@ +// +// counterTest.cpp +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include +#include "CounterCtrl.h" +using namespace std; + +int main(void) +{ + char answer; + CounterCtrl myFsm; + + do + { + cout << endl << "-------------------------------------------" << endl; + cout << " u Count up" << endl; + cout << " d Count down" << endl; + cout << " c Count" << endl; + cout << " s Stop counting" << endl; + cout << " q Quit" << endl; + + cout << endl << "Please press key: "; + cin >> answer; + cout << endl; + + switch (answer) + { + case 'u': + myFsm.process(CounterCtrl::evUp); + break; + case 'd': + myFsm.process(CounterCtrl::evDown); + break; + case 'c': + myFsm.process(CounterCtrl::evCount); + break; + case 's': + myFsm.process(CounterCtrl::evStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/counterTest.exe b/CodeTutorials/320-FSM_Realisierung/src/Pattern/counterTest.exe new file mode 100644 index 0000000..09e374c Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Pattern/counterTest.exe differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern/makefile b/CodeTutorials/320-FSM_Realisierung/src/Pattern/makefile new file mode 100644 index 0000000..2efec34 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern/makefile @@ -0,0 +1,29 @@ +# +# Makefile fuer Counter-Programm +# File: makefile +# Reto Bonderer, 21.10.2017 +# +CC = g++ +LINK = g++ +# '-pedantic' sorgt dafuer, dass gcc streng arbeitet +CFLAGS = -c -pedantic -Wall +LFLAGS = -pedantic +OBJS = Counter.o CounterCtrl.o CounterState.o counterTest.o + +counterTest: $(OBJS) + $(LINK) $(LFLAGS) -o counterTest $(OBJS) + +counterTest.o: counterTest.cpp CounterCtrl.h + $(CC) $(CFLAGS) counterTest.cpp + +Counter.o: Counter.cpp Counter.h + $(CC) $(CFLAGS) Counter.cpp + +CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h CounterState.h + $(CC) $(CFLAGS) CounterCtrl.cpp + +CounterState.o: CounterState.cpp CounterState.h Counter.h CounterCtrl.h + $(CC) $(CFLAGS) CounterState.cpp + +clean: + rm -f counterTest $(OBJS) diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/.vscode/settings.json b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/.vscode/settings.json new file mode 100644 index 0000000..38991d9 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "xmemory": "cpp", + "xstring": "cpp" + } +} \ No newline at end of file diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/Counter.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/Counter.cpp new file mode 100644 index 0000000..eb6cdf6 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/Counter.cpp @@ -0,0 +1,28 @@ +// +// Counter.cpp +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#include "Counter.h" + +Counter::Counter(int val): countValue(val) +{ +} + +void Counter::count(int step) +{ + countValue += step; +} + +int Counter::getCounter() const +{ + return countValue; +} + +void Counter::setCounter(int val) +{ + countValue = val; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/Counter.h b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/Counter.h new file mode 100644 index 0000000..7442f76 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/Counter.h @@ -0,0 +1,29 @@ +// +// Counter.h +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#ifndef COUNTER_H__ +#define COUNTER_H__ + +class Counter +{ + public: + Counter(int val=0); + + void count(int step); + // counts the counter up (step>0) or down (step<0) by step + + int getCounter() const; + // returns the counter value + + void setCounter(int val); + // sets the counter to val + private: + int countValue; +}; + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterCtrl.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterCtrl.cpp new file mode 100644 index 0000000..fd638eb --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterCtrl.cpp @@ -0,0 +1,23 @@ +// +// CounterCtrl.cpp +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// CounterCtrl is the Context class in the State pattern +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2018 +// + +#include "Counter.h" +#include "CounterState.h" +#include "CounterCtrl.h" + +CounterCtrl::CounterCtrl(int initValue) : + entity(initValue), + pState(CounterState::init(entity)) // initial state +{ +} + +void CounterCtrl::process(Event e) +{ // delegates all requests to CounterState + pState = pState->handle(entity, e); // entity: reference to entity class object +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterCtrl.h b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterCtrl.h new file mode 100644 index 0000000..3bffe53 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterCtrl.h @@ -0,0 +1,30 @@ +// +// CounterCtrl.h +// +// implements the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2017 +// + +#ifndef COUNTERCTRL_H__ +#define COUNTERCTRL_H__ +#include "Counter.h" + +class CounterState; // forward declaration + +class CounterCtrl +// this is the 'Context' class of the State pattern +{ + public: + enum Event{evUp, // count upwards + evDown, // count downwards + evCount, // count (up or down) + evStop}; // stop counting + CounterCtrl(int initValue = 0); + void process(Event e); + // changes the state of the FSM based on the event 'e' + private: + Counter entity; // entity class + CounterState* pState; // holds the current state +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterState.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterState.cpp new file mode 100644 index 0000000..c41df71 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterState.cpp @@ -0,0 +1,150 @@ +// +// CounterState.cpp +// +// implements all states of an up/down-Counter +// this file contains all classes of the state machine. +// it may make sense to have separate files for each state +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2018 +// + +#include +#include "CounterState.h" +using namespace std; + + +//class CounterState +CounterState* CounterState::init(Counter& entity) // is static +{ + CounterState* initState = IdleState::getInstance(); + initState->entryAction(entity); // executes entry action into init state + return initState; +} + +CounterState* CounterState::changeState(Counter& entity, + Action ptransAction, + CounterState* pnewState) +{ + exitAction(entity); // polymorphic call of exit action + (this->*ptransAction)(entity); // call of transition action + pnewState->entryAction(entity); // polymorphic call of entry action + return pnewState; +} + +void CounterState::showCounter(Counter& entity) +{ + cout << "counter = " << entity.getCounter() << endl; +} + +void CounterState::countUp(Counter& entity) +{ + entity.count(1); + cout << "counter = " << entity.getCounter() << endl; +} + +void CounterState::countDown(Counter& entity) +{ + entity.count(-1); + cout << "counter = " << entity.getCounter() << endl; +} + + +// class IdleState +IdleState IdleState::instance; +IdleState* IdleState::getInstance() +{ + return &instance; +} + +CounterState* IdleState::handle(Counter& entity, CounterCtrl::Event e) +{ + cout << "State: idleState" << endl; + if (CounterCtrl::evUp == e) + { + // state transition + return changeState(entity, &IdleState::showCounter, CountUpState::getInstance()); + } + else if (CounterCtrl::evDown == e) + { + // state transition + return changeState(entity, &IdleState::showCounter, CountDownState::getInstance()); + } + return this; +} + +void IdleState::entryAction(Counter& entity) +{ + cout << "Entering idleState" << endl; +} + +void IdleState::exitAction(Counter& entity) +{ + cout << "Exiting from idleState" << endl; +} + + +// class CountUpState +CountUpState CountUpState::instance; +CountUpState* CountUpState::getInstance() +{ + return &instance; +} + +CounterState* CountUpState::handle(Counter& entity, CounterCtrl::Event e) +{ + cout << "State: countUpState" << endl; + if (CounterCtrl::evCount == e) + { + // state transition + return changeState(entity, &CountUpState::countUp, CountUpState::getInstance()); + } + else if (CounterCtrl::evStop == e) + { + // state transition + return changeState(entity, &CountUpState::emptyAction, IdleState::getInstance()); + } + return this; +} + +void CountUpState::entryAction(Counter& entity) +{ + cout << "Entering countUpState" << endl; +} + +void CountUpState::exitAction(Counter& entity) +{ + cout << "Exiting from countUpState" << endl; +} + +// class CountDownState +CountDownState CountDownState::instance; +CountDownState* CountDownState::getInstance() +{ + return &instance; +} + +CounterState* CountDownState::handle(Counter& entity, CounterCtrl::Event e) +{ + cout << "State: countDownState" << endl; + if (CounterCtrl::evCount == e) + { + // state transition + return changeState(entity, &CountDownState::countDown, CountDownState::getInstance()); + } + else if (CounterCtrl::evStop == e) + { + // state transition + return changeState(entity, &CountDownState::emptyAction, IdleState::getInstance()); + } + return this; +} + +void CountDownState::entryAction(Counter& entity) +{ + cout << "Entering countDownState" << endl; +} + +void CountDownState::exitAction(Counter& entity) +{ + cout << "Exiting from countDownState" << endl; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterState.h b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterState.h new file mode 100644 index 0000000..9e08021 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/CounterState.h @@ -0,0 +1,73 @@ +// +// CounterState.h +// +// implements an up/down-Counter +// this file contains all classes of the state machine +// it may make sense to have separate files for each state +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Oct. 2018 +// + +#ifndef COUNTERSTATE_H__ +#define COUNTERSTATE_H__ +#include "CounterCtrl.h" + +class CounterState // abstract base class +{ + public: + static CounterState* init(Counter& entity); + // should be called first, returns new state + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e) = 0; + // returns new state + protected: + virtual void entryAction(Counter& entity) {}; + virtual void exitAction(Counter& entity) {}; + typedef void (CounterState::*Action)(Counter& entity); // ptr to action function + CounterState* changeState(Counter& entity, Action ptransAction, CounterState* pnewState); + + // transition actions + void emptyAction(Counter& entity) {}; + void showCounter(Counter& entity); + void countUp(Counter& entity); + void countDown(Counter& entity); +}; + +class IdleState : public CounterState // it's a singleton +{ + public: + static IdleState* getInstance(); + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e); + protected: + virtual void entryAction(Counter& entity); + virtual void exitAction(Counter& entity); + private: + IdleState() {}; + static IdleState instance; +}; + +class CountUpState : public CounterState // it's a singleton +{ + public: + static CountUpState* getInstance(); + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e); + protected: + virtual void entryAction(Counter& entity); + virtual void exitAction(Counter& entity); + private: + CountUpState() {}; + static CountUpState instance; +}; + +class CountDownState : public CounterState // it's a singleton +{ + public: + static CountDownState* getInstance(); + virtual CounterState* handle(Counter& entity, CounterCtrl::Event e); + protected: + virtual void entryAction(Counter& entity); + virtual void exitAction(Counter& entity); + private: + CountDownState() {}; + static CountDownState instance; +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/counterTest.cpp b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/counterTest.cpp new file mode 100644 index 0000000..e2be939 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/counterTest.cpp @@ -0,0 +1,52 @@ +// +// counterTest.cpp +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Nov. 2017 +// + +#include +#include "CounterCtrl.h" +using namespace std; + +int main(void) +{ + char answer; + CounterCtrl myFsm; + + do + { + cout << endl << "-------------------------------------------" << endl; + cout << " u Count up" << endl; + cout << " d Count down" << endl; + cout << " c Count" << endl; + cout << " s Stop counting" << endl; + cout << " q Quit" << endl; + + cout << endl << "Please press key: "; + cin >> answer; + cout << endl; + + switch (answer) + { + case 'u': + myFsm.process(CounterCtrl::evUp); + break; + case 'd': + myFsm.process(CounterCtrl::evDown); + break; + case 'c': + myFsm.process(CounterCtrl::evCount); + break; + case 's': + myFsm.process(CounterCtrl::evStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/makefile b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/makefile new file mode 100644 index 0000000..7c653f0 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Pattern_Action/makefile @@ -0,0 +1,30 @@ +# +# Makefile fuer Counter-Programm +# File: makefile +# Reto Bonderer, 21.10.2017 +# +CC = g++ +LINK = g++ +# '-pedantic' sorgt dafuer, dass g++ streng arbeitet +CFLAGS = -c -pedantic -Wall +LFLAGS = -pedantic +OBJS = Counter.o CounterCtrl.o CounterState.o counterTest.o +EXE = counterTest + +$(EXE): $(OBJS) + $(LINK) $(LFLAGS) -o $(EXE) $(OBJS) + +counterTest.o: counterTest.cpp CounterCtrl.h + $(CC) $(CFLAGS) counterTest.cpp + +Counter.o: Counter.cpp Counter.h + $(CC) $(CFLAGS) Counter.cpp + +CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h CounterState.h + $(CC) $(CFLAGS) CounterCtrl.cpp + +CounterState.o: CounterState.cpp CounterState.h Counter.h + $(CC) $(CFLAGS) CounterState.cpp + +clean: + rm -f $(EXE) $(OBJS) diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/Counter.cpp b/CodeTutorials/320-FSM_Realisierung/src/Table/Counter.cpp new file mode 100644 index 0000000..2054287 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table/Counter.cpp @@ -0,0 +1,28 @@ +// +// Counter.cpp +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include "Counter.h" + +Counter::Counter(int val): countValue(val) +{ +} + +void Counter::count(int step) +{ + countValue += step; +} + +int Counter::getCounter() const +{ + return countValue; +} + +void Counter::setCounter(int val) +{ + countValue = val; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/Counter.h b/CodeTutorials/320-FSM_Realisierung/src/Table/Counter.h new file mode 100644 index 0000000..84e2055 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table/Counter.h @@ -0,0 +1,29 @@ +// +// Counter.h +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTER_H__ +#define COUNTER_H__ + +class Counter +{ + public: + Counter(int val); + + void count(int step); + // counts the counter up (step>0) or down (step<0) by step + + int getCounter() const; + // returns the counter value + + void setCounter(int val); + // sets the counter to val + private: + int countValue; +}; + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/CounterCtrl.cpp b/CodeTutorials/320-FSM_Realisierung/src/Table/CounterCtrl.cpp new file mode 100644 index 0000000..10772c9 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table/CounterCtrl.cpp @@ -0,0 +1,104 @@ +// +// CounterCtrl.cpp +// +// implements the Finite State Machine (FSM) of an up/down-Counter as a table +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include +#include "CounterCtrl.h" +#include "Counter.h" +using namespace std; + +const CounterCtrl::Transition CounterCtrl::fsm[] = // this table defines the fsm +{//currentState checker function action function next state + {idleState, &CounterCtrl::checkIdleUp, &CounterCtrl::actionIdleUp, countUpState}, + {idleState, &CounterCtrl::checkIdleDown, &CounterCtrl::actionIdleDown, countDownState}, + {countUpState, &CounterCtrl::checkUpUp, &CounterCtrl::actionUpUp, countUpState}, + {countUpState, &CounterCtrl::checkUpIdle, &CounterCtrl::actionUpIdle, idleState}, + {countDownState, &CounterCtrl::checkDownDown, &CounterCtrl::actionDownDown, countDownState}, + {countDownState, &CounterCtrl::checkDownIdle, &CounterCtrl::actionDownIdle, idleState} +}; + +CounterCtrl::CounterCtrl(int initValue) : + currentState(idleState), + myCounter(initValue) +{ +} + +void CounterCtrl::process(Event e) // this function never changes +{ + for (size_t i = 0; i < sizeof(fsm) / sizeof(Transition); ++i) // let compiler determine number of transitions + { + if (fsm[i].currentState == currentState && // is there an entry in the table? + (this->*fsm[i].pChecker)(e)) + { + (this->*fsm[i].pAction)(); + currentState = fsm[i].nextState; + break; + } + } +} + +// check functions +bool CounterCtrl::checkIdleUp(Event e) +{ + return evUp == e; +} + +bool CounterCtrl::checkIdleDown(Event e) +{ + return evDown == e; +} + +bool CounterCtrl::checkUpIdle(Event e) +{ + return evStop == e; +} + +bool CounterCtrl::checkDownIdle(Event e) +{ + return evStop == e; +} + +bool CounterCtrl::checkUpUp(Event e) +{ + return evCount == e; +} + +bool CounterCtrl::checkDownDown(Event e) +{ + return evCount == e; +} + +// action functions +void CounterCtrl::actionIdleUp(void) +{ + cout << "State: idleState, counter = " << myCounter.getCounter() << endl; +} + +void CounterCtrl::actionIdleDown(void) +{ + cout << "State: idleState, counter = " << myCounter.getCounter() << endl; +} + +void CounterCtrl::actionUpIdle(void) +{ +} + +void CounterCtrl::actionDownIdle(void) +{ +} + +void CounterCtrl::actionUpUp(void) +{ + myCounter.count(1); + cout << "State: countUpState, counter = " << myCounter.getCounter() << endl; +} + +void CounterCtrl::actionDownDown(void) +{ + myCounter.count(-1); + cout << "State: countDownState, counter = " << myCounter.getCounter() << endl; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/CounterCtrl.h b/CodeTutorials/320-FSM_Realisierung/src/Table/CounterCtrl.h new file mode 100644 index 0000000..248cdde --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table/CounterCtrl.h @@ -0,0 +1,60 @@ +// +// CounterCtrl.h +// +// implements the Finite State Machine (FSM) of an up/down-Counter as a table +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTERCTRL_H__ +#define COUNTERCTRL_H__ +#include "Counter.h" + +class CounterCtrl +{ + public: + enum Event{evUp, // count upwards + evDown, // count downwards + evCount, // count (up or down) + evStop}; // stop counting + CounterCtrl(int initValue = 0); + void process(Event e); + // changes the state of the FSM based on the event 'e' + // starts the actions + + private: + enum State{idleState, // idle state + countUpState, // counting up at each count event + countDownState}; // counting down at each count event + + State currentState; // holds the current state of the FSM + Counter myCounter; + + typedef bool (CounterCtrl::*Checker)(Event); // function ptr for checker function + typedef void (CounterCtrl::*Action)(void); // function ptr for action function + // check functions + bool checkIdleUp(Event e); + bool checkIdleDown(Event e); + bool checkUpIdle(Event e); + bool checkDownIdle(Event e); + bool checkUpUp(Event e); + bool checkDownDown(Event e); + + // action functions + void actionIdleUp(void); + void actionIdleDown(void); + void actionUpIdle(void); + void actionDownIdle(void); + void actionUpUp(void); + void actionDownDown(void); + + struct Transition + { + State currentState; // current state + Checker pChecker; // pointer to checker function + Action pAction; // pointer to action function + State nextState; // next state + }; + static const Transition fsm[]; +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest b/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest new file mode 100644 index 0000000..f5b1d62 Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest.cpp b/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest.cpp new file mode 100644 index 0000000..a66cdfc --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest.cpp @@ -0,0 +1,52 @@ +// +// counterTest.cpp +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include +#include "CounterCtrl.h" +using namespace std; + +int main(void) +{ + char answer; + CounterCtrl myFsm(0); + + do + { + cout << endl << "-------------------------------------------" << endl; + cout << " u Count up" << endl; + cout << " d Count down" << endl; + cout << " c Count" << endl; + cout << " s Stop counting" << endl; + cout << " q Quit" << endl; + + cout << endl << "Please press key: "; + cin >> answer; + cout << endl; + + switch (answer) + { + case 'u': + myFsm.process(CounterCtrl::evUp); + break; + case 'd': + myFsm.process(CounterCtrl::evDown); + break; + case 'c': + myFsm.process(CounterCtrl::evCount); + break; + case 's': + myFsm.process(CounterCtrl::evStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest.exe b/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest.exe new file mode 100644 index 0000000..6f4a055 Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Table/counterTest.exe differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table/makefile b/CodeTutorials/320-FSM_Realisierung/src/Table/makefile new file mode 100644 index 0000000..dac2246 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table/makefile @@ -0,0 +1,26 @@ +# +# Makefile fuer Counter-Programm +# File: makefile +# Reto Bonderer, 07.10.2017 +# +CC = g++ +LINK = g++ +CFLAGS = -c -Wall +LFLAGS = -Wall +OBJS = Counter.o CounterCtrl.o counterTest.o +EXE = counterTest + +$(EXE): $(OBJS) + $(LINK) $(LFLAGS) -o $(EXE) $(OBJS) + +counterTest.o: counterTest.cpp CounterCtrl.h + $(CC) $(CFLAGS) counterTest.cpp + +Counter.o: Counter.cpp Counter.h + $(CC) $(CFLAGS) Counter.cpp + +CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h Counter.h + $(CC) $(CFLAGS) CounterCtrl.cpp + +clean: + rm -f $(EXE) $(OBJS) diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/Counter.cpp b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/Counter.cpp new file mode 100644 index 0000000..2054287 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/Counter.cpp @@ -0,0 +1,28 @@ +// +// Counter.cpp +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include "Counter.h" + +Counter::Counter(int val): countValue(val) +{ +} + +void Counter::count(int step) +{ + countValue += step; +} + +int Counter::getCounter() const +{ + return countValue; +} + +void Counter::setCounter(int val) +{ + countValue = val; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/Counter.h b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/Counter.h new file mode 100644 index 0000000..84e2055 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/Counter.h @@ -0,0 +1,29 @@ +// +// Counter.h +// +// implements an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTER_H__ +#define COUNTER_H__ + +class Counter +{ + public: + Counter(int val); + + void count(int step); + // counts the counter up (step>0) or down (step<0) by step + + int getCounter() const; + // returns the counter value + + void setCounter(int val); + // sets the counter to val + private: + int countValue; +}; + +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/CounterCtrl.cpp b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/CounterCtrl.cpp new file mode 100644 index 0000000..9d8134d --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/CounterCtrl.cpp @@ -0,0 +1,69 @@ +// +// CounterCtrl.cpp +// +// implements the Finite State Machine (FSM) of an up/down-Counter as a simple table +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include +#include "CounterCtrl.h" +#include "Counter.h" +using namespace std; + +const CounterCtrl::Transition CounterCtrl::fsm[] = // this table defines the fsm +{//currentState triggering event action function next state + {idleState, evUp, &CounterCtrl::actionIdleUp, countUpState}, + {idleState, evDown, &CounterCtrl::actionIdleDown, countDownState}, + {countUpState, evCount, &CounterCtrl::actionUpUp, countUpState}, + {countUpState, evStop, &CounterCtrl::actionDoNothing, idleState}, + {countDownState, evCount, &CounterCtrl::actionDownDown, countDownState}, + {countDownState, evStop, &CounterCtrl::actionDoNothing, idleState} +}; + +CounterCtrl::CounterCtrl(int initValue) : + currentState(idleState), + myCounter(initValue) +{ +} + +void CounterCtrl::process(Event e) // execution engine, this function never changes +{ + for (size_t i = 0; i < sizeof(fsm) / sizeof(Transition); ++i) // determine number of transitions automatically + { + if (fsm[i].currentState == currentState && fsm[i].ev == e) // is there an entry in the table? + { + (this->*fsm[i].pAction)(); + currentState = fsm[i].nextState; + break; + } + } +} + + +// action functions +void CounterCtrl::actionIdleUp(void) +{ + cout << "State: idleState, counter = " << myCounter.getCounter() << endl; +} + +void CounterCtrl::actionIdleDown(void) +{ + cout << "State: idleState, counter = " << myCounter.getCounter() << endl; +} + +void CounterCtrl::actionDoNothing(void) +{ +} + +void CounterCtrl::actionUpUp(void) +{ + myCounter.count(1); + cout << "State: countUpState, counter = " << myCounter.getCounter() << endl; +} + +void CounterCtrl::actionDownDown(void) +{ + myCounter.count(-1); + cout << "State: countDownState, counter = " << myCounter.getCounter() << endl; +} diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/CounterCtrl.h b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/CounterCtrl.h new file mode 100644 index 0000000..986fe20 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/CounterCtrl.h @@ -0,0 +1,51 @@ +// +// CounterCtrl.h +// +// implements the Finite State Machine (FSM) of an up/down-Counter as a simple table +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#ifndef COUNTERCTRL_H__ +#define COUNTERCTRL_H__ +#include "Counter.h" + +class CounterCtrl +{ + public: + enum Event{evUp, // count upwards + evDown, // count downwards + evCount, // count (up or down) + evStop}; // stop counting + CounterCtrl(int initValue = 0); + void process(Event e); + // changes the state of the FSM based on the event 'e' + // starts the actions + + private: + enum State{idleState, // idle state + countUpState, // counting up at each count event + countDownState}; // counting down at each count event + + State currentState; // holds the current state of the FSM + Counter myCounter; + + typedef void (CounterCtrl::*Action)(void); // function ptr for action function + + // action functions + void actionIdleUp(void); + void actionIdleDown(void); + void actionDoNothing(void); + void actionUpUp(void); + void actionDownDown(void); + + struct Transition + { + State currentState; // current state + Event ev; // event triggering the transition + Action pAction; // pointer to action function + State nextState; // next state + }; + static const Transition fsm[]; +}; +#endif diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/counterTest b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/counterTest new file mode 100644 index 0000000..bd911fa Binary files /dev/null and b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/counterTest differ diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/counterTest.cpp b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/counterTest.cpp new file mode 100644 index 0000000..db2baba --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/counterTest.cpp @@ -0,0 +1,52 @@ +// +// counterTest.cpp +// +// Test program for the Finite State Machine (FSM) of an up/down-Counter +// +// (C) R. Bonderer, HSR Hochschule Rapperswil, Okt. 2017 +// + +#include +#include "CounterCtrl.h" +using namespace std; + +int main(void) +{ + char answer; + CounterCtrl myFsm; + + do + { + cout << endl << "-------------------------------------------" << endl; + cout << " u Count up" << endl; + cout << " d Count down" << endl; + cout << " c Count" << endl; + cout << " s Stop counting" << endl; + cout << " q Quit" << endl; + + cout << endl << "Please press key: "; + cin >> answer; + cout << endl; + + switch (answer) + { + case 'u': + myFsm.process(CounterCtrl::evUp); + break; + case 'd': + myFsm.process(CounterCtrl::evDown); + break; + case 'c': + myFsm.process(CounterCtrl::evCount); + break; + case 's': + myFsm.process(CounterCtrl::evStop); + break; + default: + break; + } + } while (answer != 'q'); + + return 0; +} + diff --git a/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/makefile b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/makefile new file mode 100644 index 0000000..dac2246 --- /dev/null +++ b/CodeTutorials/320-FSM_Realisierung/src/Table_Simple/makefile @@ -0,0 +1,26 @@ +# +# Makefile fuer Counter-Programm +# File: makefile +# Reto Bonderer, 07.10.2017 +# +CC = g++ +LINK = g++ +CFLAGS = -c -Wall +LFLAGS = -Wall +OBJS = Counter.o CounterCtrl.o counterTest.o +EXE = counterTest + +$(EXE): $(OBJS) + $(LINK) $(LFLAGS) -o $(EXE) $(OBJS) + +counterTest.o: counterTest.cpp CounterCtrl.h + $(CC) $(CFLAGS) counterTest.cpp + +Counter.o: Counter.cpp Counter.h + $(CC) $(CFLAGS) Counter.cpp + +CounterCtrl.o: CounterCtrl.cpp CounterCtrl.h Counter.h + $(CC) $(CFLAGS) CounterCtrl.cpp + +clean: + rm -f $(EXE) $(OBJS) diff --git a/CodeTutorials/600-Advanced-C++/00-Advanced_and_Effective-C++.pdf b/CodeTutorials/600-Advanced-C++/00-Advanced_and_Effective-C++.pdf new file mode 100644 index 0000000..cd82cd1 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/00-Advanced_and_Effective-C++.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/10-effCppEmbNotes2015-04-02.pdf b/CodeTutorials/600-Advanced-C++/10-effCppEmbNotes2015-04-02.pdf new file mode 100644 index 0000000..7da45e6 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/10-effCppEmbNotes2015-04-02.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/15-Optimizing Code for Stellaris.pdf b/CodeTutorials/600-Advanced-C++/15-Optimizing Code for Stellaris.pdf new file mode 100644 index 0000000..b3ec4b6 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/15-Optimizing Code for Stellaris.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/20-Implementing_Virtual_Functions.pdf b/CodeTutorials/600-Advanced-C++/20-Implementing_Virtual_Functions.pdf new file mode 100644 index 0000000..8d91c5e Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/20-Implementing_Virtual_Functions.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/30-Avoiding_Code_Data_Bloat.pdf b/CodeTutorials/600-Advanced-C++/30-Avoiding_Code_Data_Bloat.pdf new file mode 100644 index 0000000..979f9b6 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/30-Avoiding_Code_Data_Bloat.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/40-Interface_Based_Programming.pdf b/CodeTutorials/600-Advanced-C++/40-Interface_Based_Programming.pdf new file mode 100644 index 0000000..ae2c917 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/40-Interface_Based_Programming.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/50-Dynamic_Memory_Management.pdf b/CodeTutorials/600-Advanced-C++/50-Dynamic_Memory_Management.pdf new file mode 100644 index 0000000..3f93cd4 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/50-Dynamic_Memory_Management.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/60-C++_and_ROMability.pdf b/CodeTutorials/600-Advanced-C++/60-C++_and_ROMability.pdf new file mode 100644 index 0000000..eb112a3 Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/60-C++_and_ROMability.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/70-Modeling_MMIO.pdf b/CodeTutorials/600-Advanced-C++/70-Modeling_MMIO.pdf new file mode 100644 index 0000000..894e2ad Binary files /dev/null and b/CodeTutorials/600-Advanced-C++/70-Modeling_MMIO.pdf differ diff --git a/CodeTutorials/600-Advanced-C++/src/TIHeaders/stdint.h b/CodeTutorials/600-Advanced-C++/src/TIHeaders/stdint.h new file mode 100644 index 0000000..cbebffb --- /dev/null +++ b/CodeTutorials/600-Advanced-C++/src/TIHeaders/stdint.h @@ -0,0 +1,194 @@ +/*****************************************************************************/ +/* STDINT.H v5.2.1 */ +/* Copyright (c) 2002-2009 Texas Instruments Incorporated */ +/*****************************************************************************/ +#ifndef _STDINT_H_ +#define _STDINT_H_ + +/* 7.18.1.1 Exact-width integer types */ + + typedef int int16_t; + typedef unsigned int uint16_t; + typedef long int32_t; + typedef unsigned long uint32_t; + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + typedef long long int64_t; + typedef unsigned long long uint64_t; +#endif + +/* 7.18.1.2 Minimum-width integer types */ + + typedef int16_t int_least8_t; + typedef uint16_t uint_least8_t; + + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; +#else +/* sorry, int_least64_t not implemented for C54x, C55x, MSP430 */ +#endif + +/* 7.18.1.3 Fastest minimum-width integer types */ + + typedef int16_t int_fast8_t; + typedef uint16_t uint_fast8_t; + typedef int16_t int_fast16_t; + typedef uint16_t uint_fast16_t; + + typedef int32_t int_fast32_t; + typedef uint32_t uint_fast32_t; + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + typedef int64_t int_fast64_t; + typedef uint64_t uint_fast64_t; +#endif + +/* 7.18.1.4 Integer types capable of holding object pointers */ + typedef long intptr_t; + typedef unsigned long uintptr_t; + +/* 7.18.1.5 Greatest-width integer types */ +#if defined(__TMS320C55X__) || defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + typedef long long intmax_t; + typedef unsigned long long uintmax_t; +#elif defined(_TMS320C5XX) || defined(__TMS320C27X__) || defined(__MSP430__) + typedef long intmax_t; + typedef unsigned long uintmax_t; +#endif + +/* + According to footnotes in the 1999 C standard, "C++ implementations + should define these macros only when __STDC_LIMIT_MACROS is defined + before is included." +*/ +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) + +/* 7.18.2 Limits of specified width integer types */ + + + #define INT16_MAX 0x7fff + #define INT16_MIN (-INT16_MAX-1) + #define UINT16_MAX 0xffff + + #define INT32_MAX 0x7fffffff + #define INT32_MIN (-INT32_MAX-1) + #define UINT32_MAX 0xffffffff + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + #define INT64_MAX 0x7fffffffffffffff + #define INT64_MIN (-INT64_MAX-1) + #define UINT64_MAX 0xffffffffffffffff +#endif + + #define INT_LEAST8_MAX INT16_MAX + #define INT_LEAST8_MIN INT16_MIN + #define UINT_LEAST8_MAX UINT16_MAX + + #define INT_LEAST16_MAX INT16_MAX + #define INT_LEAST16_MIN INT16_MIN + #define UINT_LEAST16_MAX UINT16_MAX + #define INT_LEAST32_MAX INT32_MAX + #define INT_LEAST32_MIN INT32_MIN + #define UINT_LEAST32_MAX UINT32_MAX + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + #define INT_LEAST64_MAX INT64_MAX + #define INT_LEAST64_MIN INT64_MIN + #define UINT_LEAST64_MAX UINT64_MAX +#endif + + #define INT_FAST8_MAX INT16_MAX + #define INT_FAST8_MIN INT16_MIN + #define UINT_FAST8_MAX UINT16_MAX + #define INT_FAST16_MAX INT16_MAX + #define INT_FAST16_MIN INT16_MIN + #define UINT_FAST16_MAX UINT16_MAX + + #define INT_FAST32_MAX INT32_MAX + #define INT_FAST32_MIN INT32_MIN + #define UINT_FAST32_MAX UINT32_MAX + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + #define INT_FAST64_MAX INT64_MAX + #define INT_FAST64_MIN INT64_MIN + #define UINT_FAST64_MAX UINT64_MAX +#endif + + #define INTPTR_MAX INT32_MAX + #define INTPTR_MIN INT32_MIN + #define UINTPTR_MAX UINT32_MAX + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + #define INTMAX_MIN INT64_MIN + #define INTMAX_MAX INT64_MAX + #define UINTMAX_MAX UINT64_MAX +#elif defined(_TMS320C5XX) || defined(__TMS320C27X__) || defined(__MSP430__) + #define INTMAX_MIN INT32_MIN + #define INTMAX_MAX INT32_MAX + #define UINTMAX_MAX UINT32_MAX +#endif + +/* 7.18.3 Limits of other integer types */ + + #define PTRDIFF_MAX INT32_MAX + #define PTRDIFF_MIN INT32_MIN + + #define SIG_ATOMIC_MIN INT32_MIN + #define SIG_ATOMIC_MAX INT32_MAX + + #define SIZE_MAX INT32_MAX + +#ifndef WCHAR_MAX +#define WCHAR_MAX 0xffffu +#endif + +#ifndef WCHAR_MIN +#define WCHAR_MIN 0 +#endif + + #define WINT_MIN INT32_MIN + #define WINT_MAX INT32_MAX + +/* 7.18.4.1 Macros for minimum-width integer constants */ + +/* + There is a defect report filed against the C99 standard concerning how + the (U)INTN_C macros should be implemented. Please refer to -- + http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_209.htm + for more information. These macros are implemented according to the + suggestion given at this web site. +*/ + + #define INT8_C(value) ((int_least8_t)(value)) + #define UINT8_C(value) ((uint_least8_t)(value)) + #define INT16_C(value) ((int_least16_t)(value)) + #define UINT16_C(value) ((uint_least16_t)(value)) + #define INT32_C(value) ((int_least32_t)(value)) + #define UINT32_C(value) ((uint_least32_t)(value)) + + +#if defined(__TMS470__) || defined(_TMS320C6X) || defined(__TMS320C28X__) + #define INT64_C(value) ((int_least64_t)(value)) + #define UINT64_C(value) ((uint_least64_t)(value)) +#endif + +/* 7.18.4.2 Macros for greatest-width integer constants */ + + #define INTMAX_C(value) ((intmax_t)(value)) + #define UINTMAX_C(value) ((uintmax_t)(value)) + +#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ + +#endif /* _STDINT_H_ */