用 C++ 为嵌入式系统实现状态机
Implementing a State Machine in C++ for Embedded System
我正在设计一个简单的电机控制器,它可以(至少)4 种状态 - 空闲 - 加速 - 最大速度 - 减速。
我认为尝试实现某种状态机是最好的方法。目前,使用 switch 语句似乎是一个很好的解决方案,因为它很简单,而且它允许我将所有 "motion stuff" 保留在一个对象中(我们称之为 Move)。
这看起来合理吗?任何人都可以建议更合适的方法吗?
我知道有些人更喜欢将每个状态拆分到它的对象中,但是有几个人告诉我在为 MCU 编写代码时要避免继承。
我不会在这里使用继承,不是因为MCU,而是因为继承意味着抽象,4个状态的抽象是不值得的(当然,也有例外)。
您必须决定是否要分离状态上下文。如果否,则将其保留在一个 class 中。如果你最终有很多方法和很多属性,你应该拆分它。
如果需要拆分,请使用状态模式,或者如果状态不多,请保持简单:
为每个状态定义一个class。这个class代表状态行为。不要忘记使用构造函数作为进入点和析构函数作为离开点。
然后定义一个FSMclass来切换状态。 FSM 应该包含一个循环来创建当前状态、运行它、检查它的状态,并在需要时销毁当前状态并创建下一个状态。
示例:
// Idle
class Idle {
public:
Idle() {
// entry point
}
~Idle() {
// leaving point
}
void step() {
// actual work
}
// some getters to examine state
private:
// helper methods
// state attributes (context)
};
class FSM {
public:
void run() {
State current(sIdle);
while (current != sExit) {
switch (current) {
case sIdle: {
Idle ctx;
ctx.step();
// examine state
// get user input or
// call step() again or
// decide next state:
current = Accelerate;
break;
}
...
}
}
我喜欢这种设计的地方是简单,没有仿函数(与状态模式不同),并且当前状态在构造下一个状态之前被销毁。此外,与状态模式不同,状态实现不知道其他状态实现。
并且不要在那里放置任何抽象。还是放那儿,但保留原版再对比。
我正在设计一个简单的电机控制器,它可以(至少)4 种状态 - 空闲 - 加速 - 最大速度 - 减速。
我认为尝试实现某种状态机是最好的方法。目前,使用 switch 语句似乎是一个很好的解决方案,因为它很简单,而且它允许我将所有 "motion stuff" 保留在一个对象中(我们称之为 Move)。
这看起来合理吗?任何人都可以建议更合适的方法吗? 我知道有些人更喜欢将每个状态拆分到它的对象中,但是有几个人告诉我在为 MCU 编写代码时要避免继承。
我不会在这里使用继承,不是因为MCU,而是因为继承意味着抽象,4个状态的抽象是不值得的(当然,也有例外)。
您必须决定是否要分离状态上下文。如果否,则将其保留在一个 class 中。如果你最终有很多方法和很多属性,你应该拆分它。
如果需要拆分,请使用状态模式,或者如果状态不多,请保持简单:
为每个状态定义一个class。这个class代表状态行为。不要忘记使用构造函数作为进入点和析构函数作为离开点。
然后定义一个FSMclass来切换状态。 FSM 应该包含一个循环来创建当前状态、运行它、检查它的状态,并在需要时销毁当前状态并创建下一个状态。
示例:
// Idle
class Idle {
public:
Idle() {
// entry point
}
~Idle() {
// leaving point
}
void step() {
// actual work
}
// some getters to examine state
private:
// helper methods
// state attributes (context)
};
class FSM {
public:
void run() {
State current(sIdle);
while (current != sExit) {
switch (current) {
case sIdle: {
Idle ctx;
ctx.step();
// examine state
// get user input or
// call step() again or
// decide next state:
current = Accelerate;
break;
}
...
}
}
我喜欢这种设计的地方是简单,没有仿函数(与状态模式不同),并且当前状态在构造下一个状态之前被销毁。此外,与状态模式不同,状态实现不知道其他状态实现。
并且不要在那里放置任何抽象。还是放那儿,但保留原版再对比。