0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式开发中C语言位结构体有哪些用途详细分析讲解

Q4MP_gh_c472c21 来源:未知 2019-02-23 09:07 次阅读

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

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

1.位结构体类型设计

[cpp]view plaincopyprint?

1.//datastructureexceptfornumberstructure

2.typedefstructsymbol_struct

3.{

4.uint_32SYMBOL_TYPE:5;//datatype,havetheaffecton"datadisplaytype"

5.uint_32reserved_1:4;

6.

7.uint_32SYMBOL_NUMBER:7;//effectivedatanumberinoneelement

8.uint_32SYMBOL_ACTIVE:1;//symbolactivestatus

9.

10.uint_32SYMBOL_INDEX:8;//dataindexinnorflash,resultisrelatedto"xxx_BASE_ADDR"

11.uint_32reserved_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只定义了8位,竟然实际占用了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位空闲,如果在下面再定义一个uint_32 reserved_3 : 8,地址也是一样的,都是以uint_32为单位取地址。

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

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

[cpp]view plaincopyprint?

1.//datastructureexceptfornumberstructure

2.typedefstructsymbol_struct

3.{

4.uint_8SYMBOL_TYPE:5;//datatype,havetheaffecton"datadisplaytype"

5.uint_8reserved_1:4;

6.

7.uint_8SYMBOL_NUMBER:7;//effectivedatanumberinoneelement

8.uint_8SYMBOL_ACTIVE:1;//symbolactivestatus

9.

10.uint_8SYMBOL_INDEX:8;//dataindexinnorflash,resultisrelatedto"xxx_BASE_ADDR"

11.uint_8reserved_2:8;

12.

13.}SYMBOL_STRUCT,_PTR_SYMBOL_STRUCT_PTR;

14.

地址数据如下:

当换成uint_8后,可以看到地址空间占用大大减小,reserved_2只占用1个字节(0x1fff069f - 0x1fff069e),其他变量也都符合上面的结论猜想。但是,注意看上面黄色和红色的语句,总感觉有些勉强,那么我又会想,前两个变量数据域是9位,那么他们实际上是不是真正的独立呢?虽然在uint_8上面他们是不同的地址,在uint_32的时候是不是也是不同的地址空间呢?

3、分析结构体内部的数据域是否连续,看下图及结果

本来假设:由前2次试验的结论,一共占用8个字节,节空间占用:(2+4)+(4+4)+(2+2+4)+(2+2)+(6)。可是,实际效果并不是想的那样。实际只占用了4个字节,系统并没有按照预想的方式,为RESERVED变量分配4个字节。

分析:

这些数据域,整体相加一共32位,占用4个字节(不考虑数据对齐问题)。而实际确实是占用了4个字节,唯一的原因就是:这些数据域以紧凑的方式链接,没有任何空闲位。实际是不是这样呢?

看下图和结果:

这里为了验证是否紧凑链接,用到了一个union数据,后面会讲到用union不会对数据组织方式有任何影响,看实际与上次的一样,也能分析出来。

主要是分析第2和第3个数据域是否紧密链接的。OBJECT_ACTIVE_PRE赋值0b00001111,NUMBER_ACTIVE赋值0b00000101,其他变量都是0,看到WORD数值0b1011111000000。分析WORD数据,可以看到这款MCU还是小端格式(高位数据在高端,低位数据在低端,这里不对大小端进行讨论),断开数据变成(0)10111 11000000,正好是0101+1111,OBJECT_ACTIVE_PRE数据域,跨越了两个字节,并不是刚开始设想的那样。这就印证了上面的紧密链接的结论,也符合数据结果输出。

4、再次实验,分析数据是否紧密链接,看下图和结果

可以看到,RESERVED数据域已经不再属于4个地址空间内了(0x1fff0518 - 0x1fff051b),但是他们整体加起来还是32个位域。这说明数据中间肯定有“空隙”存在了,空隙在哪?看一下NUMBER_STATE,如果紧密的话它应该跟NUMBER_ACTIVE在同一个字节地址上,可是他们并不在一块,“空隙”就存在这里。

这两个结构体有什么不一样?数据类型不一致,一个是uint_32,一个是uint_8。综上所述:数据类型影响的是编译器在分配物理空间时的大小单位,uint_32是以4个字节为单位,而后面的位域则是指在已经分配好的物理空间内部再紧凑的方式分配数据位,当物理空间不能满足位域时,那么系统就再次以一定大小单位进行物理空间分配,这个单位就是上面提到的uint_8或者uint_32。

举例:上面uint_32时,这些位域不管是不是在一个字节地址上,如果能够紧凑的分配在一个4字节空间大小上,就直接紧凑分配。如果不能则继续分配(总空间超过4字节),则再次以4字节空间分配,并把新的位域建立在新的地址空间上(条目1上的就是)。当uint_8时,很明显如果位域不能紧凑的放在一个字节空间上,那么就从新分配新的1字节空间大小,道理是一样的。

5、结构体组合、共用体组合是否影响上述结论

可以看到,系统并没有因为位结构体上面有uint_4的4字节变量或者共用体类型,就改变分配策略把位域都挤到4字节之内,看来他们是没有什么实质性联系的。这里把uint_32改成uint_8,或者把位结构体也替换掉,经我试验证明,都是没有任何影响的。

总结

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

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

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

4、最重要的一点:上面的所有结果,都是基于我自己的CodeWarrior10.2和MQX3.8分析出来的,不同的编译环境和操作系统,都可能会有不同的结果;而且即便是环境相同,编译器的配置和优化选项都有可能影响系统处理结果。结论并不重要,主要想告诉大家这一块隐藏陷阱,在以后处理类似问题时,要注意分析避让并掌握方法。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17148

    浏览量

    351188
  • C语言
    +关注

    关注

    180

    文章

    7604

    浏览量

    136813
  • 嵌入式开发
    +关注

    关注

    18

    文章

    1030

    浏览量

    47578

原文标题:嵌入式开发中,C语言位结构体用途详解

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    详细分析嵌入式Linux系统启动流程

    嵌入式Linux专题(一)已经对嵌入式Linux系统的架构及启动流程了初步的介绍,本文将详细分析
    发表于 11-05 09:25

    嵌入式开发为什么选择C语言?

    1、嵌入式开发为什么选择C语言?(面试题!!!)嵌入式开发操作系统是核心,需要移植,并在上层和底层做
    发表于 12-15 07:45

    嵌入式系统高级C语言编程

    嵌入式系统高级C语言编程》将以实际项目中的代码作实例来进行介绍,详细分析嵌入式系统开发中程序
    发表于 10-27 16:36 4729次阅读

    嵌入式开发就业前景分析_嵌入式领域的职业发展方向

    嵌入式开发威廉希尔官方网站 在物联网领域应用最为广泛,适合于各个领域,主要应用于消费类电子行业。嵌入式开发的入门门槛还是比较高的。那么嵌入式开发就业前景怎么样呢?嵌入式领域的职业发展方向是什么?本文
    发表于 01-29 14:09 1.9w次阅读

    嵌入式开发语言哪些_最全面嵌入式开发语言概述

    嵌入式开发语言哪些?嵌入式开发的入门门槛还是比较高的,不仅要懂较底层软件,对软件专业水平要求较高,而且必须懂得硬件的工作原理,嵌入式系统应
    发表于 01-29 14:47 9831次阅读
    <b class='flag-5'>嵌入式开发</b><b class='flag-5'>语言</b><b class='flag-5'>有</b>哪些_最全面<b class='flag-5'>嵌入式开发</b><b class='flag-5'>语言</b>概述

    嵌入式开发要学什么嵌入式开发的一些入门教材推荐

    本文档的主要内容详细介绍的是嵌入式开发要学什么嵌入式开发的一些入门教材推荐资料免费下载教材包括了:ARM嵌入式项目开发
    发表于 01-10 14:46 27次下载
    <b class='flag-5'>嵌入式开发</b>要学什么<b class='flag-5'>嵌入式开发</b>的一些入门教材推荐

    嵌入式开发通常采用哪种编程语言

    目前在嵌入式开发领域比较常见的编程语言C,另外C++、Python、JavaScript等语言也可以进行
    发表于 06-18 16:59 1.6w次阅读

    什么是嵌入式开发?为什么用C语言作为开发语言

    内部做开发的,而操作系统所有的内核都是C语言所编写的,所以说在嵌入式开发的过程也选择C
    发表于 11-02 18:50 12次下载
    什么是<b class='flag-5'>嵌入式开发</b>?为什么用<b class='flag-5'>C</b><b class='flag-5'>语言</b>作为<b class='flag-5'>开发</b><b class='flag-5'>语言</b>?

    嵌入式开发培训学什么?嵌入式开发板知识讲解

    嵌入式开发就是指在嵌入式操作系统下进行开发,一般常用的系统WinCE,ucos,vxworks,linux,android等。另外,用c
    发表于 11-02 20:21 16次下载
    <b class='flag-5'>嵌入式开发</b>培训学什么?<b class='flag-5'>嵌入式开发</b>板知识<b class='flag-5'>讲解</b>

    嵌入式开发为什么选择C语言作为开发语言

    了解嵌入式开发的朋友们都非常的清楚其核心的开发语言C语言C
    发表于 11-03 09:21 17次下载
    <b class='flag-5'>嵌入式开发</b>为什么选择<b class='flag-5'>C</b><b class='flag-5'>语言</b>作为<b class='flag-5'>开发</b><b class='flag-5'>语言</b>?

    嵌入式为什么选择C语言作为开发语言

    了解嵌入式开发的朋友们都非常的清楚其核心的开发语言C语言C
    发表于 11-03 14:06 15次下载
    <b class='flag-5'>嵌入式</b>为什么选择<b class='flag-5'>C</b><b class='flag-5'>语言</b>作为<b class='flag-5'>开发</b><b class='flag-5'>语言</b>?

    嵌入式开发为什么选择C语言?它有哪些特点?

    众所周知,C语言嵌入式开发占据着十分重要的地位,为什么嵌入式开发要选择C
    的头像 发表于 01-04 09:56 1231次阅读
    <b class='flag-5'>嵌入式开发</b><b class='flag-5'>中</b>为什么选择<b class='flag-5'>C</b><b class='flag-5'>语言</b>?它有哪些特点?

    c语言嵌入式开发

    电子发烧友网站提供《c语言嵌入式开发.zip》资料免费下载
    发表于 11-17 14:11 2次下载
    <b class='flag-5'>c</b><b class='flag-5'>语言</b><b class='flag-5'>嵌入式开发</b>

    嵌入式C语言结构特点

    嵌入式开发既有底层硬件的开发又涉及上层应用的开发,即涉及系统的硬件和软件,C语言既具有汇编
    的头像 发表于 11-24 16:16 693次阅读
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>语言</b>的<b class='flag-5'>结构</b>特点

    嵌入式开发前景怎么样?

    嵌入式开发前景非常广阔,这主要得益于物联网、人工智能、大数据等威廉希尔官方网站 的快速发展,以及嵌入式系统在各个领域的广泛应用。以下是对嵌入式开发前景的详细分析
    的头像 发表于 07-10 09:00 2707次阅读
    <b class='flag-5'>嵌入式开发</b>前景怎么样?