Reputation: 258
I made this state machine :
enum states { STATE_ENTRY, STATE_....} current_state;
enum events { EVENT_OK, EVENT_FAIL,EVENT_REPEAT, MAX_EVENTS } event;
void (*const state_table [MAX_STATES][MAX_EVENTS]) (void) = {
{ action_entry , action_entry_fail , action_entry_repeat }, /*
procedures for state 1 */
......}
void main (void){
event = get_new_event (); /* get the next event to process */
if (((event >= 0) && (event < MAX_EVENTS))
&& ((current_state >= 0) && (current_state < MAX_STATES))) {
state_table [current_state][event] (); /* call the action procedure */
printf("OK 0");
} else {
/* invalid event/state - handle appropriately */
}
}
When I modify a global variable in one state the global variable remain the same , and I need that variable in all the states . Do you now what could be the problem ? My Global variable is this structure:
#if (CPU_TYPE == CPU_TYPE_32)
typedef uint32_t word;
#define word_length 32
typedef struct BigNumber {
word words[64];
} BigNumber;
#elif (CPU_TYPE == CPU_TYPE_16)
typedef uint16_t word;
#define word_length 16
typedef struct BigNumber {
word words[128];
} BigNumber;
#else
#error Unsupported CPU_TYPE
#endif
BigNumber number1 , number2;
Here is how I modify:
//iterator is a number from where I start to modify,
//I already modified on the same way up to the iterator
for(i=iterator+1;i<32;i++){
nr_rand1=661;
nr_rand2=1601;
nr_rand3=1873;
number2.words[i]=(nr_rand1<<21) | (nr_rand2<<11) | (nr_rand3);
}
Upvotes: 0
Views: 1842
Reputation: 44339
This is not an answer - rather it is a comment. But it is too big to fit the comment field so I post it here for now.
The code posted in the question is not sufficient to find the root cause. You need to post a minimal but complete example that shows the problem.
Something like:
#include<stdio.h>
#include<stdlib.h>
#include <stdint.h>
typedef uint32_t word;
#define word_length 32
typedef struct BigNumber {
word words[4];
} BigNumber;
BigNumber number2;
enum states { STATE_0, STATE_1} current_state;
enum events { EVENT_A, EVENT_B } event;
void f1(void)
{
int i;
current_state = STATE_1;
for (i=0; i<4; ++i) number2.words[i] = i;
}
void f2(void)
{
int i;
current_state = STATE_0;
for (i=0; i<4; ++i) number2.words[i] = 42 + i*i;
}
void (*const state_table [2][2]) (void) =
{
{ f1 , f1 },
{ f2 , f2 }
};
int main (void){
current_state = STATE_0;
event = EVENT_A;
state_table [current_state][event] (); /* call the action procedure */
printf("%u %u %u %u\n", number2.words[0], number2.words[1], number2.words[2], number2.words[3]);
event = EVENT_B;
state_table [current_state][event] (); /* call the action procedure */
printf("%u %u %u %u\n", number2.words[0], number2.words[1], number2.words[2], number2.words[3]);
return 0;
}
The above can be considered minimal and complete. Now update this code with a few of your own functions and post that as the question (if it still fails).
My code doesn't fail.
Output:
0 1 2 3
42 43 46 51
Upvotes: 1
Reputation: 16522
Regarding the code that changese number2
:
for(i=iterator+1;i<32;i){
nr_rand1=661;
nr_rand2=1601;
nr_rand3=1873;
number2.words[i]=(nr_rand1<<21) | (nr_rand2<<11) | (nr_rand3);
}
I can't fail to note that:
i
is never incremented, so just one element of the array is changed (iterator+1
) over an infinite loop;i
would be incremented, only the a portion of the words
array it's changed depending on the value of iterator
(but this might be the intended behaviour).iterator
can be -1
, the element words[0]
is never changed (again this could be the intended behaviour).I would check if this is really what you intended to do.
If you're sure that it's just a visibility problem (since you said that when you declare it as local it worked as expected), the only other thing that I can think of is that you have the functions in one file and the main (or where you do your checks) in another.
Then you include the same .h
header in both files and you end up (due to the linker you're using) with two different number2
because you did not declare it as extern
in one of the two files.
Your compiler (or, better, the linker) should have (at least) warned you about this, did you check the compilation messages?
Upvotes: 2
Reputation: 16522
This is just in case you may want to change your approach for defining the FSM. I'll show you with an example; say you have the following FSM:
You may represent it as:
void function process() {
fsm {
fsmSTATE(S) {
/* do your entry actions heare */
event = getevent();
/* do you actions here */
if (event.char == 'a') fsmGOTO(A);
else fsmGOTO(E);
}
fsmSTATE(A) {
event = getevent();
if (event.char == 'b' || event.char == 'B') fsmGOTO(B);
else fsmGOTO(E);
}
fsmSTATE(B) {
event = getevent();
if (event.char == 'a' ) fsmGOTO(A);
else fsmGOTO(E);
}
fsmSTATE(E) {
/* done with the FSM. Bye bye! */
}
}
}
I do claim (but I believe someone will disagree) that this is simpler, much more readable and directly conveys the structure of the FSM than using a table. Even if I didn't put the image, drawing the FSM diagram would be rather easy.
To get this you just have to define the fsmXXX
stuff as follows:
#define fsm
#define fsmGOTO(x) goto fsm_state_##x
#define fsmSTATE(x) fsm_state_##x :
Upvotes: 2