diff --git a/Makefile.am b/Makefile.am index d4a70702..407d0f4c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -186,6 +186,23 @@ libmetal_pico_a_SOURCES = \ endif # WITH_BUILTIN_LIBMETAL_PICO + +######################################################## +# libsegger +######################################################## + +# Provide segger hook with Freedom Metal that is built when +# --with-builtin-libmetal-segger is passed to configure +if WITH_BUILTIN_LIBMETAL_SEGGER + +lib_LIBRARIES += libmetal-segger.a + +libmetal_segger_a_SOURCES = \ + gloss/crt0.S \ + segger/SEGGER_target_metal.c + +endif # WITH_BUILTIN_LIBMETAL_SEGGER + ######################################################## # libgloss ######################################################## diff --git a/Makefile.in b/Makefile.in index d700a4f1..6d5d3349 100644 --- a/Makefile.in +++ b/Makefile.in @@ -104,13 +104,21 @@ host_triplet = @host@ # Build support for picolibc if --with-builtin-libmetal-pico is passed to configure @WITH_BUILTIN_LIBMETAL_PICO_TRUE@am__append_1 = libmetal-pico.a +######################################################## +# libsegger +######################################################## + +# Provide segger hook with Freedom Metal that is built when +# --with-builtin-libmetal-segger is passed to configure +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@am__append_2 = libmetal-segger.a + ######################################################## # libgloss ######################################################## # Freedom Metal has its own libgloss implementation that is only built when # --with-builtin-libgloss is passed to configure. -@WITH_BUILTIN_LIBGLOSS_TRUE@am__append_2 = libmetal-gloss.a +@WITH_BUILTIN_LIBGLOSS_TRUE@am__append_3 = libmetal-gloss.a subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -226,6 +234,14 @@ am__libmetal_pico_a_SOURCES_DIST = pico/iob.c gloss/crt0.S \ @WITH_BUILTIN_LIBMETAL_PICO_TRUE@ gloss/sys_clock_gettime.$(OBJEXT) \ @WITH_BUILTIN_LIBMETAL_PICO_TRUE@ gloss/sys_write.$(OBJEXT) libmetal_pico_a_OBJECTS = $(am_libmetal_pico_a_OBJECTS) +libmetal_segger_a_AR = $(AR) $(ARFLAGS) +libmetal_segger_a_LIBADD = +am__libmetal_segger_a_SOURCES_DIST = gloss/crt0.S \ + segger/SEGGER_target_metal.c +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@am_libmetal_segger_a_OBJECTS = \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ gloss/crt0.$(OBJEXT) \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ segger/SEGGER_target_metal.$(OBJEXT) +libmetal_segger_a_OBJECTS = $(am_libmetal_segger_a_OBJECTS) libmetal_a_AR = $(AR) $(ARFLAGS) libmetal_a_LIBADD = am_libmetal_a_OBJECTS = src/drivers/fixed-clock.$(OBJEXT) \ @@ -306,9 +322,10 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libmetal_gloss_a_SOURCES) $(libmetal_pico_a_SOURCES) \ - $(libmetal_a_SOURCES) + $(libmetal_segger_a_SOURCES) $(libmetal_a_SOURCES) DIST_SOURCES = $(am__libmetal_gloss_a_SOURCES_DIST) \ - $(am__libmetal_pico_a_SOURCES_DIST) $(libmetal_a_SOURCES) + $(am__libmetal_pico_a_SOURCES_DIST) \ + $(am__libmetal_segger_a_SOURCES_DIST) $(libmetal_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -503,7 +520,8 @@ BUILT_SOURCES = \ ######################################################## # libmetal ######################################################## -lib_LIBRARIES = libmetal.a $(am__append_1) $(am__append_2) +lib_LIBRARIES = libmetal.a $(am__append_1) $(am__append_2) \ + $(am__append_3) libmetal_a_SOURCES = \ src/drivers/fixed-clock.c \ src/drivers/fixed-factor-clock.c \ @@ -579,6 +597,10 @@ libmetal_a_SOURCES = \ @WITH_BUILTIN_LIBMETAL_PICO_TRUE@ gloss/sys_clock_gettime.c \ @WITH_BUILTIN_LIBMETAL_PICO_TRUE@ gloss/sys_write.c +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@libmetal_segger_a_SOURCES = \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ gloss/crt0.S \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ segger/SEGGER_target_metal.c + @WITH_BUILTIN_LIBGLOSS_TRUE@libmetal_gloss_a_SOURCES = \ @WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/crt0.S \ @WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/nanosleep.c \ @@ -776,6 +798,19 @@ libmetal-pico.a: $(libmetal_pico_a_OBJECTS) $(libmetal_pico_a_DEPENDENCIES) $(EX $(AM_V_at)-rm -f libmetal-pico.a $(AM_V_AR)$(libmetal_pico_a_AR) libmetal-pico.a $(libmetal_pico_a_OBJECTS) $(libmetal_pico_a_LIBADD) $(AM_V_at)$(RANLIB) libmetal-pico.a +segger/$(am__dirstamp): + @$(MKDIR_P) segger + @: > segger/$(am__dirstamp) +segger/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) segger/$(DEPDIR) + @: > segger/$(DEPDIR)/$(am__dirstamp) +segger/SEGGER_target_metal.$(OBJEXT): segger/$(am__dirstamp) \ + segger/$(DEPDIR)/$(am__dirstamp) + +libmetal-segger.a: $(libmetal_segger_a_OBJECTS) $(libmetal_segger_a_DEPENDENCIES) $(EXTRA_libmetal_segger_a_DEPENDENCIES) + $(AM_V_at)-rm -f libmetal-segger.a + $(AM_V_AR)$(libmetal_segger_a_AR) libmetal-segger.a $(libmetal_segger_a_OBJECTS) $(libmetal_segger_a_LIBADD) + $(AM_V_at)$(RANLIB) libmetal-segger.a src/drivers/$(am__dirstamp): @$(MKDIR_P) src/drivers @: > src/drivers/$(am__dirstamp) @@ -910,6 +945,7 @@ mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gloss/*.$(OBJEXT) -rm -f pico/*.$(OBJEXT) + -rm -f segger/*.$(OBJEXT) -rm -f src/*.$(OBJEXT) -rm -f src/drivers/*.$(OBJEXT) @@ -951,6 +987,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_wait.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@pico/$(DEPDIR)/iob.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@segger/$(DEPDIR)/SEGGER_target_metal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/atomic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/button.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cache.Po@am__quote@ @@ -1330,6 +1367,8 @@ distclean-generic: -rm -f gloss/$(am__dirstamp) -rm -f pico/$(DEPDIR)/$(am__dirstamp) -rm -f pico/$(am__dirstamp) + -rm -f segger/$(DEPDIR)/$(am__dirstamp) + -rm -f segger/$(am__dirstamp) -rm -f src/$(DEPDIR)/$(am__dirstamp) -rm -f src/$(am__dirstamp) -rm -f src/drivers/$(DEPDIR)/$(am__dirstamp) @@ -1345,7 +1384,7 @@ clean-am: clean-generic clean-libLIBRARIES clean-local mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf gloss/$(DEPDIR) pico/$(DEPDIR) src/$(DEPDIR) src/drivers/$(DEPDIR) + -rm -rf gloss/$(DEPDIR) pico/$(DEPDIR) segger/$(DEPDIR) src/$(DEPDIR) src/drivers/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1393,7 +1432,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf gloss/$(DEPDIR) pico/$(DEPDIR) src/$(DEPDIR) src/drivers/$(DEPDIR) + -rm -rf gloss/$(DEPDIR) pico/$(DEPDIR) segger/$(DEPDIR) src/$(DEPDIR) src/drivers/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/configure b/configure index a6cda968..9bf71592 100755 --- a/configure +++ b/configure @@ -591,6 +591,8 @@ LIBOBJS PLATFORM_HEADER MACHINE_INLINE MACHINE_HEADER +WITH_BUILTIN_LIBMETAL_SEGGER_FALSE +WITH_BUILTIN_LIBMETAL_SEGGER_TRUE WITH_BUILTIN_LIBMETAL_PICO_FALSE WITH_BUILTIN_LIBMETAL_PICO_TRUE WITH_BUILTIN_LIBGLOSS_FALSE @@ -705,6 +707,7 @@ enable_maintainer_mode enable_dependency_tracking with_builtin_libgloss with_builtin_libmetal_pico +with_builtin_libmetal_segger with_machine_header with_machine_inline with_platform_header @@ -1364,6 +1367,8 @@ Optional Packages: --with-bultin-libgloss Build libgloss along with Metal --with-bultin-libmetal-pico Build libmetal-pico along with Metal + --with-bultin-libmetal-segger + Build libmetal-segger along with Metal --with-machine-header=PATH Path to the machine header file --with-machine-inline=PATH @@ -4053,6 +4058,16 @@ fi +# Check whether --with-builtin-libmetal-segger was given. +if test "${with_builtin_libmetal_segger+set}" = set; then : + withval=$with_builtin_libmetal_segger; with_builtin_libmetal_segger="yes" +else + with_builtin_libmetal_segger="no" + +fi + + + # Check whether --with-machine-header was given. if test "${with_machine_header+set}" = set; then : withval=$with_machine_header; @@ -4104,6 +4119,15 @@ else fi + if test "x$with_builtin_libmetal_segger" = "xyes"; then + WITH_BUILTIN_LIBMETAL_SEGGER_TRUE= + WITH_BUILTIN_LIBMETAL_SEGGER_FALSE='#' +else + WITH_BUILTIN_LIBMETAL_SEGGER_TRUE='#' + WITH_BUILTIN_LIBMETAL_SEGGER_FALSE= +fi + + # Configure the build system to pass in the preconfigured machine support files if test "x$with_machine_header" != "xno"; then : MACHINE_HEADER="$with_machine_header" @@ -4326,6 +4350,10 @@ if test -z "${WITH_BUILTIN_LIBMETAL_PICO_TRUE}" && test -z "${WITH_BUILTIN_LIBME as_fn_error $? "conditional \"WITH_BUILTIN_LIBMETAL_PICO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${WITH_BUILTIN_LIBMETAL_SEGGER_TRUE}" && test -z "${WITH_BUILTIN_LIBMETAL_SEGGER_FALSE}"; then + as_fn_error $? "conditional \"WITH_BUILTIN_LIBMETAL_SEGGER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/configure.ac b/configure.ac index 772c1e65..3feebede 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,12 @@ AC_ARG_WITH([builtin-libmetal-pico], [with_builtin_libmetal_pico="no"] ) +AC_ARG_WITH([builtin-libmetal-segger], + [AS_HELP_STRING([--with-bultin-libmetal-segger], [Build libmetal-segger along with Metal])], + [with_builtin_libmetal_segger="yes"], + [with_builtin_libmetal_segger="no"] +) + AC_ARG_WITH([machine-header], [AS_HELP_STRING([--with-machine-header=PATH], [Path to the machine header file])], [], @@ -68,6 +74,8 @@ AM_CONDITIONAL([WITH_BUILTIN_LIBGLOSS], [test "x$with_builtin_libgloss" = "xyes" AM_CONDITIONAL([WITH_BUILTIN_LIBMETAL_PICO], [test "x$with_builtin_libmetal_pico" = "xyes"]) +AM_CONDITIONAL([WITH_BUILTIN_LIBMETAL_SEGGER], [test "x$with_builtin_libmetal_segger" = "xyes"]) + # Configure the build system to pass in the preconfigured machine support files AS_IF([test "x$with_machine_header" != "xno"], [AC_SUBST([MACHINE_HEADER], "$with_machine_header")], diff --git a/metal/time.h b/metal/time.h index cf36d026..a5a880f0 100644 --- a/metal/time.h +++ b/metal/time.h @@ -5,8 +5,9 @@ #define METAL__TIME_H #include - +#ifndef __SEGGER_LIBC__ #include +#endif /*! * @file time.h diff --git a/segger/SEGGER_SEMIHOST.h b/segger/SEGGER_SEMIHOST.h new file mode 100644 index 00000000..fdbb95fc --- /dev/null +++ b/segger/SEGGER_SEMIHOST.h @@ -0,0 +1,178 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 2019 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* condition is met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this condition and the following disclaimer. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** + +-------------------------- END-OF-HEADER ----------------------------- + +File : SEGGER_SEMIHOST.h +Purpose : Semihosting implementation header file. +*/ +#include "stdarg.h" + +#ifndef SEGGER_SEMIHOST_H // Avoid multiple inclusion. +#define SEGGER_SEMIHOST_H + +#if defined(__cplusplus) +extern "C" { // Make sure we have C-declarations in C++ programs. +#endif + +/********************************************************************* + * + * Types, global + * + ********************************************************************** + */ +typedef union { + void *pV; + const void *cpV; + char *pC; + const char *cpC; + int I; +} SEGGER_SEMIHOST_PARA; + +/********************************************************************* + * + * Defines, fixed + * + ********************************************************************** + */ +// +// File handles for standard streams +// +#define SEGGER_SEMIHOST_STDIN 0 +#define SEGGER_SEMIHOST_STDOUT 1 +#define SEGGER_SEMIHOST_ERROUT 2 +// +// File modes for SYS_OPEN +// +#define SYS_FILE_MODE_READ 0 // Open the file for reading "r" +#define SYS_FILE_MODE_READBINARY 1 // Open the file for reading "rb" +#define SYS_FILE_MODE_READWRITE 2 // Open the file for reading and writing "r+" +#define SYS_FILE_MODE_READWRITEBINARY \ + 3 // Open the file for reading and writing "r+" +#define SYS_FILE_MODE_WRITE \ + 4 // Open and truncate or create the file for writing "w" +#define SYS_FILE_MODE_WRITEBINARY \ + 5 // Open and truncate or create the file for writing "wb" +#define SYS_FILE_MODE_WRITEREAD \ + 6 // Open and truncate or create the file for writing and reading "w+" +#define SYS_FILE_MODE_WRITEREADBINARY \ + 7 // Open and truncate or create the file for writing and reading "w+b" +#define SYS_FILE_MODE_APPEND 8 // Open or create the file for writing "a" +#define SYS_FILE_MODE_APPENDBINARY 9 // Open or create the file for writing "ab" +#define SYS_FILE_MODE_APPENDREAD \ + 10 // Open or create the file for writing and reading "a+" +#define SYS_FILE_MODE_APPENDREADBINARY \ + 11 // Open or create the file for writing and reading "a+b" + +// +// Semihosting operations, +// compatible to operations defined by ARM +// +#define SYS_OPEN 0x01 +#define SYS_CLOSE 0x02 +#define SYS_WRITEC 0x03 +#define SYS_WRITE0 0x04 +#define SYS_WRITE 0x05 +#define SYS_READ 0x06 +#define SYS_READC 0x07 +#define SYS_ISERROR 0x08 +#define SYS_ISTTY 0x09 +#define SYS_SEEK 0x0A + +#define SYS_FLEN 0x0C +#define SYS_TMPNAME 0x0D +#define SYS_REMOVE 0x0E +#define SYS_RENAME 0x0F +#define SYS_CLOCK 0x10 +#define SYS_TIME 0x11 +#define SYS_SYSTEM 0x12 +#define SYS_ERRNO 0x13 + +#define SYS_GET_CMDLINE 0x15 +#define SYS_HEAPINFO 0x16 + +#define SYS_EXIT 0x18 // ARM's operation name: angel_SWIreason_ReportException + +#define SYS_ELAPSED 0x30 +#define SYS_TICKFREQ 0x31 +// +// SEGGER Extensions +// +#define SYS_IS_CONNECTED 0x00 +#define SYS_WRITEF 0x40 + +/********************************************************************* + * + * API functions / Function prototypes + * + ********************************************************************** + */ +int SEGGER_SEMIHOST_Open(const char *sFilename, int Mode, int LenFilename); +int SEGGER_SEMIHOST_Close(int hFile); +int SEGGER_SEMIHOST_WriteC(char c); +int SEGGER_SEMIHOST_Write0(const char *s); +int SEGGER_SEMIHOST_Write(int hFile, const char *pBuffer, int NumBytesToWrite); +int SEGGER_SEMIHOST_Writef(const char *pFormat, va_list *pArg); +int SEGGER_SEMIHOST_Read(int hFile, char *pBuffer, int NumBytesToRead); +int SEGGER_SEMIHOST_ReadC(void); +int SEGGER_SEMIHOST_IsTTY(int hFile); +int SEGGER_SEMIHOST_Seek(int hFile, int Pos); +int SEGGER_SEMIHOST_FLen(int hFile); +int SEGGER_SEMIHOST_TmpName(char *pBuffer, int hFile, int pNumBytesName); +int SEGGER_SEMIHOST_Remove(const char *pPath, int NumBytesPath); +int SEGGER_SEMIHOST_Rename(const char *pFileName, int NumBytesFileName, + const char *pNewName, int NumBytesNewName); +int SEGGER_SEMIHOST_Clock(void); +int SEGGER_SEMIHOST_Time(void); +int SEGGER_SEMIHOST_System(const char *pCommand, int NumBytesCommand); +int SEGGER_SEMIHOST_Errno(void); +int SEGGER_SEMIHOST_GetCmdLine(char *pBuffer, char **psCmdLine, + int *pNumBytesCmdLine); +int SEGGER_SEMIHOST_Elapsed(unsigned long long *pTicks); +int SEGGER_SEMIHOST_HeapInfo(char *pDataBlock); +int SEGGER_SEMIHOST_TickFreq(void); +int SEGGER_SEMIHOST_Exit(int ExitCode); +int SEGGER_SEMIHOST_IsConnected(void); + +int SEGGER_SEMIHOST_X_Request(int Op, SEGGER_SEMIHOST_PARA *pPara); + +#if defined(__cplusplus) +} // Make sure we have C-declarations in C++ programs. +#endif + +#endif // Avoid multiple inclusion. + +/*************************** End of file ****************************/ diff --git a/segger/SEGGER_target_metal.c b/segger/SEGGER_target_metal.c new file mode 100644 index 00000000..7c1e2abd --- /dev/null +++ b/segger/SEGGER_target_metal.c @@ -0,0 +1,120 @@ +#include "SEGGER_SEMIHOST.h" +#include "__libc.h" +#include "stdio.h" +#include "time.h" +#include +#include +#include +#include + +/* metal heap start address is provided in target linker script */ +extern char metal_segment_heap_target_start; +extern char __heap_size; + +char __user_locale_name_buffer[16] __attribute__((weak)); +unsigned long __SEGGER_HeapSize = (unsigned long)&__heap_size; + +static inline int metal_writeC(char *pChar) { + int r; + + r = metal_tty_putc((int)*pChar); + return r; +} + +static inline clock_t metal_clock(void) { + int rv; + clock_t res; + static struct timeval t0; + /* we use this init var due to some RTL issue that t0 is always 0 */ + static int timeval_init = 0; + struct timeval t; + unsigned long long timebase; + + if (timeval_init == 0) { + metal_gettimeofday(&t0, 0); + timeval_init = 1; + } + + metal_gettimeofday(&t, 0); + + rv = metal_timer_get_timebase_frequency(0, &timebase); + if (rv != 0) { + return -1; + } + + long long utime = + (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec); + res = (clock_t)utime * timebase / 1000000; + return res; +} + +/********************************************************************* + * + * SEGGER_SEMIHOST_X_Request() + * + * Function description + * Notify the debugger host about the semihosting request + * + * Parameters + * Op: Operation. + * pPara: Pointer to parameter block. + * + * Return value + * Operation-specific return value, set by the debugger in R0. + */ +int SEGGER_SEMIHOST_X_Request(int Op, SEGGER_SEMIHOST_PARA *pPara) { + int r0; + + switch (Op) { + case SYS_WRITEC: + r0 = metal_writeC((char *)pPara); + break; + case SYS_READC: + r0 = 0; + break; + case SYS_CLOCK: + r0 = metal_clock(); + break; + case SYS_EXIT: + r0 = pPara[0].I; + metal_shutdown(r0); + break; + default: + r0 = -1; + } + return r0; +} + +int __SEGGER_RTL_X_get_time_of_day(struct timeval *tp) { + metal_gettimeofday(tp, 0); + return 0; +} + +int __SEGGER_RTL_X_set_time_of_day(const struct timeval *tp) { return 0; } + +int __SEGGER_RTL_stdin_getc(void) { + int r; + + r = SEGGER_SEMIHOST_ReadC(); + return r < 0 ? EOF : r; +} + +int __SEGGER_RTL_stdout_putc(int c) { + int r; + + r = SEGGER_SEMIHOST_WriteC((char)c); + return r < 0 ? EOF : r; +} + +clock_t clock(void) { return SEGGER_SEMIHOST_Clock(); } + +void _execute_at_exit_fns(void); + +void exit(int status) { + _execute_at_exit_fns(); // defined in libc_segger.a + SEGGER_SEMIHOST_Exit(status); + while (1) + ; +} + +/*************************** End of file ****************************/ diff --git a/src/time.c b/src/time.c index 303ca5f8..a40a3ced 100644 --- a/src/time.c +++ b/src/time.c @@ -4,6 +4,8 @@ #include #include +#include + int metal_gettimeofday(struct timeval *tp, void *tzp) { int rv; unsigned long long mcc, timebase; diff --git a/src/timer.c b/src/timer.c index 32d9e891..8e5859aa 100644 --- a/src/timer.c +++ b/src/timer.c @@ -4,8 +4,10 @@ #include #include #include +#ifndef __SEGGER_LIBC__ #include #include +#endif #if defined(__METAL_DT_MAX_HARTS) /* This implementation serves as a small shim that interfaces with the first