nanohub: remove -fshort-double
-fshort-double has been removed from recent gcc versions
and is not supported by clang.
Removed flag
Define a new CHRE_LOG entry point to handle sizeof(double) == 8
and leave the old to handle old chre apps that were compiled with
sizeof(double) == 4.
Add builtins to handle float -> double conversion (using gcc's
caused crashes)
Removed -lgcc from apps (we shouldn't be pulling in any functions from
libgcc.a) and added -nostdlib flag
Bug: 28938849
Test: nanoapps build/chreLog %f works same as before
Change-Id: I72a91dcfdfc2b0eba3211ac719381fcb0a0ae7ed
Signed-off-by: Ben Fennema <[email protected]>
diff --git a/firmware/app/app.mk b/firmware/app/app.mk
index 08c1a33..5272b29 100644
--- a/firmware/app/app.mk
+++ b/firmware/app/app.mk
@@ -158,7 +158,6 @@
# Miscellaneous
CFLAGS += -fno-strict-aliasing
-CFLAGS += -fshort-double
CFLAGS += -fvisibility=hidden
CFLAGS += -fno-unwind-tables
CFLAGS += -fstack-reuse=all
@@ -171,10 +170,10 @@
LDFLAGS := -T $(NANOHUB_DIR)/os/platform/$(PLATFORM)/lkr/app.lkr
LDFLAGS += -nostartfiles
+LDFLAGS += -nostdlib
LDFLAGS += -Wl,--gc-sections
LDFLAGS += -Wl,-Map,$(OUT)/$(BIN).map
LDFLAGS += -Wl,--cref
-STATIC_LIBS += -lgcc
ifeq ($(BIN_MODE),static)
LDFLAGS += -Bstatic
LDFLAGS += -Wl,--emit-relocs
diff --git a/firmware/build/common_config.mk b/firmware/build/common_config.mk
index 581709e..990db3c 100644
--- a/firmware/build/common_config.mk
+++ b/firmware/build/common_config.mk
@@ -40,6 +40,7 @@
LOCAL_LDFLAGS += \
-nostartfiles \
+ -nostdlib \
-Wl,--gc-sections \
-Wl,--no-undefined \
-Wl,--no-allow-shlib-undefined \
@@ -52,7 +53,6 @@
-mfpu=fpv4-sp-d16 \
-mno-thumb-interwork \
-ffast-math \
- -fshort-double \
-fsingle-precision-constant \
-DARM \
-DUSE_NANOHUB_FLOAT_RUNTIME \
diff --git a/firmware/firmware.mk b/firmware/firmware.mk
index ffd06d8..eeda9b1 100644
--- a/firmware/firmware.mk
+++ b/firmware/firmware.mk
@@ -58,7 +58,7 @@
FLAGS += -I../lib/include
FLAGS += -I../inc
-FLAGS += -Wall -Werror -fshort-double
+FLAGS += -Wall -Werror
#help avoid commmon embedded C mistakes
FLAGS += -Wmissing-declarations -Wlogical-op -Waddress -Wempty-body -Wpointer-arith -Wenum-compare -Wdouble-promotion -Wfloat-equal -Wshadow -fno-strict-aliasing
diff --git a/firmware/lib/builtins/Android.mk b/firmware/lib/builtins/Android.mk
index c6a1e53..aa8663c 100644
--- a/firmware/lib/builtins/Android.mk
+++ b/firmware/lib/builtins/Android.mk
@@ -29,6 +29,8 @@
moddi3.c \
udivmoddi4.c \
umoddi3.c \
+ aeabi_f2d.c \
+ aeabi_llsl.c \
LOCAL_C_INCLUDES = $(LOCAL_PATH)
LOCAL_EXPORT_C_INCLUDE_DIRS := \
diff --git a/firmware/lib/builtins/aeabi_f2d.c b/firmware/lib/builtins/aeabi_f2d.c
new file mode 100644
index 0000000..b4984d9
--- /dev/null
+++ b/firmware/lib/builtins/aeabi_f2d.c
@@ -0,0 +1,19 @@
+//===-- lib/extendsfdf2.c - single -> double conversion -----------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+#define SRC_SINGLE
+#define DST_DOUBLE
+#include "fp_extend_impl.inc"
+
+double __aeabi_f2d(float a);
+
+double __aeabi_f2d(float a) {
+ return __extendXfYf2__(a);
+}
diff --git a/firmware/lib/builtins/aeabi_llsl.c b/firmware/lib/builtins/aeabi_llsl.c
new file mode 100644
index 0000000..529c0ae
--- /dev/null
+++ b/firmware/lib/builtins/aeabi_llsl.c
@@ -0,0 +1,43 @@
+/* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ashldi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a << b */
+
+/* Precondition: 0 <= b < bits_in_dword */
+
+di_int __aeabi_llsl(di_int a, si_int b);
+
+di_int
+__aeabi_llsl(di_int a, si_int b)
+{
+ const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */
+ {
+ result.s.low = 0;
+ result.s.high = input.s.low << (b - bits_in_word);
+ }
+ else /* 0 <= b < bits_in_word */
+ {
+ if (b == 0)
+ return a;
+ result.s.low = input.s.low << b;
+ result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b));
+ }
+ return result.all;
+}
diff --git a/firmware/lib/builtins/fp_extend.h b/firmware/lib/builtins/fp_extend.h
new file mode 100644
index 0000000..bff285a
--- /dev/null
+++ b/firmware/lib/builtins/fp_extend.h
@@ -0,0 +1,89 @@
+//===-lib/fp_extend.h - low precision -> high precision conversion -*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Set source and destination setting
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FP_EXTEND_HEADER
+#define FP_EXTEND_HEADER
+
+#include "int_lib.h"
+
+#if defined SRC_SINGLE
+typedef float src_t;
+typedef su_int src_rep_t;
+#define SRC_REP_C(c) c ## UL
+static const int srcSigBits = 23;
+#define src_rep_t_clz __builtin_clz
+
+#elif defined SRC_DOUBLE
+typedef double src_t;
+typedef du_int src_rep_t;
+#define SRC_REP_C(c) c ## ULL
+static const int srcSigBits = 52;
+static __inline int src_rep_t_clz(src_rep_t a) {
+#if defined __LP64__
+ return __builtin_clzl(a);
+#else
+ if (a & REP_C(0xffffffff00000000))
+ return __builtin_clz(a >> 32);
+ else
+ return 32 + __builtin_clz(a & REP_C(0xffffffff));
+#endif
+}
+
+#elif defined SRC_HALF
+typedef uint16_t src_t;
+typedef uint16_t src_rep_t;
+#define SRC_REP_C UINT16_C
+static const int srcSigBits = 10;
+#define src_rep_t_clz __builtin_clz
+
+#else
+#error Source should be half, single, or double precision!
+#endif //end source precision
+
+#if defined DST_SINGLE
+typedef float dst_t;
+typedef su_int dst_rep_t;
+#define DST_REP_C(c) c ## UL
+static const int dstSigBits = 23;
+
+#elif defined DST_DOUBLE
+typedef double dst_t;
+typedef du_int dst_rep_t;
+#define DST_REP_C(c) c ## ULL
+static const int dstSigBits = 52;
+
+#elif defined DST_QUAD
+typedef long double dst_t;
+typedef __uint128_t dst_rep_t;
+#define DST_REP_C (__uint128_t)
+static const int dstSigBits = 112;
+
+#else
+#error Destination should be single, double, or quad precision!
+#endif //end destination precision
+
+// End of specialization parameters. Two helper routines for conversion to and
+// from the representation of floating-point data as integer values follow.
+
+static __inline src_rep_t srcToRep(src_t x) {
+ const union { src_t f; src_rep_t i; } rep = {.f = x};
+ return rep.i;
+}
+
+static __inline dst_t dstFromRep(dst_rep_t x) {
+ const union { dst_t f; dst_rep_t i; } rep = {.i = x};
+ return rep.f;
+}
+// End helper routines. Conversion implementation follows.
+
+#endif //FP_EXTEND_HEADER
diff --git a/firmware/lib/builtins/fp_extend_impl.inc b/firmware/lib/builtins/fp_extend_impl.inc
new file mode 100644
index 0000000..b785cc7
--- /dev/null
+++ b/firmware/lib/builtins/fp_extend_impl.inc
@@ -0,0 +1,108 @@
+//=-lib/fp_extend_impl.inc - low precision -> high precision conversion -*-- -//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a fairly generic conversion from a narrower to a wider
+// IEEE-754 floating-point type. The constants and types defined following the
+// includes below parameterize the conversion.
+//
+// It does not support types that don't use the usual IEEE-754 interchange
+// formats; specifically, some work would be needed to adapt it to
+// (for example) the Intel 80-bit format or PowerPC double-double format.
+//
+// Note please, however, that this implementation is only intended to support
+// *widening* operations; if you need to convert to a *narrower* floating-point
+// type (e.g. double -> float), then this routine will not do what you want it
+// to.
+//
+// It also requires that integer types at least as large as both formats
+// are available on the target platform; this may pose a problem when trying
+// to add support for quad on some 32-bit systems, for example. You also may
+// run into trouble finding an appropriate CLZ function for wide source types;
+// you will likely need to roll your own on some platforms.
+//
+// Finally, the following assumptions are made:
+//
+// 1. floating-point types and integer types have the same endianness on the
+// target platform
+//
+// 2. quiet NaNs, if supported, are indicated by the leading bit of the
+// significand field being set
+//
+//===----------------------------------------------------------------------===//
+
+#include "fp_extend.h"
+
+static __inline dst_t __extendXfYf2__(src_t a) {
+ // Various constants whose values follow from the type parameters.
+ // Any reasonable optimizer will fold and propagate all of these.
+ const int srcBits = sizeof(src_t)*CHAR_BIT;
+ const int srcExpBits = srcBits - srcSigBits - 1;
+ const int srcInfExp = (1 << srcExpBits) - 1;
+ const int srcExpBias = srcInfExp >> 1;
+
+ const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits;
+ const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits;
+ const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits);
+ const src_rep_t srcAbsMask = srcSignMask - 1;
+ const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1);
+ const src_rep_t srcNaNCode = srcQNaN - 1;
+
+ const int dstBits = sizeof(dst_t)*CHAR_BIT;
+ const int dstExpBits = dstBits - dstSigBits - 1;
+ const int dstInfExp = (1 << dstExpBits) - 1;
+ const int dstExpBias = dstInfExp >> 1;
+
+ const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits;
+
+ // Break a into a sign and representation of the absolute value
+ const src_rep_t aRep = srcToRep(a);
+ const src_rep_t aAbs = aRep & srcAbsMask;
+ const src_rep_t sign = aRep & srcSignMask;
+ dst_rep_t absResult;
+
+ // If sizeof(src_rep_t) < sizeof(int), the subtraction result is promoted
+ // to (signed) int. To avoid that, explicitly cast to src_rep_t.
+ if ((src_rep_t)(aAbs - srcMinNormal) < srcInfinity - srcMinNormal) {
+ // a is a normal number.
+ // Extend to the destination type by shifting the significand and
+ // exponent into the proper position and rebiasing the exponent.
+ absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits);
+ absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits;
+ }
+
+ else if (aAbs >= srcInfinity) {
+ // a is NaN or infinity.
+ // Conjure the result by beginning with infinity, then setting the qNaN
+ // bit (if needed) and right-aligning the rest of the trailing NaN
+ // payload field.
+ absResult = (dst_rep_t)dstInfExp << dstSigBits;
+ absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits);
+ absResult |= (dst_rep_t)(aAbs & srcNaNCode) << (dstSigBits - srcSigBits);
+ }
+
+ else if (aAbs) {
+ // a is denormal.
+ // renormalize the significand and clear the leading bit, then insert
+ // the correct adjusted exponent in the destination type.
+ const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal);
+ absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale);
+ absResult ^= dstMinNormal;
+ const int resultExponent = dstExpBias - srcExpBias - scale + 1;
+ absResult |= (dst_rep_t)resultExponent << dstSigBits;
+ }
+
+ else {
+ // a is zero.
+ absResult = 0;
+ }
+
+ // Apply the signbit to (dst_t)abs(a).
+ const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits);
+ return dstFromRep(result);
+}
diff --git a/firmware/lib/builtins/int_lib.h b/firmware/lib/builtins/int_lib.h
index 2840710..3d968a8 100644
--- a/firmware/lib/builtins/int_lib.h
+++ b/firmware/lib/builtins/int_lib.h
@@ -19,11 +19,23 @@
#define CHAR_BIT 8
typedef unsigned su_int;
+typedef int si_int;
+
typedef unsigned long long du_int;
typedef long long di_int;
typedef union
{
+ di_int all;
+ struct
+ {
+ su_int low;
+ si_int high;
+ } s;
+} dwords;
+
+typedef union
+{
du_int all;
struct
{
diff --git a/firmware/lib/lib.mk b/firmware/lib/lib.mk
index e964f16..41d84ee 100644
--- a/firmware/lib/lib.mk
+++ b/firmware/lib/lib.mk
@@ -75,11 +75,13 @@
BUILTINS_PATH := $(NANOHUB_DIR)/lib/builtins
-#SRCS += $(BUILTINS_PATH)/aeabi_ldivmod.S
-#SRCS += $(BUILTINS_PATH)/aeabi_uldivmod.S
+SRCS += $(BUILTINS_PATH)/aeabi_ldivmod.S
+SRCS += $(BUILTINS_PATH)/aeabi_uldivmod.S
SRCS += $(BUILTINS_PATH)/divdi3.c
SRCS += $(BUILTINS_PATH)/divmoddi4.c
SRCS += $(BUILTINS_PATH)/moddi3.c
SRCS += $(BUILTINS_PATH)/udivmoddi4.c
SRCS += $(BUILTINS_PATH)/umoddi3.c
+SRCS += $(BUILTINS_PATH)/aeabi_f2d.c
+SRCS += $(BUILTINS_PATH)/aeabi_llsl.c
CFLAGS += -I$(BUILTINS_PATH)
diff --git a/firmware/os/core/nanohub_chre.c b/firmware/os/core/nanohub_chre.c
index 2e156f2..6dd32d6 100644
--- a/firmware/os/core/nanohub_chre.c
+++ b/firmware/os/core/nanohub_chre.c
@@ -30,6 +30,7 @@
#include <syscall.h>
#include <timer.h>
#include <util.h>
+#include <printf.h>
#include <chre.h>
#include <chreApi.h>
@@ -74,12 +75,26 @@
va_list innerArgs;
enum chreLogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */);
const static char levels[] = "EWIDV";
- char clevel = level > CHRE_LOG_DEBUG || level < 0 ? 'V' : levels[level];
+ char clevel = (level > CHRE_LOG_DEBUG || level < 0) ? 'V' : levels[level];
const char *str = va_arg(args, const char*);
uintptr_t inner = va_arg(args, uintptr_t);
va_copy(innerArgs, INTEGER_TO_VA_LIST(inner));
- osLogv(clevel, str, innerArgs);
+ osLogv(clevel, PRINTF_FLAG_CHRE, str, innerArgs);
+ va_end(innerArgs);
+}
+
+static void osChreApiLogLogvOld(uintptr_t *retValP, va_list args)
+{
+ va_list innerArgs;
+ enum chreLogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */);
+ const static char levels[] = "EWIDV";
+ char clevel = (level > CHRE_LOG_DEBUG || level < 0) ? 'V' : levels[level];
+ const char *str = va_arg(args, const char*);
+ uintptr_t inner = va_arg(args, uintptr_t);
+
+ va_copy(innerArgs, INTEGER_TO_VA_LIST(inner));
+ osLogv(clevel, PRINTF_FLAG_CHRE | PRINTF_FLAG_SHORT_DOUBLE, str, innerArgs);
va_end(innerArgs);
}
@@ -409,6 +424,7 @@
static const struct SyscallTable chreMainApiTable = {
.numEntries = SYSCALL_CHRE_MAIN_API_LAST,
.entry = {
+ [SYSCALL_CHRE_MAIN_API_LOG_OLD] = { .func = osChreApiLogLogvOld },
[SYSCALL_CHRE_MAIN_API_LOG] = { .func = osChreApiLogLogv },
[SYSCALL_CHRE_MAIN_API_GET_APP_ID] = { .func = osChreApiGetAppId },
[SYSCALL_CHRE_MAIN_API_GET_INST_ID] = { .func = osChreApiGetInstanceId },
diff --git a/firmware/os/core/osApi.c b/firmware/os/core/osApi.c
index c0206b6..1716f09 100644
--- a/firmware/os/core/osApi.c
+++ b/firmware/os/core/osApi.c
@@ -89,7 +89,7 @@
const char *str = va_arg(args, const char*);
va_list innerArgs;
va_copy(innerArgs, INTEGER_TO_VA_LIST(va_arg(args, uintptr_t)));
- osLogv((char)level, str, innerArgs);
+ osLogv((char)level, 0, str, innerArgs);
va_end(innerArgs);
}
diff --git a/firmware/os/core/printf.c b/firmware/os/core/printf.c
index 2192653..53e91d4 100644
--- a/firmware/os/core/printf.c
+++ b/firmware/os/core/printf.c
@@ -185,7 +185,7 @@
return *(*fmtP)++;
}
-uint32_t cvprintf(printf_write_c putc_f, void* userData, const char* fmtStr, va_list vl)
+uint32_t cvprintf(printf_write_c putc_f, uint32_t flags, void* userData, const char* fmtStr, va_list vl)
{
char c, t;
@@ -404,21 +404,37 @@
#undef GET_UVAL64
#undef GET_SVAL64
- case 'f':
- case 'g':
+ case 'F':
- if (useLongDouble) {
- ldbl = va_arg(vl, long double);
- data.number = *(uint64_t *)(&ldbl);
+ data.flags |= FLAG_CAPS;
+
+ case 'f':
+
+ if (flags & PRINTF_FLAG_CHRE) {
+ if (flags & PRINTF_FLAG_SHORT_DOUBLE) {
+ if (useLongDouble) {
+ dbl = va_arg(vl, double);
+ data.number = *(uint64_t *)(&dbl);
+ } else {
+ // just grab the 32-bits
+ data.number = va_arg(vl, uint32_t);
+ }
+ } else {
+ if (useLongDouble) {
+ ldbl = va_arg(vl, long double);
+ data.number = *(uint64_t *)(&ldbl);
+ } else {
+ dbl = va_arg(vl, double);
+ data.number = *(uint64_t *)(&dbl);
+ }
+ }
+ data.base = 16;
+ data.flags |= FLAG_ALT;
+ data.posChar = '\0';
+ numPrinted += StrPrvPrintfEx_number(putc_f, &data, &bail);
} else {
- dbl = va_arg(vl, double);
- data.number = *(uint32_t *)(&dbl);
+ bail = true;
}
- data.base = 16;
- data.flags &= ~FLAG_CAPS;
- data.flags |= FLAG_ALT;
- data.posChar = '\0';
- numPrinted += StrPrvPrintfEx_number(putc_f, &data, &bail);
if (bail)
goto out;
break;
diff --git a/firmware/os/core/seos.c b/firmware/os/core/seos.c
index 55a680c..f220dc3 100644
--- a/firmware/os/core/seos.c
+++ b/firmware/os/core/seos.c
@@ -1360,12 +1360,12 @@
return false;
}
-void osLogv(char clevel, const char *str, va_list vl)
+void osLogv(char clevel, uint32_t flags, const char *str, va_list vl)
{
void *userData = platLogAllocUserData();
platLogPutcharF(userData, clevel);
- cvprintf(platLogPutcharF, userData, str, vl);
+ cvprintf(platLogPutcharF, flags, userData, str, vl);
platLogFlush(userData);
}
@@ -1375,7 +1375,7 @@
va_list vl;
va_start(vl, str);
- osLogv((char)level, str, vl);
+ osLogv((char)level, 0, str, vl);
va_end(vl);
}
diff --git a/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c b/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c
index d58a99c..9e10ec4 100644
--- a/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c
+++ b/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c
@@ -4096,7 +4096,7 @@
uint32_t ret;
va_start(vl, fmtStr);
- ret = cvprintf(writeF, writeD, fmtStr, vl);
+ ret = cvprintf(writeF, 0, writeD, fmtStr, vl);
va_end(vl);
return ret;
diff --git a/firmware/os/inc/chreApi.h b/firmware/os/inc/chreApi.h
index ef43429..f494236 100644
--- a/firmware/os/inc/chreApi.h
+++ b/firmware/os/inc/chreApi.h
@@ -40,7 +40,7 @@
#define SYSCALL_CHRE_MAIN_API_GET_APP_ID 0 // (void) -> uint64_t
#define SYSCALL_CHRE_MAIN_API_GET_INST_ID 1 // (void) -> uint32_t
-#define SYSCALL_CHRE_MAIN_API_LOG 2 // (enum LogLevel, const char *, uintptr_t) -> void
+#define SYSCALL_CHRE_MAIN_API_LOG_OLD 2 // (enum LogLevel, const char *, uintptr_t) -> void
#define SYSCALL_CHRE_MAIN_API_GET_TIME 3 // (void) -> uint64_t
#define SYSCALL_CHRE_MAIN_API_TIMER_SET 4 // (uint64_t, const void *, bool) -> uint32_t
#define SYSCALL_CHRE_MAIN_API_TIMER_CANCEL 5 // (uint32_t) -> bool
@@ -56,7 +56,8 @@
#define SYSCALL_CHRE_MAIN_API_GET_OS_API_VERSION 15 //
#define SYSCALL_CHRE_MAIN_API_GET_OS_VERSION 16 //
#define SYSCALL_CHRE_MAIN_API_GET_PLATFORM_ID 17 //
-#define SYSCALL_CHRE_MAIN_API_LAST 18 // always last. holes are allowed, but not immediately before this
+#define SYSCALL_CHRE_MAIN_API_LOG 18 // (enum LogLevel, const char *, uintptr_t) -> void
+#define SYSCALL_CHRE_MAIN_API_LAST 19 // always last. holes are allowed, but not immediately before this
//called by os entry point to export the api
void osChreApiExport(void);
diff --git a/firmware/os/inc/printf.h b/firmware/os/inc/printf.h
index f3c26cd..9d44166 100644
--- a/firmware/os/inc/printf.h
+++ b/firmware/os/inc/printf.h
@@ -25,9 +25,12 @@
#include <stdint.h>
#include <stdarg.h>
-typedef bool (*printf_write_c)(void* userData, char c); //callback can return false anytime to abort printing immediately
+#define PRINTF_FLAG_CHRE 0x00000001
+#define PRINTF_FLAG_SHORT_DOUBLE 0x00000002
-uint32_t cvprintf(printf_write_c writeF, void* writeD, const char* fmtStr, va_list vl);
+typedef bool (*printf_write_c)(void* userData, char c); //callback can return false anytime to abort printing immediately
+
+uint32_t cvprintf(printf_write_c writeF, uint32_t flags, void* writeD, const char* fmtStr, va_list vl);
#ifdef __cplusplus
}
diff --git a/firmware/os/inc/seos.h b/firmware/os/inc/seos.h
index 5a8c866..f10108a 100644
--- a/firmware/os/inc/seos.h
+++ b/firmware/os/inc/seos.h
@@ -276,7 +276,7 @@
LOG_DEBUG = 'D',
};
-void osLogv(char clevel, const char *str, va_list vl);
+void osLogv(char clevel, uint32_t flags, const char *str, va_list vl);
void osLog(enum LogLevel level, const char *str, ...) PRINTF_ATTRIBUTE(2, 3);
#ifndef INTERNAL_APP_INIT
diff --git a/firmware/os/platform/stm32/stm32.mk b/firmware/os/platform/stm32/stm32.mk
index 103ca3d..60c55a9 100644
--- a/firmware/os/platform/stm32/stm32.mk
+++ b/firmware/os/platform/stm32/stm32.mk
@@ -26,7 +26,7 @@
DELIVERABLES += showsizes
FLAGS += -I. -fno-unwind-tables -fstack-reuse=all -ffunction-sections -fdata-sections
FLAGS += -Wl,--gc-sections -nostartfiles
-FLAGS_os += -nostdlib
+FLAGS += -nostdlib
#platform bootloader
SRCS_bl += os/platform/$(PLATFORM)/bl.c