chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

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

結(jié)構(gòu)體對(duì)齊在STM32中的具體體現(xiàn)和如何進(jìn)行不同對(duì)齊方式的設(shè)置

玩轉(zhuǎn)單片機(jī)與嵌入式 ? 來(lái)源:玩轉(zhuǎn)單片機(jī)與嵌入式 ? 2023-08-22 09:31 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

引言

嵌入式系統(tǒng)開(kāi)發(fā)中,結(jié)構(gòu)體作為一種常見(jiàn)的數(shù)據(jù)組織方式,在內(nèi)存中的布局方式對(duì)于程序性能和內(nèi)存占用具有重要影響。本文將深入探討單片機(jī)C語(yǔ)言中的結(jié)構(gòu)體對(duì)齊原理、重要性以及不同的對(duì)齊方式,并通過(guò)示例演示結(jié)構(gòu)體對(duì)齊如何影響內(nèi)存占用、訪(fǎng)問(wèn)性能以及傳輸與存儲(chǔ)。同時(shí),我們將關(guān)注STM32這樣的嵌入式系統(tǒng),討論結(jié)構(gòu)體對(duì)齊在STM32中的具體體現(xiàn)和如何進(jìn)行不同對(duì)齊方式的設(shè)置。

結(jié)構(gòu)體對(duì)齊原理

1、為什么需要對(duì)齊?

在計(jì)算機(jī)內(nèi)存中,數(shù)據(jù)的存儲(chǔ)通常需要按照一定規(guī)則進(jìn)行,這被稱(chēng)為內(nèi)存對(duì)齊。內(nèi)存對(duì)齊的目的是為了提高訪(fǎng)問(wèn)數(shù)據(jù)的效率,特別是對(duì)于硬件平臺(tái)而言。不同的處理器架構(gòu)可能有不同的對(duì)齊要求。

2、不同的對(duì)齊方式

單字節(jié)對(duì)齊(Byte Alignment):每個(gè)數(shù)據(jù)類(lèi)型從內(nèi)存的任意地址開(kāi)始存儲(chǔ),不需要對(duì)齊到特定字節(jié)邊界。

雙字節(jié)對(duì)齊(Half-Word Alignment):數(shù)據(jù)類(lèi)型的變量必須從內(nèi)存的偶數(shù)地址開(kāi)始存儲(chǔ),即地址必須是2的倍數(shù)。

四字節(jié)對(duì)齊(Word Alignment):數(shù)據(jù)類(lèi)型的變量必須從內(nèi)存的4字節(jié)邊界開(kāi)始存儲(chǔ),即地址必須是4的倍數(shù)。

3、結(jié)構(gòu)體對(duì)齊示例

下面的C代碼示例演示了不同對(duì)齊方式在內(nèi)存中如何存儲(chǔ)一個(gè)簡(jiǎn)單的結(jié)構(gòu)體。

#include 


// 結(jié)構(gòu)體定義
struct Example {
    char a;
    int b;
    char c;
};


int main() {
    struct Example e;


    // 計(jì)算各成員的地址
    printf("Address of a: %p
", &e.a);
    printf("Address of b: %p
", &e.b);
    printf("Address of c: %p
", &e.c);


    return 0;
}

在這個(gè)示例中,我們定義了一個(gè)名為Example的結(jié)構(gòu)體,包含一個(gè)字符a、一個(gè)整數(shù)b和一個(gè)字符c。通過(guò)printf語(yǔ)句,我們可以查看不同對(duì)齊方式下各成員的地址。該結(jié)構(gòu)體在內(nèi)存中存儲(chǔ)的方式如下:

9526646a-4077-11ee-ac96-dac502259ad0.png

喜歡的讀者可以自行打印確定printf的輸出結(jié)果,觀(guān)察不同的地址有何規(guī)律。

4、結(jié)構(gòu)體對(duì)齊的影響

(1)內(nèi)存占用

結(jié)構(gòu)體對(duì)齊可以影響內(nèi)存的占用情況??紤]以下示例:

struct Example1 {
    char a;
    int b;
    char c;
};


struct Example2 {
    char a;
    char b;
    char c;
};

在示例1中,int類(lèi)型需要四字節(jié)對(duì)齊,因此struct Example1的大小為12字節(jié)。而在示例2中,所有成員都是字符類(lèi)型,無(wú)需對(duì)齊,因此struct Example2的大小為3字節(jié)。這突顯了對(duì)齊規(guī)則如何影響內(nèi)存占用。

(2)訪(fǎng)問(wèn)性能

結(jié)構(gòu)體對(duì)齊還會(huì)影響訪(fǎng)問(wèn)性能。在訪(fǎng)問(wèn)一個(gè)結(jié)構(gòu)體變量的成員時(shí),如果成員沒(méi)有正確對(duì)齊,可能需要多次內(nèi)存訪(fǎng)問(wèn)操作,從而降低了訪(fǎng)問(wèn)速度。合適的對(duì)齊可以減少內(nèi)存訪(fǎng)問(wèn)次數(shù),提高程序性能。

(3)傳輸和存儲(chǔ)

結(jié)構(gòu)體對(duì)齊也會(huì)影響數(shù)據(jù)的傳輸和存儲(chǔ)。當(dāng)結(jié)構(gòu)體作為數(shù)據(jù)包進(jìn)行傳輸時(shí),如果接收端和發(fā)送端的對(duì)齊方式不一致,可能需要進(jìn)行字節(jié)序轉(zhuǎn)換,以確保數(shù)據(jù)的正確傳輸。

這增加了編程的復(fù)雜性,因?yàn)?a href="http://www.brongaenegriffin.com/v/tag/1730/" target="_blank">程序員需要處理不同對(duì)齊方式可能導(dǎo)致的字節(jié)序問(wèn)題。

下面是一個(gè)傳輸和存儲(chǔ)的C代碼示例,演示了在不同對(duì)齊方式下數(shù)據(jù)的傳輸和存儲(chǔ):

#include 
#include 


// 結(jié)構(gòu)體定義
struct SensorData {
    uint16_t sensor1;
    uint32_t sensor2;
} __attribute__((packed));  // 使用編譯器指令取消結(jié)構(gòu)體對(duì)齊


int main() {
    struct SensorData data;
    data.sensor1 = 0x1234;
    data.sensor2 = 0x56789ABC;


    // 數(shù)據(jù)存儲(chǔ)到內(nèi)存中
    uint8_t buffer[sizeof(struct SensorData)];
    memcpy(buffer, &data, sizeof(struct SensorData));


    // 模擬傳輸過(guò)程
    // 接收端假設(shè)數(shù)據(jù)是按照雙字節(jié)對(duì)齊方式接收
    struct SensorData* receivedData = (struct SensorData*)buffer;


    printf("Received sensor1: 0x%04X
", receivedData->sensor1);
    printf("Received sensor2: 0x%08X
", receivedData->sensor2);


    return 0;
}

在這個(gè)示例中,我們定義了一個(gè)SensorData結(jié)構(gòu)體,包含一個(gè)16位整數(shù)和一個(gè)32位整數(shù)。使用__attribute__((packed))編譯器指令取消了結(jié)構(gòu)體對(duì)齊,以確保數(shù)據(jù)在內(nèi)存中是連續(xù)存儲(chǔ)的。然后,我們將數(shù)據(jù)存儲(chǔ)到內(nèi)存中,并模擬了傳輸過(guò)程。接收端假設(shè)數(shù)據(jù)是按照雙字節(jié)對(duì)齊方式接收,但由于我們?nèi)∠藢?duì)齊,需要進(jìn)行字節(jié)序轉(zhuǎn)換。

結(jié)構(gòu)體對(duì)齊在STM32中的體現(xiàn)

1、外設(shè)寄存器對(duì)齊要求

在STM32這樣的嵌入式系統(tǒng)中,外設(shè)寄存器通常要求雙字節(jié)或四字節(jié)對(duì)齊,以確保寄存器的訪(fǎng)問(wèn)性能和正確性。不滿(mǎn)足對(duì)齊要求可能導(dǎo)致未定義的行為或性能問(wèn)題。

在STM32中,可以使用編譯器指令來(lái)實(shí)現(xiàn)對(duì)齊設(shè)置。例如,在Keil工程中,可以使用__align()指令來(lái)指定對(duì)齊方式。例如,要將一個(gè)結(jié)構(gòu)體成員對(duì)齊到4字節(jié)邊界,可以這樣定義:

struct Example {
    char a;
    int b;
    char c;
} __attribute__((aligned(4)));

2、內(nèi)存池分配

在嵌入式系統(tǒng)中,經(jīng)常使用內(nèi)存池來(lái)分配內(nèi)存。內(nèi)存池分配會(huì)確保分配的內(nèi)存塊是按照對(duì)齊要求進(jìn)行的,以滿(mǎn)足處理器的要求。這可以防止未對(duì)齊內(nèi)存訪(fǎng)問(wèn),提高代碼的穩(wěn)定性和可靠性。

在STM32中,常用的內(nèi)存池分配庫(kù)如FreeRTOS提供了對(duì)齊設(shè)置的選項(xiàng),以確保分配的內(nèi)存塊滿(mǎn)足處理器的要求。

3、DMA操作

嵌入式系統(tǒng)中常常使用DMA(直接內(nèi)存訪(fǎng)問(wèn))來(lái)進(jìn)行數(shù)據(jù)傳輸。DMA操作通常要求數(shù)據(jù)緩沖區(qū)是雙字節(jié)或四字節(jié)對(duì)齊的。不滿(mǎn)足對(duì)齊要求可能導(dǎo)致DMA傳輸失敗或性能下降。

在STM32中,配置DMA時(shí)可以使用寄存器來(lái)設(shè)置數(shù)據(jù)對(duì)齊方式,以確保DMA傳輸?shù)恼_性和性能。

結(jié)論

作為嵌入式工程師的我們。在編寫(xiě)代碼時(shí),程序員需要根據(jù)目標(biāo)硬件平臺(tái)的對(duì)齊要求。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    20069

    瀏覽量

    242751
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6071

    文章

    45256

    瀏覽量

    660060
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    39

    文章

    7692

    瀏覽量

    170027
  • STM32
    +關(guān)注

    關(guān)注

    2301

    文章

    11073

    瀏覽量

    369363
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    183

    文章

    7634

    瀏覽量

    143913

原文標(biāo)題:結(jié)構(gòu)體對(duì)齊原理及在STM32中的設(shè)計(jì)原則和實(shí)現(xiàn)

文章出處:【微信號(hào):玩轉(zhuǎn)單片機(jī)與嵌入式,微信公眾號(hào):玩轉(zhuǎn)單片機(jī)與嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    C語(yǔ)言結(jié)構(gòu)對(duì)齊介紹

    大家好,我是嵌入式老林,從事嵌入式軟件開(kāi)發(fā)多年,今天分享的內(nèi)容是C語(yǔ)言結(jié)構(gòu)對(duì)齊介紹,希望能對(duì)你有所幫助
    發(fā)表于 07-11 11:50 ?3181次閱讀
    C語(yǔ)言<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b><b class='flag-5'>對(duì)齊</b>介紹

    C語(yǔ)言-結(jié)構(gòu)對(duì)齊詳解

    4字節(jié)對(duì)齊處存放,結(jié)構(gòu)對(duì)齊后的大小必須4的倍數(shù),如果編譯器設(shè)置為8字節(jié)對(duì)齊,則這里的4就是8。
    發(fā)表于 07-12 16:41

    CCS3.3 結(jié)構(gòu)成員對(duì)齊

    : expected a type specifier error: expected a ";" 這個(gè)錯(cuò)誤。是CCS3.3編譯器本身不支持__packed這種結(jié)構(gòu)成員的對(duì)齊方式
    發(fā)表于 06-21 10:16

    請(qǐng)問(wèn)ccs4.2 怎么設(shè)置結(jié)構(gòu)的字節(jié)對(duì)齊?

    請(qǐng)問(wèn)ccs4.2 怎么設(shè)置結(jié)構(gòu)的字節(jié)對(duì)齊,用于網(wǎng)絡(luò)數(shù)據(jù)發(fā)送的。是:]__attribute
    發(fā)表于 08-02 07:47

    請(qǐng)問(wèn)z-stack結(jié)構(gòu)默認(rèn)對(duì)齊方式是一字節(jié)嗎?

    z-stack的結(jié)構(gòu)默認(rèn)對(duì)齊方式是一字節(jié)嗎?z-stack可以將一般指針強(qiáng)制轉(zhuǎn)換為
    發(fā)表于 08-18 07:38

    測(cè)試結(jié)構(gòu)成員內(nèi)存對(duì)齊方式方法

    //測(cè)試環(huán)境:keil for ARM//測(cè)試目的:通過(guò)keil仿真,介紹結(jié)構(gòu)成員對(duì)齊方式 #pragma pack ()//定義一個(gè)聯(lián)合體類(lèi)型 struct stru {int a
    發(fā)表于 12-21 07:37

    ARM內(nèi)存邊界對(duì)齊以及sizeof問(wèn)題

    默認(rèn)情況下,32位cpu里,gcc對(duì)于結(jié)構(gòu)對(duì)齊方式是按照四個(gè)字節(jié)來(lái)對(duì)齊的。
    發(fā)表于 06-16 11:10 ?3163次閱讀

    CSS對(duì)齊方式的詳細(xì)講解

    本文基于Html基礎(chǔ),主要介紹了Html對(duì)齊方式,對(duì)于對(duì)齊的標(biāo)簽做了詳細(xì)的講解,用豐富的案例 ,代碼效果圖的展示,幫助大家更好理解 。
    的頭像 發(fā)表于 12-24 15:38 ?1645次閱讀

    解析C語(yǔ)言結(jié)構(gòu)字節(jié)如何對(duì)齊

    我們不使用宏#pragma pack,采用默認(rèn)字節(jié)對(duì)齊方式。 先拋出結(jié)論: 一個(gè)結(jié)構(gòu)第一個(gè)
    的頭像 發(fā)表于 06-12 17:42 ?3553次閱讀

    STM32 終極字節(jié)對(duì)齊解析

    字節(jié)對(duì)齊。uint64_t定義變量地址要8字節(jié)對(duì)齊。指針變量是4字節(jié)對(duì)齊。二、結(jié)構(gòu)成員對(duì)齊問(wèn)題
    發(fā)表于 11-23 18:06 ?11次下載
    <b class='flag-5'>STM32</b> 終極字節(jié)<b class='flag-5'>對(duì)齊</b>解析

    對(duì)結(jié)構(gòu)對(duì)齊理解上有點(diǎn)偏差

    總結(jié)一下: 結(jié)構(gòu)對(duì)齊不再是簡(jiǎn)單的字節(jié)個(gè)數(shù)的拼湊,而是要與內(nèi)存地址進(jìn)行掛鉤~一般我們也可以理解為內(nèi)存地址分配是多少字節(jié)的倍數(shù),就是多少直接對(duì)齊
    的頭像 發(fā)表于 08-10 18:08 ?1686次閱讀
    對(duì)<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>的<b class='flag-5'>對(duì)齊</b>理解上有點(diǎn)偏差

    結(jié)構(gòu)對(duì)齊為什么那么重要?

    以前我也沒(méi)覺(jué)得懂得這個(gè)結(jié)構(gòu)對(duì)齊或者內(nèi)存對(duì)齊有多重要,直到已經(jīng)從事了嵌入式開(kāi)發(fā)經(jīng)驗(yàn)不斷積累,才慢慢體會(huì)到,這是一種很基礎(chǔ)的知識(shí),就因?yàn)檫@個(gè)東西不常用,而出現(xiàn)相關(guān)的問(wèn)題是非常致命的,排查
    的頭像 發(fā)表于 04-03 10:13 ?1731次閱讀

    為什么要結(jié)構(gòu)對(duì)齊?為什么結(jié)構(gòu)對(duì)齊那么重要?

    C語(yǔ)言結(jié)構(gòu)對(duì)齊問(wèn)題,是面試必備問(wèn)題。我參與招聘技術(shù)面試的時(shí)候,也喜歡問(wèn)這個(gè)技術(shù)點(diǎn)。
    的頭像 發(fā)表于 05-26 14:10 ?1851次閱讀
    為什么要<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b><b class='flag-5'>對(duì)齊</b>?為什么<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b><b class='flag-5'>對(duì)齊</b>那么重要?

    keil arm工程結(jié)構(gòu)1字節(jié)對(duì)齊如何實(shí)現(xiàn)

    的默認(rèn)對(duì)齊方式和規(guī)則 結(jié)構(gòu)Keil Arm工程的默認(rèn)對(duì)
    的頭像 發(fā)表于 01-05 14:40 ?5965次閱讀

    鴻蒙ArkUI開(kāi)發(fā):【彈性布局(主軸&amp;交叉軸對(duì)齊方式)】

    通過(guò)justifyContent參數(shù)設(shè)置主軸方向的對(duì)齊方式,和Row、Column的主軸對(duì)齊方式
    的頭像 發(fā)表于 05-14 15:33 ?1408次閱讀
    鴻蒙ArkUI開(kāi)發(fā):【彈性布局(主軸&amp;交叉軸<b class='flag-5'>對(duì)齊</b><b class='flag-5'>方式</b>)】