2916|0

70

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于MISRA:规则 18.4 不允许使用联合体 [复制链接]

以下是《嵌入式C 标准研究报告》中关于MISRA对联合体的使用约束说明

规则 18.4 不允许使用联合体
这事一个不太近情理的规定,在具体阐述为何MISRA-C:2004如此痛恨联合体之前,首先需要明确与联合体相关的细节:
  1)联合体的末尾有多少个填充单元
  2)联合体的各个成员如何对齐
  3)多字节的数据类型高低字节如何排放顺序
  4)如果包含位字段 (bit-field),各位如何排放

  针对细节3举个例子
   程序段2.1

typedef union{
    uint32_t word;
    uint8_t bytes[4];
}word_msg_t;

uint32_t read_msg(void)
{
    word_msg_t tmp;
/* tmp.byte[0] 对应于tmp.word的高8位
   tmp.byte[1]对应于tmp.word的次高8位,依此类推 */
    tmp.bytes[0]  = read_byte();
    tmp.bytes[1]  = read_byte();
    tmp.bytes[2]  = read_byte();
    tmp.bytes[3]  = read_byte();
    return (tmp.word);
}


以上代码在各种通信协议中使用的频率很高,接收端接收到的数据一般都以字节为单位存放,主控程序需要根据相应的协议将接受到的多个字节进行组合。为了实现相同的功能,MISRA-C:2004推荐恶劣read_msg()函数的另外一种写法.

程序段2.2

uint32_t read_msg(void)
{
    uint32_t word;
    word = ((uint32_t)read_byte() ) << 24;
    word = word | (((uint32_t)read_byte()) << 16);
    word = word | (((uint32_t)read_bytes()) << 8);
    word = word | ((uint32_t)read_byte());
    return (word);
}
无论从程序的可读性还是从执行效率来讲,程序段2.1都要优于程序段2.2。然而,程序段2.1在Intel 80x86/Pentium体系(little-endian,存储多字节整数的时候低位字节存放在低地址)CPU和在Motorola 68K体系(big-endian)中的执行结果完全不一样。假设read_byte()函数返回的数据依次是0x01,0x02,0x03,0x04,则在Intel体系中,程序段2.1 read_msg返回的值是0x4321,在Motorola体系中,返回的则是0x1234.     无论在Intel体系还是在Motorola体系中,程序段 2.2 中read_msg的返回值都是0x1234


这样的话在处理通信协议的时候真的是很麻烦了,比如我要写一个TCP/IP协议斩,不让用联合,也不让用指针类型转换??!!有什么更好的方法么??
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表