Skip to content

Commit 2cf56b8

Browse files
authored
Merge pull request #11891 from hugueskamba/hk-enable-minimal-printf-in-tools
minimal-printf: Enable using a target configuration parameter
2 parents 34c9cf9 + d5aef28 commit 2cf56b8

File tree

7 files changed

+140
-11
lines changed

7 files changed

+140
-11
lines changed

platform/source/minimal-printf/README.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ Floating point limitations:
2626
* All floating points are treated as %f.
2727
* No support for inf, infinity or nan
2828

29+
## Usage
30+
31+
32+
To replace the standard implementation of the printf functions with the ones in this library:
33+
34+
Modify your application configuration file to override the parameter `target.printf` with the value `minimal-printf` as shown below:
35+
36+
```json
37+
"target_overrides": {
38+
"*": {
39+
"target.printf": "minimal-printf",
40+
}
41+
}
42+
```
43+
44+
2945
## Configuration
3046

3147

@@ -60,24 +76,14 @@ In mbed_app.json:
6076
```json
6177
"target_overrides": {
6278
"*": {
79+
"target.printf": "minimal-printf",
6380
"platform.minimal-printf-enable-floating-point": false,
6481
"platform.minimal-printf-set-floating-point-max-decimals": 6,
6582
"platform.minimal-printf-enable-64-bit": false
6683
}
6784
}
6885
```
6986

70-
## Usage
71-
72-
73-
To replace the standard implementation of the printf functions with the ones in this library:
74-
75-
Compile with mbed-cli using the custom `minimal-printf` profile. For example, to compile in release mode:
76-
77-
```
78-
$ mbed compile -t <toolchain> -m <target> --profile release --profile mbed-os/tools/profiles/extensions/minimal-printf.json
79-
```
80-
8187
## Size comparison
8288

8389

targets/targets.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"default_lib": "std",
1616
"bootloader_supported": false,
1717
"static_memory_defines": true,
18+
"printf_lib": "std",
1819
"config": {
1920
"console-uart": {
2021
"help": "Target has UART console on pins STDIO_UART_TX, STDIO_UART_RX. Value is only significant if target has SERIAL device.",
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python
2+
# Copyright (c) 2019 Arm Limited and Contributors. All rights reserved.
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
"""Test the arm toolchain."""
7+
8+
import os
9+
import sys
10+
from unittest import TestCase
11+
12+
import mock
13+
14+
15+
ROOT = os.path.abspath(
16+
os.path.join(os.path.dirname(__file__), "..", "..", "..")
17+
)
18+
sys.path.insert(0, ROOT)
19+
20+
from tools.toolchains.arm import ARM_STD, ARM_MICRO, ARMC6
21+
from tools.toolchains.gcc import GCC_ARM
22+
from tools.toolchains.iar import IAR
23+
24+
25+
class TestArmToolchain(TestCase):
26+
"""Test Arm classes."""
27+
28+
def test_arm_minimal_printf(self):
29+
"""Test that linker flags are correctly added to an instance of ARM."""
30+
mock_target = mock.MagicMock()
31+
mock_target.core = "Cortex-M4"
32+
mock_target.printf_lib = "minimal-printf"
33+
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
34+
35+
arm_std_obj = ARM_STD(mock_target)
36+
arm_micro_obj = ARM_MICRO(mock_target)
37+
arm_c6_obj = ARMC6(mock_target)
38+
39+
self.assertIn("-DMBED_MINIMAL_PRINTF", arm_std_obj.flags["common"])
40+
self.assertIn("-DMBED_MINIMAL_PRINTF", arm_micro_obj.flags["common"])
41+
self.assertIn("-DMBED_MINIMAL_PRINTF", arm_c6_obj.flags["common"])
42+
43+
44+
class TestGccToolchain(TestCase):
45+
"""Test the GCC class."""
46+
47+
def test_gcc_minimal_printf(self):
48+
"""Test that linker flags are correctly added to an instance of GCC_ARM."""
49+
mock_target = mock.MagicMock()
50+
mock_target.core = "Cortex-M4"
51+
mock_target.printf_lib = "minimal-printf"
52+
mock_target.supported_toolchains = ["GCC_ARM"]
53+
mock_target.is_TrustZone_secure_target = False
54+
55+
gcc_obj = GCC_ARM(mock_target)
56+
57+
self.assertIn("-DMBED_MINIMAL_PRINTF", gcc_obj.flags["common"])
58+
59+
minimal_printf_wraps = [
60+
"-Wl,--wrap,printf",
61+
"-Wl,--wrap,sprintf",
62+
"-Wl,--wrap,snprintf",
63+
"-Wl,--wrap,vprintf",
64+
"-Wl,--wrap,vsprintf",
65+
"-Wl,--wrap,vsnprintf",
66+
"-Wl,--wrap,fprintf",
67+
"-Wl,--wrap,vfprintf",
68+
]
69+
70+
for i in minimal_printf_wraps:
71+
self.assertIn(i, gcc_obj.flags["ld"])
72+
73+
74+
class TestIarToolchain(TestCase):
75+
"""Test the IAR class."""
76+
77+
def test_iar_minimal_printf(self):
78+
"""Test that linker flags are correctly added to an instance of GCC_ARM."""
79+
mock_target = mock.MagicMock()
80+
mock_target.core = "Cortex-M4"
81+
mock_target.printf_lib = "minimal-printf"
82+
mock_target.supported_toolchains = ["IAR"]
83+
mock_target.is_TrustZone_secure_target = False
84+
85+
iar_obj = IAR(mock_target)
86+
var = "-DMBED_MINIMAL_PRINTF"
87+
self.assertIn("-DMBED_MINIMAL_PRINTF", iar_obj.flags["common"])

tools/toolchains/arm.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ def __init__(self, target, notify=None, macros=None,
8181
if "--library_type=microlib" not in self.flags['common']:
8282
self.flags['common'].append("--library_type=microlib")
8383

84+
self.check_and_add_minimal_printf(target)
85+
8486
cpu = {
8587
"Cortex-M0+": "Cortex-M0plus",
8688
"Cortex-M4F": "Cortex-M4.fp.sp",
@@ -568,6 +570,8 @@ def __init__(self, target, *args, **kwargs):
568570
if "--library_type=microlib" not in self.flags['asm']:
569571
self.flags['asm'].append("--library_type=microlib")
570572

573+
self.check_and_add_minimal_printf(target)
574+
571575
if target.is_TrustZone_secure_target:
572576
if kwargs.get('build_dir', False):
573577
# Output secure import library
@@ -767,3 +771,4 @@ def get_binary_commands(self, bin_arg, bin, elf):
767771
cmd.insert(1, "--ide=mbed")
768772

769773
return cmd
774+

tools/toolchains/gcc.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,26 @@ def __init__(self, target, notify=None, macros=None, build_profile=None,
5858
self.flags["common"].append("-DMBED_RTOS_SINGLE_THREAD")
5959
self.flags["ld"].append("--specs=nano.specs")
6060

61+
self.check_and_add_minimal_printf(target)
62+
63+
if getattr(target, "printf_lib", "std") == "minimal-printf":
64+
minimal_printf_wraps = [
65+
"-Wl,--wrap,printf",
66+
"-Wl,--wrap,sprintf",
67+
"-Wl,--wrap,snprintf",
68+
"-Wl,--wrap,vprintf",
69+
"-Wl,--wrap,vsprintf",
70+
"-Wl,--wrap,vsnprintf",
71+
"-Wl,--wrap,fprintf",
72+
"-Wl,--wrap,vfprintf",
73+
]
74+
75+
# Add the linker option to wrap the f\v\s\printf functions if not
76+
# already added.
77+
for minimal_printf_wrap in minimal_printf_wraps:
78+
if minimal_printf_wrap not in self.flags["ld"]:
79+
self.flags["ld"].append(minimal_printf_wrap)
80+
6181
self.cpu = []
6282
if target.is_TrustZone_secure_target:
6383
# Enable compiler security extensions

tools/toolchains/iar.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ def __init__(self, target, notify=None, macros=None, build_profile=None,
6969
define_string = self.make_ld_define("DOMAIN_NS", "0x1")
7070
self.flags["ld"].append(define_string)
7171

72+
self.check_and_add_minimal_printf(target)
73+
7274
core = target.core_without_NS
7375
cpu = {
7476
"Cortex-M7F": "Cortex-M7.fp.sp",

tools/toolchains/mbed_toolchain.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,14 @@ def dump_build_profile(self):
10851085
self._overwrite_when_not_equal(where, json.dumps(
10861086
to_dump, sort_keys=True, indent=4))
10871087

1088+
def check_and_add_minimal_printf(self, target):
1089+
"""Add toolchain flag if minimal-printf is selected."""
1090+
if (
1091+
getattr(target, "printf_lib", "std") == "minimal-printf"
1092+
and "-DMBED_MINIMAL_PRINTF" not in self.flags["common"]
1093+
):
1094+
self.flags["common"].append("-DMBED_MINIMAL_PRINTF")
1095+
10881096
@staticmethod
10891097
def _overwrite_when_not_equal(filename, content):
10901098
if not exists(filename) or content != open(filename).read():

0 commit comments

Comments
 (0)