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

[c++] Move ABI implementation to own module, add option to use exceptions and RTTI #343

Merged
merged 5 commits into from
Mar 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 41 additions & 0 deletions examples/stm32f469_discovery/exceptions_rtti/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2020, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <typeinfo>

using namespace Board;

// ----------------------------------------------------------------------------
int
main()
{
Board::initialize();
LedD13::setOutput(modm::Gpio::Low);
uint32_t counter(0);

MODM_LOG_INFO << "TypeId for LedD13: " << typeid(LedD13).name() << modm::endl;

while (true)
{
LedBlue::toggle();
modm::delayMilliseconds(500);

try {
throw counter++;
}
catch (uint32_t code) {
MODM_LOG_ERROR << "Caught exception #" << code << modm::endl;
}
}

return 0;
}
12 changes: 12 additions & 0 deletions examples/stm32f469_discovery/exceptions_rtti/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<library>
<extends>modm:disco-f469ni</extends>
<options>
<option name="modm:build:build.path">../../../build/stm32f469_discovery/exceptions_rtti</option>
<option name="modm:stdc++:exceptions">true</option>
<option name="modm:stdc++:rtti">true</option>
</options>
<modules>
<module>modm:platform:gpio</module>
<module>modm:build:scons</module>
</modules>
</library>
44 changes: 44 additions & 0 deletions ext/gcc/cxxabi.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2009-2011, Fabian Greif
* Copyright (c) 2010, Martin Rosekeit
* Copyright (c) 2012, Sascha Schade
* Copyright (c) 2012-2014, 2020, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/architecture/interface/assert.hpp>

extern "C"
{

/**
* \brief Pure-virtual workaround.
*
* The libc does not support a default implementation for handling
* possible pure-virtual calls. This is a short and empty workaround for this.
*/
void
__cxa_pure_virtual()
{
modm_assert_debug(0, "cxa", "virtual", "pure");
}

%% if target.platform in ["avr"]
int __cxa_atexit(void (*)(void *), void *, void *)
%% else
// ARM EABI specifies __aeabi_atexit instead of __cxa_atexit
int __aeabi_atexit(void (*)(void *), void *, void *)
%% endif
{
return 0;
}

void* __dso_handle = (void*) &__dso_handle;

}
24 changes: 24 additions & 0 deletions ext/gcc/libcabi_cortex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2020, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/architecture/interface/assert.hpp>

// ------------------------------------------------------------------------
extern "C"
{

extern void _exit(int);
void _exit(int status)
{
modm_assert(false, "libc", "libc", "exit", status);
}

}
108 changes: 96 additions & 12 deletions ext/gcc/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,113 @@
def init(module):
module.name = ":stdc++"
module.description = """\
# C++ Standard Library
# C++ Standard Environment

A partial port of GCC 8 libstdc++ for AVR.
Refines the C++ language to make it easier to use on embedded targets.
Depending on the module options, the compiler options are appended with either:

- `-fno-exceptions`: no C++ exceptions.
- `-fno-rtti`: no C++ run-time type information.

or:

- `-fexceptions`: with C++ exceptions.
- `-frtti`: with C++ run-time type information.

## AVR

A partial port of GCC 8 libstdc++ is provided:
See https://github.com/modm-io/avr-libstdcpp.

## ARM Cortex-M

Additional compiler options:

- `-fno-threadsafe-statics`: No thread-safe static initialization provided.
- `--specs=nano.specs`: use Newlib Nano (when not using exceptions).
- `--specs=nosys.specs`: No additional C library features are implemented.
"""


def prepare(module, options):
if options[":target"].identifier.platform != "avr":
is_avr = options[":target"].identifier.platform == "avr"
is_cortex_m = options[":target"].has_driver("core:cortex-m*")
if not (is_avr or is_cortex_m):
return False

module.add_option(
BooleanOption(
name="use_modm_assert",
description="Assert on error in stdlib. Set to False to save flash.",
default=True))
if is_avr:
module.add_option(
BooleanOption(
name="use_modm_assert", default=True,
description="Assert on exception in stdlib. Set to False to save flash."))

elif is_cortex_m:
module.add_option(
BooleanOption(
name="exceptions", default=False,
description=descr_exceptions))
module.add_option(
BooleanOption(
name="rtti", default=False,
description=descr_rtti))

module.depends(":architecture:assert",
":architecture:memory")

return True


def build(env):
env.collect(":build:path.include", "modm/ext/gcc/libstdc++/include")

is_avr = env[":target"].identifier.platform == "avr"
is_cortex_m = env[":target"].has_driver("core:cortex-m*")
env.substitutions = {"target": env[":target"].identifier}
env.outbasepath = "modm/ext/gcc"
env.copy(".", ignore=env.ignore_files("*.lb", "*.md", "*.in", "examples"))
env.template("assert.cpp.in", "assert.cpp")
env.template("cxxabi.cpp.in")

if is_avr:
env.collect(":build:path.include", "modm/ext/gcc/libstdc++/include")
env.copy("libstdc++", ignore=env.ignore_files("*.lb", "*.md", "*.in", "examples"))
env.template("assert.cpp.in", "assert.cpp")

env.copy("newdelete_avr.cpp", "newdelete.cpp")

elif is_cortex_m:
env.copy("libcabi_cortex.cpp", "libcabi.cpp")
env.copy("newdelete_cortex.cpp", "newdelete.cpp")

# Compilation flags
env.collect(":build:cxxflags", "-fuse-cxa-atexit", "-fno-threadsafe-statics")
if env.get("exceptions", False):
env.collect(":build:cxxflags", "-fexceptions", "-funwind-tables")
else:
env.collect(":build:cxxflags", "-fno-exceptions", "-fno-unwind-tables")
if env.get("rtti", False):
env.collect(":build:cxxflags", "-frtti")
else:
env.collect(":build:cxxflags", "-fno-rtti")

if is_cortex_m:
env.collect(":build:linkflags", "--specs=nosys.specs")
if not env.get("exceptions", False):
# Newlib Nano does not support C++ exceptions at all
env.collect(":build:linkflags", "--specs=nano.specs")

# ============================ Option Descriptions ============================

descr_exceptions = """# C++ Exceptions

Enables the full use of C++ exception handling.

!!! warning "Check your code size"
The inclusion of the stack unwind tables will increase your code size quite
a bit. Check whether your target has enough memory for this!
"""

descr_rtti = """# C++ Runtime Type Information

Enables the full use of C++ runtime type information.

!!! warning "Check your code size"
The inclusion of the RTTI information will increase your code size quite a
bit. Check whether your target has enough memory for this!
"""
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
*/
// ----------------------------------------------------------------------------

#include "ram.hpp"
#include <new>
#include <modm/architecture/interface/memory.hpp>
#include <modm/architecture/interface/assert.hpp>
#include <modm/platform/core/ram.hpp>

void *
operator new(size_t size)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009-2010, Martin Rosekeit
* Copyright (c) 2009-2011, Fabian Greif
* Copyright (c) 2011-2012, 2014, 2016, Niklas Hauser
* Copyright (c) 2011-2012, 2014, 2016, 2020, Niklas Hauser
* Copyright (c) 2012, Sascha Schade
* Copyright (c) 2013, Kevin Läufer
*
Expand All @@ -13,63 +13,12 @@
*/
// ----------------------------------------------------------------------------

/**
* \file cxxabi.cpp
* \brief Minimal C++ support, no exception handling, no RTTI
*/
// ----------------------------------------------------------------------------

#include <stdlib.h> // for prototypes of malloc() and free()
#include <new>
#include <modm/architecture/interface/memory.hpp>
#include <modm/architecture/interface/assert.hpp>

extern "C"
{
// ------------------------------------------------------------------------
void* __dso_handle = (void *) &__dso_handle;

void
__cxa_pure_virtual()
{
modm_assert_debug(0, "core", "cxa", "purevirtual");
}

// ------------------------------------------------------------------------
__extension__ typedef int __guard __attribute__((mode (__DI__)));

int
__cxa_guard_acquire(__guard *g)
{
return !*(char *)(g);
}

void
__cxa_guard_release (__guard *g)
{
*(char *) g = 1;
}

void
__cxa_guard_abort (__guard *)
{
}

// ------------------------------------------------------------------------
int
__aeabi_atexit(void */*object*/, void (*/*destructor*/)(void *), void */*dso_handle*/)
{
return 0;
}

extern void * malloc_tr(size_t, uint32_t);

extern void _exit(int);
void _exit(int status)
{
modm_assert(false, "core", "libc", "exit", status);
}
}
extern "C" void * malloc_tr(size_t, uint32_t);

// ----------------------------------------------------------------------------
void *
Expand Down
57 changes: 0 additions & 57 deletions src/modm/platform/core/avr/cxxabi.cpp

This file was deleted.

Loading