мысли об объединениях в C, в отношении MISRA

Мишра говорит запретить все союзы. Я также знаю, что отклонения допускаются, если они тщательно обсуждаются и документируются.

У нас есть микроконтроллер и внешний eeprom для хранения статистических данных (, регистрации событий/ошибок, настроек параметров и многого другого ).

Журнал событий состоит из более чем 80 счетчиков событий, некоторые из которых имеют 8, 16 и 32 бита (и все беззнаковые ). Хранилище параметров состоит примерно из 200 параметров, также смешанных с 8-, 16- и 32-битными значениями (без знака ).

Мы переписываем весь код, чтобы он соответствовал MISRA, и поскольку эти значения были определены ранее, они выглядят следующим образом:

typedef struct
{
  U16BIT eventLogVar1;
  U32BIT eventLogVar2;
  U8BIT  eventLogVar3;
  U8BIT  eventLogVar4;
  U32BIT eventLogVar5;
} EVENT_LOG;

typedef union
{
  EVENT_LOG log;
  U8BIT     array[sizeof(EVENT_LOG)];
} ELOG;

ELOG log;

Теперь это не совсем соответствует требованиям MISRA. То же самое касается журнала параметров. Однако это самый простой способ чтения и записи из eeprom, потому что мне просто нужно читать/записывать через массив для чтения/записи из eeprom.

У нас есть еще несколько правил, которые нам просто не позволено нарушать. Нет глобальных (внешних )переменных (через заголовочные файлы ). Все локальные переменные, при необходимости, должны быть доступны только через функции get/set.

Это означает, что если нам нужно полностью записать все эти параметры, каждый из них должен получить свои собственные функции получения/установки для их изменения в приложении.

Одно из решений, о которых я думал, было следующим:

#ifdef EITHER
enum
{
    eventLogVar1 = 0; /* 00 */
    pad01;            /* 01 */
    eventLogVar2;     /* 02 */
    pad03;            /* 03 */
    pad04;            /* 04 */
    pad05;            /* 05 */
    eventLogVar3;     /* 06 */
    eventLogVar4;     /* 07 */
    eventLogVar5;     /* 08 */
    pad09;            /* 09 */
    pad10;            /* 10 */
    pad11;            /* 11 */
}
#else /* OR */
#define eventLogVar1 0 /* 2 bytes */
#define eventLogVar2 2 /* 4 bytes */
#define eventLogVar3 6 /* 1 byte  */
#define eventLogVar4 7 /* 1 byte  */
#define eventLogVar5 8 /* 4 bytes */
#endif
#define eventLogLastLength 4

U8BIT eventLog[eventLogVar5 + eventLogLastLength];

U8BIT getU8BIT(U8BIT index){}
U16BIT getU16BIT(U8BIT index){}
U32BIT getU32BIT(U8BIT index){}

void setU8BIT(U8BIT index, U8BIT val){}  
void setU16BIT(U8BIT index, U16BIT val){}
void setU32BIT(U8BIT index, U32BIT val){}

Однако это создает громоздкий рефакторинг, если значения добавляются или удаляются. Это также означает, что нельзя использовать значения типа array (, и есть несколько ), которые можно изменить с помощью определения длины, если используется более или менее определенный тип, например, датчики.


Что вы думаете об этой конкретной проблеме.Будет ли мне/нам лучше задокументировать наше отклонение от стандарта MISRA -в этом конкретном случае и использовать это отклонение только в этом конкретном месте, или есть лучшие решения этой проблемы?

5
задан Peter K. 9 August 2012 в 12:03
поделиться