嵌入式系统开发:C语言中的位结构体

来源:互联网 发布:mac的qq怎么看群相册 编辑:程序博客网 时间:2024/06/06 00:15

转载自:http://blog.csdn.net/duwufeng/article/details/8207115

[置顶] 嵌入式系统开发:C语言中的位结构体

分类: 嵌入式系统开发 973人阅读 评论(5) 收藏 举报
语言c位结构体嵌入式struct

       在嵌入式开发中,经常需要表示各种系统状态,位结构体的出现大大方便了我们,尤其是在进行一些硬件层操作时。但是在使用位结构体的过程中,有没有深入思考一下它的相关属性?有没有真正用到它的便利性,来提高系统效率?

下面我将进行一些相关实验(这里以项目开发中的实际代码为例):


1.位结构体类型设计

[cpp] view plaincopyprint?
  1. //data structure except for number structure  
  2. typedef struct symbol_struct  
  3. {  
  4. uint_32 SYMBOL_TYPE     :5;  //data type,have the affect on "data display type"  
  5. uint_32 reserved_1      :4;  
  6.   
  7. uint_32 SYMBOL_NUMBER  :7;  //effective data number in one element  
  8. uint_32 SYMBOL_ACTIVE  :1;//symbol active status  
  9.   
  10. uint_32 SYMBOL_INDEX   :8;  //data index in norflash,result is related to "xxx_BASE_ADDR"  
  11. uint_32 reserved_2     :8;  
  12.   
  13. }SYMBOL_STRUCT,_PTR_ SYMBOL_STRUCT_PTR;  

分析:

       这里定义了一个位结构体类型SYMBOL_STRUCT,那么用该类型定义的变量都哪些属性呢?看下面运行结果:


        WORDS是定义的另一个外层类型定义封装,这里可以把它当作变量来看待。WORDS变量里前5个变量地址都是0x1ffff082c,最后reserved_2地址0x1fff0830,紧接着下一个PressureState变量0x1fff0834。
       本来是假设reserved_1和SYMBOL_TYPE不在一个地址上的,因为他们5+4共9位,超过了1个字节地址,但这里发现他们公用首地址了;而且reserved_2竟然实际占用了4个字节(0x1fff0834 - 0x1fff0830),我本来是想让他占用1个字节的。WORDS整体占了8个字节(0x1fff0834 - 0x1fff082c),设计时分析占用5个字节(SYMBOL_TYPE 1个;reserved_1 1个;SYMBOL_NUMBER+SYMBOL_ACTIVE 1个;SYMBOL_INDEX 1个;reserved_2 1个)。中间一定有什么没有预想到的问题。

       uint_32 reserved_2:8;占用4个字节,估计是uint_32在起作用,而这里写的8位,只是我使用的有效位数,另外24位空闲,如果在下面再定义一个reserved_3:8,地址也是一样的,都是以uint_32为单位取地址。

       同理,上面的5个变量,共用一个地址就不足为奇了。而且有效位的分配不是连续进行的,例如SYMBOL_TYPE+reserved_1 共9位,超过了一个字节,索性系统就分配两个字节给他们,每人一个;SYMBOL_NUMBER+SYMBOL_ACTIVE 共8位,一个字节就能搞定。


2、修改数据结构,验证上述猜想

[cpp] view plaincopyprint?
  1. //data structure except for number structure  
  2.    typedef struct symbol_struct  
  3.    {  
  4.    uint_8 SYMBOL_TYPE    :5;  //data type,have the affect on "data display type"  
  5.    uint_8 reserved_1     :4;  
  6.      
  7.    uint_8 SYMBOL_NUMBER   :7;  //effective data number in one element  
  8.    uint_8 SYMBOL_ACTIVE   :1; //symbol active status  
  9.      
  10.    uint_8 SYMBOL_INDEX    :8;  //data index in norflash,result is related to "xxx_BASE_ADDR"  
  11.    uint_8 reserved_2      :8;  
  12.      
  13.    }SYMBOL_STRUCT,_PTR_ SYMBOL_STRUCT_PTR;  
  14.     

地址数据如下:


       当换成uint_8后,可以看到地址空间占用大大减小,reserved_2只占用1个字节(0x1fff069f - 0x1fff069e),其他变量也都符合上面的结论猜想。


总结:

    1、在操作位结构体时,要关注变量的位域是否在一个uint_8上,判断占用空间大小

    2、除了位域,还要关注变量定义类型,因为编译器空间分配始终是按类型分配的,位域只是指出了有效位(小于类型占用空间),而且如果位域大于类型空间,编译器直接报错(如 uint_8  test  :15,可自行实验)。

    3、这两个因素都影响变量占用空间大小,具体可以结合调试窗口,通过地址分配分析判断

原创粉丝点击