Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete rewrite #13

Merged
merged 23 commits into from
Feb 27, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Start using exceptions.
  • Loading branch information
ashtuchkin committed Feb 9, 2017
commit aedecc0224c1fcdba559cd6f976f9c89028dff6a
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ set(SOURCE_FILES
src/mavlink.cpp
src/outputs.cpp
src/pulse_processor.cpp
src/platform.cpp

src/primitives/timestamp.cpp
src/primitives/string_utils.cpp
Expand Down
10 changes: 10 additions & 0 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ https://google.github.io/styleguide/cppguide.html
### Git submodule management
* Update submodules to latest on branches/tags: `git submodule update --remote`
* When changing .gitmodules, do `git submodule sync`

### GCC Headers search for #include <..>

/usr/local/Caskroom/gcc-arm-embedded/6_2-2016q4,20161216/gcc-arm-none-eabi-6_2-2016q4
/arm-none-eabi/include/c++/6.2.1
/arm-none-eabi/include/c++/6.2.1/arm-none-eabi
/arm-none-eabi/include/c++/6.2.1/backward
/lib/gcc/arm-none-eabi/6.2.1/include
/lib/gcc/arm-none-eabi/6.2.1/include-fixed
/arm-none-eabi/include
62 changes: 62 additions & 0 deletions src/platform.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <exception>
#include <assert.h>
#include <stdlib.h>

// This file contains support functions that make it possible to use C++ exceptions and other niceties
// in a meaningful way on Teensy.
// See https://andriidevel.blogspot.com/2016/05/size-cost-of-c-exception-handling-on.html for some tricks used.

// NOTE: gcc-arm-embedded uses 'newlib' as stdlib. To be properly used, newlib needs several "Syscall" functions
// to be implemented, see https://sourceware.org/newlib/libc.html#Syscalls .
// For Teensy, some of them are defined in teensy3/mk20dx128.c but we need to


// ==== 1. Termination ================================

// abort() is a C stdlib function to do an abnormal program termination.
// It's being called for example when exception handling mechanisms themselves fail.
// It's not defined by default, so we need to implement it.
void abort() {
// TODO: Write to eeprom.
while(1);
}

// terminate_handler is called on std::terminate() and handles uncaught exceptions, exception-in-exceptions, etc.
// We install it statically below (__cxxabiv1::__terminate_handler) to avoid linking with default GCC
// __verbose_terminate_handler, which adds 30kb of code.
// See also: https://gcc.gnu.org/onlinedocs/libstdc++/manual/termination.html
// https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/vterminate.cc#L44
void terminate_handler() {
// TODO: Get exception name and write to eeprom.
while(1);
}

namespace __cxxabiv1 {
std::terminate_handler __terminate_handler = terminate_handler; // Default terminate handler for gcc c++ impl.
}

// TODO: We might want to re-define _exit() and __cxa_pure_virtual() as well to provide meaningful actions.


// ==== 2. Memory ================================

// Low-leve _sbrk() syscall to allocate memory is defined in teensy3/mk20dx128.c and very simple - just moves
// __brkval, current top of the heap.
// malloc() uses _sbrk().
// Teensy defines basic "operator new()", but it's too simple for our case, so we use standard one instead.

// Nice lib to get memory stats: https://github.com/michaeljball/RamMonitor
// Or, use standard interface mallinfo(); (uordblks = bytes in use, fordblks = bytes free.)


// ==== 3. Assertions ================================

// assert() macro in debug mode is defined to call __assert_func when assertion fails.
// We must redefine it statically to avoid linking to additional 15kb of code.
// Default implementation: https://github.com/bminor/newlib/blob/master/newlib/libc/stdlib/assert.c#L53
void __assert_func(const char *file, int line, const char *function_name, const char *expression) {
// TODO: Write to EEPROM.
while(1);
}


18 changes: 10 additions & 8 deletions teensy-arm.toolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,19 @@ set_property(CACHE TEENSY_USB_MODE PROPERTY STRINGS SERIAL HID SERIAL_HID MIDI R

set(TARGET_FLAGS "-mcpu=cortex-m4 -mthumb -mfp16-format=ieee")
set(OPTIMIZE_FLAGS "-O2" CACHE STRING "Optimization flags") # Remember to reset cache and rebuild cmake when changing this.
set(CMAKE_C_FLAGS "${OPTIMIZE_FLAGS} -Wall -nostdlib -ffunction-sections -fdata-sections ${TARGET_FLAGS}" CACHE STRING "C/C++ flags")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=gnu++14 -fno-exceptions -fno-rtti -felide-constructors -fsingle-precision-constant -Woverloaded-virtual" CACHE STRING "c++ flags")
set(CMAKE_C_FLAGS "${OPTIMIZE_FLAGS} -Wall -ffunction-sections -fdata-sections ${TARGET_FLAGS}" CACHE STRING "C/C++ flags")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=gnu++14 -fno-rtti -fsingle-precision-constant -Woverloaded-virtual" CACHE STRING "C++ flags")

set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG" CACHE STRING "" FORCE) # Don't do -O3 because it increases the size. Just remove asserts.
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG" CACHE STRING "" FORCE)

link_libraries(m)
set(LINKER_FLAGS "--gc-sections,--relax,--defsym=__rtc_localtime=0" CACHE STRING "Ld flags")
set(CXX_LINKER_FLAGS "${OPTIMIZE_FLAGS} -Wl,${LINKER_FLAGS} ${TARGET_FLAGS} -T${TEENSY_ROOT}/mk20dx256.ld")

set(CMAKE_SHARED_LINKER_FLAGS "${CXX_LINKER_FLAGS}" CACHE STRING "Linker flags" FORCE)
set(CMAKE_MODULE_LINKER_FLAGS "${CXX_LINKER_FLAGS}" CACHE STRING "Linker flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "${CXX_LINKER_FLAGS}" CACHE STRING "Linker flags" FORCE)

# Don't pass regular CMAKE_CXX_FLAGS because that causes undefined symbols
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_SHARED_LINKER_FLAGS "${CXX_LINKER_FLAGS}" CACHE STRING "Shared Linker flags" FORCE)
set(CMAKE_MODULE_LINKER_FLAGS "${CXX_LINKER_FLAGS}" CACHE STRING "Module Linker flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "${CXX_LINKER_FLAGS}" CACHE STRING "Executable Linker flags" FORCE)


add_definitions("-DARDUINO=${ARDUINO_VERSION}")
Expand All @@ -79,6 +79,7 @@ add_definitions("-D__${TEENSY_MODEL}__")
add_definitions("-DUSB_${TEENSY_USB_MODE}")
add_definitions("-DF_CPU=${TEENSY_FREQUENCY}000000")
add_definitions("-DLAYOUT_US_ENGLISH")
add_definitions("-DNEW_H") # Don't include new.h header as it defines non-standard operator new().
add_definitions("-MMD")

# Define target for the Teensy 'core' library.
Expand All @@ -88,6 +89,7 @@ if (NOT TARGET TeensyCore AND NOT ${CMAKE_SOURCE_DIR} MATCHES "CMakeTmp")
file(GLOB TEENSY_C_CORE_FILES "${TEENSY_ROOT}/*.c")
list(REMOVE_ITEM TEENSY_C_CORE_FILES "${TEENSY_ROOT}/math_helper.c") # legacy cmsis file - not needed anyway.
file(GLOB TEENSY_CXX_CORE_FILES "${TEENSY_ROOT}/*.cpp")
list(REMOVE_ITEM TEENSY_CXX_CORE_FILES "${TEENSY_ROOT}/new.cpp") # Don't use non-standard operator new.
add_library(TeensyCore ${TEENSY_C_CORE_FILES} ${TEENSY_CXX_CORE_FILES})
link_libraries(TeensyCore)
include_directories(${TEENSY_ROOT})
Expand Down