0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

學習嵌入式C編程語言:了解聯(lián)合數(shù)據(jù)對象

嵌入式星球 ? 2020-09-28 09:58 ? 次閱讀
嵌入式C中struct與union的區(qū)別

在本系列的上一篇文章中,我們討論了嵌入式C中的結構允許我們對不同數(shù)據(jù)類型的變量進行分組并將它們作為單個數(shù)據(jù)對象進行處理。
除了結構之外,C語言還支持另一個稱為聯(lián)合的數(shù)據(jù)結構,該結構可以將不同的數(shù)據(jù)類型組合為一個數(shù)據(jù)對象。本文將提供有關工會的一些基本信息。我們首先來看一個聲明并集的介紹性示例,然后研究該數(shù)據(jù)對象的重要應用。

入門實例聲明一個聯(lián)合就像聲明一個結構。我們只需要將關鍵字“ struct”替換為“ union”即可??紤]以下示例代碼:
uniontest{
uint8_tc;
uint32_ti;
};

這指定了一個模板,該模板具有兩個成員:“ c”(占用一個字節(jié))和“ i”(占用四個字節(jié))。

現(xiàn)在,我們可以創(chuàng)建該聯(lián)合模板的變量:

uniontestu1;

使用成員運算符(。),我們可以訪問“ u1”聯(lián)合的成員。例如,以下代碼將10分配給上述聯(lián)合的第二個成員,并將“ c”的值復制到“ m”變量(其類型必須為uint8_t)。
u1.i=10;
m=u1.c;

將分配多少存儲空間來存儲“ u1”變量?盡管結構的大小至少等于其成員的大小之和,但并集的大小等于其最大變量的大小。分配給工會的內(nèi)存空間將在所有工會成員之間共享。在上面的示例中,“ u1”的大小等于uint32_t的大小,即四個字節(jié)。此存儲空間在“ i”和“ c”之間共享。因此,為這兩個成員之一分配值將更改另一個成員的值。
您可能想知道,“使用相同的內(nèi)存空間來存儲多個變量有什么意義?此功能有什么應用程序?” 我們將在下一部分中探討此問題。

我們需要共享的內(nèi)存空間嗎?
讓我們看一個示例,其中聯(lián)合可以是有用的數(shù)據(jù)對象。假定,如下圖1所示,系統(tǒng)中有兩個設備需要相互通信。


圖1

“設備A”應將狀態(tài),速度和位置信息發(fā)送到“設備B”。狀態(tài)信息由三個變量組成,這些變量指示電池電量,操作模式和環(huán)境溫度。該位置由兩個變量表示,這些變量顯示了x軸和y軸的位置。最后,速度由單個變量表示。假定這些變量的大小如下表所示。

表.png

如果“設備B”需要不斷獲取所有這些信息,我們可以將所有這些變量存儲在結構中,并將該結構發(fā)送到“設備B”。結構大小將至少等于這些變量的大小之和,即9個字節(jié)。

因此,每次“設備A”與“設備B”對話時,都需要通過兩個設備之間的通信鏈路傳輸9字節(jié)的數(shù)據(jù)幀。圖2描繪了“設備A”用來存儲變量和需要通過通信鏈接的數(shù)據(jù)幀的結構。


圖2
但是,讓我們考慮另一種情況,我們僅偶爾需要發(fā)送狀態(tài)信息。另外,假設沒有必要在給定時間同時獲取位置和速度信息。換句話說,有時我們僅發(fā)送位置,有時僅發(fā)送速度,有時僅發(fā)送狀態(tài)信息。在這種情況下,將信息存儲為9字節(jié)結構并通過通信鏈接進行傳輸似乎不是一個好主意。

狀態(tài)信息只能由三個字節(jié)表示。對于位置和速度,我們分別只需要四個和兩個字節(jié)。因此,“設備A”在一次傳輸中需要發(fā)送的最大字節(jié)數(shù)為4,因此,我們僅需要四個字節(jié)的內(nèi)存即可存儲此信息。這四個字節(jié)的內(nèi)存空間將在我們的三種消息類型之間共享(請參見圖3)。

此外,請注意,通過通信鏈路傳遞的數(shù)據(jù)幀的長度從九個字節(jié)減少到四個字節(jié)。


圖3
總而言之,如果我們的程序具有互斥的變量,我們可以將它們存儲在共享的內(nèi)存區(qū)域中,以保留寶貴的內(nèi)存空間。這可能很重要,尤其是在內(nèi)存受限的嵌入式系統(tǒng)中。在這種情況下,我們可以使用聯(lián)合創(chuàng)建所需的共享內(nèi)存空間。

上面的示例表明,使用聯(lián)合來處理互斥變量也可以幫助我們節(jié)省通信帶寬。節(jié)省通信帶寬有時甚至比節(jié)省內(nèi)存更為重要。

對消息包使用聯(lián)合
讓我們看看如何使用聯(lián)合存儲上面示例的變量。我們有三種不同的消息類型:狀態(tài),位置和速度。我們可以為狀態(tài)和位置消息的變量創(chuàng)建一個結構(以便將這些消息的變量分組并作為單個數(shù)據(jù)對象進行操作)。
以下結構用于此目的:

struct{
uint8_tpower;
unit8_top_mode;
uint8_ttemp;
}status;

struct{
uint16_tx_pos;
unit16_ty_pos;
}position;

現(xiàn)在,我們可以將這些結構與“ vel”變量一起放在一個并集中:

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

struct{
uint16_tx_pos;
unit16_ty_pos;
}position;

uint16_tvel;

}msg_union;

上面的代碼指定了聯(lián)合模板,并創(chuàng)建了該模板的變量(名為“ msg_union”)。在該聯(lián)合內(nèi)部,有兩個結構(“狀態(tài)”和“位置”)和一個兩個字節(jié)的變量(“ vel”)。此聯(lián)合的大小將等于其最大成員的大小,即“位置”結構,該結構占用四個字節(jié)的內(nèi)存。此存儲空間在“狀態(tài)”,“位置”和“ vel”變量之間共享。

如何跟蹤結構體活躍成員
我們可以使用上述聯(lián)合的共享內(nèi)存空間來存儲我們的變量;但是,仍然存在一個問題:接收方應如何確定已發(fā)送哪種類型的消息?接收者需要識別消息類型才能成功解釋接收到的信息。例如,如果我們發(fā)送“位置”消息,則接收到的數(shù)據(jù)的所有四個字節(jié)都很重要,但是對于“速度”消息,僅應使用接收到的字節(jié)中的兩個。

要解決此問題,我們需要將聯(lián)合與另一個變量關聯(lián),例如“ msg_type”,該變量指示消息類型(或最后寫入的聯(lián)合成員)。結合有離散值(表示該聯(lián)盟的活動成員)的聯(lián)合稱為“區(qū)分聯(lián)合”或“標記聯(lián)合”。

關于“ msg_type”變量的數(shù)據(jù)類型,我們可以使用C語言的枚舉數(shù)據(jù)類型來創(chuàng)建符號常量。但是,我們將使用字符來指定消息類型,只是為了使事情盡可能簡單:

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”表示“狀態(tài)”消息,“ p”表示“位置”消息,“ v”表示“速度”消息?,F(xiàn)在,我們可以將“消息”結構發(fā)送到“設備B”,并使用“ msg_type”變量的值作為消息類型的指示符。例如,如果接收到的“ msg_type”的值為“ p”,則“設備B”將知道共享內(nèi)存空間包含兩個2字節(jié)變量。

注意,由于我們需要傳遞“ msg_type”變量,因此必須在通過通信鏈接發(fā)送的數(shù)據(jù)幀中添加另一個字節(jié)。還請注意,使用此解決方案,接收者無需提前知道傳入的是哪種消息。

替代解決方案:動態(tài)內(nèi)存分配
我們看到,并集使我們可以聲明一個共享內(nèi)存區(qū)域,以節(jié)省內(nèi)存空間和通信帶寬。但是,還有另一種存儲互斥變量的方法,例如上面的示例。第二種解決方案使用動態(tài)內(nèi)存分配來存儲每種消息類型的變量。

同樣,我們將需要有一個變量“ msg_type”來指定通信鏈路的發(fā)送器和接收器端的消息類型。例如,如果“設備A”需要發(fā)送位置消息,它將“ msg_type”設置為“ p”并分配四個字節(jié)的存儲空間來存儲“ x_pos”和“ y_pos”變量。接收器將檢查“ msg_type”的值,并根據(jù)其值創(chuàng)建適當?shù)拇鎯臻g以存儲和解釋傳入的數(shù)據(jù)幀。

就內(nèi)存使用而言,動態(tài)內(nèi)存的使用會更有效,因為我們?yōu)槊糠N消息類型分配的空間恰到好處?;诼?lián)合的解決方案并非如此。在那里,我們有四個字節(jié)的共享內(nèi)存來存儲所有三種消息類型,盡管“狀態(tài)”消息和“速度”消息分別僅需要三個字節(jié)和兩個字節(jié)。但是,動態(tài)內(nèi)存分配可能會變慢,并且程序員需要包含釋放分配的內(nèi)存的代碼。因此,程序員通常更喜歡使用基于聯(lián)合的解決方案。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
收藏 人收藏

    評論

    相關推薦

    零基礎嵌入式開發(fā)學習路線

    嵌入式開發(fā)”沒有接觸過的同學可能會不明覺厲,但是只要你了解了,感興趣并且有一個正確的學習路線的話,零基礎也能入門。給大家介紹一個簡單易懂的學習路線,讓你能夠從零開始
    發(fā)表于 10-25 15:55

    嵌入式學習建議

    原理的嵌入式操作系統(tǒng)進行學習。不要一開始就學習幾種操作系統(tǒng),理解了基本原理,實踐中確有實際需要再學習也不遲。人總是要不斷學習的。 ⑨關于匯
    發(fā)表于 10-22 11:41

    嵌入式系統(tǒng)怎么學?

    一系列課程和技術,包括但不限于以下內(nèi)容: 1、基礎知識:學習計算機組成原理、數(shù)字電路、模擬電路等基礎知識,建立對計算機硬件的認知與理解。 2、編程語言:掌握至少一種嵌入式系統(tǒng)常用的
    發(fā)表于 07-02 10:10

    如何提升嵌入式編程能力?

    其他硬件的數(shù)據(jù)手冊,了解其特性和編程接口。 6. 學習低級編程嵌入式
    發(fā)表于 06-21 10:01

    如何成為一名嵌入式C語言高手?

    相關教材、參加在線課程或者參考編程書籍來系統(tǒng)地學習C語言的基礎知識,并通過編寫簡單的程序進行實踐。 二、深入了解
    發(fā)表于 04-07 16:03

    如何成為一名嵌入式C語言高手?

    相關教材、參加在線課程或者參考編程書籍來系統(tǒng)地學習C語言的基礎知識,并通過編寫簡單的程序進行實踐。 二、深入了解
    發(fā)表于 03-25 14:12

    嵌入式軟件開發(fā)應該掌握哪些知識?

    掌握的知識 1.基礎知識 1.1 c/c++編程語言和數(shù)據(jù)結構 C/C++ 是
    發(fā)表于 02-19 11:23

    嵌入式學習步驟

    開發(fā)。 嵌入式學習步驟總結如下: (1).確定目標平臺:選擇適合您要開發(fā)的嵌入式系統(tǒng)的硬件平臺。這取決于您要控制的設備以及您需要執(zhí)行的任務。 (2).選擇編程
    發(fā)表于 02-02 15:24

    聊一聊嵌入式C語言

    作為一名嵌入式軟件開發(fā)者,熟練掌握嵌入式C語言對我的日常工作至關重要。
    的頭像 發(fā)表于 01-22 09:28 ?509次閱讀

    嵌入式C語言高手煉成之內(nèi)存操作篇

    嵌入式系統(tǒng)的編程中,常常要求在特定的內(nèi)存單元讀寫內(nèi)容,匯編有對應的MOV指令,而除C/C++以外的其它編程
    的頭像 發(fā)表于 12-11 17:20 ?475次閱讀

    嵌入式C語言的結構特點

    過程中,不論是基于寄存器開發(fā)還是基于庫開發(fā),深入理解和掌握嵌入式C語言的函數(shù)、指針、結構體是學習STM32的關鍵。嵌入式
    的頭像 發(fā)表于 11-24 16:16 ?616次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>的結構特點

    嵌入式系統(tǒng)的C語言

    電子發(fā)燒友網(wǎng)站提供《嵌入式系統(tǒng)的C語言.doc》資料免費下載
    發(fā)表于 11-18 14:39 ?2次下載
    <b class='flag-5'>嵌入式</b>系統(tǒng)的<b class='flag-5'>C</b><b class='flag-5'>語言</b>

    C語言進階之嵌入式系統(tǒng)高級C語言編程

    電子發(fā)燒友網(wǎng)站提供《C語言進階之嵌入式系統(tǒng)高級C語言編程.rar》資料免費下載
    發(fā)表于 11-18 10:32 ?1次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>進階之<b class='flag-5'>嵌入式</b>系統(tǒng)高級<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>編程</b>

    c語言嵌入式開發(fā)

    電子發(fā)燒友網(wǎng)站提供《c語言嵌入式開發(fā).zip》資料免費下載
    發(fā)表于 11-17 14:11 ?2次下載
    <b class='flag-5'>c</b><b class='flag-5'>語言</b><b class='flag-5'>嵌入式</b>開發(fā)

    C語言嵌入式系統(tǒng)編程修煉之一:背景篇

    電子發(fā)燒友網(wǎng)站提供《C語言嵌入式系統(tǒng)編程修煉之一:背景篇.rar》資料免費下載
    發(fā)表于 11-17 11:35 ?1次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>嵌入式</b>系統(tǒng)<b class='flag-5'>編程</b>修煉之一:背景篇