From a32142a332202494cb361734d54d6dfccaee51b0 Mon Sep 17 00:00:00 2001 From: u48 <6582469+u48@users.noreply.github.com> Date: Wed, 9 Jan 2019 11:07:22 +0000 Subject: [PATCH 1/6] fix Print.printf() The printf() method always uses self instance of the class Print, without additional implementation of the output to UARTs, TFTs, and etc. --- STM32F1/cores/maple/Print.cpp | 38 ++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/STM32F1/cores/maple/Print.cpp b/STM32F1/cores/maple/Print.cpp index a8aa07d69..2e9e76838 100644 --- a/STM32F1/cores/maple/Print.cpp +++ b/STM32F1/cores/maple/Print.cpp @@ -208,20 +208,48 @@ size_t Print::println(const Printable& x) return n; } + #ifdef SUPPORTS_PRINTF #include #include + // Work in progress to support printf. // Need to implement stream FILE to write individual chars to chosen serial port +// *** implement stream for uarts, lcd, more tft - nicht! +// *** We will use the standard path - fopencookie(), that work on all plathorm with GLIBC. +// *** (On AVR platfotm has an equivalent solution) + + + // Write block to device. + // Non class function for use from libc.printf, + // pointer to class Print passed in argumwent dev. + static ssize_t cookie_write_helper(void *dev, const char* buff, size_t len) + { + Print* pPrint = (Print*)(dev); //pointer to class Print + size_t write_len = 0; + for (uint8_t *ptr = (uint8_t*) buff; len-- > 0; write_len++, ptr++ ) { + if ( *ptr == '\n') pPrint->print((char)'\r'); + pPrint->print( (char)*ptr ); + } + return write_len; + } + int Print::printf (__const char *__restrict __format, ...) { -FILE *__restrict __stream; - int ret_status = 0; - - + FILE *__restrict __stream; + + __stream = fopencookie( (void*) this, "rw+", (cookie_io_functions_t) { + (cookie_read_function_t* ) NULL, + (cookie_write_function_t*) cookie_write_helper, + (cookie_seek_function_t* ) NULL, + (cookie_close_function_t*) NULL + } ); + setvbuf(__stream, NULL, _IONBF, 0); //turn off buffer + //(Note: Buffer from stdlib need only for multithread code, + // and not alternative for uart buffers and fifo.) va_list args; va_start(args,__format); - ret_status = vfprintf(__stream, __format, args); + int ret_status = vfprintf(__stream, __format, args); va_end(args); return ret_status; } From 1bbc5c47e159cf64abe2468e916f00a95c8e0a25 Mon Sep 17 00:00:00 2001 From: u48 <6582469+u48@users.noreply.github.com> Date: Fri, 25 Jan 2019 23:35:19 +0300 Subject: [PATCH 2/6] Update Print.h enable printf by default --- STM32F1/cores/maple/Print.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/STM32F1/cores/maple/Print.h b/STM32F1/cores/maple/Print.h index f265facc2..1ee2ae326 100644 --- a/STM32F1/cores/maple/Print.h +++ b/STM32F1/cores/maple/Print.h @@ -67,10 +67,9 @@ class Print { size_t println(double, int=2); size_t println(const __FlashStringHelper *); size_t println(const Printable&); -#ifdef SUPPORTS_PRINTF -// Roger Clark. Work in progress to add printf support - int printf(const char * format, ...); -#endif + + size_t printf(const char * format, ...); + Print() : write_error(0) {} int getWriteError() { return write_error; } From c4933ace0d5dd0e167d18b1805b32b7bac1052ad Mon Sep 17 00:00:00 2001 From: u48 <6582469+u48@users.noreply.github.com> Date: Fri, 25 Jan 2019 23:58:11 +0300 Subject: [PATCH 3/6] Update Print.cpp Fix bug with use fopencookie() for implemet Print.printf(). I checked it, and Print.printf() now works. --- STM32F1/cores/maple/Print.cpp | 84 ++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/STM32F1/cores/maple/Print.cpp b/STM32F1/cores/maple/Print.cpp index 2e9e76838..16a1aeb3f 100644 --- a/STM32F1/cores/maple/Print.cpp +++ b/STM32F1/cores/maple/Print.cpp @@ -209,51 +209,71 @@ size_t Print::println(const Printable& x) } -#ifdef SUPPORTS_PRINTF +//#ifdef SUPPORTS_PRINTF +//Note: ifdef not need - not used printf is not linked + +// method uses the GLIBS extension fopencookie (), which works on the platforms STM32, SAMD, ESP8266, Linux .. +// And work with any devices: Serial, TFT, Flash &etc. +//( For avr-libc, a similar functional is implemented through specific properties of type FILE, without any functions.) + #include #include -// Work in progress to support printf. -// Need to implement stream FILE to write individual chars to chosen serial port -// *** implement stream for uarts, lcd, more tft - nicht! -// *** We will use the standard path - fopencookie(), that work on all plathorm with GLIBC. -// *** (On AVR platfotm has an equivalent solution) +/* +//Bug detected +//failed: fopencookie( 0, "w+", { NULL, WR_fn, NULL, NULL }) - failed on gcc stm32. +//failed: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) - failed on gcc stm32. +// +//worked: fopencookie( 0, "rw+", { RD_fn, WR_fn, NULL, NULL }) - failed on gcc stm32. +//worked: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) - failed on gcc stm32. +// +//Resume: To fix - you should always specify the cookies_read function, zero is not valid. +*/ - // Write block to device. + // Read/Write blocks to device. // Non class function for use from libc.printf, // pointer to class Print passed in argumwent dev. - static ssize_t cookie_write_helper(void *dev, const char* buff, size_t len) + static ssize_t cookie_read_helper(void *dev __attribute__((unused)) , const char* buff __attribute__((unused)) , size_t len __attribute__((unused)) ) { - Print* pPrint = (Print*)(dev); //pointer to class Print - size_t write_len = 0; - for (uint8_t *ptr = (uint8_t*) buff; len-- > 0; write_len++, ptr++ ) { - if ( *ptr == '\n') pPrint->print((char)'\r'); - pPrint->print( (char)*ptr ); - } - return write_len; - } - -int Print::printf (__const char *__restrict __format, ...) - { - FILE *__restrict __stream; + return 0; + } + + static ssize_t cookie_write_helper(void *dev, const char* buff, size_t size) + { + Print* pPrint=(Print*)dev; + ssize_t len=0; + for(char* c = (char*)buff; size-- >0; len++) pPrint->print(*c++); + return len; - __stream = fopencookie( (void*) this, "rw+", (cookie_io_functions_t) { - (cookie_read_function_t* ) NULL, + } + + +size_t Print::printf(const char *format, ...) +{ + FILE* stream = fopencookie( (void*) this, "rw+", (cookie_io_functions_t) { + (cookie_read_function_t* ) cookie_read_helper, (cookie_write_function_t*) cookie_write_helper, (cookie_seek_function_t* ) NULL, (cookie_close_function_t*) NULL } ); - setvbuf(__stream, NULL, _IONBF, 0); //turn off buffer - //(Note: Buffer from stdlib need only for multithread code, - // and not alternative for uart buffers and fifo.) - va_list args; - va_start(args,__format); - int ret_status = vfprintf(__stream, __format, args); - va_end(args); - return ret_status; - } - #endif + if(!stream){ print("\nERROR:opencookie - failed\n"); return 0; } // for dbg only + + setvbuf(stream, NULL, _IONBF, 0); //turn off buffer + //(Note: Buffer from stdlib need only for multithread code, + // and not alternative for uart buffers and fifo.) + + va_list args; + va_start(args,format); + int ret_status = vfprintf(stream, format, args); + va_end(args); + fclose(stream); + + + return ret_status>0 ? (size_t)ret_status : 0; +} +// #endif + /* * Private methods From 402854b07e81119ceb58a6363eb78c8f84f4a707 Mon Sep 17 00:00:00 2001 From: u48 <6582469+u48@users.noreply.github.com> Date: Sat, 26 Jan 2019 00:04:11 +0300 Subject: [PATCH 4/6] Update Print.cpp cleanup source --- STM32F1/cores/maple/Print.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/STM32F1/cores/maple/Print.cpp b/STM32F1/cores/maple/Print.cpp index 16a1aeb3f..f220a81e4 100644 --- a/STM32F1/cores/maple/Print.cpp +++ b/STM32F1/cores/maple/Print.cpp @@ -221,32 +221,32 @@ size_t Print::println(const Printable& x) /* //Bug detected -//failed: fopencookie( 0, "w+", { NULL, WR_fn, NULL, NULL }) - failed on gcc stm32. -//failed: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) - failed on gcc stm32. +//failed: fopencookie( 0, "w+", { NULL, WR_fn, NULL, NULL }) +//failed: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) // -//worked: fopencookie( 0, "rw+", { RD_fn, WR_fn, NULL, NULL }) - failed on gcc stm32. -//worked: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) - failed on gcc stm32. +//worked: fopencookie( 0, "rw+", { RD_fn, WR_fn, NULL, NULL }) +//worked: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) // //Resume: To fix - you should always specify the cookies_read function, zero is not valid. */ - // Read/Write blocks to device. - // Non class function for use from libc.printf, - // pointer to class Print passed in argumwent dev. - static ssize_t cookie_read_helper(void *dev __attribute__((unused)) , const char* buff __attribute__((unused)) , size_t len __attribute__((unused)) ) - { +// Read/Write blocks to device. +// Non class function for use from libc.printf, +// pointer to class Print passed in argumwent dev. +static ssize_t cookie_read_helper(void *dev __attribute__((unused)) , const char* buff __attribute__((unused)) , + size_t len __attribute__((unused)) ) +{ return 0; - } +} - static ssize_t cookie_write_helper(void *dev, const char* buff, size_t size) - { +static ssize_t cookie_write_helper(void *dev, const char* buff, size_t size) +{ Print* pPrint=(Print*)dev; ssize_t len=0; for(char* c = (char*)buff; size-- >0; len++) pPrint->print(*c++); return len; - - } +} size_t Print::printf(const char *format, ...) @@ -268,7 +268,6 @@ size_t Print::printf(const char *format, ...) int ret_status = vfprintf(stream, format, args); va_end(args); fclose(stream); - return ret_status>0 ? (size_t)ret_status : 0; } From 041b8683a5487e8da4fe5dcba4247f6cd064a96b Mon Sep 17 00:00:00 2001 From: u48 <6582469+u48@users.noreply.github.com> Date: Tue, 29 Jan 2019 09:48:50 +0300 Subject: [PATCH 5/6] Update Print.cpp add #define _GNU_SOURCE So more correct for use fopencookie() --- STM32F1/cores/maple/Print.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/STM32F1/cores/maple/Print.cpp b/STM32F1/cores/maple/Print.cpp index f220a81e4..116c57548 100644 --- a/STM32F1/cores/maple/Print.cpp +++ b/STM32F1/cores/maple/Print.cpp @@ -216,6 +216,7 @@ size_t Print::println(const Printable& x) // And work with any devices: Serial, TFT, Flash &etc. //( For avr-libc, a similar functional is implemented through specific properties of type FILE, without any functions.) +#define _GNU_SOURCE #include #include From c0416702798299caf1538fcf6fbc53e656d49bcf Mon Sep 17 00:00:00 2001 From: u48 <6582469+u48@users.noreply.github.com> Date: Thu, 28 Feb 2019 13:23:32 +0300 Subject: [PATCH 6/6] Update Print.cpp delete contradictory information --- STM32F1/cores/maple/Print.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/STM32F1/cores/maple/Print.cpp b/STM32F1/cores/maple/Print.cpp index 116c57548..5d45d6393 100644 --- a/STM32F1/cores/maple/Print.cpp +++ b/STM32F1/cores/maple/Print.cpp @@ -220,18 +220,6 @@ size_t Print::println(const Printable& x) #include #include -/* -//Bug detected -//failed: fopencookie( 0, "w+", { NULL, WR_fn, NULL, NULL }) -//failed: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) -// -//worked: fopencookie( 0, "rw+", { RD_fn, WR_fn, NULL, NULL }) -//worked: fopencookie( 0, "rw+", { NULL, WR_fn, NULL, NULL }) -// -//Resume: To fix - you should always specify the cookies_read function, zero is not valid. -*/ - - // Read/Write blocks to device. // Non class function for use from libc.printf, // pointer to class Print passed in argumwent dev. @@ -253,8 +241,9 @@ static ssize_t cookie_write_helper(void *dev, const char* buff, size_t size) size_t Print::printf(const char *format, ...) { FILE* stream = fopencookie( (void*) this, "rw+", (cookie_io_functions_t) { - (cookie_read_function_t* ) cookie_read_helper, - (cookie_write_function_t*) cookie_write_helper, + (cookie_read_function_t* ) cookie_read_helper, // Even if reading is not required, you must pass a + // pointer to the dummy function, but not NULL + (cookie_write_function_t*) cookie_write_helper, (cookie_seek_function_t* ) NULL, (cookie_close_function_t*) NULL } );