Merge remote-tracking branch 'origin/edge' into feature/new_build
authorAdam Green <adamgr@foo.bar>
Fri, 1 Mar 2013 07:11:49 +0000 (23:11 -0800)
committerAdam Green <adamgr@foo.bar>
Fri, 1 Mar 2013 07:11:49 +0000 (23:11 -0800)
Conflicts:
.gitignore
build/mbed_custom.c
gcc4mbed/build/gcc4mbed.mk
makefile
mbed/src/vendor/NXP/cmsis/LPC1768/GCC_ARM/LPC1768.ld

Fixed conflicts caused by heap tagging commit which modified several
files that had been moved around for this new build system.

NOTE: HEAP_TAGS has been disabled since it isn't compatible with newlib
      nano.  If we decide that we want to stay with newlib nano then I
      can update the heap tag code to work with this newer library.

1  2 
.gitignore
build/common.mk
build/mbed_custom.cpp
build/osx64/README.TXT
mbed/src/vendor/NXP/cmsis/LPC1768/GCC_ARM/LPC1768.ld
src/libs/USBDevice/USBMSD/SDCard.h
src/makefile
src/modules/utils/player/Player.cpp
src/modules/utils/simpleshell/SimpleShell.cpp
src/mpu.h

diff --cc .gitignore
@@@ -5,17 -5,22 +5,19 @@@
  *.elf
  *.hex
  *.map
 -*.ar
 -*.o
  mri.log
+ gdb.txt
+ deploy
  debug
 -.svn/
 -.hg/
 -LPC176x/
 -/gcc4mbed/BuildShell
 -/gcc4mbed/BuildShellDebug
 -/gcc4mbed/BuildShell.cmd
 -/gcc4mbed/BuildShellDebug.cmd
 -/gcc4mbed/external/mbed_download.sh
 -/gcc4mbed/gcc-arm-none-eabi/
 -/gcc4mbed/mac_install.log
 -/gcc4mbed/win_install.log
 -/gcc4mbed/linux_install.log
 -*~
 +/mbed/src/Debug/
 +/mbed/src/Release/
 +/LPC1768/
 +/mbed/drop/
 +/gcc-arm-none-eabi/
 +/BuildShell
 +/BuildShellDebug
 +/BuildShell.cmd
 +/BuildShellDebug.cmd
 +/mac_install.log
 +/win_install.log
 +/linux_install.log
diff --cc build/common.mk
index b9ddc0d,0000000..b03382f
mode 100755,000000..100755
--- /dev/null
@@@ -1,261 -1,0 +1,274 @@@
- # Setup wraps for newlib read/writes to redirect to MRI debugger. 
- ifeq "$(MRI_ENABLE)" "1"
- MRI_WRAPS=,--wrap=_read,--wrap=_write,--wrap=semihost_connected
- else
- MRI_WRAPS=
- endif
 +#Copyright (C) 2011 by Sagar G V
 +#
 +#Permission is hereby granted, free of charge, to any person obtaining a copy
 +#of this software and associated documentation files (the "Software"), to deal
 +#in the Software without restriction, including without limitation the rights
 +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 +#copies of the Software, and to permit persons to whom the Software is
 +#furnished to do so, subject to the following conditions:
 +#
 +#The above copyright notice and this permission notice shall be included in
 +#all copies or substantial portions of the Software.
 +#
 +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 +#THE SOFTWARE.
 +#
 +# Updates: 
 +#    Arthur Wolf & Adam Green in 2011 - 2012 - Updated to work with mbed.
 +###############################################################################
 +# Check for undefined variables.
 +ifndef PROJECT
 +$(error makefile must set PROJECT variable.)
 +endif
 +
 +ifndef BUILD_DIR
 +$(error makefile must set BUILD_DIR.)
 +endif
 +
 +# Set VERBOSE make variable to 1 to output all tool commands.
 +VERBOSE?=0
 +ifeq "$(VERBOSE)" "0"
 +Q=@
 +else
 +Q=
 +endif
 +
 +
 +# Default variables.
 +SRC ?= .
 +BUILD_TYPE ?= Release
 +MRI_BREAK_ON_INIT ?= 1
 +MRI_UART ?= MRI_UART_MBED_USB
++HEAP_TAGS ?= 0
++WRITE_BUFFER_DISABLE ?= 0
++STACK_SIZE ?= 0
 +
 +
 +# Configure MRI variables based on BUILD_TYPE build type variable.
 +ifeq "$(BUILD_TYPE)" "Release"
 +OPTIMIZATION ?= 2
 +MRI_ENABLE = 0
 +MRI_SEMIHOST_STDIO ?= 0
 +endif
 +
 +
 +ifeq "$(BUILD_TYPE)" "Debug"
 +OPTIMIZATION = 0
 +MRI_ENABLE ?= 1
 +MRI_SEMIHOST_STDIO ?= 1
 +endif
 +
 +
 +ifeq "$(BUILD_TYPE)" "Checked"
 +OPTIMIZATION ?= 2
 +MRI_ENABLE = 1
 +MRI_SEMIHOST_STDIO ?= 1
 +endif
 +
 +MRI_INIT_PARAMETERS=$(MRI_UART)
 +
 +# Output Object Directory
 +OUTDIR=../$(DEVICE)
 +
 +# List of sources to be compiled/assembled
 +CSRCS = $(wildcard $(SRC)/*.c $(SRC)/*/*.c $(SRC)/*/*/*.c $(SRC)/*/*/*/*.c $(SRC)/*/*/*/*/*.c)
 +ASRCS =  $(wildcard $(SRC)/*.S $(SRC)/*/*.S $(SRC)/*/*/*.S $(SRC)/*/*/*/*.S $(SRC)/*/*/*/*/*.S)
 +ifneq "$(OS)" "Windows_NT"
 +ASRCS +=  $(wildcard $(SRC)/*.s $(SRC)/*/*.s $(SRC)/*/*/*.s $(SRC)/*/*/*/*.s $(SRC)/*/*/*/*/*.s)
 +endif
 +CPPSRCS = $(wildcard $(SRC)/*.cpp $(SRC)/*/*.cpp $(SRC)/*/*/*.cpp $(SRC)/*/*/*/*.cpp $(SRC)/*/*/*/*/*.cpp)
 +
 +# List of the objects files to be compiled/assembled
 +OBJECTS = $(patsubst %.c,$(OUTDIR)/%.o,$(CSRCS)) $(patsubst %.s,$(OUTDIR)/%.o,$(patsubst %.S,$(OUTDIR)/%.o,$(ASRCS))) $(patsubst %.cpp,$(OUTDIR)/%.o,$(CPPSRCS))
 +
 +# Add in the MBED customization stubs which allow hooking in the MRI debug monitor.
 +OBJECTS += $(OUTDIR)/mbed_custom.o
 +
 +# List of the header dependency files, one per object file.
 +DEPFILES = $(patsubst %.o,%.d,$(OBJECTS))
 +
 +# Linker script to be used.  Indicates what code should be placed where in memory.
 +LSCRIPT=$(MBED_DIR)/$(DEVICE)/GCC_ARM/$(DEVICE).ld
 +
 +# Location of external library and header dependencies.
 +MBED_DIR = $(BUILD_DIR)/../mbed/drop
 +MRI_DIR  = $(BUILD_DIR)/../mri
 +
 +# Include path which points to external library headers and to subdirectories of this project which contain headers.
 +SUBDIRS = $(wildcard $(SRC)/* $(SRC)/*/* $(SRC)/*/*/* $(SRC)/*/*/*/* $(SRC)/*/*/*/*/*)
 +PROJINCS = $(sort $(dir $(SUBDIRS)))
 +INCDIRS += $(SRC) $(PROJINCS) $(MRI_DIR) $(MBED_DIR) $(MBED_DIR)/$(DEVICE)
 +
 +# DEFINEs to be used when building C/C++ code
 +DEFINES += -DTARGET_$(DEVICE)
 +DEFINES += -DMRI_ENABLE=$(MRI_ENABLE) -DMRI_INIT_PARAMETERS='"$(MRI_INIT_PARAMETERS)"' 
 +DEFINES += -DMRI_BREAK_ON_INIT=$(MRI_BREAK_ON_INIT) -DMRI_SEMIHOST_STDIO=$(MRI_SEMIHOST_STDIO)
++DEFINES += -DWRITE_BUFFER_DISABLE=$(WRITE_BUFFER_DISABLE) -DSTACK_SIZE=$(STACK_SIZE)
 +
 +ifeq "$(OPTIMIZATION)" "0"
 +DEFINES += -DDEBUG
 +endif
 +
 +# Libraries to be linked into final binary
 +MBED_LIBS = $(MBED_DIR)/$(DEVICE)/GCC_ARM/libmbed.a
 +SYS_LIBS = -lstdc++_s -lsupc++_s -lm -lgcc -lc_s -lgcc -lc_s -lnosys
 +LIBS = $(LIBS_PREFIX) 
 +
 +ifeq "$(MRI_ENABLE)" "1"
 +LIBS += $(MRI_DIR)/mri.ar
 +endif
 +
 +LIBS += $(MBED_LIBS)
 +LIBS += $(SYS_LIBS)
 +LIBS += $(LIBS_SUFFIX)
 +
 +# Compiler flags used to enable creation of header dependencies.
 +DEPFLAGS = -MMD -MP
 +
++# Setup wraps for newlib read/writes to redirect to MRI debugger. 
++ifeq "$(MRI_ENABLE)" "1"
++MRI_WRAPS=,--wrap=_read,--wrap=_write,--wrap=semihost_connected
++else
++MRI_WRAPS=
++endif
++
++# Setup wraps to memory allocations routines if we want to tag heap allocations.
++HEAP_WRAPS=
++ifeq "$(HEAP_TAGS)" "1"
++HEAP_WRAPS=,--wrap=malloc,--wrap=realloc,--wrap=free
++DEFINES += -DHEAP_TAGS
++endif
++
 +# Compiler Options
 +GCFLAGS += -O$(OPTIMIZATION) -g3 $(DEVICE_CFLAGS)
 +GCFLAGS += -ffunction-sections -fdata-sections  -fno-exceptions -fno-delete-null-pointer-checks
 +GCFLAGS += $(patsubst %,-I%,$(INCDIRS))
 +GCFLAGS += $(DEFINES)
 +GCFLAGS += $(DEPFLAGS)
 +GCFLAGS += -Wall -Wextra -Wno-unused-parameter -Wcast-align -Wpointer-arith -Wredundant-decls -Wcast-qual -Wcast-align
 +
 +GPFLAGS += $(GCFLAGS) -fno-rtti -std=gnu++11
 +
 +AS_GCFLAGS += -g3 $(DEVICE_FLAGS) -x assembler-with-cpp
 +AS_GCFLAGS += $(patsubst %,-I%,$(INCDIRS))
 +AS_FLAGS += -g3 $(DEVICE_FLAGS)
 +
 +
- LDFLAGS = $(DEVICE_FLAGS) -specs=$(BUILD_DIR)/startfile.spec -Wl,-Map=$(OUTDIR)/$(PROJECT).map,--cref,--gc-sections,--wrap=_isatty$(MRI_WRAPS) -T$(LSCRIPT)
 +# Linker Options.
- $(OUTDIR)/mbed_custom.o : $(BUILD_DIR)/mbed_custom.c makefile
++LDFLAGS = $(DEVICE_FLAGS) -specs=$(BUILD_DIR)/startfile.spec 
++LDFLAGS += -Wl,-Map=$(OUTDIR)/$(PROJECT).map,--cref,--gc-sections,--wrap=_isatty$(MRI_WRAPS)$(HEAP_WRAPS)
++LDFLAGS += -T$(LSCRIPT)  -L $(EXTERNAL_DIR)/gcc/LPC1768
 +ifneq "$(NO_FLOAT_SCANF)" "1"
 +LDFLAGS += -u _scanf_float
 +endif
 +ifneq "$(NO_FLOAT_PRINTF)" "1"
 +LDFLAGS += -u _printf_float
 +endif
 +
 +
 +#  Compiler/Assembler/Linker Paths
 +GCC = arm-none-eabi-gcc
 +GPP = arm-none-eabi-g++
 +AS = arm-none-eabi-as
 +LD = arm-none-eabi-g++
 +OBJCOPY = arm-none-eabi-objcopy
 +OBJDUMP = arm-none-eabi-objdump
 +SIZE = arm-none-eabi-size
 +
 +# Some tools are different on Windows in comparison to Unix.
 +ifeq "$(OS)" "Windows_NT"
 +REMOVE = del
 +SHELL=cmd.exe
 +REMOVE_DIR = rd /s /q
 +MKDIR = mkdir
 +QUIET=>nul 2>nul & exit 0
 +BLANK_LINE=echo -
 +else
 +REMOVE = rm
 +REMOVE_DIR = rm -r -f
 +MKDIR = mkdir -p
 +QUIET=> /dev/null 2>&1 ; exit 0
 +BLANK_LINE=echo
 +endif
 +
 +# Create macro which will convert / to \ on Windows.
 +ifeq "$(OS)" "Windows_NT"
 +define convert-slash
 +$(subst /,\,$1)
 +endef
 +else
 +define convert-slash
 +$1
 +endef
 +endif
 +
 +#########################################################################
 +.PHONY: all clean size
 +
 +all:: $(OUTDIR)/$(PROJECT).hex $(OUTDIR)/$(PROJECT).bin $(OUTDIR)/$(PROJECT).disasm size
 +
 +$(OUTDIR)/$(PROJECT).bin: $(OUTDIR)/$(PROJECT).elf
 +      @echo Extracting $@
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(OBJCOPY) -O binary $< $@
 +
 +$(OUTDIR)/$(PROJECT).hex: $(OUTDIR)/$(PROJECT).elf
 +      @echo Extracting $@
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(OBJCOPY) -R .stack -O ihex $< $@
 +      
 +$(OUTDIR)/$(PROJECT).disasm: $(OUTDIR)/$(PROJECT).elf
 +      @echo Extracting disassembly to $@
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(OBJDUMP) -d -f -M reg-names-std --demangle $< >$@
 +      
 +$(OUTDIR)/$(PROJECT).elf: $(LSCRIPT) $(OBJECTS)
 +      @echo Linking $@
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
 +
 +size: $(OUTDIR)/$(PROJECT).elf
 +      $(Q) $(SIZE) $<
 +      @$(BLANK_LINE)
 +
 +clean:
 +      @echo Cleaning up all build generated files
 +      $(Q) $(REMOVE_DIR) $(OUTDIR) $(QUIET)
 +
 +-include $(DEPFILES)
 +
 +#########################################################################
 +#  Default rules to compile .c and .cpp file to .o
 +#  and assemble .s files to .o
 +
-       $(Q) $(GCC) $(GCFLAGS) -c $< -o $@
++$(OUTDIR)/mbed_custom.o : $(BUILD_DIR)/mbed_custom.cpp makefile
 +      @echo Compiling $<
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
++      $(Q) $(GPP) $(GPFLAGS) -c $< -o $@
 +
 +$(OUTDIR)/%.o : %.cpp makefile
 +      @echo Compiling $<
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(GPP) $(GPFLAGS) -c $< -o $@
 +
 +$(OUTDIR)/%.o : %.c makefile
 +      @echo Compiling $<
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(GCC) $(GCFLAGS) -c $< -o $@
 +
 +$(OUTDIR)/%.o : %.S makefile
 +      @echo Assembling $<
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(GCC) $(AS_GCFLAGS) -c $< -o $@
 +
 +$(OUTDIR)/%.o : %.s makefile
 +      @echo Assembling $<
 +      $(Q) $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
 +      $(Q) $(AS) $(AS_FLAGS) -o $@ $<
 +
 +#########################################################################
index 0000000,4eb7ded..c884696
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,352 +1,335 @@@
 -extern "C" int __aeabi_unwind_cpp_pr0(int state, void* controlBlock, void* context)
 -{
 -    abort();
 -}
 -
 -
 -extern "C" int __aeabi_unwind_cpp_pr1(int state, void* controlBlock, void* context)
 -{
 -    abort();
 -}
 -
 -
 -extern "C" int __aeabi_unwind_cpp_pr2(int state, void* controlBlock, void* context)
 -{
 -    abort();
 -}
 -
+ /* Copyright 2013 Adam Green (http://mbed.org/users/AdamGreen/)
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+        http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+ /* Provide routines which hook the MRI debug monitor into GCC4MBED projects. */
+ #include <string.h>
+ #include <sys/types.h>
+ #include <errno.h>
+ #include <mri.h>
+ #include <cmsis.h>
+ #include "mpu.h"
+ static unsigned int g_maximumHeapAddress;
+ static void fillUnusedRAM(void);
+ static void configureStackSizeLimit(unsigned int stackSizeLimit);
+ static unsigned int alignTo32Bytes(unsigned int value);
+ static void configureMpuToCatchStackOverflowIntoHeap(unsigned int maximumHeapAddress);
+ static void configureMpuRegionToAccessAllMemoryWithNoCaching(void);
+ /* Symbols exposed from the linker script. */
+ extern unsigned int     __bss_start__;
+ extern unsigned int     __bss_end__;
+ extern unsigned int     __StackTop;
+ extern "C" unsigned int __end__;
+ extern "C" int  main(void);
+ extern "C" void __libc_init_array(void);
+ extern "C" void exit(int ErrorCode);
+ extern "C" void _start(void)
+ {
+     int bssSize = (int)&__bss_end__ - (int)&__bss_start__;
+     int mainReturnValue;
+     
+     memset(&__bss_start__, 0, bssSize);
+     fillUnusedRAM();
+     
+     if (STACK_SIZE)
+     {
+         configureStackSizeLimit(STACK_SIZE);
+     }
+     if (WRITE_BUFFER_DISABLE)
+     {
+         disableMPU();
+         configureMpuRegionToAccessAllMemoryWithNoCaching();    
+         enableMPU();
+     }
+     if (MRI_ENABLE)
+     {
+         __mriInit(MRI_INIT_PARAMETERS);
+         if (MRI_BREAK_ON_INIT)
+             __debugbreak();
+     }
+     __libc_init_array();
+     mainReturnValue = main();
+     exit(mainReturnValue);
+ }
+ static __attribute__((naked)) void fillUnusedRAM(void)
+ {
+     __asm (
+         ".syntax unified\n"
+         ".thumb\n"
+         // Fill 2 words (8 bytes) at a time with 0xdeadbeef.
+         " ldr   r2, =__FillStart\n"
+         " movw  r0, #0xbeef\n"
+         " movt  r0, #0xdead\n"
+         " mov   r1, r0\n"
+         // Don't fill past current stack pointer value.
+         " mov   r3, sp\n"
+         " bics  r3, r3, #7\n"
+         "1$:\n"
+         " strd  r0, r1, [r2], #8\n"
+         " cmp   r2, r3\n"
+         " blo   1$\n"
+         " bx    lr\n"
+     );
+ }
+ static void configureStackSizeLimit(unsigned int stackSizeLimit)
+ {
+     // Note: 32 bytes are reserved to fall between top of heap and top of stack for minimum MPU guard region.
+     g_maximumHeapAddress = alignTo32Bytes((unsigned int)&__StackTop - stackSizeLimit - 32);
+     configureMpuToCatchStackOverflowIntoHeap(g_maximumHeapAddress);
+ }
+ static unsigned int alignTo32Bytes(unsigned int value)
+ {
+     return (value + 31) & ~31;
+ }
+ static void configureMpuToCatchStackOverflowIntoHeap(unsigned int maximumHeapAddress)
+ {
+     #define MPU_REGION_SIZE_OF_32_BYTES ((5-1) << MPU_RASR_SIZE_SHIFT)  // 2^5 = 32 bytes.
+     
+     prepareToAccessMPURegion(getHighestMPUDataRegionIndex());
+     setMPURegionAddress(maximumHeapAddress);
+     setMPURegionAttributeAndSize(MPU_REGION_SIZE_OF_32_BYTES | MPU_RASR_ENABLE);
+     enableMPUWithDefaultMemoryMap();
+ }
+ static void configureMpuRegionToAccessAllMemoryWithNoCaching(void)
+ {
+     static const uint32_t regionToStartAtAddress0 = 0U;
+     static const uint32_t regionReadWrite = 1  << MPU_RASR_AP_SHIFT;
+     static const uint32_t regionSizeAt4GB = 31 << MPU_RASR_SIZE_SHIFT; /* 4GB = 2^(31+1) */
+     static const uint32_t regionEnable    = MPU_RASR_ENABLE;
+     static const uint32_t regionSizeAndAttributes = regionReadWrite | regionSizeAt4GB | regionEnable;
+     uint32_t regionIndex = STACK_SIZE ? getHighestMPUDataRegionIndex() - 1 : getHighestMPUDataRegionIndex();
+     
+     prepareToAccessMPURegion(regionIndex);
+     setMPURegionAddress(regionToStartAtAddress0);
+     setMPURegionAttributeAndSize(regionSizeAndAttributes);
+ }
+ extern "C" int __real__read(int file, char *ptr, int len);
+ extern "C" int __wrap__read(int file, char *ptr, int len)
+ {
+     if (MRI_SEMIHOST_STDIO && file < 3)
+         return __mriNewlib_SemihostRead(file, ptr, len);
+      return __real__read(file, ptr, len);
+ }
+ extern "C" int __real__write(int file, char *ptr, int len);
+ extern "C" int __wrap__write(int file, char *ptr, int len)
+ {
+     if (MRI_SEMIHOST_STDIO && file < 3)
+         return __mriNewlib_SemihostWrite(file, ptr, len);
+     return __real__write(file, ptr, len);
+ }
+ extern "C" int __real__isatty(int file);
+ extern "C" int __wrap__isatty(int file)
+ {
+     /* Hardcoding the stdin/stdout/stderr handles to be interactive tty devices, unlike mbed.ar */
+     if (file < 3)
+         return 1;
+     return __real__isatty(file);
+ }
+ extern "C" int __wrap_semihost_connected(void)
+ {
+     /* MRI makes it look like there is no mbed interface attached since it disables the JTAG portion but MRI does
+        support some of the mbed semihost calls when it is running so force it to return -1, indicating that the
+        interface is attached. */
+     return -1;
+ }
+ extern "C" void abort(void)
+ {
+     if (MRI_ENABLE)
+         __debugbreak();
+         
+     exit(1);
+ }
+ extern "C" void __cxa_pure_virtual(void)
+ {
+     abort();
+ }
+ /* Trap calls to malloc/free/realloc in ISR. */
+ extern "C" void __malloc_lock(void)
+ {
+     if (__get_IPSR() != 0)
+         __debugbreak();
+ }
+ extern "C" void __malloc_unlock(void)
+ {
+ }
+ /* Turn off the errno macro and use actual external global variable instead. */
+ #undef errno
+ extern int errno;
+ static int doesHeapCollideWithStack(unsigned int newHeap);
+ /* Dynamic memory allocation related syscalls. */
+ extern "C" caddr_t _sbrk(int incr) 
+ {
+     static unsigned char* heap = (unsigned char*)&__end__;
+     unsigned char*        prev_heap = heap;
+     unsigned char*        new_heap = heap + incr;
+     if (doesHeapCollideWithStack((unsigned int)new_heap)) 
+     {
+         errno = ENOMEM;
+         return (caddr_t)-1;
+     }
+     
+     heap = new_heap;
+     return (caddr_t) prev_heap;
+ }
+ static int doesHeapCollideWithStack(unsigned int newHeap)
+ {
+     return ((newHeap >= __get_MSP()) ||
+             (STACK_SIZE && newHeap >= g_maximumHeapAddress));
+ }
+ /* Optional functionality which will tag each heap allocation with the caller's return address. */
+ #ifdef HEAP_TAGS
+ const unsigned int* __smoothieHeapBase = &__end__;
+ extern "C" void* __real_malloc(size_t size);
+ extern "C" void* __real_realloc(void* ptr, size_t size);
+ extern "C" void  __real_free(void* ptr);
+ static void setTag(void* pv, unsigned int tag);
+ static unsigned int* footerForChunk(void* pv);
+ static unsigned int* headerForChunk(void* pv);
+ static unsigned int sizeOfChunk(unsigned int* pHeader);
+ static int isChunkInUse(void* pv);
+ extern "C" __attribute__((naked)) void __wrap_malloc(size_t size)
+ {
+     __asm (
+         ".syntax unified\n"
+         ".thumb\n"
+         "mov r1,lr\n"
+         "b mallocWithTag\n"
+     );
+ }
+ extern "C" void* mallocWithTag(size_t size, unsigned int tag)
+ {
+     void* p = __real_malloc(size + sizeof(tag));
+     if (!p && __smoothieHeapBase)
+         return p;
+     setTag(p, tag);
+     return p;
+ }
+ static void setTag(void* pv, unsigned int tag)
+ {
+     unsigned int* pFooter = footerForChunk(pv);
+     *pFooter = tag;
+ }
+ static unsigned int* footerForChunk(void* pv)
+ {
+     unsigned int* pHeader = headerForChunk(pv);
+     unsigned int  size = sizeOfChunk(pHeader);
+     return (unsigned int*)(void*)((char*)pHeader + size);
+ }
+ static unsigned int* headerForChunk(void* pv)
+ {
+     // Header is allocated two words (8 bytes) before the publicly returned allocation chunk address.
+     unsigned int* p = (unsigned int*)pv;
+     return &p[-2];
+ }
+ static unsigned int sizeOfChunk(unsigned int* pHeader)
+ {
+     /* Remove previous chunk in use flag. */
+     return pHeader[1] & ~1;
+ }
+ extern "C" __attribute__((naked)) void __wrap_realloc(void* ptr, size_t size)
+ {
+     __asm (
+         ".syntax unified\n"
+         ".thumb\n"
+         "mov r2,lr\n"
+         "b reallocWithTag\n"
+     );
+ }
+ extern "C" void* reallocWithTag(void* ptr, size_t size, unsigned int tag)
+ {
+     void* p = __real_realloc(ptr, size + sizeof(tag));
+     if (!p)
+         return p;
+     setTag(p, tag);
+     return p;
+ }
+ extern "C" void __wrap_free(void* ptr)
+ {
+     if (!isChunkInUse(ptr))
+         __debugbreak();
+     __real_free(ptr);
+ }
+ static int isChunkInUse(void* pv)
+ {
+     unsigned int* pFooter = footerForChunk(pv);
+     return pFooter[1] & 1;
+ }
+ __attribute__((naked)) void* operator new(size_t size)
+ {
+     __asm (
+         ".syntax unified\n"
+         ".thumb\n"
+         "push {r4,lr}\n"
+         "mov r1,lr\n"
+         "bl mallocWithTag\n"
+         "cbnz r0, 1$\n"
+         "bl abort\n"
+         "1$:\n"
+         "pop {r4,pc}\n"
+     );
+     // This line never executes but silences no return value warning from compiler.
+     return (void*)1;
+ }
+ #endif // HEAP_TAGS
Simple merge
 -/* Linker script for mbed LPC1768 */\r
 -MEMORY\r
 -{\r
 -/* FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K */\r
 -  FLASH (rx) : ORIGIN = 16K, LENGTH = (512K - 16K)\r
 -  RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8)\r
 -\r
 -  USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K\r
 -  ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K\r
 -}\r
 -\r
 -/* Linker script to place sections and symbol values. Should be used together\r
 - * with other linker script that defines memory regions FLASH and RAM.\r
 - * It references following symbols, which must be defined in code:\r
 - *   Reset_Handler : Entry of reset handler\r
 - * \r
 - * It defines following symbols, which code can use without definition:\r
 - *   __exidx_start\r
 - *   __exidx_end\r
 - *   __etext\r
 - *   __data_start__\r
 - *   __preinit_array_start\r
 - *   __preinit_array_end\r
 - *   __init_array_start\r
 - *   __init_array_end\r
 - *   __fini_array_start\r
 - *   __fini_array_end\r
 - *   __data_end__\r
 - *   __bss_start__\r
 - *   __bss_end__\r
 - *   __end__\r
 - *   end\r
 - *   __HeapLimit\r
 - *   __StackLimit\r
 - *   __StackTop\r
 - *   __stack\r
 - */\r
 -ENTRY(Reset_Handler)\r
 -\r
 -SECTIONS\r
 -{\r
 -    .text :\r
 -    {\r
 -              __cs3_region_start_rom = .;\r
 -        KEEP(*(.isr_vector))\r
 -        *(.text*)\r
 -\r
 -        KEEP(*(.init))\r
 -        KEEP(*(.fini))\r
 -\r
 -        /* .ctors */\r
 -        *crtbegin.o(.ctors)\r
 -        *crtbegin?.o(.ctors)\r
 -        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)\r
 -        *(SORT(.ctors.*))\r
 -        *(.ctors)\r
 -\r
 -        /* .dtors */\r
 -        *crtbegin.o(.dtors)\r
 -        *crtbegin?.o(.dtors)\r
 -        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)\r
 -        *(SORT(.dtors.*))\r
 -        *(.dtors)\r
 -\r
 -        *(.rodata*)\r
 -\r
 -        KEEP(*(.eh_frame*))\r
 -    } > FLASH\r
 -\r
 -    .ARM.extab : \r
 -    {\r
 -        *(.ARM.extab* .gnu.linkonce.armextab.*)\r
 -    } > FLASH\r
 -\r
 -    __exidx_start = .;\r
 -    .ARM.exidx :\r
 -    {\r
 -        *(.ARM.exidx* .gnu.linkonce.armexidx.*)\r
 -    } > FLASH\r
 -    __exidx_end = .;\r
 -\r
 -    __etext = .;\r
 -        \r
 -    .data : AT (__etext)\r
 -    {\r
 -              __cs3_region_start_ram = .;\r
 -        __data_start__ = .;\r
 -        Image$$RW_IRAM1$$Base = .;\r
 -        *(vtable)\r
 -        *(.data*)\r
 -\r
 -        . = ALIGN(4);\r
 -        /* preinit data */\r
 -        PROVIDE (__preinit_array_start = .);\r
 -        KEEP(*(.preinit_array))\r
 -        PROVIDE (__preinit_array_end = .);\r
 -\r
 -        . = ALIGN(4);\r
 -        /* init data */\r
 -        PROVIDE (__init_array_start = .);\r
 -        KEEP(*(SORT(.init_array.*)))\r
 -        KEEP(*(.init_array))\r
 -        PROVIDE (__init_array_end = .);\r
 -\r
 -\r
 -        . = ALIGN(4);\r
 -        /* finit data */\r
 -        PROVIDE (__fini_array_start = .);\r
 -        KEEP(*(SORT(.fini_array.*)))\r
 -        KEEP(*(.fini_array))\r
 -        PROVIDE (__fini_array_end = .);\r
 -\r
 -        . = ALIGN(4);\r
 -        /* All data end */\r
 -        __data_end__ = .;\r
 -\r
 -    } > RAM\r
 -\r
 -    .bss :\r
 -    {\r
 -        __bss_start__ = .;\r
 -        *(.bss*)\r
 -        *(COMMON)\r
 -        __bss_end__ = .;\r
 -        Image$$RW_IRAM1$$ZI$$Limit = . ;\r
 -    } > RAM\r
 -    \r
 -    .heap :\r
 -    {\r
 -        __end__ = .;\r
 -        end = __end__;\r
 -        *(.heap*)\r
 -        __HeapLimit = .;\r
 -    } > RAM\r
 -\r
 -    /* .stack_dummy section doesn't contains any symbols. It is only\r
 -     * used for linker to calculate size of stack sections, and assign\r
 -     * values to stack symbols later */\r
 -    .stack_dummy :\r
 -    {\r
 -        *(.stack)\r
 -    } > RAM\r
 -\r
 -    /* Set stack top to end of RAM, and stack limit move down by\r
 -     * size of stack_dummy section */\r
 -    __StackTop = ORIGIN(RAM) + LENGTH(RAM);\r
 -    __StackLimit = __StackTop - SIZEOF(.stack_dummy);\r
 -    PROVIDE(__stack = __StackTop);\r
 -    \r
 -    /* Area of memory, heap and stack, to fill on startup - 8 bytes at a time. */\r
 -    __FillStart = ALIGN(__end__, 8);\r
 -    \r
 -    /* Check if data + heap + stack exceeds RAM limit */\r
 -    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")\r
 -\r
 -\r
 -    /* Code can explicitly ask for data to be \r
 -       placed in these higher RAM banks where\r
 -       they will be left uninitialized. \r
 -    */\r
 -    .AHBSRAM0 (NOLOAD):\r
 -    {\r
 -        Image$$RW_IRAM2$$Base = . ;\r
 -        *(AHBSRAM0)\r
 -        Image$$RW_IRAM2$$ZI$$Limit = .;\r
 -    } > USB_RAM\r
 -\r
 -    .AHBSRAM1 (NOLOAD):\r
 -    {\r
 -        Image$$RW_IRAM3$$Base = . ;\r
 -        *(AHBSRAM1)\r
 -        Image$$RW_IRAM3$$ZI$$Limit = .;\r
 -    } > ETH_RAM\r
 -}\r
 +/* Linker script for mbed LPC1768 */
 +MEMORY
 +{
 +/* FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K */
 +  FLASH (rx) : ORIGIN = 16K, LENGTH = (512K - 16K)
 +  RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8)
 +
 +  USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
 +  ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
 +}
 +
 +/* Linker script to place sections and symbol values. Should be used together
 + * with other linker script that defines memory regions FLASH and RAM.
 + * It references following symbols, which must be defined in code:
 + *   Reset_Handler : Entry of reset handler
 + * 
 + * It defines following symbols, which code can use without definition:
 + *   __exidx_start
 + *   __exidx_end
 + *   __etext
 + *   __data_start__
 + *   __preinit_array_start
 + *   __preinit_array_end
 + *   __init_array_start
 + *   __init_array_end
 + *   __fini_array_start
 + *   __fini_array_end
 + *   __data_end__
 + *   __bss_start__
 + *   __bss_end__
 + *   __end__
 + *   end
 + *   __HeapLimit
 + *   __StackLimit
 + *   __StackTop
 + *   __stack
 + */
 +ENTRY(Reset_Handler)
 +
 +SECTIONS
 +{
 +    .text :
 +    {
 +        KEEP(*(.isr_vector))
 +        *(.text*)
 +
 +        KEEP(*(.init))
 +        KEEP(*(.fini))
 +
 +        /* .ctors */
 +        *crtbegin.o(.ctors)
 +        *crtbegin?.o(.ctors)
 +        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
 +        *(SORT(.ctors.*))
 +        *(.ctors)
 +
 +        /* .dtors */
 +        *crtbegin.o(.dtors)
 +        *crtbegin?.o(.dtors)
 +        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
 +        *(SORT(.dtors.*))
 +        *(.dtors)
 +
 +        *(.rodata*)
 +
 +        KEEP(*(.eh_frame*))
 +    } > FLASH
 +
 +    .ARM.extab : 
 +    {
 +        *(.ARM.extab* .gnu.linkonce.armextab.*)
 +    } > FLASH
 +
 +    __exidx_start = .;
 +    .ARM.exidx :
 +    {
 +        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
 +    } > FLASH
 +    __exidx_end = .;
 +
 +    __etext = .;
 +        
 +    .data : AT (__etext)
 +    {
 +        __data_start__ = .;
 +        Image$$RW_IRAM1$$Base = .;
 +        *(vtable)
 +        *(.data*)
 +
 +        . = ALIGN(4);
 +        /* preinit data */
 +        PROVIDE (__preinit_array_start = .);
 +        KEEP(*(.preinit_array))
 +        PROVIDE (__preinit_array_end = .);
 +
 +        . = ALIGN(4);
 +        /* init data */
 +        PROVIDE (__init_array_start = .);
 +        KEEP(*(SORT(.init_array.*)))
 +        KEEP(*(.init_array))
 +        PROVIDE (__init_array_end = .);
 +
 +
 +        . = ALIGN(4);
 +        /* finit data */
 +        PROVIDE (__fini_array_start = .);
 +        KEEP(*(SORT(.fini_array.*)))
 +        KEEP(*(.fini_array))
 +        PROVIDE (__fini_array_end = .);
 +
 +        . = ALIGN(4);
 +        /* All data end */
 +        __data_end__ = .;
 +
 +    } > RAM
 +
 +    .bss :
 +    {
 +        __bss_start__ = .;
 +        *(.bss*)
 +        *(COMMON)
 +        __bss_end__ = .;
 +        Image$$RW_IRAM1$$ZI$$Limit = . ;
 +    } > RAM
 +    
 +    .heap :
 +    {
 +        __end__ = .;
 +        end = __end__;
 +        *(.heap*)
 +        __HeapLimit = .;
 +    } > RAM
 +
 +    /* .stack_dummy section doesn't contains any symbols. It is only
 +     * used for linker to calculate size of stack sections, and assign
 +     * values to stack symbols later */
 +    .stack_dummy :
 +    {
 +        *(.stack)
 +    } > RAM
 +
 +    /* Set stack top to end of RAM, and stack limit move down by
 +     * size of stack_dummy section */
 +    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
 +    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
 +    PROVIDE(__stack = __StackTop);
 +    PROVIDE(__heapLimit = __HeapLimit);
 +    PROVIDE(__stackSize = __StackTop - __HeapLimit);
++
++    /* Area of memory, heap and stack, to fill on startup - 8 bytes at a time. */
++    __FillStart = ALIGN(__end__, 8);
 +    
 +    /* Check if data + heap + stack exceeds RAM limit */
 +    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
 +
 +
 +    /* Code can explicitly ask for data to be 
 +       placed in these higher RAM banks where
 +       they will be left uninitialized. 
 +    */
 +    .AHBSRAM0 (NOLOAD):
 +    {
 +        Image$$RW_IRAM2$$Base = . ;
 +        *(AHBSRAM0)
 +        Image$$RW_IRAM2$$ZI$$Limit = .;
 +    } > USB_RAM
 +
 +    .AHBSRAM1 (NOLOAD):
 +    {
 +        Image$$RW_IRAM3$$Base = . ;
 +        *(AHBSRAM1)
 +        Image$$RW_IRAM3$$ZI$$Limit = .;
 +    } > ETH_RAM
 +}
@@@ -99,7 -99,7 +99,7 @@@ protected
      uint32_t _sd_sectors();\r
      uint32_t _sectors;\r
  \r
--    SPI _spi;\r
++    ::SPI _spi;\r
      GPIO _cs;\r
  \r
      volatile bool busyflag;\r
diff --cc src/makefile
@@@ -1,13 -1,39 +1,26 @@@
 -# Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)\r
 -#\r
 -# Licensed under the Apache License, Version 2.0 (the "License");\r
 -# you may not use this file except in compliance with the License.\r
 -# You may obtain a copy of the License at\r
 -#\r
 -#     http://www.apache.org/licenses/LICENSE-2.0\r
 -#\r
 -# Unless required by applicable law or agreed to in writing, software\r
 -# distributed under the License is distributed on an "AS IS" BASIS,\r
 -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
 -# See the License for the specific language governing permissions and\r
 -# limitations under the License.\r
  PROJECT=main\r
 -GCC4MBED_DIR=./gcc4mbed\r
 -INCDIRS=\r
 -LIBS_PREFIX=\r
 -LIBS_SUFFIX=\r
 -SRC=./src\r
 +BUILD_DIR=../build\r
 +DEVICES=lpc1768\r
  \r
 -#GCC4MBED_TYPE=Debug\r
 -#GCC4MBED_TYPE=Release\r
 -GCC4MBED_TYPE=Checked\r
 +# BUILD_TYPE can be set to the following values:\r
 +#  Checked - Optimizations enabled with MRI debug monitor support. (Recommended Type)\r
 +#  Release - Optimizations enabled.\r
 +#  Debug - Optimization disabled with MRI debug monitor support.\r
 +BUILD_TYPE=Checked\r
  \r
 -HEAP_TAGS=1\r
+ # Set to 1 to tag each heap allocation with the caller's return address.\r
 -WRITE_BUFFER_DISABLE=1\r
++# NOTE: Can't be enabled with latest build as not compatible with newlib nano.\r
++HEAP_TAGS=0\r
\r
+ # Set to 1 configure MPU to disable write buffering and eliminate imprecise bus faults.\r
++WRITE_BUFFER_DISABLE=0\r
\r
+ # Set to non zero value if you want checks to be enabled which reserve a\r
+ # specific amount of space for the stack.  The heap's growth will be\r
+ # constrained to reserve this much space for the stack and the stack won't be\r
+ # able to grow larger than this amount.\r
+ STACK_SIZE=3072\r
\r
  # Set to 1 to allow MRI debug monitor to take full control of UART0 and use it\r
  # as a dedicated debug channel.  If you are using the USB based serial port for\r
  # the console then this should cause you no problems.  Set MRI_BREAK_ON_INIT to\r
Simple merge
diff --cc src/mpu.h
index 0000000,9091221..9091221
mode 000000,100644..100644
--- /dev/null
+++ b/src/mpu.h