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

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

3天内不再提示

学习嵌入式C编程语言:了解联合数据对象

嵌入式星球 2020-09-28 09:58 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式C中struct与union的区别

在本系列的上一篇文章中,我们讨论了嵌入式C中的结构允许我们对不同数据类型的变量进行分组并将它们作为单个数据对象进行处理。
除了结构之外,C语言还支持另一个称为联合的数据结构,该结构可以将不同的数据类型组合为一个数据对象。本文将提供有关工会的一些基本信息。我们首先来看一个声明并集的介绍性示例,然后研究该数据对象的重要应用。

入门实例声明一个联合就像声明一个结构。我们只需要将关键字“ struct”替换为“ union”即可。考虑以下示例代码:
uniontest{
uint8_tc;
uint32_ti;
};

这指定了一个模板,该模板具有两个成员:“ c”(占用一个字节)和“ i”(占用四个字节)。

现在,我们可以创建该联合模板的变量:

uniontestu1;

使用成员运算符(。),我们可以访问“ u1”联合的成员。例如,以下代码将10分配给上述联合的第二个成员,并将“ c”的值复制到“ m”变量(其类型必须为uint8_t)。
u1.i=10;
m=u1.c;

将分配多少存储空间来存储“ u1”变量?尽管结构的大小至少等于其成员的大小之和,但并集的大小等于其最大变量的大小。分配给工会的内存空间将在所有工会成员之间共享。在上面的示例中,“ u1”的大小等于uint32_t的大小,即四个字节。此存储空间在“ i”和“ c”之间共享。因此,为这两个成员之一分配值将更改另一个成员的值。
您可能想知道,“使用相同的内存空间来存储多个变量有什么意义?此功能有什么应用程序?” 我们将在下一部分中探讨此问题。

我们需要共享的内存空间吗?
让我们看一个示例,其中联合可以是有用的数据对象。假定,如下图1所示,系统中有两个设备需要相互通信


图1

“设备A”应将状态,速度和位置信息发送到“设备B”。状态信息由三个变量组成,这些变量指示电池电量,操作模式和环境温度。该位置由两个变量表示,这些变量显示了x轴和y轴的位置。最后,速度由单个变量表示。假定这些变量的大小如下表所示。

表.png

如果“设备B”需要不断获取所有这些信息,我们可以将所有这些变量存储在结构中,并将该结构发送到“设备B”。结构大小将至少等于这些变量的大小之和,即9个字节。

因此,每次“设备A”与“设备B”对话时,都需要通过两个设备之间的通信链路传输9字节的数据帧。图2描绘了“设备A”用来存储变量和需要通过通信链接的数据帧的结构。


图2
但是,让我们考虑另一种情况,我们仅偶尔需要发送状态信息。另外,假设没有必要在给定时间同时获取位置和速度信息。换句话说,有时我们仅发送位置,有时仅发送速度,有时仅发送状态信息。在这种情况下,将信息存储为9字节结构并通过通信链接进行传输似乎不是一个好主意。

状态信息只能由三个字节表示。对于位置和速度,我们分别只需要四个和两个字节。因此,“设备A”在一次传输中需要发送的最大字节数为4,因此,我们仅需要四个字节的内存即可存储此信息。这四个字节的内存空间将在我们的三种消息类型之间共享(请参见图3)。

此外,请注意,通过通信链路传递的数据帧的长度从九个字节减少到四个字节。


图3
总而言之,如果我们的程序具有互斥的变量,我们可以将它们存储在共享的内存区域中,以保留宝贵的内存空间。这可能很重要,尤其是在内存受限的嵌入式系统中。在这种情况下,我们可以使用联合创建所需的共享内存空间。

上面的示例表明,使用联合来处理互斥变量也可以帮助我们节省通信带宽。节省通信带宽有时甚至比节省内存更为重要。

对消息包使用联合
让我们看看如何使用联合存储上面示例的变量。我们有三种不同的消息类型:状态,位置和速度。我们可以为状态和位置消息的变量创建一个结构(以便将这些消息的变量分组并作为单个数据对象进行操作)。
以下结构用于此目的:

struct{
uint8_tpower;
unit8_top_mode;
uint8_ttemp;
}status;

struct{
uint16_tx_pos;
unit16_ty_pos;
}position;

现在,我们可以将这些结构与“ vel”变量一起放在一个并集中:

union{
struct{
uint8_tpower;
unit8_top_mode;
uint8_ttemp;
}status;

struct{
uint16_tx_pos;
unit16_ty_pos;
}position;

uint16_tvel;

}msg_union;

上面的代码指定了联合模板,并创建了该模板的变量(名为“ msg_union”)。在该联合内部,有两个结构(“状态”和“位置”)和一个两个字节的变量(“ vel”)。此联合的大小将等于其最大成员的大小,即“位置”结构,该结构占用四个字节的内存。此存储空间在“状态”,“位置”和“ vel”变量之间共享。

如何跟踪结构体活跃成员
我们可以使用上述联合的共享内存空间来存储我们的变量;但是,仍然存在一个问题:接收方应如何确定已发送哪种类型的消息?接收者需要识别消息类型才能成功解释接收到的信息。例如,如果我们发送“位置”消息,则接收到的数据的所有四个字节都很重要,但是对于“速度”消息,仅应使用接收到的字节中的两个。

要解决此问题,我们需要将联合与另一个变量关联,例如“ msg_type”,该变量指示消息类型(或最后写入的联合成员)。结合有离散值(表示该联盟的活动成员)的联合称为“区分联合”或“标记联合”。

关于“ msg_type”变量的数据类型,我们可以使用C语言的枚举数据类型来创建符号常量。但是,我们将使用字符来指定消息类型,只是为了使事情尽可能简单:

struct{
uint8_tmsg_type;
union{
struct{
uint8_tpower;
unit8_top_mode;
uint8_ttemp;
}status;

struct{
uint16_tx_pos;
unit16_ty_pos;
}position;

uint16_tvel;

}msg_union;
}message;

我们可以为“ msg_type”变量考虑三个可能的值:“ s”表示“状态”消息,“ p”表示“位置”消息,“ v”表示“速度”消息。现在,我们可以将“消息”结构发送到“设备B”,并使用“ msg_type”变量的值作为消息类型的指示符。例如,如果接收到的“ msg_type”的值为“ p”,则“设备B”将知道共享内存空间包含两个2字节变量。

注意,由于我们需要传递“ msg_type”变量,因此必须在通过通信链接发送的数据帧中添加另一个字节。还请注意,使用此解决方案,接收者无需提前知道传入的是哪种消息。

替代解决方案:动态内存分配
我们看到,并集使我们可以声明一个共享内存区域,以节省内存空间和通信带宽。但是,还有另一种存储互斥变量的方法,例如上面的示例。第二种解决方案使用动态内存分配来存储每种消息类型的变量。

同样,我们将需要有一个变量“ msg_type”来指定通信链路的发送器和接收器端的消息类型。例如,如果“设备A”需要发送位置消息,它将“ msg_type”设置为“ p”并分配四个字节的存储空间来存储“ x_pos”和“ y_pos”变量。接收器将检查“ msg_type”的值,并根据其值创建适当的存储空间以存储和解释传入的数据帧。

就内存使用而言,动态内存的使用会更有效,因为我们为每种消息类型分配的空间恰到好处。基于联合的解决方案并非如此。在那里,我们有四个字节的共享内存来存储所有三种消息类型,尽管“状态”消息和“速度”消息分别仅需要三个字节和两个字节。但是,动态内存分配可能会变慢,并且程序员需要包含释放分配的内存的代码。因此,程序员通常更喜欢使用基于联合的解决方案。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何成为一名高薪嵌入式工程师?

    精通指针、内存管理、结构体、位操作等,理解底层硬件交互原理。 C++(可选):面向对象编程嵌入式Linux或复杂系统中应用广泛,如驱动开发、中间件设计。 汇编
    发表于 04-09 09:03

    嵌入式单片机开发学习路径

    学习C语言 C语言嵌入式开发的基础。掌握C
    发表于 02-09 15:42

    什么是嵌入式应用开发?

    包括ARM7、ARM9、ARM11、PowerPC、MIPS等。这些处理器和编程语言的选择取决于具体的硬件条件和开发需求‌。 综上所述,嵌入式应用开发是一个综合性的技术领域,涉及硬件和软件的紧密结合,广泛应用于各种设备和系统中
    发表于 01-12 16:13

    C语言嵌入式系统编程注意事项-内存操作

    C语言嵌入式系统编程注意事项之内存操作 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,
    发表于 01-04 07:31

    嵌入式应掌握的几种能力

    1. 编程语言 基本掌握嵌入式必备的编程语言C语言
    发表于 12-08 06:05

    分享一个嵌入式开发学习路线

    如果你想要学习嵌入式开发,我建议按照这个学习路线准备: 1. 基础铺垫期(1-2个月) 理解嵌入式系统的“硬件基础”和“编程入门”,能看懂
    发表于 12-04 11:01

    CW32嵌入式软件开发的必备知识

    嵌入式软件开发作为计算机科学和电子工程的交叉领域,要求开发人员具备一系列的专业知识和技能。 而基于CW32的嵌入式软件开发必备知识包括以下部分: 1 、编程语言 熟练掌握
    发表于 11-28 07:48

    C语言嵌入式开发中的应用

    C 语言可以利用 Socket 编程等技术,实现嵌入式设备与服务器之间的 TCP/IP 通信,确保数据的可靠传输。同时,
    发表于 11-21 08:09

    2025年最佳的嵌入式编程语言有哪些呢?

    嵌入式系统是现代科技不可或缺的一部分。它们存在于家用电器、汽车、住宅、医院、商店等各个领域。它们与我们的社会紧密相连。选择合适的语言来构建嵌入式系统对于成功至关重要。那么,2025年最佳的嵌入
    的头像 发表于 11-14 10:27 1745次阅读
    2025年最佳的<b class='flag-5'>嵌入式</b><b class='flag-5'>编程</b><b class='flag-5'>语言</b>有哪些呢?

    C语言是否会阻碍嵌入式的发展?

    门老朋友:C语言。电子工业已经走过了50多年,而C语言仍然是超过六成嵌入式项目的首选。它驱动着全球数以亿计,甚至以万亿计的设备。但它的统治地
    的头像 发表于 11-14 10:27 520次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>是否会阻碍<b class='flag-5'>嵌入式</b>的发展?

    一文了解Mojo编程语言

    ,利用硬件加速提升效率。 科学计算与数据处理 高效处理大规模数值分析、基因组学数据等任务。 系统工具开发 开发操作系统级工具,结合 Python 的便捷性和 C 的性能优势。 嵌入式
    发表于 11-07 05:59

    嵌入式需要掌握哪些核心技能?

    嵌入式需要掌握哪些核心技能? 若想通过学习嵌入式技术提升就业竞争力,需重点掌握C语言嵌入式
    发表于 10-21 16:25

    盘点嵌入式就业所需要的技能有哪些?

    ,把握未来的职业机遇。 1.智能汽车行业: - 熟悉嵌入式编程语言,如C/C++、Python等。 - 掌握
    发表于 08-11 15:43

    入行嵌入式应该怎么准备?

    知识: 一、C/C++编程C/C++是嵌入式系统开发中最常用的
    发表于 08-06 10:34

    嵌入式开发入门指南:从零开始学习嵌入式

    特定功能的计算机系统,广泛应用于智能家居、工业控制、医疗设备、车载系统等领域。 2. 学习嵌入式开发的前置知识熟悉C语言编程掌握基本的
    发表于 05-15 09:29