Popovici Sebi Popovici Sebi - 3 months ago 15
C Question

How to use global variables on a state machine

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);
}

Answer

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