From 368ef242ff59b6556e155ba4007630991c328cff Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Jan 2020 18:49:55 +0100 Subject: [PATCH 1/4] CCSDSTime bugfix for atmel Possible good for other cases too? --- timemanager/CCSDSTime.cpp | 43 +++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 32032716..2eb6c4b5 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -154,32 +154,41 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* if (length < 19) { return RETURN_FAILED; } - uint16_t year; - uint8_t month; - uint16_t day; - uint8_t hour; - uint8_t minute; - float second; -//try Code A (yyyy-mm-dd) - int count = sscanf((char *) from, "%4hi-%2hhi-%2hiT%2hhi:%2hhi:%fZ", &year, - &month, &day, &hour, &minute, &second); - if (count == 6) { + // In the size optimized nano library used by ATMEL, floating point conversion + // is not allowed. There is a linker flag to allow it apparently, but I + // could not manage to make it run (removing -specs=nano.specs in linker flags works though, + // but we propably should include this). Using floats with sscanf is also expensive. + // Furthermore, the stdio.c library by ATMEL can't resolve the %hhi specifiers + // Therefore, I adapted this function. + int year; + int month; + int day; + int hour; + int minute; + int second; + int usecond; + // try Code A (yyyy-mm-dd) + //int count = sscanf((char *) from, "%4hi-%2hi-%2hiT%2hi:%2hi:%fZ", &year, + // &month, &day, &hour, &minute, &second); + int count = sscanf((char *) from, "%4d-%2d-%2dT%2d:%2d:%2d.%dZ", &year, + &month, &day, &hour, &minute, &second, &usecond); + if (count == 7) { to->year = year; to->month = month; to->day = day; to->hour = hour; to->minute = minute; to->second = second; - to->usecond = (second - floor(second)) * 1000000; + to->usecond = usecond;//(second - floor(second)) * 1000000; return RETURN_OK; } - //try Code B (yyyy-ddd) - count = sscanf((char *) from, "%4hi-%3hiT%2hhi:%2hhi:%fZ", &year, &day, - &hour, &minute, &second); - if (count == 5) { + // try Code B (yyyy-ddd) + count = sscanf((char *) from, "%4i-%3iT%2i:%2i:%2i.%iZ", &year, &day, + &hour, &minute, &second, &usecond); + if (count == 6) { uint8_t tempDay; - ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, &month, + ReturnValue_t result = CCSDSTime::convertDaysOfYear((uint16_t)day,(uint16_t) year,(uint8_t *) &month, &tempDay); if (result != RETURN_OK) { return RETURN_FAILED; @@ -190,7 +199,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* to->hour = hour; to->minute = minute; to->second = second; - to->usecond = (second - floor(second)) * 1000000; + to->usecond = usecond; return RETURN_OK; } From ea904642d1c8b4085b03fdd2837912ebe242c20c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 21 Apr 2020 16:16:02 +0200 Subject: [PATCH 2/4] CCSDS time possible bugfix for sscanf() --- timemanager/CCSDSTime.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 32032716..8a0e65b7 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -1,5 +1,6 @@ #include #include +#include #include CCSDSTime::CCSDSTime() { @@ -160,9 +161,10 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* uint8_t hour; uint8_t minute; float second; -//try Code A (yyyy-mm-dd) - int count = sscanf((char *) from, "%4hi-%2hhi-%2hiT%2hhi:%2hhi:%fZ", &year, - &month, &day, &hour, &minute, &second); + //try Code A (yyyy-mm-dd) + int count = sscanf((char *) from, "%4" SCNu16 "-%2" SCNu8 "-%2" SCNu16 + "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &month, &day, + &hour, &minute, &second); if (count == 6) { to->year = year; to->month = month; @@ -175,8 +177,8 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* } //try Code B (yyyy-ddd) - count = sscanf((char *) from, "%4hi-%3hiT%2hhi:%2hhi:%fZ", &year, &day, - &hour, &minute, &second); + count = sscanf((char *) from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 + ":%2" SCNu8 ":%fZ", &year, &day, &hour, &minute, &second); if (count == 5) { uint8_t tempDay; ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, &month, @@ -193,7 +195,6 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* to->usecond = (second - floor(second)) * 1000000; return RETURN_OK; } - return UNSUPPORTED_TIME_FORMAT; } From c30cae3431d586304bf0d3fd1c5d1ff05d7f9691 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 21 Apr 2020 16:32:39 +0200 Subject: [PATCH 3/4] added back NoC99 io section --- timemanager/CCSDSTime.cpp | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 8a0e65b7..e00beb27 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -155,6 +155,51 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* if (length < 19) { return RETURN_FAILED; } + // Newlib nano can't parse uint8, see SCNu8 documentation and https://sourceware.org/newlib/README + // Suggestion: use uint16 all the time. This should work on all systems. +#ifdef NEWLIB_NANO_NO_C99_IO + uint16_t year; + uint16_t month; + uint16_t day; + uint16_t hour; + uint16_t minute; + float second; + int count = sscanf((char *) from, "%4" SCNu16 "-%2" SCNu16 "-%2" + SCNu16 "T%2" SCNu16 ":%2" SCNu16 ":%fZ", &year, &month, &day, &hour, + &minute, &second); + if (count == 6) { + to->year = year; + to->month = month; + to->day = day; + to->hour = hour; + to->minute = minute; + to->second = second; + to->usecond = (second - floor(second)) * 1000000; + return RETURN_OK; + } + + // try Code B (yyyy-ddd) + count = sscanf((char *) from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu16 ":%2" + SCNu16 ":%fZ", &year, &day, &hour, &minute, &second); + if (count == 5) { + uint8_t tempDay; + ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, + reinterpret_cast(&month), reinterpret_cast(&tempDay)); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + to->year = year; + to->month = month; + to->day = tempDay; + to->hour = hour; + to->minute = minute; + to->second = second; + to->usecond = (second - floor(second)) * 1000000; + return RETURN_OK; + } + // Warning: Compiler/Linker fails ambiguously if library does not implement + // C99 I/O +#else uint16_t year; uint8_t month; uint16_t day; @@ -195,6 +240,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* to->usecond = (second - floor(second)) * 1000000; return RETURN_OK; } +#endif return UNSUPPORTED_TIME_FORMAT; } From ef2a44c683fe0d236dfa55ad935c09d8f7472f2e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 13 Jul 2020 22:15:38 +0200 Subject: [PATCH 4/4] added back inttypes.h for cleaner code --- timemanager/CCSDSTime.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 47cab911..71b2539d 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -205,9 +205,10 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* uint8_t hour; uint8_t minute; float second; - //try Code A (yyyy-mm-dd) - int count = sscanf((char *) from, "%4hi-%2hhi-%2hiT%2hhi:%2hhi:%fZ", &year, - &month, &day, &hour, &minute, &second); + //try Code A (yyyy-mm-dd) + int count = sscanf((char *) from, "%4" SCNu16 "-%2" SCNu8 "-%2" SCNu16 + "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &month, &day, + &hour, &minute, &second); if (count == 6) { to->year = year; to->month = month; @@ -219,9 +220,9 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* return RETURN_OK; } - //try Code B (yyyy-ddd) - count = sscanf((char *) from, "%4hi-%3hiT%2hhi:%2hhi:%fZ", &year, &day, - &hour, &minute, &second); + //try Code B (yyyy-ddd) + count = sscanf((char *) from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 + ":%2" SCNu8 ":%fZ", &year, &day, &hour, &minute, &second); if (count == 5) { uint8_t tempDay; ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, &month,