国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Keil5,ARM編譯器 軟件優(yōu)化注意事項(xiàng)

這篇具有很好參考價(jià)值的文章主要介紹了Keil5,ARM編譯器 軟件優(yōu)化注意事項(xiàng)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

優(yōu)化C代碼中的環(huán)路終止

循環(huán)是大多數(shù)程序中的常見(jiàn)結(jié)構(gòu)。由于大量的執(zhí)行時(shí)間通?;ㄙM(fèi)在循環(huán)中,因此值得關(guān)注時(shí)間關(guān)鍵循環(huán)。

如果不謹(jǐn)慎地編寫,環(huán)路終止條件可能會(huì)導(dǎo)致大量開(kāi)銷。在可能的情況下:

  • 使用簡(jiǎn)單的終止條件。

  • 寫入倒計(jì)時(shí)到零循環(huán)。

  • 使用?unsigned int?類型的計(jì)數(shù)器。

  • 測(cè)試與零的相等性。

單獨(dú)或組合遵循這些準(zhǔn)則中的任何或全部準(zhǔn)則可能會(huì)產(chǎn)生更好的代碼。

下表顯示了用于計(jì)算?n!?的例程的兩個(gè)示例實(shí)現(xiàn),它們共同說(shuō)明了環(huán)路終止開(kāi)銷。第一個(gè)實(shí)現(xiàn)使用遞增循環(huán)計(jì)算 n!,而第二個(gè)例程使用遞減循環(huán)計(jì)算?n!。

表7-1 遞增和遞減循環(huán)的C代碼

遞增循環(huán) 遞減循環(huán)
int fact1(int n)
{
    int i, fact = 1;
    for (i = 1; i <= n; i++)
        fact *= i;
    return (fact);
}
int fact2(int n)
{
    unsigned int i, fact = 1;
    for (i = n; i != 0; i--)
        fact *= i;
    return (fact);
}

下表顯示了?armclang -Os -S --target=armv8a-arm-none-eabi?針對(duì)上述每個(gè)示例實(shí)現(xiàn)生成的機(jī)器代碼的相應(yīng)反匯編。

表 7-2 C 遞增和遞減循環(huán)的反匯編

遞增循環(huán) 遞減循環(huán)
fact1:                                  
        mov     r1, r0
        mov     r0, #1
        cmp     r1, #1
        bxlt    lr
        mov     r2, #0
.LBB0_1:                                
        add     r2, r2, #1
        mul     r0, r0, r2
        cmp     r1, r2
        bne     .LBB0_1
        bx      lr
fact2:                                  
        mov     r1, r0
        mov     r0, #1
        cmp     r1, #0
        bxeq    lr
.LBB1_1:                                
        mul     r0, r0, r1
        subs    r1, r1, #1
        bne     .LBB1_1
        bx      lr

比較反匯編表明,遞增循環(huán)反匯編中的?ADD?和?CMP?指令對(duì)已替換為遞減循環(huán)反匯編中的單個(gè)?SUBS?指令。由于?SUBS?指令更新?tīng)顟B(tài)標(biāo)志(包括 Z 標(biāo)志),因此不需要顯式?CMP r1、r2?指令。

除了在循環(huán)中保存指令外,變量?n?不必在循環(huán)的生命周期內(nèi)可用,從而減少了必須維護(hù)的寄存器數(shù)量。這簡(jiǎn)化了寄存器分配。如果原始終止條件涉及函數(shù)調(diào)用,則更為重要。例如:

for (...; i < get_limit(); ...);

將循環(huán)計(jì)數(shù)器初始化為所需迭代次數(shù),然后遞減到零的技術(shù)也適用于?while?和?do?語(yǔ)句。

?

C 代碼中的循環(huán)展開(kāi)

循環(huán)是大多數(shù)程序中的常見(jiàn)結(jié)構(gòu)。由于大量的執(zhí)行時(shí)間通?;ㄙM(fèi)在循環(huán)中,因此值得關(guān)注時(shí)間關(guān)鍵循環(huán)。

可以展開(kāi)小循環(huán)以獲得更高的性能,但缺點(diǎn)是代碼大小增加。展開(kāi)循環(huán)時(shí),循環(huán)計(jì)數(shù)器需要更新的頻率較低,執(zhí)行的分支也較少。如果循環(huán)只迭代幾次,則可以完全展開(kāi),使循環(huán)開(kāi)銷完全消失。編譯器在 -O3 -Otime?處自動(dòng)展開(kāi)循環(huán)。否則,任何展開(kāi)都必須在源代碼中完成。

注意

手動(dòng)展開(kāi)循環(huán)可能會(huì)阻礙編譯器自動(dòng)重新滾動(dòng)循環(huán)和其他循環(huán)優(yōu)化。

可以使用下表中所示的兩個(gè)示例例程來(lái)說(shuō)明循環(huán)展開(kāi)的優(yōu)缺點(diǎn)。這兩個(gè)例程都通過(guò)提取最低位并對(duì)其進(jìn)行計(jì)數(shù)來(lái)有效地測(cè)試單個(gè)位,然后將該位移出。

第一種實(shí)現(xiàn)使用循環(huán)來(lái)計(jì)算位數(shù)。第二個(gè)例程是第一個(gè)展開(kāi)四次的實(shí)現(xiàn),通過(guò)將?n?的四個(gè)班次合并為一個(gè)班次來(lái)應(yīng)用優(yōu)化。

頻繁展開(kāi)提供了新的優(yōu)化機(jī)會(huì)。

表 7-3 滾動(dòng)和展開(kāi)位計(jì)數(shù)循環(huán)的 C 代碼

位計(jì)數(shù)循環(huán) 展開(kāi)的位計(jì)數(shù)循環(huán)
int countbit1(unsigned int n)
{
    int bits = 0;
    while (n != 0)
    {
        if (n & 1) bits++;
        n >>= 1;
    }
    return bits;
}
int countbit2(unsigned int n)
{
    int bits = 0;
    while (n != 0)
    {
        if (n & 1) bits++;
        if (n & 2) bits++;
        if (n & 4) bits++;
        if (n & 8) bits++;
        n >>= 4;
    }
    return bits;
}

下表顯示了編譯器為上述每個(gè)示例實(shí)現(xiàn)生成的機(jī)器代碼的相應(yīng)反匯編,其中每個(gè)實(shí)現(xiàn)的 C 代碼已使用?armclang -Os -S --target=armv8a-arm-none-eabi?編譯。

表7-4 滾動(dòng)和展開(kāi)的位計(jì)數(shù)循環(huán)的反匯編

位計(jì)數(shù)循環(huán) 展開(kāi)的位計(jì)數(shù)循環(huán)
countbit1:                              
        mov     r1, r0
        mov     r0, #0
        cmp     r1, #0
        bxeq    lr
        mov     r2, #0
.LBB0_1:                                
        and     r3, r1, #1
        cmp     r2, r1, lsr #1
        add     r0, r0, r3
        lsr     r3, r1, #1
        mov     r1, r3
        bne     .LBB0_1
        bx      lr
countbit2:                              
        mov     r1, r0
        mov     r0, #0
        cmp     r1, #0
        bxeq    lr
        mov     r2, #0
.LBB1_1:                                
        and     r3, r1, #1
        cmp     r2, r1, lsr #4
        add     r0, r0, r3
        ubfx    r3, r1, #1, #1
        add     r0, r0, r3
        ubfx    r3, r1, #2, #1
        add     r0, r0, r3
        ubfx    r3, r1, #3, #1
        add     r0, r0, r3
        lsr     r3, r1, #4
        mov     r1, r3
        bne     .LBB1_1
        bx      lr

位計(jì)數(shù)循環(huán)的展開(kāi)版本比原始版本更快,但代碼大小更大。

?

編譯器優(yōu)化和 volatile 關(guān)鍵字

較高的優(yōu)化級(jí)別可以揭示某些程序中的問(wèn)題,這些問(wèn)題在較低的優(yōu)化級(jí)別下并不明顯,例如,缺少易失性限定符。

這可以通過(guò)多種方式表現(xiàn)出來(lái)。輪詢硬件時(shí),代碼可能會(huì)卡在循環(huán)中,多線程代碼可能會(huì)表現(xiàn)出奇怪的行為,或者優(yōu)化可能會(huì)導(dǎo)致刪除實(shí)現(xiàn)故意計(jì)時(shí)延遲的代碼。在這種情況下,可能需要將某些變量聲明為可變變量。

將變量聲明為?volatile?告訴編譯器,該變量可以在實(shí)現(xiàn)外部隨時(shí)修改,例如,由操作系統(tǒng)、另一個(gè)執(zhí)行線程(如中斷例程或信號(hào)處理程序)或硬件進(jìn)行修改。由于可變限定變量的值可以隨時(shí)更改,因此每當(dāng)在代碼中引用該變量時(shí),都必須始終訪問(wèn)內(nèi)存中的實(shí)際變量。這意味著編譯器無(wú)法對(duì)變量執(zhí)行優(yōu)化,例如,將其值緩存在寄存器中以避免內(nèi)存訪問(wèn)。同樣,在實(shí)現(xiàn)睡眠或計(jì)時(shí)器延遲的上下文中使用時(shí),將變量聲明為可變變量會(huì)告訴編譯器有特定類型的行為是有意的,并且此類代碼不得以刪除預(yù)期功能的方式進(jìn)行優(yōu)化。

相反,當(dāng)變量未聲明為可變變量時(shí),編譯器可以假定其值不能以意外方式修改。因此,編譯器可以對(duì)變量執(zhí)行優(yōu)化。

下表中的兩個(gè)示例例程說(shuō)明了?volatile?關(guān)鍵字的用法。這兩個(gè)例程都在循環(huán)中讀取緩沖區(qū),直到狀態(tài)標(biāo)志?buffer_full?設(shè)置為 true。buffer_full的狀態(tài)可以隨程序流異步更改。

例程的兩個(gè)版本僅在聲明buffer_full的方式上有所不同。第一個(gè)例程版本不正確。請(qǐng)注意,變量?buffer_full?在此版本中未限定為?volatile。相比之下,例程的第二個(gè)版本顯示了相同的循環(huán),其中buffer_full被正確地限定為易失性。

表 7-5 非易失性和易失性緩沖器環(huán)路的 C 代碼

緩沖環(huán)路的非易失性版本 緩沖區(qū)循環(huán)的易失性版本
int buffer_full;
int read_stream(void)
{
    int count = 0;
    while (!buffer_full)
    {
        count++;
    }
    return count;
}
volatile int buffer_full;
int read_stream(void)
{
    int count = 0;
    while (!buffer_full)
    {
        count++;
    }
    return count;
}

下表顯示了編譯器為上述每個(gè)示例生成的機(jī)器代碼的相應(yīng)反匯編,其中每個(gè)實(shí)現(xiàn)的 C 代碼已使用?armclang -Os -S --target=armv8a-arm-none-eabi?進(jìn)行編譯。

表7-6 非易失性和易失性緩沖器環(huán)路的反匯編

緩沖環(huán)路的非易失性版本 緩沖區(qū)循環(huán)的易失性版本
read_stream:                            
        movw    r0, :lower16:buffer_full
        movt    r0, :upper16:buffer_full
        ldr     r1, [r0]
        mvn     r0, #0
.LBB0_1:                                
        add     r0, r0, #1
        cmp     r1, #0
        beq     .LBB0_1     ; infinite loop
        bx      lr
read_stream:                            
        movw    r1, :lower16:buffer_full
        mvn     r0, #0
        movt    r1, :upper16:buffer_full
.LBB1_1:                                
        ldr     r2, [r1]     ; buffer_full
        add     r0, r0, #1
        cmp     r2, #0
        beq     .LBB1_1
        bx      lr

在上表中緩沖環(huán)路的非易失性版本的反匯編中,語(yǔ)句 LDR r1?[r0]?將?buffer_full?的值加載到寄存器?r1?外部標(biāo)記為?.LBB0_1。由于?buffer_full?未聲明為易失性,因此編譯器假定其值不能在程序外部修改。編譯器已將?buffer_full?的值讀入?r0?中,因此在啟用優(yōu)化時(shí)會(huì)省略重新加載變量,因?yàn)槠渲禑o(wú)法更改。結(jié)果是標(biāo)記為 的無(wú)限循環(huán)。LBB0_1。

相反,在反匯編緩沖區(qū)循環(huán)的易失性版本時(shí),編譯器假定?buffer_full?的值可以在程序外部更改,并且不執(zhí)行任何優(yōu)化。因此,buffer_full?的值被加載到寄存器?r2?中,該寄存器位于標(biāo)記為?的循環(huán)中。LBB1_1。因此,循環(huán)?.LBB1_1在匯編代碼中正確實(shí)現(xiàn)。

為了避免由實(shí)現(xiàn)外部的程序狀態(tài)更改引起的優(yōu)化問(wèn)題,每當(dāng)變量的值可能以實(shí)現(xiàn)未知的方式意外更改時(shí),就必須將變量聲明為可變變量。

在實(shí)踐中,每當(dāng)出現(xiàn)以下情況時(shí),都必須將變量聲明為可變變量:

  • 訪問(wèn)內(nèi)存映射的外圍設(shè)備。

  • 在多個(gè)線程之間共享全局變量。

  • 訪問(wèn)中斷例程或信號(hào)處理程序中的全局變量。

編譯器不會(huì)優(yōu)化已聲明為可變變量的變量。

?

C 和 C++ 中的堆棧使用

C 和 C++ 都大量使用堆棧。

例如,堆棧包含:

  • 函數(shù)的返回地址。

  • 必須保留的寄存器,由 ARM 64 位架構(gòu) (AAPCS64) 的 ARM 體系結(jié)構(gòu)過(guò)程調(diào)用標(biāo)準(zhǔn)確定,例如,在進(jìn)入子例程時(shí)保存寄存器內(nèi)容時(shí)。

  • 局部變量,包括局部數(shù)組、結(jié)構(gòu)、聯(lián)合,在 C++ 中還包括類。

有些堆棧使用并不明顯,例如:

  • 如果局部整數(shù)或浮點(diǎn)變量溢出(即未分配給寄存器),則會(huì)為其分配堆棧內(nèi)存。

  • 結(jié)構(gòu)通常分配給堆棧。堆棧上保留了一個(gè)等效于?sizeof(struct)?的空間,該空間填充為 16 個(gè)字節(jié)的倍數(shù)。編譯器嘗試將結(jié)構(gòu)分配給寄存器。

  • 如果在編譯時(shí)已知數(shù)組大小的大小,則編譯器會(huì)在堆棧上分配內(nèi)存。同樣,在堆棧上保留了一個(gè)等效于?sizeof(struct)?的空間,該空間填充為 16 個(gè)字節(jié)的倍數(shù)。

    注意

    可變長(zhǎng)度數(shù)組的內(nèi)存在運(yùn)行時(shí)在堆上分配。
  • 一些優(yōu)化可以引入新的臨時(shí)變量來(lái)保存中間結(jié)果。優(yōu)化包括:CSE 消除、實(shí)時(shí)范圍拆分和結(jié)構(gòu)拆分。編譯器嘗試將這些臨時(shí)變量分配給寄存器。如果沒(méi)有,它會(huì)將它們溢出到堆棧中。

  • 通常,為僅支持 16 位編碼的 Thumb 指令的處理器編譯的代碼比 A64 代碼、ARM 代碼和為支持 32 位編碼的 Thumb 指令的處理器編譯的代碼更多地使用堆棧。這是因?yàn)?16 位編碼的 Thumb 指令只有 8 個(gè)寄存器可供分配,而 ARM 代碼和 32 位編碼的 Thumb 指令則有 14 個(gè)寄存器。

  • AAPCS64要求通過(guò)堆棧而不是寄存器傳遞某些函數(shù)參數(shù),具體取決于它們的類型、大小和順序。

估算堆棧使用情況的方法

堆棧使用情況很難估計(jì),因?yàn)樗蕾囉诖a,并且根據(jù)程序在執(zhí)行時(shí)采用的代碼路徑,在運(yùn)行之間可能會(huì)有所不同。但是,可以使用以下方法手動(dòng)估計(jì)堆棧利用率的程度:

  • 使用 --callgraph?鏈接以生成靜態(tài)調(diào)用圖。這顯示了有關(guān)所有功能的信息,包括堆棧使用情況。

    這將使用?.debug_frame?部分中的 DWARF 幀信息。使用?-g?選項(xiàng)進(jìn)行編譯以生成必要的 DWARF 信息。

  • 使用 --info=stack 或?--info=summarystack?鏈接以列出所有全局符號(hào)的堆棧使用情況。

  • 使用調(diào)試器在堆棧中的最后一個(gè)可用位置設(shè)置觀察點(diǎn),并查看是否命中了觀察點(diǎn)。

  • 使用調(diào)試器,然后:

    1. 在內(nèi)存中為比預(yù)期需要的堆棧大得多的堆棧分配空間。

    2. 用已知值的副本填充堆棧空間,例如?0xDEADDEAD。

    3. 運(yùn)行應(yīng)用程序或應(yīng)用程序的固定部分。目標(biāo)是在測(cè)試運(yùn)行中使用盡可能多的堆??臻g。例如,嘗試執(zhí)行最深嵌套的函數(shù)調(diào)用和靜態(tài)分析找到的最壞情況路徑。嘗試在適當(dāng)?shù)奈恢蒙芍袛?,以便將它們包含在堆棧跟蹤中?/span>

    4. 應(yīng)用程序完成執(zhí)行后,檢查內(nèi)存的堆??臻g,查看有多少已知值已被覆蓋。該空間在已使用部分中有垃圾,其余部分有已知值。

    5. 計(jì)算垃圾值的數(shù)量,然后乘以?sizeof(value),以給出它們的大?。ㄒ宰止?jié)為單位)。

    計(jì)算結(jié)果顯示了堆棧大小是如何增長(zhǎng)的(以字節(jié)為單位)。

  • 使用固定虛擬平臺(tái) (FVP),并使用映射文件定義一個(gè)內(nèi)存區(qū)域,不允許在內(nèi)存中堆棧的正下方進(jìn)行訪問(wèn)。如果堆棧溢出到禁止區(qū)域,則會(huì)發(fā)生數(shù)據(jù)中止,調(diào)試器可能會(huì)捕獲數(shù)據(jù)中止。

減少堆棧使用的方法

通常,可以通過(guò)以下方式降低程序的堆棧要求:

  • 編寫只需要少量變量的小函數(shù)。

  • 避免使用大型局部結(jié)構(gòu)或數(shù)組。

  • 例如,通過(guò)使用替代算法來(lái)避免遞歸。

  • 最小化函數(shù)中每個(gè)點(diǎn)在任何給定時(shí)間使用的變量數(shù)。

  • 使用 C 塊作用域并僅在需要的地方聲明變量,因此與不同作用域使用的內(nèi)存重疊。

C 塊作用域的使用涉及僅在需要的地方聲明變量。這通過(guò)重疊不同作用域所需的內(nèi)存來(lái)最大程度地減少堆棧的使用。

?

最小化函數(shù)參數(shù)傳遞開(kāi)銷的方法

有多種方法可以最大程度地減少將參數(shù)傳遞給函數(shù)的開(kāi)銷。

例如:

  • 在 AArch64 狀態(tài)下,可以有效地傳遞 8 個(gè)整數(shù)參數(shù)和 8 個(gè)浮點(diǎn)參數(shù)(總共 16 個(gè))。在 AArch32 狀態(tài)下,如果每個(gè)參數(shù)的大小不超過(guò)一個(gè)字,則確保函數(shù)采用四個(gè)或更少的參數(shù)。在 C++ 中,確保非靜態(tài)成員函數(shù)采用的參數(shù)不超過(guò)一個(gè)參數(shù),因?yàn)橥ǔT?R0?中傳遞隱式?this?指針參數(shù)。
  • 如果函數(shù)需要超過(guò)參數(shù)的有效限制,請(qǐng)確保函數(shù)執(zhí)行大量工作,以便超過(guò)傳遞堆疊參數(shù)的成本。
  • 將相關(guān)參數(shù)放在結(jié)構(gòu)中,并在任何函數(shù)調(diào)用中傳遞指向該結(jié)構(gòu)的指針。這減少了參數(shù)的數(shù)量并提高了可讀性。
  • 對(duì)于 32 位體系結(jié)構(gòu),應(yīng)盡量減少 long?long?參數(shù)的數(shù)量,因?yàn)檫@些參數(shù)需要兩個(gè)參數(shù)字,這兩個(gè)參數(shù)字必須在偶數(shù)寄存器索引上對(duì)齊。
  • 對(duì)于 32 位體系結(jié)構(gòu),在使用軟件浮點(diǎn)時(shí),請(qǐng)盡量減少雙精度參數(shù)的數(shù)量。

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-779239.html

C 代碼中的整數(shù)除以零錯(cuò)誤

對(duì)于不支持?SDIV?除法指令的目標(biāo),可以使用相應(yīng)的 C 庫(kù)輔助函數(shù) __aeabi_idiv0() 和?__rt_raise(?捕獲和識(shí)別整數(shù)除以零錯(cuò)誤

關(guān)于使用 __aeabi_idiv0() 捕獲整數(shù)除以零錯(cuò)誤

您可以使用 C 庫(kù)輔助函數(shù)?__aeabi_idiv0()?捕獲整數(shù)除以零錯(cuò)誤,以便除以零返回一些標(biāo)準(zhǔn)結(jié)果,例如零。

整數(shù)除法是通過(guò) C 庫(kù)輔助函數(shù) __aeabi_idiv() 和?__aeabi_uidiv()?在代碼中實(shí)現(xiàn)的。這兩個(gè)函數(shù)都檢查除以零。

當(dāng)檢測(cè)到整數(shù)除以零時(shí),將創(chuàng)建?__aeabi_idiv0()?的分支。因此,要將除法捕獲為零,只需在?__aeabi_idiv0()?上放置一個(gè)斷點(diǎn)。

該庫(kù)提供了?__aeabi_idiv0()?的兩種實(shí)現(xiàn)。默認(rèn)值不執(zhí)行任何操作,因此如果檢測(cè)到除以零,則除法函數(shù)返回零。但是,如果使用信號(hào)處理,則會(huì)選擇調(diào)用?__rt_raise(SIGFPE, DIVBYZERO)?的替代實(shí)現(xiàn)。

如果您提供自己的?__aeabi_idiv0()?版本,則除法函數(shù)將調(diào)用此函數(shù)。__aeabi_idiv0()?的函數(shù)原型為:

int __aeabi_idiv0(void);

如果?__aeabi_idiv0()?返回一個(gè)值,則該值用作除法函數(shù)返回的商。

關(guān)于使用 __rt_raise() 捕獲整數(shù)除以零錯(cuò)誤

默認(rèn)情況下,整數(shù)除以零返回零。如果要截獲除以零,可以重新實(shí)現(xiàn) C 庫(kù)輔助函數(shù)?__rt_raise()。

__rt_raise()?的函數(shù)原型為:

void __rt_raise(int signal, int type);

如果重新實(shí)現(xiàn)?__rt_raise(),則庫(kù)會(huì)自動(dòng)提供?__aeabi_idiv0() 的信號(hào)處理庫(kù)版本,該版本調(diào)用?__rt_raise(),則該庫(kù)版本的?__aeabi_idiv0()?將包含在最終映像中。

在這種情況下,當(dāng)發(fā)生除以零錯(cuò)誤時(shí),__aeabi_idiv0()?調(diào)用?__rt_raise(SIGFPE, DIVBYZERO)。因此,如果重新實(shí)現(xiàn)?__rt_raise(),則必須選中?(signal == SIGFPE) & (type == DIVBYZERO)?以確定是否發(fā)生了除以零的情況。

識(shí)別 C 代碼中的整數(shù)除以零錯(cuò)誤

進(jìn)入?__aeabi_idiv0() 時(shí),鏈路寄存器?LR?包含應(yīng)用程序代碼中調(diào)用?__aeabi_uidiv()?除法例程后的指令地址。

通過(guò)在調(diào)試器中查找?LR?給出的地址處的 C 代碼行,可以識(shí)別源代碼中的違規(guī)行。

?

到了這里,關(guān)于Keil5,ARM編譯器 軟件優(yōu)化注意事項(xiàng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • KEIL5MDK安裝及V5編譯器的安裝

    KEIL5MDK安裝及V5編譯器的安裝

    目前keil官網(wǎng)最新版本的安裝包都是默認(rèn)安裝V6編譯器,不再自動(dòng)安裝V5編譯器,而V5與V6編譯器在編譯的時(shí)候有很多代碼不兼容,導(dǎo)致工程編譯失敗,所以我們使用新版keil5的時(shí)候,要用V5編譯器就要自己安裝V5編譯器。 教程中所需的安裝包(keil、破解工具、V5編譯器)百度網(wǎng)盤

    2024年02月11日
    瀏覽(39)
  • KEIL MDK arm編譯器 添加教程

    KEIL MDK arm編譯器 添加教程

    1.下載編譯器安裝文件 arm編譯器6.16(適用于windows 64位)安裝文件可在如下網(wǎng)址免費(fèi)下載: arm編譯器6.16(適用于Windows64位)-嵌入式文檔類資源-CSDN文庫(kù) https://download.csdn.net/download/WG_IECAS/87342708 如需其他版本編譯器,可到KEIL官網(wǎng)查找下載,快速網(wǎng)址: Arm Compiler downloads index h

    2023年04月08日
    瀏覽(26)
  • KEIL5MDK最新版(3.37)安裝以及舊編譯器(V5)安裝

    KEIL5MDK最新版(3.37)安裝以及舊編譯器(V5)安裝

    方式一:keil5官網(wǎng)鏈接。需要填寫信息(如左圖,可以亂填),然后提交,點(diǎn)擊軟件下載(如右圖),問(wèn)題就是下載慢,但問(wèn)題不大。 方式二:keil5云盤鏈接鏈接,提取碼:1234,筆者當(dāng)時(shí)最新的版本是3.37。 下載后安裝,需要注意的是不要出現(xiàn)任何中文就行。 破解軟件鏈接:

    2023年04月08日
    瀏覽(25)
  • proteus結(jié)合keil-arm編譯器構(gòu)建STM32單片機(jī)項(xiàng)目進(jìn)行仿真

    proteus結(jié)合keil-arm編譯器構(gòu)建STM32單片機(jī)項(xiàng)目進(jìn)行仿真

    ? ? proteus是可以直接創(chuàng)建設(shè)計(jì)圖和源碼的,但是源碼編譯它需要借助keil-arm編譯器,也就是我們安裝keil-mdk之后自帶的編譯器。 ? ? 下面給出一個(gè)完整的示例,主要是做一個(gè)LED燈閃爍的效果。 ? ? 新建工程指定路徑,Schematic,PCB layout都選擇默認(rèn),在最后創(chuàng)建項(xiàng)目工程向?qū)У臅r(shí)

    2024年02月13日
    瀏覽(21)
  • ARM嵌入式編譯器編譯優(yōu)化選項(xiàng) -O

    Arm嵌入式編譯器可以執(zhí)行一些優(yōu)化來(lái)減少代碼量并提高應(yīng)用程序的性能。不同的優(yōu)化級(jí)別有不同的優(yōu)化目標(biāo),不僅如此,針對(duì)某個(gè)目標(biāo)進(jìn)行優(yōu)化會(huì)對(duì)其他目標(biāo)產(chǎn)生影響。比如想減小生成的代碼量,勢(shì)必會(huì)影響到該代碼的性能。所以優(yōu)化級(jí)別總是這些不同目標(biāo)(代碼量,程序性

    2024年02月16日
    瀏覽(22)
  • 物聯(lián)網(wǎng)|ARM|Keil同時(shí)安裝Keil的C51、C251和MDK|增加V5編譯器|物聯(lián)網(wǎng)開(kāi)發(fā)系列課程之零基礎(chǔ)玩轉(zhuǎn)Cortex-M系列CPU-學(xué)習(xí)筆記(1)

    物聯(lián)網(wǎng)|ARM|Keil同時(shí)安裝Keil的C51、C251和MDK|增加V5編譯器|物聯(lián)網(wǎng)開(kāi)發(fā)系列課程之零基礎(chǔ)玩轉(zhuǎn)Cortex-M系列CPU-學(xué)習(xí)筆記(1)

    1.物聯(lián)網(wǎng)的定義 利用局部網(wǎng)絡(luò)或互聯(lián)網(wǎng)等通信技術(shù)把傳感器、控制器、機(jī)器、人員和物等通過(guò)新的方式聯(lián)在一起,形成人與物、物與物相聯(lián),實(shí)現(xiàn)信息化、遠(yuǎn)程管理控制和智能化的網(wǎng)絡(luò)。 2.物聯(lián)網(wǎng)的組成 3.物聯(lián)網(wǎng)應(yīng)用舉例智能家居 1物聯(lián)網(wǎng)的數(shù)據(jù)源頭 2物聯(lián)的局域網(wǎng)絡(luò)源頭 1

    2024年02月05日
    瀏覽(28)
  • Keil MDK安裝armcc V5編譯器

    Keil MDK安裝armcc V5編譯器

    ????????不知道從什么時(shí)候開(kāi)始,Keil MDK默認(rèn)不支持V5的編譯器了,里面默認(rèn)只有V6的編譯器,設(shè)置界面跟V5有很大的差異不太熟悉。最可怕的是,之前使用V5編譯的工程,換成V6編譯器后居然報(bào)錯(cuò)...雖然修改一下應(yīng)該也可以正常編譯,但,人總是習(xí)慣自己熟悉的東西。所以,

    2024年04月27日
    瀏覽(19)
  • ARM編譯器5.06下載安裝

    ARM編譯器5.06下載安裝

    進(jìn)入官方網(wǎng)站ARM Complier v5.06官網(wǎng)下載頁(yè)面 進(jìn)入后的界面為 往下翻,找到如圖位置的5.06 for windows的文件,點(diǎn)擊下載,下載時(shí)需要登錄賬號(hào) 先解壓下載的壓縮文件,在installer文件夾里面有一個(gè) setup.exe 文件,雙擊它, 同意協(xié)議,在安裝位置選擇 keil 安裝位置的 ARM 文件夾下,在

    2024年02月22日
    瀏覽(24)
  • arm系列交叉編譯器各版本區(qū)別

    交叉編譯器的命名規(guī)則:arch [-vendor] [-os] [-(gnu)eabi] [-language] arch - 體系架構(gòu), 如arm(ARM-32bit)、aarch64(ARM-64bit)、x86等; vendor -工具鏈提供商,經(jīng)常省略,或用 none 替代; os - 目標(biāo)操作系統(tǒng), 如linux,沒(méi)針對(duì)具體 os 則 用 none 替代。同時(shí)沒(méi)有 vendor 和os 使用一個(gè) none 替代。

    2024年02月01日
    瀏覽(26)
  • KEIL MDK5.37版本自行添加AC5(ARMCC)編譯器

    KEIL MDK5.37版本自行添加AC5(ARMCC)編譯器

    從MDK5.37開(kāi)始,AC5(ARMCC)編譯器不再默認(rèn)安裝,需要獨(dú)立安裝。 下面是總結(jié)的安裝步驟: 下載AC5(ARMCC)編譯器: 1.官方頁(yè)面(可能下載不成功) Legacy Arm Compilers – Arm Developer https://developer.arm.com/downloads/-/legacy-compilers 2.安富萊論壇(推薦,比較容易下載) 【安富萊】MDK5.29,5.30,

    2024年02月02日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包