Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
I am just wondering if anyone know of some good tutorials on the Internet for developing state machines. Or ebooks?
I am starting working on state machines and just need something general to get me started.
State machines are very simple in C if you use function pointers.
Basically you need 2 arrays - one for state function pointers and one for state transition rules. Every state function returns the code, you lookup state transition table by state and return code to find the next state and then just execute it.
int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);
/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};
enum ret_codes { ok, fail, repeat};
struct transition {
enum state_codes src_state;
enum ret_codes ret_code;
enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
{entry, ok, foo},
{entry, fail, end},
{foo, ok, bar},
{foo, fail, end},
{foo, repeat, foo},
{bar, ok, end},
{bar, fail, end},
{bar, repeat, foo}};
#define EXIT_STATE end
#define ENTRY_STATE entry
int main(int argc, char *argv[]) {
enum state_codes cur_state = ENTRY_STATE;
enum ret_codes rc;
int (* state_fun)(void);
for (;;) {
state_fun = state[cur_state];
rc = state_fun();
if (EXIT_STATE == cur_state)
break;
cur_state = lookup_transitions(cur_state, rc);
}
return EXIT_SUCCESS;
}
I don't put lookup_transitions() function as it is trivial.
That's the way I do state machines for years.
I prefer using function pointers over gigantic switch statements, but in contrast to qrdl's answer I normally don't use explicit return codes or transition tables.
Also, in most cases you'll want a mechanism to pass along additional data. Here's an example state machine:
#include <stdio.h>
struct state;
typedef void state_fn(struct state *);
struct state
{
state_fn * next;
int i; // data
};
state_fn foo, bar;
void foo(struct state * state)
{
printf("%s %i\n", __func__, ++state->i);
state->next = bar;
}
void bar(struct state * state)
{
printf("%s %i\n", __func__, ++state->i);
state->next = state->i < 10 ? foo : 0;
}
int main(void)
{
struct state state = { foo, 0 };
while(state.next) state.next(&state);
}
Unfortunately, most of the articles on state machines are written for C++ or other languages that have direct support for polymorphism as it's nice to model the states in an FSM implementation as classes that derive from an abstract state class.
However, it's pretty easy to implement state machines in C using either switch statements to dispatch events to states (for simple FSMs, they pretty much code right up) or using tables to map events to state transitions.
There are a couple of simple, but decent articles on a basic framework for state machines in C here:
http://www.gedan.net/2008/09/08/finite-state-machine-matrix-style-c-implementation/
http://www.gedan.net/2009/03/18/finite-state-machine-matrix-style-c-implementation-function-pointers-addon/
Edit: Site "under maintenance", web archive links:
http://web.archive.org/web/20160517005245/http://www.gedan.net/2008/09/08/finite-state-machine-matrix-style-c-implementation
http://web.archive.org/web/20160808120758/http://www.gedan.net/2009/03/18/finite-state-machine-matrix-style-c-implementation-function-pointers-addon/
switch statement-based state machines often use a set of macros to 'hide' the mechanics of the switch statement (or use a set of if/then/else statements instead of a switch) and make what amounts to a "FSM language" for describing the state machine in C source. I personally prefer the table-based approach, but these certainly have merit, are widely used, and can be effective especially for simpler FSMs.
One such framework is outlined by Steve Rabin in "Game Programming Gems" Chapter 3.0 (Designing a General Robust AI Engine).
A similar set of macros is discussed here:
https://contrarymotion.net/2008/02/12/some-code-snippets-for-a-simple-c-state-machine/
If you're also interested in C++ state machine implementations there's a lot more that can be found. I'll post pointers if you're interested.
State machines are not something that inherently needs a tutorial to be explained or even used. What I suggest is that you take a look at the data and how it needs to be parsed.
For example, I had to parse the data protocol for a Near Space balloon flight computer, it stored data on the SD card in a specific format (binary) which needed to be parsed out into a comma seperated file. Using a state machine for this makes the most sense because depending on what the next bit of information is we need to change what we are parsing.
The code is written using C++, and is available as ParseFCU. As you can see, it first detects what version we are parsing, and from there it enters two different state machines.
It enters the state machine in a known-good state, at that point we start parsing and depending on what characters we encounter we either move on to the next state, or go back to a previous state. This basically allows the code to self-adapt to the way the data is stored and whether or not certain data exists at all even.
In my example, the GPS string is not a requirement for the flight computer to log, so processing of the GPS string may be skipped over if the ending bytes for that single log write is found.
State machines are simple to write, and in general I follow the rule that it should flow. Input going through the system should flow with certain ease from state to state.
This is all you need to know.
int state = 0;
while (state < 3)
{
switch (state)
{
case 0:
// Do State 0 Stuff
if (should_go_to_next_state)
{
state++;
}
break;
case 1:
// Do State 1 Stuff
if (should_go_back)
{
state--;
}
else if (should_go_to_next_state)
{
state++;
}
break;
case 2:
// Do State 2 Stuff
if (should_go_back_two)
{
state -= 2;
}
else if (should_go_to_next_state)
{
state++;
}
break;
default:
break;
}
}
Real-Time Object-Oriented Modeling was fantastic (published in 1994 and now selling for as little as 81 cents, plus $3.99 shipping).
There is a lot of lesson to learn handcrafting state machines in C, but let me also suggest Ragel state machine compiler:
http://www.complang.org/ragel/
It has quite simple way of defining state machines and then you can generate graphs, generate code in different styles (table-driven, goto-driven), analyze that code if you want to, etc. And it's powerful, can be used in production code for various protocols.
State machines can be very complex for a complex problem. They are also subject to unexpected bugs. They can turn into a nightmare if someone runs into a bug or needs to change the logic in the future. They are also difficult to follow and debug without the state diagram. Structured programming is much better (for example you would probably not use a state machine at mainline level). You can use structured programming even in interrupt context (which is where state machines are usually used). See this article "Macros to simulate multi-tasking/blocking code at interrupt level" found at codeproject.com.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am using a FSM to model the behaviour of an embedded system I am developing. After some initial tests I have a FSM coded in C working quite well. The approach I used to code the FSM was the pointer-to-function table where I define a table with all the functions that takes place in each state.
void(*state_table[])(void) = {
conection,
Idle,
cal,
bi,
pot,
gal,
eis,
PrepE,
Pret,
Meas,
FS_ch,
Ending,
Error };
Now the next step is to modeling some complexities of the requirements that I could not solve with the first approach. In this new model I would like to use some concurrency to model two FSMs that should work at the "same time", and I also used some hierarchy to put those FSMs inside a superstate.
The problem I have now is that I am not sure how to code this concurrency and hierarchy using C. I was taking a look to the QP framework but I think my FSM is not still so complex to begin to use those kind of frameworks.
This is the FSM I designed.
The states 71 and 72 are the concurrent states inside the superstate 7. The execution is acutally independent between them, they doesn't share any variable.
How could I implement this concurrency and hierarchy using C?
The outer state-machine runs in a continuous loop, while sub-states and sub-state-machines must run to completion. Concurrency in the absence of a preemptive scheduler must be implemented cooperatively - the "concurrent" states must be executed sequentially, but each should perform a deterministic guaranteed-to-complete operation on each invocation - i.e. no indefinite busy-waits or delays or processing that take longer that your real-time constraints allow (this is fundamental to state-machine constraint in any case).
The substate-machines can be implemented identically to the main state machine but without the "big-loop". For example:
// Main state machine
static int current_state0 = 0 ;
int main( void )
{
static const void(*state_table[])(void) =
{
conection,
Idle,
cal,
bi,
pot,
gal,
eis,
PrepE,
Pret,
Meas,
FS_ch,
Ending,
Error
} ;
// Main loop - execute the current state
for(;;)
{
state_table[current_state0]() ;
}
}
void superState7()
{
// Execute concurrent sub-statemachines
subStateMachine71() ;
subStateMachine72() ;
}
// Sub-state machine
static int current_state71 = 0 ;
void subStateMachine71()
{
static const void(*state_table[])(void) =
{
state711,
state712,
state713,
state714
} ;
// Execute current substate
state_table[current_state71]() ;
}
...
Our customer provided source code has portions of code that will be executed based on tool type. A sample code portion is given below. The function has common portions and tool specific(hardware platform) portions. The code is written in C and runs in VxWorks. Addition or deletion of new tool type has code modification. The customer wants addition or deletion new tool type with minimal code change and testing effort
int vsp_recv(char *const recv_text)
{
int rc = 0;
const int type = get_tool_type();
// Common Code
if (MODEL_CR == type)
{
rc = beamoff(recv_text);
}
else
{
rc = vsp_set(recv_text);
}
return(rc);
}
Is it the right technique to separate the code to two methods as given below, keep them in separate source files and define separate make files to generate tool specific binary? Is there any better ways to do this?
Tool type MODEL_CR code
int vsp_recv_tool_speccific(char *const recv_text)
{
return beamoff(recv_text);
}
Tool type MODEL_CV code
int vsp_recv_tool_speccific(char *const recv_text)
{
return vsp_set(recv_text);
}
Refactored method
int vsp_recv(char *const recv_text)
{
int rc = 0;
const int type = get_tool_type();
// Common Code
rc = vsp_recv_tool_speccific(recv_text);
}
Define a shared library for each tool and a configuration file that defines what functions get called for each tool. Load the shared libraries at startup and provide a signal catcher to reload if the configuration file changes.
the OPs question (and posted code) says that 3 places will need to be modified.
the function: get_tool_type()
the header file with the definitions of MODEL_CV, MODEL_CR, etc
the if-then-else list.
were it me, I would implement a table of function pointers, have get_tool_type() return an index into that table. Then all the if/then/else code would become a single statement that invokes a function from the table.
Then any updates would be additions to the table, modifications to 'get_too_type(), and the additional functions likebeam_off()`
The loss of a tool type would not require any code change.
the addition of a tool type would require appending an entry to the table, mod to get_tool_type() to recognize the new tool, and the new function to process the new tool type.
Of course, this could result in code that is never executed.
long time listener, first time caller.
I've been backporting features from upstream code as recent as 4.12-rc-whatever to a 3.4-base kernel for an older Qualcomm SoC board (apq8064, ridiculous undertaking I know).
Thus far I've been successful in almost every core api, with any compatibility issues solved by creative shims and ducttape, with the exception of cpufreq.
Keep in mind that I'm still using legacy platform drivers and clocking, no dt's or common clock frame work.
My issue begins with the inclusion of stuct cpufreq_frequency_table into struct cpufreq_policy, as part of the move from percpu to per-policy in the api. In 3.13, registering a platform's freq_table becomes more difficult for unique cases, as using cpufreq_frequency_table_get_attr is no longer an option.
In my case, the cpufreq_driver's init is generic, and relies on my platform's scaling driver (acpuclock-krait) to register the freq_table, which is fine for the older api, but becomes incompatible with the per-policy setup. The upstream so I requires the driver to manually initialize policy->freq_table and mine uses both a cpu, and an array of 35 representing the tables in the platform code. As well, it accounts for the 6 different speedbin/pvs values when choosing a table. I'm considering either dropping the "cpu" param from it and using cpumask_copy, and perhaps even combining the two drivers into one and making the clock driver a probe, but yeah, thus far init is a mystery for me. Here is the snippet of my table registration, if anyone can think of something hackable, I'd be eternally grateful...
ifdef CONFIG_CPU_FREQ_MSM
static struct cpufreq_frequency_table.freq_table[NR_CPUS][35];
extern int console_batt_stat;
static void __init cpufreq_table_init(void)
{
int cpu;
int freq_cnt = 0;
for_each_possible_cpu(cpu) {
int i;
/* Construct the freq_table tables from acpu_freq_tbl. */
for (i = 0, freq_cnt = 0; drv.acpu_freq_tbl[i].speed.khz != 0
&& freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
if (drv.acpu_freq_tbl[i].use_for_scaling) {
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency
= drv.acpu_freq_tbl[i].speed.khz;
freq_cnt++;
}
}
/* freq_table not big enough to store all usable freqs. */
BUG_ON(drv.acpu_freq_tbl[i].speed.khz != 0);
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
/* Register table with CPUFreq. */
cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
}
dev_info(drv.dev, "CPU Frequencies Supported: %d\n", freq_cnt);
}
UPDATE!!! I wanted to update the initial registration BEFORE merging all the core changes back in, and am pretty certain that I've done so. Previously, the array in question referenced a percpu dummy array that looked like this: freq_table[NR_CPUS][35] that required the cpu parameter to be listed as part of the table. I've made some changes here that allows me a percpu setup AND the platform-specific freq management( which cpufreq doesn't need to see), but with a dummy table representing the "index," which cpufreq does need to see. Commit is here, next one fixed obvious mistakes: https://github.com/robcore/machinex/commit/59d7e5307104c2396a2e4c2a5e0b07f950dea10f
I'm currently making a very simple Tic-Tac-Toe game with an AT89C51RC2 and I am having issues getting the button input right.
Basically, the input is a 3x3 Button Matrix which I want to utilize by scanning through the rows with a pulse while checking the columns for a connection; pretty basic. However, the way I wanted to do this was by making a unique scroll method that received the row parameter and set it to HIGH accordingly.
I already have
sbit R1 = P1^0;
all through the needed inputs, but I'm not sure if this is correct.
Then, on my main method, I run something like
while(TRUE)
{
scroll(R1);
}
which is named scroll, I have this
void scroll (bit P)
{
P = HIGH; //Sets the row being checked to HIGH (HIGH is already defined as a 1). Same goes with the aformentioned TRUE
...
}
So, this is not working. I know I'm not doing this right, but I had to start somewhere. Is what I am attempting to do possible? Sending a single Pin adress as an overload for a method? If so, what datatype should it be? I was juggling between char and bit but I can't settle.
I hope my question is understandable! If not, I will gladly elaborate and maybe post all the code (although it is quite messy). Thanks, everyone, in advance!
If I understand your question correctly, I could expand your code snippets to look like this:
sbit R1 = P1^0;
sbit R2 = P1^1;
sbit R3 = P1^2;
while(TRUE)
{
scroll(R1);
scroll(R2);
scroll(R3);
}
(Your scroll function remains as is). You are trying to define one function that you can call multiple times, passing in a different pin to assert each time you call the function.
Unfortunately, I am not aware of a way to do exactly what you want to do, because you may not define sbits in a function, either as locals or parameters. I'm sure there's a non-intuitive way to do it in inline assembly with the SETB and CLR instructions (maybe someone else can chime in), but with Keil the C compiler alone it is a no go.
Instead, perhaps you could make a helper function to do the pin assignment. That would let you do something like this:
void setRow(char whichRow, bit whatValue)
{
switch (whichRow)
{
case 1:
R1 = whatValue;
break;
case 2:
R2 = whatValue;
break;
case 3:
R3 = whatValue;
break;
default:
break;
}
}
void scroll (char row)
{
setRow(row, HIGH); //Sets the row being checked to HIGH (HIGH is already defined as a 1). Same goes with the aformentioned TRUE
...
}
And then in your main:
while(TRUE)
{
scroll(1);
scroll(2);
scroll(3);
}
Good luck.
I saw you we're using Keil (really good 8051 compiler IMO). THis compiler gives you a header file for the MCU you are using, which already declares individual bit's of a port to access each of them on Keil page dedicated to Atmel's family of 8051 compiler.
(AT89C51RC2 Keil's webpage http://www.keil.com/dd/chip/3681.htm)
That way, accessing each of the SFR of your chip will be way easier then re-defining them (UART, TIMER, etc).
Usually, a compiler which support's a chip will develop a header file for it's customers.
You can then, after including this header file in your project, access a bit this way :
unsigned char ucBTN = P1_0; //ucBTN equals P1_0 value;
It's, most of the time, the same for every 8051 you'll use, as they use the same "CORE" architecture.
I'm a bit confused about how to implement my state machine.
I already know it's hierarchical since some states share the same action.
I determine what I need to do by these parameters:
Class (Values are: Base, Derived, Specific)
OpCode
Parameter 1 - optional
Parameter 2 - optional
My hierarchy is determined by the Class and the OpCode represents the action.
Derived can use the OpCodes of Base and Specific can use OpCodes of both Base and Derived.
The naive implementation is the following:
void (*const state_table [MAX_CLASSES][MAX_OPCODES]) (state *) {
{base_state1, base_state2, NULL, NULL},
{base_state1, base_state2, derived_state1, NULL},
{base_state1,base_state2, derived_state1, specific_state3},
};
void dispatch(state *s)
{
if (state_table[s->Class][s->OpCode] != NULL)
state_table[s->Class][s->OpCode](s);
}
This will turn unmaintainable really quick.
Is there another way to map the state to a superclass?
EDIT:
Further calcualtion leads me to think that I'll probably use most if not all OpCodes but I will not use all of the Classes available to me.
Another clarification:
Some OpCodes might be shared through multiple derived and base Classes.
For example:
I have a Class called Any
which is a Base class. It has the
OpCodes: STATE_ON, STATE_OFF, STATE_SET.
I have another Class called
MyGroup which is a Derived class. It has the OpCodes:
STATE_FLIP, STATE_FLOP.
The third Class is a Specific
class called ThingInMyGroup which
has the OpCode:
STATE_FLIP_FLOP_AND_FLOOP.
So a message with class Any is sent from the server, recieved in all clients and processed.
A message with class MyGroup is sent from the server, recieved in all clients and processed only on clients that belong to MyGroup, any OpCodes that are valid for the Any class are valid for the MyGroup class.
A message with class ThingInMyGroup is sent from the server, recieved in all clients and processed only on clients that belong to MyGroup and are a ThingInMyGroup*, any **OpCodes that are valid for the Any class and MyGroup class are valid for the ThingInMyGroup class.
After a message is received the client will ACK/NACK accordingly.
I prefer not to use switch cases or const arrays as they will become unmaintainable when they get bigger.
I need a flexible design that allows me:
To specify which OpCodes are available
for each Class.
To specify a superclass for each Class and through that specification to allow me to call the function pointer that is represented by the current OpCode.
There are several ways to deal with this. Here is one:
edit -- with general purpose hierarchy added
typedef unsigned op_code_type;
typedef void (*dispatch_type)(op_code_type);
typedef struct hierarchy_stack hierarchy_stack;
struct hierarchy_stack {
dispatch_type func;
hierarchy_stack *tail;
};
void dispatch(state *s, hierarchy_stack *stk) {
if (!stk) {
printf("this shouldn't have happened");
} else {
stk->func(s, stk->tail);
}
}
void Base(state *s, hierarchy_stack *stk ) {
switch (s->OpCode) {
case bstate1:
base_state1(s);
break;
case bstate2:
base_state(2);
break;
default:
dispatch(s, stk);
}
}
void Derived(state *s, hierarchy_stack *stk ) {
switch(s->opcode) {
case dstate1:
deriveds_state1(s);
break;
default:
dispatch(s, stk);
}
}
...
NOTE : All function calls are tail calls.
This localizes your "class"es a good bit so that if you decide that Derived needs 100 more methods/opcodes then you only have to edit methods and the enum (or whatever) that you use to define opcodes.
Another, more dynamic way, to deal with this would be to have a parent pointer within each "class" that pointed to the "class" that would handle anything that it could not handle.
The 2D table approach is fast and flexible (Derived could have a different handler than Base for opcode 0), but it grows fast.
I wrote a little tool that generates code similar to your naive implementation based on a mini-language. The language just specified the state-opcode-action relationships, all of the actions were just C functions conforming to a typedef.
It didn't handle the HSM aspect, but this would be relatively easy to add to a language.
I'd recommend taking this approach -- create a little language that gives you a clean way to describe the state machine, and then generate code based on that machine description. That way when you need to insert a new state a month from now, the whole thing isn't a tangled mess to edit.
Let me know if you want the code and I'll make sure it's still available somewhere.