BSP430  20141115
Board Support Package for MSP430 microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Using the GNU msp430-elf Compiler System

Table of Contents

BSP430 was initially developed using the MSPGCC toolchain, a port of the GNU compiler collection to the MSP430 that was begun by Dmitry Diky and Chris Liechti in 2001. Because copyright assignments could not be obtained from some past contributors this port could not be integrated by GNU so in 2012 TI funded Red Hat to create a new back-end for the MSP430.

In late 2014 this port reached maturity, and is now fully supported by BSP430. It is selected by setting WITH_GCC_MSP430_ELF=1 in the environment or passed through as an option to make. In a future release this toolchain will become the default, with MSPGCC available as an alternative using WITH_GCC_MSPGCC=1. (To disable a selected toolchain use WITH_GCC_MSP430_ELF= leaving an empty string as the value.)

How to Build the Toolchain

Texas Instruments provides a vendor-supported fork of the GCC compiler but BSP430 is developed using the fully open source release as built from the upstream repositories.

The script maintainer/msp430-elf provided in BSP430 can be used to do the build. It assumes you have updated workspaces for the required packages already cloned onto your system:

The development trunk of each project should always work, but the versions listed in Release Notes and API Changes have been tested.

Please do not ask the BSP430 maintainer for help with toolchain building. If you are uncomfortable building a compiler toolchain, look to TI or your OS vendor for packaged releases.

Overriding Linker Scripts

By default the linker script provided by the TI device bundle is used. BSP430 allows you to override this by defining an alternative with the LDSCRIPT Make variable. See make/Makefile.common for details.

20-Bit Support

Large memory model is specified by adding MEMORY_MODEL=large to the make options. This changes the default LDSCRIPT value, since the TI-provided ones do not currently include sections placed in far memory.

Due to limitations in the msp430-elf linker, it is only possible to place either read-only data or code above the 64 kiB boundary. By default code is placed in high memory, but if read-only data is large it can be placed there by using LDSCRIPT_LARGE_SUFFIX=far-rodata.

C Library Support

Newlib is an open-source implementation of the standard C library, and is used as the libc implementation in BSPACM's primary toolchain, GNU Tools for ARM Embedded Processors. It was designed for use in embedded systems, using a small set of externally-supplied functions to interface with the system.

While newlib is still too large for the smallest MSP430 processors, the efforts of the GNU for ARM Embedded folks to create "newlib-nano" are slowly being integrated into newlib, and as of late 2014 there are options that allow it to be small enough to work on most MSP430 processors.

The default build options suggested by maintainer/msp430-elf-build result in the following issues:

System Interface

newlib expects each target to provide an implementation of certain low-level functions to interact with the system environment. If nothing provides an implementation of one of these functions (e.g., write()) but the application requires one, the application will fail to link. The following symbols are referenced by the msp430 newlib infrastructure:

extern char ** environ;
int _chown (const char * path, uid_t owner, gid_t group);
int close (int fd);
int execve (const char * filename, char * const argv[], char * const envp[]);
pid_t fork (void);
int fstat (int fd, struct stat * buf);
pid_t getpid (void);
int gettimeofday (struct timeval * tv, struct timezone * tz);
int isatty (int fd);
int kill (pid_t pid, int sig);
int link (const char * oldpath, const char * newpath);
off_t lseek (int fd, off_t offset, int whence);
int open (const char * pathname, int flags);
_READ_WRITE_RETURN_TYPE read (int fd, void * buf, size_t count);
ssize_t _readlink (const char * path, char * buf, size_t bufsiz);
void * sbrk (ptrdiff_t increment);
int stat (const char * path, struct stat * buf);
int _symlink (const char * oldpath, const char * newpath);
clock_t times (struct tms *buf);
int unlink (const char * pathname);
pid_t wait (int * status);
_READ_WRITE_RETURN_TYPE write (int fd, const void * buf, size_t count);
void _exit (int status);

BSP430's Makefile.common uses the NEWLIB_SYS variable to identify the provider of these functions. The default is to use newlib/nosys.c which provides weak definitions for each required function.

Most of the weak definitions simply return an error code.

Dynamic Memory Management

BSP430 provides a function sbrk() which controls dynamic memory allocation, with several implementations in newlib/sbrk.c with the default being to dynamically allocate memory between static allocations and the bottom of the stack. See <bsp430/newlib/system.h> for details on these options and how to override them.

A highlight of this implementation is that if dynamic allocation fails the system will invoke an _bsp430_sbrk_error() allowing the application to recover appropriately. The default implementation of that function spins in place with interrupts disabled, allowing a debugger to inspect the call stack to locate the problematic allocation.

Formatted Input/Output

MSPGCC used a custom libc implementation that was highly optimized to reduce code space. Support for formatted output is particularly bloated in many other libc implementations, resulting in a fork of msp430-libc's version into embtextf.

With the "nano" options selected newlib for MSP430 is competitive with embtextf; a basic check showed that overriding newlib's routines with embtextf for formatted output reduced code size and data size by about 350 bytes each. However, newlib's printf will attempt to dynamically allocate memory for buffers which an introduce problems on very small devices.

newlib also assumes that descriptors for stdin (0), stdout (1), and stderr(2) are provided by the system and are supported by provided definitions of read() and write(). When console support is enabled BSP430 supports this by ensuring that read() and write() are overridden to use the console UART.

Standard I/O Descriptors

At this time BSP430 provides no infrastructure for generalized file descriptor operations. Should this ever change, the techniques used by BSPACM are likely to be ported to BSP430. Copyright 2012-2014, Peter A. Bigot