有学做衣服的网站吗,网站建设 成本,做业帮网站,上海中学官网登录如果供应商为我自己的项目提供了一个起点#xff0c;那就太好了。工作blinky始终是一个伟大的首发。方便总是有代价#xff0c;而且“blinky”就是夸大“切换GPIO引脚”的代码大小。对于具有少量RAM和FLASH的设备#xff0c;这可能会引起关注#xff1a;如果blinky占用那么…如果供应商为我自己的项目提供了一个起点那就太好了。工作blinky始终是一个伟大的首发。方便总是有代价而且“blinky”就是夸大“切换GPIO引脚”的代码大小。对于具有少量RAM和FLASH的设备这可能会引起关注如果blinky占用那么多我的应用程序是否适合该设备不要担心可以轻松地修剪掉或任何其他项目。 恩智浦LPC845-BRK主板上的Binky
我在这里使用一个blinky项目作为一个例子修剪技巧也适用于任何其他类型的项目。
在本教程中我在BRK突破板上使用NXPLPC845 恩智浦LPC845-BRK板
1、Blinky示例
我所使用的是基于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、大小信息
有关大小信息的含义请阅读“ textdata和bssCode and Data Size Explained ”。查看我的设备上使用空间的正常方法是检查链接器映射文件* .map 链接器映射文件
但是这个map文件很难阅读而且对于专家来说更是如此它列出了具有地址和大小的部分 链接器映射文件内容
使用MCUXpresso IDE V11有一个很好的“图像信息”视图它基本上是一个更好的map文件信息查看器 图像信息查看
我可以过滤和排序数据这让我知道代码和数据使用了多少空间 图像信息存储器内容
当然它需要一些关于应用程序应该做什么的知识。我总是浏览视图中的项目列表看看是否有任何我不希望的东西也许应用程序正在使用可以删除的东西。
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% 或者使用较小的变体或实现。有关此问题的更多背景信息请参阅本文末尾的链接。
6、DEBUG和NDEBUG
接下来要检查编译器是否定义了列出的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初始化对于真正的应用程序是有意义的所以我现在停在这里。
9、RAM堆和堆栈
看起来不正确的是SRAM的使用。heap使用了一大块 堆内存使用情况
该堆用于动态内存分配malloc。嵌入式编程的一般规则是避免它。但它默认在这里。它可以在链接器设置中关闭演示使用1K用于堆和堆栈。由于我没有使用malloc我可以将堆大小设置为0x0。对于真正依赖于应用程序的保留堆栈。在ARM Cortex上MSP用于启动/主控和中断参见“ ARMCortex-M中断和FreeRTOS ”。0x100256字节应该足够我的眨眼。 堆和堆栈大小
这让我了解到一点 Memory region Used Size Region Size %age Used PROGRAM_FLASH 1456 B 64 KB 2.22 SRAM 392 B 16 KB 2.39
如果它是关于进一步减小堆栈大小我可以查看调用图信息它给出了有关使用多少堆栈空间的信息 堆栈大小的图形显示
有一些项目的大小信息未知标有“”因为它们在库中。验证实际堆栈使用情况的方法是编写模式例如0xffffffff然后运行应用程序一段时间 使用的堆栈
这表明实际使用了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。如果缩小尺寸请确保进行了足够的分析以证明堆叠尺寸合理。
10、MTB
剩下的一件事就是使用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进行半主机再次为什么我不喜欢printfXFormat轻量级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/。权属归原作者所有。
欢迎关注