From 0e1fc8641119b52ea4fa1f1caf4972d0ba1f2d2d Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Tue, 24 Dec 2024 23:19:31 +0100 Subject: [PATCH 1/3] [build] Upgrade macOS GCC to v13 --- docs/src/guide/installation.md | 2 +- tools/build_script_generator/scons/resources/SConscript.in | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/guide/installation.md b/docs/src/guide/installation.md index 4b1b5196f2..740de65ee7 100644 --- a/docs/src/guide/installation.md +++ b/docs/src/guide/installation.md @@ -196,7 +196,7 @@ brew link --force avr-gcc@13 To compile modm *for x86_64 macOS* you need to install these tools too: ```sh -brew install boost gcc +brew install boost gcc@13 ``` diff --git a/tools/build_script_generator/scons/resources/SConscript.in b/tools/build_script_generator/scons/resources/SConscript.in index 20f9bd2f6d..28853161d0 100644 --- a/tools/build_script_generator/scons/resources/SConscript.in +++ b/tools/build_script_generator/scons/resources/SConscript.in @@ -22,8 +22,8 @@ env["COMPILERPREFIX"] = "avr-" env["COMPILERPREFIX"] = "arm-none-eabi-" %% endif %% if family == "darwin" -# Using homebrew gcc-12 on macOS instead of clang -env["COMPILERSUFFIX"] = "-12" +# Using homebrew gcc-13 on macOS instead of clang +env["COMPILERSUFFIX"] = "-13" %% endif %% endif From e7fc5eb3bfd11485a3381bd33e80de8a2614325a Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Mon, 30 Dec 2024 17:29:43 +0100 Subject: [PATCH 2/3] [cortex-m] Invalidate CM7 caches only after enabling them --- src/modm/platform/core/cortex/startup.c.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modm/platform/core/cortex/startup.c.in b/src/modm/platform/core/cortex/startup.c.in index ac300c50f2..20c2346746 100644 --- a/src/modm/platform/core/cortex/startup.c.in +++ b/src/modm/platform/core/cortex/startup.c.in @@ -101,13 +101,13 @@ void __modm_startup(void) %# %% if with_icache // Enable instruction cache - SCB_InvalidateICache(); SCB_EnableICache(); + SCB_InvalidateICache(); %% endif %% if with_dcache // Enable data cache with default WBWA policy - SCB_CleanInvalidateDCache(); SCB_EnableDCache(); + SCB_CleanInvalidateDCache(); %% endif %# %% if core != "cortex-m0" From 3f2f6473ec94bd296a1a69a0f8d3054f74a02690 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Sun, 29 Dec 2024 14:09:27 +0100 Subject: [PATCH 3/3] [io] Add more stdc++ types to IOStream formatting --- src/modm/architecture/interface/clock.hpp | 32 ---- src/modm/io/iostream.hpp.in | 15 +- src/modm/io/iostream_chrono.hpp.in | 208 ++++++++++++++++++++++ src/modm/io/iostream_printf.cpp.in | 12 +- src/modm/io/module.lb | 12 +- 5 files changed, 235 insertions(+), 44 deletions(-) create mode 100644 src/modm/io/iostream_chrono.hpp.in diff --git a/src/modm/architecture/interface/clock.hpp b/src/modm/architecture/interface/clock.hpp index 40a88a27c3..086e6f342a 100644 --- a/src/modm/architecture/interface/clock.hpp +++ b/src/modm/architecture/interface/clock.hpp @@ -95,35 +95,3 @@ using PreciseClock = chrono::micro_clock; using namespace ::std::chrono_literals; } // namespace modm - -#if MODM_HAS_IOSTREAM -#include - -namespace modm -{ - -/// @ingroup modm_architecture_clock -template -modm::IOStream& -operator << (modm::IOStream& s, const std::chrono::time_point& m) -{ - s << m.time_since_epoch(); - return s; -} - -/// @ingroup modm_architecture_clock -template -modm::IOStream& -operator << (modm::IOStream& s, const std::chrono::duration& m) -{ - s << m.count(); - if constexpr (std::is_same_v) s << "ns"; - if constexpr (std::is_same_v) s << "us"; - if constexpr (std::is_same_v) s << "ms"; - if constexpr (std::is_same_v>) s << "min"; - if constexpr (std::is_same_v>) s << 'h'; - return s; -} - -} // modm namespace -#endif diff --git a/src/modm/io/iostream.hpp.in b/src/modm/io/iostream.hpp.in index d176f7e547..505f7c5d66 100644 --- a/src/modm/io/iostream.hpp.in +++ b/src/modm/io/iostream.hpp.in @@ -25,11 +25,13 @@ #include #include #include +#include +#include #include "iodevice.hpp" #include "iodevice_wrapper.hpp" // convenience -%% if using_printf +%% if options.with_printf /// @cond extern "C" { @@ -214,6 +216,13 @@ public: operator << (const char* s) { device->write(s); return *this; } + inline IOStream& + operator << (const std::string_view sv) + { + for (const auto c : sv) device->write(c); + return *this; + } + /// write the hex value of a pointer inline IOStream& operator << (const void* p) @@ -290,7 +299,7 @@ private: private: IODevice* const device; Mode mode = Mode::Ascii; -%% if using_printf +%% if options.with_printf static void out_char(char c, void* arg) { if (c) reinterpret_cast(arg)->write(c); } printf_output_gadget_t output_gadget{out_char, this, NULL, 0, INT_MAX}; @@ -363,4 +372,6 @@ white(IOStream& ios); } // namespace modm +#include "iostream_chrono.hpp" + #endif // MODM_IOSTREAM_HPP diff --git a/src/modm/io/iostream_chrono.hpp.in b/src/modm/io/iostream_chrono.hpp.in new file mode 100644 index 0000000000..fa9d72ca5a --- /dev/null +++ b/src/modm/io/iostream_chrono.hpp.in @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2024 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include +%% if options.with_printf +#include +%% endif + +namespace modm +{ + +/// @ingroup modm_io +/// @{ + +%% if not is_avr +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::year year) +{ +%% if options.with_printf + return s.printf("%04" PRIi16, int16_t(int(year))); +%% else + return s << int(year); +%% endif +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::month month) +{ + static constexpr std::string_view map = "???JanFebMarAprMayJunJulAugSepOctNovDec"; + return s << map.substr((unsigned(month) <= 12 ? unsigned(month) : 0u) * 3, 3); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::day day) +{ +%% if options.with_printf + return s.printf("%02" PRIu8, uint8_t(unsigned(day))); +%% else + return s << unsigned(day); +%% endif +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::weekday wd) +{ + static constexpr std::string_view map = "SunMonTueWedThuFriSat???"; + return s << map.substr((wd.c_encoding() < 7u ? wd.c_encoding() : 7u) * 3, 3); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::weekday_indexed wdi) +{ + s << wdi.weekday(); + const auto index = wdi.index(); + if (1 <= index and index <= 5) return s << '[' << index << ']'; + return s << "[?]"; +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::weekday_last wdl) +{ + return s << wdl.weekday() << "[last]"; +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::month_day md) +{ + return s << md.month() << '/' << md.day(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::month_day_last mdl) +{ + return s << mdl.month() << "/last"; +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::month_weekday mwd) +{ + return s << mwd.month() << '/' << mwd.weekday_indexed(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::month_weekday_last mwdl) +{ + return s << mwdl.month() << '/' << mwdl.weekday_last(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::year_month ym) +{ + return s << ym.year() << '/' << ym.month(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::year_month_day& ymd) +{ +%% if options.with_printf + return s.printf("%04" PRIi16 "-%02" PRIu8 "-%02" PRIu8, + int16_t(int(ymd.year())), uint8_t(unsigned(ymd.month())), uint8_t(unsigned(ymd.day()))); +%% else + return s << ymd.year() << '-' << unsigned(ymd.month()) << '-' << ymd.day(); +%% endif +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::year_month_day_last& ymdl) +{ + return s << ymdl.year() << '/' << ymdl.month_day_last(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::year_month_weekday& ymwd) +{ + return s << ymwd.year() << '/' << ymwd.month() << '/' << ymwd.weekday_indexed(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::year_month_weekday_last& ymwdl) +{ + return s << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); +} + +template< class Duration > +modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::hh_mm_ss& hms) +{ +%% if options.with_printf + s.printf("%02" PRIu8 ":%02" PRIu8 ":%02" PRIu8 ".%03" PRIu16, + uint8_t(hms.hours().count()), uint8_t(hms.minutes().count()), uint8_t(hms.seconds().count()), + uint16_t(std::chrono::duration_cast(hms.subseconds()).count())); +%% else + s << uint8_t(hms.hours().count()) << ':' << uint8_t(hms.minutes().count()) << ':' << uint8_t(hms.seconds().count()); + s << '.' << uint16_t(std::chrono::duration_cast(hms.subseconds()).count()); +%% endif + return s; +} +%% endif + +template< class Rep, class Period > +inline modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::duration& d) +{ + s << d.count(); + + if constexpr (std::is_same_v) s << "as"; + if constexpr (std::is_same_v) s << "fs"; + if constexpr (std::is_same_v) s << "ps"; + if constexpr (std::is_same_v) s << "ns"; + if constexpr (std::is_same_v) s << "us"; + if constexpr (std::is_same_v) s << "ms"; + if constexpr (std::is_same_v) s << "cs"; + if constexpr (std::is_same_v) s << "ds"; + if constexpr (std::is_same_v>) s << 's'; + if constexpr (std::is_same_v) s << "as"; + if constexpr (std::is_same_v) s << "hs"; + if constexpr (std::is_same_v) s << "ks"; + if constexpr (std::is_same_v) s << "Ms"; + if constexpr (std::is_same_v) s << "Gs"; + if constexpr (std::is_same_v) s << "Ts"; + if constexpr (std::is_same_v) s << "Ps"; + if constexpr (std::is_same_v) s << "Es"; + + if constexpr (std::is_same_v>) s << "min"; + if constexpr (std::is_same_v>) s << 'h'; + if constexpr (std::is_same_v>) s << 'd'; + + return s; +} + +template< class Clock, class Duration > +modm::IOStream& +operator << (modm::IOStream& s, const std::chrono::time_point& tp) +{ + return s << tp.time_since_epoch(); +} + +inline modm::IOStream& +operator << (modm::IOStream& s, const std::tm& tm) +{ +%% if options.with_printf + s.printf("%04" PRIu16 "-%02" PRIu8 "-%02" PRIu8 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8, + uint16_t(tm.tm_year + 1900u), uint8_t(tm.tm_mon), uint8_t(tm.tm_mday), + uint8_t(tm.tm_hour), uint8_t(tm.tm_min), uint8_t(tm.tm_sec)); +%% else + s << (tm.tm_year + 1900u) << '-' << tm.tm_mon << '-' << tm.tm_mday << ' '; + s << tm.tm_hour << ':' << tm.tm_min << ':' << tm.tm_sec; +%% endif + return s; +} + +/// @} + +} + + + diff --git a/src/modm/io/iostream_printf.cpp.in b/src/modm/io/iostream_printf.cpp.in index 8a2312c264..57408972a1 100644 --- a/src/modm/io/iostream_printf.cpp.in +++ b/src/modm/io/iostream_printf.cpp.in @@ -22,7 +22,7 @@ #include #include "iostream.hpp" -%% if using_printf +%% if options.with_printf #include #include @@ -76,7 +76,7 @@ IOStream::vprintf(const char *fmt, va_list ap) void IOStream::writeInteger(int16_t value) { -%% if using_printf +%% if options.with_printf print_integer(&output_gadget, uint16_t(value < 0 ? -value : value), value < 0, 10, 0, 0, FLAGS_SHORT); %% else @@ -90,7 +90,7 @@ IOStream::writeInteger(int16_t value) void IOStream::writeInteger(uint16_t value) { -%% if using_printf +%% if options.with_printf print_integer(&output_gadget, value, false, 10, 0, 0, FLAGS_SHORT); %% else // hard coded for 32'768 @@ -103,7 +103,7 @@ IOStream::writeInteger(uint16_t value) void IOStream::writeInteger(int32_t value) { -%% if using_printf +%% if options.with_printf print_integer(&output_gadget, uint32_t(value < 0 ? -value : value), value < 0, 10, 0, 0, FLAGS_LONG); %% else @@ -117,7 +117,7 @@ IOStream::writeInteger(int32_t value) void IOStream::writeInteger(uint32_t value) { -%% if using_printf +%% if options.with_printf print_integer(&output_gadget, value, false, 10, 0, 0, FLAGS_LONG); %% else // hard coded for 4294967295 @@ -146,7 +146,7 @@ IOStream::writeInteger(uint64_t value) void IOStream::writeDouble(const double& value) { -%% if using_printf +%% if options.with_printf print_floating_point(&output_gadget, value, 0, 0, 0, true); %% else if(!std::isfinite(value)) { diff --git a/src/modm/io/module.lb b/src/modm/io/module.lb index 8aed1e8976..a065c41169 100644 --- a/src/modm/io/module.lb +++ b/src/modm/io/module.lb @@ -41,16 +41,20 @@ def prepare(module, options): def build(env): core = env[":target"].get_driver("core")["type"] + target = env[":target"].identifier env.substitutions = { - "is_hosted": env[":target"].identifier.platform == "hosted", - "family": env[":target"].identifier.family, + "is_hosted": target.platform == "hosted", + "is_avr": target.platform == "avr", + "family": target.family, "core": core, - "using_printf": env.has_module(":printf"), } env.outbasepath = "modm/src/modm/io" - env.copy(".", ignore=env.ignore_files("io.hpp", "iostream_printf.cpp.in", "iostream.hpp.in")) + env.copy("iodevice.hpp") + env.copy("iodevice_wrapper.hpp") env.template("iostream_printf.cpp.in") env.template("iostream.hpp.in") + env.template("iostream_chrono.hpp.in") + env.copy("iostream.cpp") env.outbasepath = "modm/src/modm" env.copy("io.hpp")