Skip to content

Commit cac01a7

Browse files
marcuschangarmhugueskamba
authored andcommitted
Add support for fprintf and vfprintf (ARMmbed#21)
Debug print is routed to stderr which relies on [v]fprintf. This change adds support for overwriting the build-in [v]fprintf.
1 parent e08a316 commit cac01a7

File tree

12 files changed

+226
-76
lines changed

12 files changed

+226
-76
lines changed

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,31 @@ To contribute to this documentation, please see the [mbed-os-5-docs repository](
5151

5252
Library supports both printf and snprintf in 1252 bytes of flash.
5353

54-
Prints directly to stdio/UART without using malloc. All flags and precision modifiers are ignored. Floating point is disabled by default.
54+
Prints directly to stdio/UART without using malloc. All flags and precision modifiers are ignored.
55+
Floating point is disabled by default.
56+
Printing to a FILE stream is enabled by default.
5557

5658
Supports:
5759
* %d: signed integer [h, hh, (none), l, ll, z, j, t].
5860
* %i: signed integer [h, hh, (none), l, ll, z, j, t].
5961
* %u: unsigned integer [h, hh, (none), l, ll, z, j, t].
60-
* %x: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., FF).
62+
* %x: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., ff).
6163
* %X: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., FF).
6264
* %f: floating point (disabled by default).
63-
* %F: floating point (disabled by default).
64-
* %g: floating point (disabled by default).
65-
* %G: floating point (disabled by default).
65+
* %F: floating point (disabled by default, treated as %f).
66+
* %g: floating point (disabled by default, treated as %f).
67+
* %G: floating point (disabled by default, treated as %f).
6668
* %c: character.
6769
* %s: string.
6870
* %p: pointer (e.g. 0x00123456).
6971

72+
Unrecognized format specifiers are treated as ordinary characters.
73+
74+
Floating point support:
75+
* Floating point is disabled by default.
76+
* All floating points are treated as %f.
77+
* No support for inf, infinity or nan
78+
7079
To replace the standard implementations of the printf functions with the ones in this library:
7180

7281
* Add the library to your project.
@@ -77,7 +86,7 @@ To replace the standard implementations of the printf functions with the ones in
7786
$ mbed compile -t <toolchain> -m <target> --profile mbed-printf/profiles/release.json
7887
```
7988

80-
## Enabling floating point, 64 bit integers, new line conversion, and setting baud rate
89+
## Enabling floating point, FILE stream, 64 bit integers, new line conversion, and setting baud rate
8190

8291
In mbed_app.json:
8392

@@ -86,7 +95,8 @@ In mbed_app.json:
8695
"*": {
8796
"platform.stdio-baud-rate": 115200,
8897
"platform.stdio-convert-newlines": false,
89-
"minimal-printf.enable-floating-point": false,
98+
"minimal-printf.enable-file-stream": true,
99+
"minimal-printf.enable-floating-point": true,
90100
"minimal-printf.set-floating-point-max-decimals": 6,
91101
"minimal-printf.enable-64-bit": true
92102
}

TESTS/minimal-printf/compliance/main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,48 +45,63 @@ static control_t test_printf_d(const size_t call_count)
4545
{
4646
int result_baseline;
4747
int result_minimal;
48+
int result_file;
4849

4950
/*************************************************************************/
5051
/*************************************************************************/
5152
result_minimal = mbed_printf("hhd: %hhd\r\n", SCHAR_MIN);
53+
result_file = mbed_fprintf(stderr, "hhd: %hhd\r\n", SCHAR_MIN);
5254
result_baseline = printf("hhd: %hhd\r\n", SCHAR_MIN);
5355
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
56+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
5457

5558
result_minimal = mbed_printf("hhd: %hhd\r\n", SCHAR_MAX);
59+
result_file = mbed_fprintf(stderr, "hhd: %hhd\r\n", SCHAR_MAX);
5660
result_baseline = printf("hhd: %hhd\r\n", SCHAR_MAX);
5761
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
62+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
5863

5964
result_minimal = mbed_printf("hd: %hd\r\n", SHRT_MIN);
6065
result_baseline = printf("hd: %hd\r\n", SHRT_MIN);
6166
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
67+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
6268

6369
result_minimal = mbed_printf("hd: %hd\r\n", SHRT_MAX);
6470
result_baseline = printf("hd: %hd\r\n", SHRT_MAX);
6571
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
72+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
6673

6774
result_minimal = mbed_printf("d: %d\r\n", INT_MIN);
6875
result_baseline = printf("d: %d\r\n", INT_MIN);
6976
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
77+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
7078

7179
result_minimal = mbed_printf("d: %d\r\n", INT_MAX);
7280
result_baseline = printf("d: %d\r\n", INT_MAX);
7381
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
82+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
7483

7584
result_minimal = mbed_printf("ld: %ld\r\n", LONG_MIN);
7685
result_baseline = printf("ld: %ld\r\n", LONG_MIN);
7786
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
87+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
7888

7989
result_minimal = mbed_printf("ld: %ld\r\n", LONG_MAX);
8090
result_baseline = printf("ld: %ld\r\n", LONG_MAX);
8191
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
92+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
8293

8394
result_minimal = mbed_printf("lld: %lld\r\n", LLONG_MIN);
95+
result_file = mbed_fprintf(stderr, "lld: %lld\r\n", LLONG_MIN);
8496
result_baseline = printf("lld: %lld\r\n", LLONG_MIN);
8597
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
98+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
8699

87100
result_minimal = mbed_printf("lld: %lld\r\n", LLONG_MAX);
101+
result_file = mbed_fprintf(stderr, "lld: %lld\r\n", LLONG_MAX);
88102
result_baseline = printf("lld: %lld\r\n", LLONG_MAX);
89103
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
104+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
90105

91106
printf("%%jd not supported by mbed\r\n");
92107

@@ -125,48 +140,62 @@ static control_t test_printf_u(const size_t call_count)
125140
{
126141
int result_baseline;
127142
int result_minimal;
143+
int result_file;
128144

129145
/*************************************************************************/
130146
/*************************************************************************/
131147
result_minimal = mbed_printf("hhu: %hhu\r\n", 0);
148+
result_file = mbed_fprintf(stderr, "hhu: %hhu\r\n", 0);
132149
result_baseline = printf("hhu: %hhu\r\n", 0);
133150
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
151+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
134152

135153
result_minimal = mbed_printf("hhu: %hhu\r\n", UCHAR_MAX);
154+
result_file = mbed_fprintf(stderr, "hhu: %hhu\r\n", UCHAR_MAX);
136155
result_baseline = printf("hhu: %hhu\r\n", UCHAR_MAX);
137156
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
157+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
138158

139159
result_minimal = mbed_printf("hu: %hu\r\n", 0);
140160
result_baseline = printf("hu: %hu\r\n", 0);
141161
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
162+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
142163

143164
result_minimal = mbed_printf("hu: %hu\r\n", USHRT_MAX);
144165
result_baseline = printf("hu: %hu\r\n", USHRT_MAX);
145166
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
167+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
146168

147169
result_minimal = mbed_printf("u: %u\r\n", 0);
148170
result_baseline = printf("u: %u\r\n", 0);
149171
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
172+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
150173

151174
result_minimal = mbed_printf("u: %u\r\n", UINT_MAX);
152175
result_baseline = printf("u: %u\r\n", UINT_MAX);
153176
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
177+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
154178

155179
result_minimal = mbed_printf("lu: %lu\r\n", 0);
156180
result_baseline = printf("lu: %lu\r\n", 0UL);
157181
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
182+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
158183

159184
result_minimal = mbed_printf("lu: %lu\r\n", ULONG_MAX);
160185
result_baseline = printf("lu: %lu\r\n", ULONG_MAX);
161186
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
187+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
162188

163189
result_minimal = mbed_printf("llu: %llu\r\n", 0);
164190
result_baseline = printf("llu: %llu\r\n", 0ULL);
165191
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
192+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
166193

167194
result_minimal = mbed_printf("llu: %llu\r\n", ULLONG_MAX);
195+
result_file = mbed_fprintf(stderr, "llu: %llu\r\n", ULLONG_MAX);
168196
result_baseline = printf("llu: %llu\r\n", ULLONG_MAX);
169197
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
198+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
170199

171200
result_minimal = mbed_printf("ju: %ju\r\n", 0);
172201
result_baseline = printf("ju: %ju\r\n",(uintmax_t) 0);
@@ -199,6 +228,7 @@ static control_t test_printf_x(const size_t call_count)
199228
{
200229
int result_baseline;
201230
int result_minimal;
231+
int result_file;
202232

203233
/*************************************************************************/
204234
/*************************************************************************/
@@ -211,6 +241,7 @@ static control_t test_printf_x(const size_t call_count)
211241
result_minimal = mbed_printf("hhx: %hhx\r\n", UCHAR_MAX);
212242
result_baseline = printf("hhx: %hhx\r\n", UCHAR_MAX);
213243
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
244+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
214245

215246
result_minimal = mbed_printf("hx: %hx\r\n", 0);
216247
result_baseline = printf("hx: %hx\r\n", 0);
@@ -219,6 +250,7 @@ static control_t test_printf_x(const size_t call_count)
219250
result_minimal = mbed_printf("hx: %hx\r\n", USHRT_MAX);
220251
result_baseline = printf("hx: %hx\r\n", USHRT_MAX);
221252
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
253+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
222254

223255
result_minimal = mbed_printf("x: %x\r\n", 0);
224256
result_baseline = printf("x: %x\r\n", 0);
@@ -227,6 +259,7 @@ static control_t test_printf_x(const size_t call_count)
227259
result_minimal = mbed_printf("x: %x\r\n", UINT_MAX);
228260
result_baseline = printf("x: %x\r\n", UINT_MAX);
229261
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
262+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
230263

231264
result_minimal = mbed_printf("x: %x\r\n", 0);
232265
result_baseline = printf("x: %x\r\n", 0);
@@ -235,6 +268,7 @@ static control_t test_printf_x(const size_t call_count)
235268
result_minimal = mbed_printf("lx: %lx\r\n", ULONG_MAX);
236269
result_baseline = printf("lx: %lx\r\n", ULONG_MAX);
237270
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
271+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
238272

239273
result_minimal = mbed_printf("llx: %llx\r\n", 0);
240274
result_baseline = printf("llx: %llx\r\n", 0ULL);
@@ -243,6 +277,7 @@ static control_t test_printf_x(const size_t call_count)
243277
result_minimal = mbed_printf("llx: %llx\r\n", ULLONG_MAX);
244278
result_baseline = printf("llx: %llx\r\n", ULLONG_MAX);
245279
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
280+
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
246281

247282
result_minimal = mbed_printf("jx: %jx\r\n", 0);
248283
result_baseline = printf("jx: %jx\r\n", (uintmax_t) 0);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"target_overrides": {
3+
"*": {
4+
"minimal-printf.enable-file-stream": 1
5+
}
6+
}
7+
}

mbed_printf.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ int mbed_printf(const char *format, ...)
416416
{
417417
va_list arguments;
418418
va_start(arguments, format);
419-
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments);
419+
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
420420
va_end(arguments);
421421

422422
return result;
@@ -426,18 +426,35 @@ int mbed_snprintf(char* buffer, size_t length, const char* format, ...)
426426
{
427427
va_list arguments;
428428
va_start(arguments, format);
429-
int result = mbed_minimal_formatted_string(buffer, length, format, arguments);
429+
int result = mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
430430
va_end(arguments);
431431

432432
return result;
433433
}
434434

435435
int mbed_vprintf(const char* format, va_list arguments)
436436
{
437-
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments);
437+
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
438438
}
439439

440440
int mbed_vsnprintf(char* buffer, size_t length, const char* format, va_list arguments)
441441
{
442-
return mbed_minimal_formatted_string(buffer, length, format, arguments);
442+
return mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
443443
}
444+
445+
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
446+
int mbed_fprintf(FILE* stream, const char *format, ...)
447+
{
448+
va_list arguments;
449+
va_start(arguments, format);
450+
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, stream);
451+
va_end(arguments);
452+
453+
return result;
454+
}
455+
456+
int mbed_vfprintf(FILE* stream, const char* format, va_list arguments)
457+
{
458+
return mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, stream);
459+
}
460+
#endif

mbed_printf.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ int mbed_printf(const char *format, ...);
5151
*/
5252
int mbed_snprintf(char* buffer, size_t length, const char* format, ...);
5353

54+
#if MBED_CONF_MINIMAL_PRINTF_ENABLE_FILE_STREAM
55+
/**
56+
* Minimal fprintf
57+
*
58+
* Prints directly to file stream without using malloc.
59+
*/
60+
int mbed_fprintf(FILE* stream, const char *format, ...);
61+
62+
/**
63+
* Minimal vfprintf
64+
*
65+
* Prints directly to file stream without using malloc.
66+
*/
67+
int mbed_vfprintf(FILE* stream, const char* format, va_list arguments);
68+
#endif
69+
5470
#ifdef __cplusplus
5571
}
5672
#endif

mbed_printf_armlink_overrides.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int $Sub$$__2printf(const char *format, ...)
3838
{
3939
va_list arguments;
4040
va_start(arguments, format);
41-
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments);
41+
int result = mbed_minimal_formatted_string(NULL, LONG_MAX, format, arguments, NULL);
4242
va_end(arguments);
4343

4444
return result;
@@ -48,7 +48,7 @@ int $Sub$$__2sprintf(char* buffer, const char* format, ...)
4848
{
4949
va_list arguments;
5050
va_start(arguments, format);
51-
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments);
51+
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments, NULL);
5252
va_end(arguments);
5353

5454
return result;
@@ -58,7 +58,7 @@ int $Sub$$__2snprintf(char* buffer, size_t length, const char* format, ...)
5858
{
5959
va_list arguments;
6060
va_start(arguments, format);
61-
int result = mbed_minimal_formatted_string(buffer, length, format, arguments);
61+
int result = mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
6262
va_end(arguments);
6363

6464
return result;
@@ -68,15 +68,15 @@ int $Sub$$__2vprintf(char* buffer, const char* format, ...)
6868
{
6969
va_list arguments;
7070
va_start(arguments, format);
71-
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments);
71+
int result = mbed_minimal_formatted_string(buffer, LONG_MAX, format, arguments, NULL);
7272
va_end(arguments);
7373

7474
return result;
7575
}
7676

7777
int $Sub$$__2vsnprintf(char* buffer, size_t length, const char* format, va_list arguments)
7878
{
79-
return mbed_minimal_formatted_string(buffer, length, format, arguments);
79+
return mbed_minimal_formatted_string(buffer, length, format, arguments, NULL);
8080
}
8181

8282
/**

0 commit comments

Comments
 (0)