Syncing C state machine code with unit tests and doxygen/graphwiz diagrams

144 Views Asked by At

I'm writing medical software. In that end, I've come up with a workflow that allows me to show people with limited programming knowledge that the program I've made is the same as the program I was supposed to make. The workflow is the following:

  1. Make a human readable document stating what the program must do, and what it must not do.

  2. Convert that document into state machine diagrams.

  3. Write unit tests that prove to be written C code implements the diagrams from step 2

  4. Write code that passes the unit tests from step 3.

Step 1 and 2 can not be automated. I'm looking for a way to automate step 3 and 4. Basically I need some program that keeps the following statements in sync:

State machine diagram:

/** \page parallel_lcd
 * parallel lcd state machine \n
 * \dot
 * digraph statemachine {
 *  node [shape=record];
 *  ST_LCD_INIT [ label="Init" , color = red];
 *  ST_LCD_INITA [ label="Init A" , color = red];
 *  ST_LCD_INITB [ label="Init B" , color = red];
 *
 *  ST_LCD_INIT -> ST_LCD_INITA [ label ="(1)", arrowhead="open", style="solid" , color = green];
 *  ST_LCD_INITA -> ST_LCD_INITB [ label ="(2)", arrowhead="open", style="solid" , color = green];
 * }
 * \enddot
 */

Unit tests:

//arrow (1)
myLCD.state = ST_LCD_INIT;
parLcdExecute();
TEST_ASSERT_EQUAL_INT(ST_LCD_INITA,myLCD.state);

//arrow (2)
myLCD.state = ST_LCD_INITA;
parLcdExecute();
TEST_ASSERT_EQUAL_INT(ST_LCD_INITB,myLCD.state);

Code:

static TPARALLELLCD* myLcd = NULL;

void parLcdExecute (void)
{
    switch (myLcd->state)
    {
        case ST_LCD_INIT:
        {
            //do something
            myLcd->state = ST_LCD_INIT_A;
            break;
        }
        case ST_LCD_INITA:
        {
            //do something
            myLcd->state = ST_LCD_INIT_B;
            break;
        }
        case ST_LCD_INIT_B:
        {
            //do something
            break;
        }
    }
}

void parLcdInit(TPARALLELLCD* lcd)
{
    myLcd = lcd;
}

Header file:

typedef enum
{
    ST_LCD_INIT,
    ST_LCD_INIT_A,
    ST_LCD_INIT_B,
}TPARLCDSTATES;

typedef struct
{   
    uint8_t lines[PAR_LCD_NUM_LINES][PAR_LCD_LINE_SIZE];
    TPARLCDSTATES state;
}TPARALLELLCD;

void parLcdExecute (void);
void parLcdInit(TPARALLELLCD* lcd);

I'm using the C testing framework "unity": https://www.throwtheswitch.org/unity

I've looked for state machine generators/compilers. I've found SMC: The State Machine Compiler, but as far as I can see it can't do what I'm trying to do: http://smc.sourceforge.net

Does anybody know of software that can do this?

Cheers, Cedric

0

There are 0 best solutions below