Сокращение или устранение дублирующихся записей массива

Я хотел бы исключить или радикально сократить записи константного массива для поиска, который включает наборы констант или следующее состояние. Возможно, это очень просто сделать, я просто не знаю, какую структуру использовать. Я пишу встроенный C-код, где пытаюсь сделать все очень быстро, но некоторые из этих массивов становятся очень большими, поэтому мне нужно найти баланс между скоростью кода и пространством. У меня нет большого опыта встраиваемого кода, и у нас нет опыта в моей компании.

В качестве небольшого примера рассмотрим три флаговые переменные, которые определяют следующее состояние: fEnable, fDone и fFault. Допустим, я кодирую fEnable как бит 2, fDone как бит 1, а fFault как бит 0. Тогда у меня будет такая таблица, чтобы определить состояние:

const uint8_t NEXT_STATE[] = {
    SEQ_SAME, // 000
    SEQ_PREV, // 001
    SEQ_PREV, // 010
    SEQ_PREV, // 011
    SEQ_SAME, // 100
    SEQ_PREV, // 101
    SEQ_NEXT, // 110
    SEQ_PREV  // 111
};

Мое следующее состояние определяется закодированным вводом:

p->state = NEXT_STATE[ p->encodedInput ];

У меня есть несколько таких константных массивов для моего кода, для временных констант и других значений (не только для следующего состояния).

Мой вопрос заключается в том, каков наилучший способ устранения избыточных записей в таблице поиска, такой как эта? Например, вы можете использовать сокращение логики и знать, что если fFault когда-либо установлен, вы хотите SEQ_PREV. Если нет, если fDone не установлен, вы хотите SEQ_SAME. Для (! FFault)(fDone)(fEnabled) = SEQ_PREV, (! FFault)(fDone)(! FEnabled) = SEQ_NEXT. Я могу как-то увидеть, как вы доберетесь с постоянной двоичной таблицей, но я не уверен, что это лучший способ сделать это.

В качестве примера таблицы намного большего размера рассмотрим эту (извините за форматирование здесь):

const enum PowerState_t PWR_TRANSITION_TABLE[16][PWR_NUM_STATES] =
{   // PWR_OFF          PWR_T_ON        PWR_ON          PWR_T_OFF       PWR_FAULT       PWR_CRIT_FAULT
    {PWR_FAULT,         PWR_T_OFF,      PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT  },          // 0000
    {PWR_FAULT,         PWR_T_ON,       PWR_FAULT,      PWR_T_ON,       PWR_FAULT,      PWR_CRIT_FAULT  },           // 0001
    {PWR_FAULT,         PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 0010
    {PWR_FAULT,         PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 0011
    {PWR_OFF,           PWR_OFF,        PWR_FAULT,      PWR_OFF,        PWR_OFF,        PWR_OFF         },  // 0100
    {PWR_T_ON,          PWR_T_ON,       PWR_FAULT,      PWR_T_ON,       PWR_FAULT,      PWR_CRIT_FAULT  },  // 0101
    {PWR_FAULT,         PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 0110
    {PWR_FAULT,         PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 0111
    {PWR_CRIT_FAULT,    PWR_T_OFF,      PWR_T_OFF,      PWR_T_OFF,      PWR_FAULT,      PWR_CRIT_FAULT  },  // 1000
    {PWR_CRIT_FAULT,    PWR_ON,         PWR_ON,         PWR_T_ON,       PWR_FAULT,      PWR_CRIT_FAULT  },  // 1001
    {PWR_CRIT_FAULT,    PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT,        PWR_CRIT_FAULT  },  // 1010
    {PWR_CRIT_FAULT,    PWR_FAULT,      PWR_FAULT,      PWR_FAULT,      PWR_CRIT_FAULT,        PWR_CRIT_FAULT  },  // 1011
    {PWR_CRIT_FAULT,    PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 1100
    {PWR_CRIT_FAULT,    PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 1101
    {PWR_CRIT_FAULT,    PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT  },  // 1110
    {PWR_CRIT_FAULT,    PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT, PWR_CRIT_FAULT  }   // 1111
};

Заранее спасибо за помощь.

0 ответов

Другие вопросы по тегам