Skip to content

Commit

Permalink
[avr] port a subset of libstdc++ to the AVR platform
Browse files Browse the repository at this point in the history
This will allow for using large parts of the C++ standard library inside modm.
Almost the complete implementation is copied from libstdc++ sources released
with GCC 8.2.0. Most headers do not require any modifications.

Some parts have been deliberately excluded because they are unavailable on
embedded platforms or the provided implementation is inherently unsuitable for
AVR and requires considerable porting efforts. For instance, the string conversion
functions contain kilobytes of static data that would be put into RAM.

IOStreams and std::string are also not available.
All stream-related code is removed from the supplied headers.

The following parts are included:

- Containers
- Algorithms (<algorithm>)
- Iterators library (<iterator>, except for iostream iterators)
- Numerics library (<complex>, <numeric>, <ratio>, <valarray>)
- Utilities library (<type_traits>, <any>, <optional>, <variant>, <tuple>, <utility>, <chrono>, …)
- Numeric limits (<limits>)
- C headers except for C99/C11 additions not supported by AVR libc (<c*>)
- Memory management (<new>, <memory>, <scoped_allocator>), except for std::shared_ptr
- String view (<string_view>)

Not included (may be incomplete):

- std::string and string conversions, regex
- Anything that requires an OS to work (threads, filesystem, locales, ...)
- Atomics
- iostreams and related headers
- Random number generation (<random>)
- std::shared_ptr (build on atomics, high porting effort)
- std::bitset
- Polymorphic allocators (<memory_resource>), experimental in libstdc++
- Exception headers
- RTTI headers
  • Loading branch information
salkinium committed Oct 10, 2018
2 parents e3c2712 + dd7d9c0 commit eba68a4
Show file tree
Hide file tree
Showing 19 changed files with 270 additions and 778 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "ext/arm/cmsis"]
path = ext/arm/cmsis
url = https://github.com/modm-io/cmsis-5-partial.git
[submodule "ext/gcc/libstdc++"]
path = ext/gcc/libstdc++
url = https://github.com/modm-io/avr-libstdcpp.git
80 changes: 80 additions & 0 deletions ext/gcc/assert.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2018, Christopher Durand
*
* 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 <cstdint>
#include <bits/functexcept.h>
#include <modm/utils/bit_constants.hpp>

%% if options["use_modm_assert"]
#include <modm/architecture/interface/assert.hpp>

#define __modm_stdcpp_failure(failure) modm_assert(false, "stdc++", "stdc++", failure);__builtin_abort();
%% else
#define __modm_stdcpp_failure(failure) __builtin_abort();
%% endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

void
__throw_logic_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("logic_error"); }

void
__throw_domain_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("domain_error"); }

void
__throw_invalid_argument(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("invalid_argument"); }

void
__throw_length_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("length_error"); }

void
__throw_out_of_range(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("out_of_range"); }

void
__throw_runtime_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("runtime_error"); }

void
__throw_range_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("range_error"); }

void
__throw_overflow_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("overflow_error"); }

void
__throw_underflow_error(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("underflow_error"); }

void
__throw_bad_optional_access()
{ __modm_stdcpp_failure("bad_optional"); }

void
__throw_bad_variant_access(const char* __s __attribute__((unused)))
{ __modm_stdcpp_failure("bad_variant"); }

void
__throw_bad_function_call()
{ __modm_stdcpp_failure("bad_function_call"); }

void
__throw_bad_any_cast()
{ __modm_stdcpp_failure("bad_any_cast"); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
1 change: 1 addition & 0 deletions ext/gcc/libstdc++
Submodule libstdc++ added at 2030cc
14 changes: 11 additions & 3 deletions src/stdc++/module.lb → ext/gcc/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#
# Copyright (c) 2016-2017, Niklas Hauser
# Copyright (c) 2017-2018, Fabian Greif
# Copyright (c) 2018, Christopher Durand
#
# This file is part of the modm project.
#
Expand All @@ -21,11 +22,18 @@ def prepare(module, options):
if target["platform"] != "avr":
return False

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

return True


def build(env):
env.add_metadata("include_path", "modm/src/stdc++")
env.add_metadata("include_path", "modm/ext/gcc/libstdc++/include")

env.outbasepath = "modm/src/stdc++"
env.copy(".")
env.outbasepath = "modm/ext/gcc"
env.copy(".", ignore=env.ignore_files("*.lb", "*.md", "*.in", "examples"))
env.template("assert.cpp.in", "assert.cpp")
24 changes: 24 additions & 0 deletions src/modm/platform/core/avr/newdelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ operator new[](size_t size, modm::MemoryTraits)
return ptr;
}

void*
operator new(std::size_t size, const std::nothrow_t&) noexcept
{
return modm::platform::allocateMemory(size);
}

void*
operator new[](std::size_t size, const std::nothrow_t&) noexcept
{
return modm::platform::allocateMemory(size);
}

void
operator delete(void* ptr)
{
Expand All @@ -72,3 +84,15 @@ operator delete[](void* ptr, size_t)
{
modm::platform::freeMemory(ptr);
}

void
operator delete(void* ptr, const std::nothrow_t&) noexcept
{
modm::platform::freeMemory(ptr);
}

void
operator delete[](void* ptr, const std::nothrow_t&) noexcept
{
modm::platform::freeMemory(ptr);
}
19 changes: 0 additions & 19 deletions src/stdc++/algorithm

This file was deleted.

103 changes: 0 additions & 103 deletions src/stdc++/cmath

This file was deleted.

41 changes: 0 additions & 41 deletions src/stdc++/cstddef

This file was deleted.

Loading

0 comments on commit eba68a4

Please sign in to comment.