日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何优化代码和RAM大小

發布時間:2024/7/23 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何优化代码和RAM大小 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果供應商為我自己的項目提供了一個起點,那就太好了。工作'blinky'始終是一個偉大的首發。方便總是有代價,而且“blinky”就是夸大“切換GPIO引腳”的代碼大小。對于具有少量RAM和FLASH的設備,這可能會引起關注:如果'blinky'占用那么多,我的應用程序是否適合該設備?不要擔心:可以輕松地修剪掉(或任何其他項目)。

恩智浦LPC845-BRK主板上的Binky

我在這里使用一個'blinky'項目作為一個例子:修剪技巧也適用于任何其他類型的項目。

在本教程中,我在BRK(突破)板上使用NXPLPC845:

恩智浦LPC845-BRK板

1Blinky示例

我所使用的是基于Eclipse的NXP MCUXpresso IDE:

選擇SDK板

我使用供應商默認設置創建了'blinky'項目:

Blinky項目

一個'blinky'應該閃爍一個LED,對任何項目來說都是一個好的開手機。構建相當小的項目,代碼大小如下:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

10536 B

64 KB

16.08%

SRAM:

2424 B

16 KB

14.79%

text

data

bss

dec

hex

filename

10532

4

2420

12956

329c

lpc845breakout_led_blinky.axf

該信息也在控制臺中顯示,分為文本,數據和bss:

10K的'blinky'看起來有點夸張。但是我們現在將在接下來的步驟中修改它。

2、大小信息

有關大小信息的含義,請閱讀“?text,data和bss:Code and Data Size Explained?”。查看我的設備上使用空間的正常方法是檢查鏈接器映射文件(* .map):

鏈接器映射文件

但是這個map文件很難閱讀,而且對于專家來說更是如此:它列出了具有地址和大小的部分:

鏈接器映射文件內容

使用MCUXpresso IDE V11,有一個很好的“圖像信息”視圖,它基本上是一個更好的ma'p文件信息查看器:

圖像信息查看

我可以過濾和排序數據,這讓我知道代碼和數據使用了多少空間:

圖像信息存儲器內容

當然,它需要一些關于應用程序應該做什么的知識。我總是瀏覽視圖中的項目列表,看看是否有任何我不希望的東西:也許應用程序正在使用可以刪除的東西。

3、源代碼

對于一個簡單的眨眼,這是相當小的。首先要檢查程序正在做什么。main.c有這個:

/* * Copyright 2017 NXP* All rights reserved.** SPDX-License-Identifier: BSD-3-Clause*/#include "board.h" #include "fsl_gpio.h"#include "pin_mux.h" /******************************************************************************** Definitions******************************************************************************/ #define BOARD_LED_PORT 1U#define BOARD_LED_PIN 2U /******************************************************************************** Prototypes******************************************************************************/ /******************************************************************************** Variables******************************************************************************/ volatile uint32_t g_systickCounter; /******************************************************************************** Code******************************************************************************/void SysTick_Handler(void) {if (g_systickCounter != 0U){g_systickCounter--;} }void SysTick_DelayTicks(uint32_t n) {g_systickCounter = n;while (g_systickCounter != 0U){} }/*! * @brief Main function */ int main(void) {/* Define the init structure for the output LED pin*/gpio_pin_config_t led_config = {kGPIO_DigitalOutput,0,};/* Board pin init */BOARD_InitPins();BOARD_InitBootClocks();BOARD_InitDebugConsole();/* Init output LED GPIO. */GPIO_PortInit(GPIO, BOARD_LED_PORT);GPIO_PinInit(GPIO, BOARD_LED_PORT, BOARD_LED_PIN, &led_config);/* Set systick reload value to generate 1ms interrupt */if (SysTick_Config(SystemCoreClock / 1000U)){while (1){}}while (1){/* Delay 1000 ms */SysTick_DelayTicks(1000U);GPIO_PortToggle(GPIO, BOARD_LED_PORT, 1u << BOARD_LED_PIN);} }

基本上,代碼正在初始化引腳,時鐘,設置SysTick定時器,然后在循環中執行'blinky',使用Systick計數器延遲閃爍周期。

4、調試控制臺

但我可以看到它初始化一個調試控制臺(以及它的UART硬件):

BOARD_InitDebugConsole();

去掉這些,我們就可以得到:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

5616 B

64 KB

8.57%

SRAM:

2400 B

16 KB

14.65%

在許多情況下,演示應用程序會設置一些通信通道,但之后就不會使用它們。鏈接器可以很好地刪除未使用的對象(函數/變量),但前提是它們沒有被引用。

5、半主控和printf()

接下來要看的是是否存在任何半主機或printf()。該項目正在使用'Redlib',這是一個優化的庫,與'標準'newlib或較小標準的newlib-nano相比:

Redlib

盡管如此,該庫可能會增加代碼大小,因為它使用半主機(通過調試器發送消息)。查看Memory視圖,我可以直接或間接地看到所需的所有這些標準I / O函數:

stdio功能

擁有該功能的所有鉤子只有在使用它時才有意義,并且“blinky”不會使用它。因此,擺脫半主機和所有未使用的標準I / O意味著使用'none'變體:

沒有標準I / O的庫

這讓我們了解到這一點:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

3372 B

64 KB

5.15%

SRAM:

2208 B

16 KB

13.48%

?

或者使用較小的變體或實現。有關此問題的更多背景信息,請參閱本文末尾的鏈接。

6DEBUGNDEBUG

接下來要檢查編譯器是否定義了列出的DEBUG。事實上,情況就是這樣:

DEBUG定義

使用該定義集,SDK和示例驅動程序中有許多額外的代碼,它們使用'assert()'宏檢查好的值:

SDK代碼中斷言的用法

在這里,圖像信息視圖再次有用:它向我展示了使用assert()的所有地方:

斷言用法

實際上,在代碼中使用斷言來盡早捕獲編程錯誤是一種很好的做法。但是所有的assert()代碼確實加起來了。要關閉額外的代碼(和安全帶!),我將宏更改為NDEBUG:

NDEBUG

這讓我們了解到一點:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

3144 B

64 KB

4.80%

SRAM:

2208 B

16 KB

13.48%

7、中斷和向量

圖像信息視圖再次是一個很好的起點。我正在檢查使用過的中斷。Blinky正在使用預期的SysTick中斷。但是仍然使用UART中斷?

使用中斷

大多數中斷都實現為“weak”:實現為默認/空,可以被應用程序覆蓋。但UART沒有意義,因為”blinky”沒有使用任何UART通信?

事實證明,NXP SDK默認啟用了UART事務API:

UART Transactional API設置

事務API允許在通信組塊/事務中發送/接收UART數據。但我們不需要在我們的眨眼中,所以讓我們把它關掉:

關閉UART TransactionalAPI

這樣一來,內存情況為:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

2964 B

64 KB

4.52%

SRAM:

2184 B

16 KB

13.33%

但我認為CMSIS(設置中斷優先級,通用時鐘設置)非常有用,所以我不在這里觸摸它。應用程序中最大的功能是SysTick代碼用來將定時器的優先級設置為最低優先級,以節省另外220個字節:

CMSIS作為最大的單一功能代碼大小貢獻者

8、優化

到目前為止,我已經刪除了不需要的或未使用的功能。接下來我可以打開編譯器優化。默認情況下,項目設置為-O0:

編譯器優化

-O0表示無優化:代碼直觀且易于調試。

-O1主要優化函數進入/退出代碼,并且能夠在不影響調試的情況下減少代碼大小。在這個例子中,它將代碼大小減少了一半!

?

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1540 B

64 KB

2.35%

SRAM:

2184 B

16 KB

13.33%

-O2優化更多并盡可能地將事物保存在寄存器中。因為應用程序中的功能相當小,所以改進并不大:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1516 B

64 KB

2.31%

SRAM:

2184 B

16 KB

13.33%

-O3通過額外的內聯優化最佳。-O3的目標是速度,所以難怪代碼大小再次增加:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1792 B

64 KB

2.73%

SRAM:

2184 B

16 KB

13.33%

代碼大小優化的最佳選擇是-Os(針對大小進行優化):

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1456 B

64 KB

2.22%

SRAM:

2184 B

16 KB

13.33%

現在看起來很合理!當然現在有一些方法可以為“裸露的裸眼”切斷更多,但是現有的一切(啟動代碼,時鐘和GPIO初始化)對于真正的應用程序是有意義的,所以我現在停在這里。

9RAM:堆和堆棧

看起來不正確的是SRAM的使用。'heap'使用了一大塊:

堆內存使用情況

該堆用于動態內存分配(malloc())。嵌入式編程的一般規則是避免它。但它默認在這里。它可以在鏈接器設置中關閉:演示使用1K用于堆和堆棧。由于我沒有使用malloc(),我可以將堆大小設置為0x0。對于真正依賴于應用程序的保留堆棧。在ARM Cortex上,MSP用于啟動/主控和中斷(參見“?ARMCortex-M中斷和FreeRTOS?”)。0x100(256字節)應該足夠我的眨眼。

堆和堆棧大小

這讓我了解到一點:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1456 B

64 KB

2.22%

SRAM:

392 B

16 KB

2.39%

如果它是關于進一步減小堆棧大小,我可以查看調用圖信息,它給出了有關使用多少堆棧空間的信息:

堆棧大小的圖形顯示

有一些項目的大小信息未知(標有“?”)因為它們在庫中。驗證實際堆棧使用情況的方法是編寫模式(例如0xffff'ffff),然后運行應用程序一段時間:

使用的堆棧

這表明實際使用了72個字節。有一點余地,在這種情況下將堆棧大小設置為128字節看起來是合理的。這給出了:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1456 B

64 KB

2.22%

SRAM:

264 B

16 KB

1.61%

堆棧溢出可能是嵌入式應用程序中最常見的問題。如果可以的話,可以為堆棧提供盡可能多的RAM。如果縮小尺寸,請確保進行了足夠的分析以證明堆疊尺寸合理。

10MTB

剩下的一件事就是使用RAM空間:MTB緩沖區。微跟蹤緩沖區用于跟蹤,這非常有用(請參閱“?使用MTB跟蹤調試ARM Cortex-M0 +硬故障?”)。可以使用宏禁用緩沖區:

mtb.c

__MTB_DISABLE

這讓我對此:

Memory region

Used Size

Region Size

%age Used

PROGRAM_FLASH:

1456 B

64 KB

2.22%

SRAM:

136 B

16 KB

0.83%

我想在這里我們可以很開心

11、摘要

供應商的例子很棒:它們給了我一個很好的起點。它們沒有經過優化,這是故意的。但它們可能帶有我不需要的功能和功能。了解使用切斷功能或調整設置來優化應用程序的不同方法對于優化RAM和FLASH使用非常有用。在本教程中,我展示了如何將'blinky'降低到大約1KB閃存和大約136字節的SRAM。當然這一切都取決于功能和用法,但我認為現在為我的應用程序添加額外的功能是一個非常合理的狀態。

我希望這些提示可能對您的項目有用。

12、鏈接

  • 文本,數據和bss:代碼和數據大小說明
  • 拆箱恩智浦LPC845-BRK板
  • 教程:使用恩智浦LPC845-BRK主板閃爍
  • 使用恩智浦Kinetis SDK V2.0進行半主機(再次!)
  • 為什么我不喜歡printf()
  • XFormat,輕量級printf()和sprintf()替代品
  • 優化Kinetis gcc啟動
  • 新的恩智浦MCUXpresso Eclipse IDE v11.0

聲明: 此篇由 Erich Styger的《Tutorial: How to Optimize Code and RAM?Size》翻譯。原文地址為:https://mcuoneclipse.com/2019/08/17/tutorial-how-to-optimize-code-and-ram-size/。權屬歸原作者所有。

歡迎關注:

總結

以上是生活随笔為你收集整理的如何优化代码和RAM大小的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。