Skip to Navigation
Home
  • Company
    • Quick Facts
    • Board of Directors
    • Management Team
    • Press Releases
    • News Coverage
    • Newsletter
    • Careers
    • Articles
    • Ember Chronology
    • Contact Us
  • Products
    • ZigBee Chips
    • ZigBee Software
    • ZigBee Development Tools
    • Documentation
  • Buy
    • Digi-Key (Online)
    • Distributors
  • Applications
    • AMI & AMR
    • Integrated Home Automation
    • Building Automation
    • Others
  • ZigBee
    • About ZigBee
    • Ember & ZigBee
    • ZigBee FAQ
    • Download Specifications
    • ZigBee Events
  • Partners
  • Support
    • Training
  • Events
Home › FAQs

Reducing Flash usage on the EM250

Categories:
  • Software : Embedded
  • xIDE
  • EM250

This article explains various techniques for minimizing flash memory consumption for EmberZNet applications developed on the EM250 platform.

NOTE1: This How-To article describes Flash memory conservation techniques. If it is RAM you are concerned about, there are a number of configuration parameters that are variable by the application’s CONFIGURATION_HEADER file and can affect the amount of static memory used by the EmberZNet stack. Please consult the Reducing RAM usage on the EM250 article.

NOTE2: This article was written in respect to EmberZNet 3.x. While there may be some references here to items specific to EmberZNet 3, these guidelines below generally hold true for EmberZNet 2.x versions as well. The following are some considerations and techniques for reducing/conserving flash space on the EM250:

Review your code for possible flash efficiency improvements.

Many applications have a fair number of places where the code can be re-written or optimized to conserve code size. Code may have been written inefficiently in cases where the author was not accustomed to embedded development in a resource-constrained environment, cases where the code was ported/reused from an architecture or application design with more relaxed memory constraints, cases where the code was written in haste, or cases where the implementation has changed such that the variable or subroutine is no longer used in the manner originally intended by the author.

Make sure that any Flash-based variables (with the PGM keyword, like the EmberEndpointDescription structures comprising the emberEndpoints[] array) are only as large as they need to be.

Take care in the usage of constants (especially string literals), as these are stored in Flash memory and the available space for this kind of data is limited. (8KB is the default size of CONST data in the EM250 memory map. Be aware the compiler will adjust the size to 16KB if more CONST space is needed, but only if the CODE space has 16k free, due to constraints in the memory map. If the 16KB "Big CONST" segment is required, the 8KB for the smaller CONST segment will go unused and can't be reclaimed for CODE, so 24KB of flash is effectively used up.)

If possible, remove or reduce the size of any string literals (such as those used in Printf statements) that provide only informational detail.

Developers who are comfortable with assembly language may want to review the linker output from the build (found in the list file, which ends in the LST extension and is found in the build output directory) and observe how changes to code (such as conversion from functions to macros or unrolling of loops into individual statements) affect the assembly instructions chosen by the linker (and thus the size of the resulting code).

If there are any routines or modules in your code (like diagnostics routines or HAL drivers for certain peripherals) that you don’t make use of during development, consider commenting these out (perhaps conditionally) or excluding the files from your build, just in case the xIDE DeadStrip utility doesn’t happen to fully exclude all of the code from these pieces.

Consider using the Application Bootloader or Serial-only Bootloader

Moving from the EM250 Standalone Bootloader (the default) to the Application Bootloader or Serial-only Bootloader (a variation of the Standalone Bootloader, but without any OTA update support, only a UART XModem upload option) can save you about 5KB of Flash space and, in the case of the Application Bootloader, generally allows for more flexibility in the bootloading process (because the application has control of the loading and installation of the new image).

Keep in mind, however, that the Application Bootloader model requires an external data storage chip (128KB), which would be connected via SPI or I2C, to hold the downloaded image before it’s been installed into the main program area. And using the Serial-only Bootloader may limit your ability to perform field updates of your devices, depending on how accessible the UART interface is on your design.

To use the Serial Bootloader: Add $SERIAL_UART_BTL to your list of Assembler defines for your application build; when uploading a bootloader image, make sure to select the serial UART bootloader, which can be found in build/ezsp-ncp-uart-em250 (for most EM250 releases) or tool/bootloader/serial-bootloader (in more recent EM250 releases).

To use the Application Bootloader: Add $APP_BTL to your list of Assembler defines for your application build; when uploading a bootloader image, make sure to select the appropriate Application Bootloader (I2C or SPI) variant, which can be found in tool/bootloader/app-bootloader. Also, some additional application code will be necessary to assist with the bootloading process. (Hence the name "application bootloader".) Please refer to the “Application Bootloading” section (10.1.3 in the latest revision) of the Application Developer’s Guide and to the Application Bootloader Demo sample application (found in /app/app-bootloader-demo) for more details on how the Application Bootloader works.

Consider using a different stack variant

The ZigBee Pro stack in EmberZNet 3.x is included as 3 different library variants: a “debug” stack (ending in the -debug suffix), a “debug off” stack (ending in the -debug_off suffix), and a normal, “release” stack (no special suffix).

While the Debug stack contains additional error-checking and a lot of extra diagnostic detail (in the form of APITrace events for most emberXXX calls, which show up in InSight Desktop traces, as well as a DebugPrintf capability that appears in InSight Desktop’s event log too), it also adds a significant amount of flash space to the build (usually 3 or 4KB).

By moving to the Release stack, additional space can be recovered for use by the application, and application can then use Virtual UART (in place of the DebugPrintf interface and the APITrace events) to echo diagnostic data back into InSight Desktop for debugging purposes. (The Virtual UART is an emulation of a serial port using Port 0 of the UART driver from /app/util/serial/serial.c. For more information see the how-to on the virtual serial port.

SerialPrintf statements from the application to the physical UART port (Port 1 in the serial driver), or, if no serial port is available, diagnostics might be visual indications such as LEDs or digital signals that can be toggled and viewed on an oscilloscope. for more details on this subject.)

The Release stack still offers some basic informational traces in InSight Desktop during major events, including CoreDump, Reset and NodeInfo traces, in addition to the RF-level PacketTrace information coming from the chip’s PTI port (provided that PACKET_TRACE is not disabled in the HAL); this stack variant is the one we generally advise customers to use for their product deployments.

If flash usage is still over limit by a considerable amount when using the Release stack, the Debug-Off variant can be used. This flavor of the library has the Virtual UART and very basic ISD trace information stripped out, saving an additional 2KB from the Release stack. With this stack variant, only PacketTrace information is available in ISD, so diagnostics would generally be in the form of SerialPrintf statements from the application to the physical UART port (Port 1 in the serial driver), or, if no serial port is available, diagnostics might be visual indications such as LEDs or digital signals that can be toggled and viewed on an oscilloscope.

Use “stub” libraries where appropriate.

In addition to different variants of the core stack library, EmberZNet also provides support for different ZigBee features in the form of libraries, such as end-device-bind-library, binding-table-library, and standard-security-library.

However, if the features contained in one of these libraries isn’t being used at all by the application, the project can use a “stub” version of the library, which contains empty or minimal placeholders for the functions of that module, such that code space for those unused features is minimized.

For example, if security is disabling during testing or initial debugging, the stub-security-library can be substituted for the standard-security-library, saving about 5 or 6KB of space. See the Application Developer’s Guide for more information on the different libraries (and stubs) available.

Consider removing bootloader support during the initial phases of development/debugging

In the early stages of development, more debugging is generally preferred, so you’ll want to use the stack variant (see above paragraph) that gives you the most debugging that you can accommodate given your code size constraints.

By contrast, the early debugging/development stage generally occurs in a controlled development environment where chip-programming devices (like the InSight Adapter or InSight USB Link) are available to load code into the chip directly, rather than using a serial interface or over-the-air (OTA) interface to accomplish firmware updates. In this kind of typical scenario, if flash space becomes an issue, the application can remove the bootloader support from the application to recover more space for debugging features.

For example, the Sensor/Sink example application included in the software releases uses a USE_BOOTLOADER_LIB symbol define to control the inclusion of supporting code into the application for facilitating Standalone Bootloader functionality (launching the bootloader for use as a download target via serial or OTA mechanisms, sending bootloader packets to a target, looking for nodes to upload, etc.)

By undefining this symbol, the application can save several KB in code space because it will no longer use functions required for interfacing with the Standalone Bootloader. A similar tactic can be applied to the Application Bootloader (which generally saves even more space because the Application Bootloader requires more support by the application to do its job).

Variations on this theme include removing only a portion of the bootloader-supporting functionality, such as allowing only for serial updates or only for the node to act as an OTA bootload target rather than an OTA bootload source or passthrough node as well. If the flash usage is still significantly over the limit (5-10KB) even after removing this support from the application, a last-resort option to consider is removing the bootloader from the flash map entirely during this initial debugging phase. (NOTE: This is not something Ember recommends doing for released product, since it will make field upgrades much more difficult [since SIF programming tools will be required] and might necessitate device replacement rather than device upgrade for your customers.)

Operating will a “null” bootloader in the flash map can be accomplished by defining the “NULL_BTL” symbol in the compiler definitions and the “$NULL_BTL” symbol in the assembler definitions for the build. This will free up 10KB for the Standalone Bootloader or 5KB in the case of the Application Bootloader, excluding any savings from the application being able to remove the supporting code for the associated bootloader.

Increase optimization level of the compiler

The xIDE compiler allows for three different optimization settings for the compiler: Off, Normal and High.

The higher the optimization level, the more the code size is compacted during the build, but the less information (such as global or local variables) will be available while using the xIDE debugger to step through program execution.

If you don’t plan on using the debugger often or at all, make sure this setting is set to High for all of your targets, such that the code is generated to be as efficiently packed as possible.

Update to EmberZNet 3.4 or higher

For the EM250 platform, the xIDE compiler used with EmberZNet releases prior to 3.3 is xIDE For EM250 version 1.x. EmberZNet 3.3 uses xIDE For EM250 version 2.0, and EmberZNet 3.4 and later use xIDE For EM250 version 2.1. These later xIDE versions provide significant code size optimizations, such that code generated in xIDE 2.1 is approximately 15% smaller than code generated by xIDE 1.6. By using the latest EmberZNet version, you're able to leverage these more efficient releases of xIDE, such that the stack libraries and your resulting application code are much smaller than in previous versions. This means that applications that may not have been possible to fit at all in EmberZNet 3.2 or 3.3 might fit comfortably in EmberZNet 3.4 and later.

What about External Memory?

As far as external memory goes (Flash or RAM), the EM250 chip does not have any native support (e.g. address bus lines) for interfacing to external memory, so any external circuitry must be controlled by driver managed by the application. Some of Ember’s customers have accomplished interfaces to external memory storage chips by SPI, others by I2C and occasionally some using manipulation of digital GPIO signals. For some examples of an external memory interface, refer to the mc24aa1025.c and at45db011b.c files in the /hal/micro/xap2b/em250 directory of EmberZNet 3.0.2 or higher.

The NCP option

If, after taking all of the above into consideration, you still feel that the Flash memory constraints of the EM250 are not compatible with your design, another alternative to using external memory is to consider migrating your design to Ember's EM260 chip, which is similar in technical specifications to the EM250, though slightly smaller and slightly lower unit cost, but which is intended for use as a network coprocessor (NCP).

Although this can add some additional cost to the design (due to the addition of a host microcontroller and any one-time re-design costs for existing hardware and software), it can also add flexibility because the EM260 can be controlled (using EmberZNet Serial Protocol [EZSP]) via UART or SPI, so the host architecture can be any MCU/MPU that supports one of these interfaces. Given that much of EZSP is a direct mapping of EmberZNet stack API commands into serial protocol commands, the porting effort from the EM250 to EZSP can be fairly straightforward, especially if the host architecture implements an abstraction of EZSP that closely mirrors the design of the EmberZNet API.

See the sample code in the /app/util/ezsp directory of the EmberZNet releases for EM260 for an example EZSP-SPI host implementation for the Atmel AVR ATmega32 microcontroller. Additional code pertaining to a Linux implementation of the EZSP-UART host architecture can be found in /app/util/ezsp-uart-host. Since it is possible [though not officially supported for anything other than experimentation] to run the EZSP NCP firmware on the EM250, the supporting files for EZSP-UART are also available in the EM250 stack releases as well in these same locations, including EZSP-UART host versions of the sample applications, which end in the -host suffix.

Using this NCP model allows the application to have complete controller of its own host processor without interfering with stack operations. It also makes the host application immune to changes in the stack implementation (across different EM260 firmware versions or future NCP chipsets, for example), so long as the EZSP interface itself remains unchanged.

See Also: 
Reducing RAM usage in EmberZNet PRO
How do I know how much Flash is used by my application?
Why does App builder show 112kB as maximum flash available?
  • Printer-friendly version

Search

FAQs

  • All (160)
  • Software : Embedded (62)
  • Software : Networking (70)
  • Hardware : Design (22)
  • Hardware : Manufacturing (10)
  • Tools : Dev Boards (2)
  • Tools : ISD/ISA (17)
  • Tools : xIDE (6)
  • Tools : Other (7)
  • ZigBee (1)
  • Change Notification (0)
Primary links
  • Developer Blog
  • Documentation
    • Release Notes
  • Contributed Software
  • FAQs
  • Change Notifications
  • Training
Portal
  • My Account
  • Search
User login
  • Request new password

Company | Products | Buy | Applications | ZigBee | Partners | Support | Events | Contact Us

©2007-2008 Ember Corporation | All rights reserved | Privacy