*.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
--- /dev/null
- # 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 $@ $<
+
+#########################################################################
--- /dev/null
-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
-/* 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
+}
uint32_t _sd_sectors();\r
uint32_t _sectors;\r
\r
-- SPI _spi;\r
++ ::SPI _spi;\r
GPIO _cs;\r
\r
volatile bool busyflag;\r
-# 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