Skip to content

Instantly share code, notes, and snippets.

@m-mcgowan
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m-mcgowan/3be364276b7a6b573047 to your computer and use it in GitHub Desktop.
Save m-mcgowan/3be364276b7a6b573047 to your computer and use it in GitHub Desktop.

The binaries consumed in the Particle ecosystem should include "module info" descriptors that appear at fixed locations in the binary. There are 2 module info structures:

  • start info: appears at the start of the binary, this defines the platform, version, module type, module dependencies
  • end info: appears at the end of the binary. Defines product ID and version, as set in user code and provides storage for the SHA256 and CRC32 hashes that are added after the binary is built.

Compiling Module Info

The module info structures are defined in dynalib/inc/module_info.h. The structures are instantiated in dynalib/inc/module_info.inc which defines the default values for all platforms.

The main project compiles the module info structure instances into a module_info.o object file - main/src/module_info.c simply includes module_info.inc from dynalib so the instance declarations become static data.

Linking Module Info

Your project's linker script describes how the various object files are placed into the final firmware image. The module infos need to be placed at specific locations, and so we must use linker scripting to instruct the linker to place these at the desired locations.

We provide some linker scripts to make this process simple (and avoid copy/pasting code.) All the linker scripts are stored in build/arm/linker. If not already done, you should add this directory to the linker search path with

LDFLAGS += -L$(COMMON_BUILD)/arm/linker

Add this alongside the other linker flags defines in your HAL include.mk file.

All the linker script changes add data to the program memory region - this is where the main executable code is stored. To reuse our linker scripts that inject the module info, this section should be named APP_FLASH. For example,

.somesection : 
{
  // .. declarations
} > APP_FLASH

.text :
{
  // .. more declarations
} > APP_FLASH

Module Start Symbol

A symbol for the module start is used to compute various offsets.

Add this include before any other APP_FLASH section.

INCLUDE 'module_start.ld'

In the example, this would come before .somesection.

Module Info Start

After any mandatory sections in program memory, such as ISR vector tables, add

INCLUDE 'module_info.ld'

In the example, this would come after .somesection if that section must remain at the start of the binary image. If .somesection can appear anywhere, the include would be placed before it so that the module info is placed at the very beginning of the module.

Module Info End

After all other APP_FLASH sections, add

INCLUDE 'module_end.ld'

In the example, this would be placed after the .text section.

Troubleshooting

Without the module info end structures in place, building main will fail since the module info end data isn't present. This includes default SHA256 and CRC32 values that are built into the binary, and the buidl will fail when those do not match the values expected. This is a sanity check in the build that it's overwriting the correct data when writing the SHA256 and CRC32 hashes to offsets from the end of the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment