Misra说,取缔所有的工会。我也知道,只要对它们进行彻底讨论和记录,就可以允许偏差。思考用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函数来访问。
这意味着,如果我们需要充分写出所有这些参数,这些每个人都应该得到自己的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){}
然而,这造成如果添加或删除值的combersome重构。这也意味着不能使用类型数组的值(并且有少数),如果使用了某种类型的(例如,传感器)或多或少的某些类型的数据,则可以通过定义长度来改变这些值。
你对这个特定问题有什么看法。我/我们是否会更好地记录我们在这个特定情况下与MISRA标准的偏差,并且仅在这个特定地点使用这种偏差还是有更好的解决方案来解决这个问题?
不使用硬件寄存器可以是1-8-16-32位寻址的联合有点傻,但我想我应该从标准委员会那里期待典型的控制器硬件寄存器是一个很好的例子,例如:一个寄存器必须被读写为32位,但实际上是一个令人讨厌的位域集合,一些有用,有些不关心,有些从不写1。 CAN控制器寄存器(汽车中不为人知的东西:)是一个很好的例子。 Soddin'委员会.. – 2012-08-09 15:14:17
@马丁:请记住,工会和比特场是不同的东西。并且C位字段不是用来模拟寄存器或文件格式位字段的好东西 - 就在上周我碰到了一些使用位字段来模拟MPEG标头的代码,并且您知道些什么:x86编译器将它们放在不同的位置比ARM编译器。无论你如何看待工会,避免C位字段。使用明确的转换,掩码和位代替 - 即使你必须将它们隐藏在宏后面。 – 2012-08-13 07:21:14
@马丁 - 我们正在寻找新的 [R&DFC] –
Andrew
2012-11-08 07:34:40
杯志愿者加入,可以随意提供