Skip to content

Add Mbed Configuration Option Range Limits #8673

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 65 additions & 8 deletions tools/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import json
import six
import os
import re
from os.path import dirname, abspath, exists, join, isabs
import sys
from collections import namedtuple
Expand Down Expand Up @@ -101,15 +102,19 @@ def __init__(self, name, data, unit_name, unit_kind):
data - the data associated with the configuration parameter
unit_name - the unit (target/library/application) that defines this
parameter
unit_ kind - the kind of the unit ("target", "library" or "application")
unit_kind - the kind of the unit ("target", "library" or "application")
"""

self.name = self.get_full_name(name, unit_name, unit_kind,
allow_prefix=False)
self.defined_by = self.get_display_name(unit_name, unit_kind)
self.set_value(data.get("value", None), unit_name, unit_kind)
self.help_text = data.get("help", None)
self.required = data.get("required", False)
self.macro_name = data.get("macro_name", "MBED_CONF_%s" %
self.value_min = data.get("value_min")
self.value_max = data.get("value_max")
self.accepted_values = data.get("accepted_values")
self.help_text = data.get("help", None)
self.required = data.get("required", False)
self.macro_name = data.get("macro_name", "MBED_CONF_%s" %
self.sanitize(self.name.upper()))
self.config_errors = []

Expand Down Expand Up @@ -749,7 +754,7 @@ def _generate_bootloader_build(self, rom_start, rom_size):
if start > rom_start + rom_size:
raise ConfigException("Not enough memory on device to fit all "
"application regions")

@staticmethod
def _find_sector(address, sectors):
target_size = -1
Expand All @@ -762,13 +767,13 @@ def _find_sector(address, sectors):
if (target_size < 0):
raise ConfigException("No valid sector found")
return target_start, target_size

@staticmethod
def _align_floor(address, sectors):
target_start, target_size = Config._find_sector(address, sectors)
sector_num = (address - target_start) // target_size
return target_start + (sector_num * target_size)

@staticmethod
def _align_ceiling(address, sectors):
target_start, target_size = Config._find_sector(address, sectors)
Expand Down Expand Up @@ -1058,9 +1063,61 @@ def validate_config(self):

Arguments: None
"""

params, _ = self.get_config_data()
err_msg = ""

for name, param in sorted(params.items()):
min = param.value_min
max = param.value_max
accepted = param.accepted_values
value = param.value

# Config parameters that are only defined but do not have a default
# value should not be range limited
if value is not None:
if (min is not None or max is not None) and (accepted is not None):
err_msg += "\n%s has both a range and list of accepted values specified. Please only "\
"specify either value_min and/or value_max, or accepted_values"\
% param
else:
if re.match(r'^(0[xX])[A-Fa-f0-9]+$|^[0-9]+$', str(value)):
# Value is a hexadecimal or numerical string value
# Convert to a python integer and range check/compare to
# accepted list accordingly

if min is not None or max is not None:
# Numerical range check
# Convert hex strings to integers for range checks

value = int(str(value), 0)
min = int(str(min), 0) if min is not None else None
max = int(str(max), 0) if max is not None else None

if (value < min or (value > max if max is not None else False)):
err_msg += "\nInvalid config range for %s, is not in the required range: [%s:%s]"\
% (param,
min if min is not None else "-inf",
max if max is not None else "inf")

# Numerical accepted value check
elif accepted is not None and value not in accepted:
err_msg += "\nInvalid value for %s, is not an accepted value: %s"\
% (param, ", ".join(map(str, accepted)))
else:
if min is not None or max is not None:
err_msg += "\nInvalid config range settings for %s. Range specifiers are not "\
"applicable to non-decimal/hexadecimal string values" % param

if accepted is not None and value not in accepted:
err_msg += "\nInvalid config range for %s, is not an accepted value: %s"\
% (param, ", ".join(accepted))

if (err_msg):
raise ConfigException(err_msg)

for error in self.config_errors:
if (isinstance(error, UndefinedParameter) and
if (isinstance(error, UndefinedParameter) and
error.param in params):
continue
else:
Expand Down
38 changes: 38 additions & 0 deletions tools/test/config/range_limits/lib1/mbed_lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "lib1",
"config": {
"config1": {
"help": "The default value should pass as it is in the list of accepted values",
"value": 5,
"accepted_values": [0, 5, 10]
},
"config2": {
"help": "The default value should pass as it is in the range of accepted values",
"value": 7,
"value_min": 0,
"value_max": 10
},
"config3": {
"help": "The default value should pass as it is in the range of accepted values",
"value": "foo",
"accepted_values": ["foo", "bar"]
},
"config4": {
"help": "The default value should pass as it is in the range of accepted values",
"value": "0x1000",
"value_min": "0x10",
"value_max": "0x8000"
},
"config5": {
"help": "The default value should pass as it is in the range of accepted values",
"value": "0x2000",
"value_min": 0,
"value_max": "0x8000"
},
"config6": {
"help": "The default value should pass as it is in the list of accepted values",
"value": "0x8000",
"accepted_values": ["0x1000", "0x8000", "0x12000"]
}
}
}
9 changes: 9 additions & 0 deletions tools/test/config/range_limits/targets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"test_target": {
"core": "Cortex-M0",
"extra_labels": [],
"features": [],
"default_lib": "std",
"supported_toolchains": ["GCC_ARM"]
}
}
10 changes: 10 additions & 0 deletions tools/test/config/range_limits/test_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"test_target": {
"lib1.config1": 5,
"lib1.config2": 7,
"lib1.config3": "foo",
"lib1.config4": "0x1000",
"lib1.config5": "0x2000",
"lib1.config6": "0x8000"
}
}
42 changes: 42 additions & 0 deletions tools/test/config/range_limits_invalid/lib1/mbed_lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "lib1",
"config": {
"config1": {
"help": "The default value should fail as it is not in the range of accepted values",
"value": 99,
"accepted_values": [0, 5, 10]
},
"config2": {
"help": "The default value should fail as it is not in the range of accepted values",
"value": 100,
"value_min": 0,
"value_max": 10
},
"config3": {
"help": "The default value should fail as it is not in the range of accepted values",
"value": 101,
"value_min": 102
},
"config4": {
"help": "The default value should fail as it is not in the range of accepted values",
"value": 102,
"value_max": 101
},
"config5": {
"help": "The default value should fail as it specified both a range and list of accepted values",
"value": 103,
"value_max": 104,
"accepted_values": ["103"]
},
"config6": {
"help": "The default value should fail as it is not in the range of accepted values",
"value": "0x1000",
"value_max": "0x500"
},
"config7": {
"help": "The default value should fail as it is a non-decimal string with a max value",
"value": "test",
"value_max": "?"
}
}
}
9 changes: 9 additions & 0 deletions tools/test/config/range_limits_invalid/targets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"test_target": {
"core": "Cortex-M0",
"extra_labels": [],
"features": [],
"default_lib": "std",
"supported_toolchains": ["GCC_ARM"]
}
}
5 changes: 5 additions & 0 deletions tools/test/config/range_limits_invalid/test_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"test_target": {
"exception_msg": "\nInvalid value for lib1.config1 = 99 (macro name: \"MBED_CONF_LIB1_CONFIG1\"), is not an accepted value: 0, 5, 10\nInvalid config range for lib1.config2 = 100 (macro name: \"MBED_CONF_LIB1_CONFIG2\"), is not in the required range: [0:10]\nInvalid config range for lib1.config3 = 101 (macro name: \"MBED_CONF_LIB1_CONFIG3\"), is not in the required range: [102:inf]\nInvalid config range for lib1.config4 = 102 (macro name: \"MBED_CONF_LIB1_CONFIG4\"), is not in the required range: [-inf:101]\nlib1.config5 = 103 (macro name: \"MBED_CONF_LIB1_CONFIG5\") has both a range and list of accepted values specified. Please only specify either value_min and/or value_max, or accepted_values\nInvalid config range for lib1.config6 = 0x1000 (macro name: \"MBED_CONF_LIB1_CONFIG6\"), is not in the required range: [-inf:1280]\nInvalid config range settings for lib1.config7 = test (macro name: \"MBED_CONF_LIB1_CONFIG7\"). Range specifiers are not applicable to non-decimal/hexadecimal string values"
}
}
11 changes: 11 additions & 0 deletions tools/test/config/range_limits_override_invalid/lib1/mbed_lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "lib1",
"config": {
"config1": {
"help": "The default value should pass, but will be overridden out of bounds and should error",
"value": 8,
"value_min": 0,
"value_max": 10
}
}
}
7 changes: 7 additions & 0 deletions tools/test/config/range_limits_override_invalid/mbed_app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"target_overrides": {
"test_target": {
"lib1.config1": 12
}
}
}
9 changes: 9 additions & 0 deletions tools/test/config/range_limits_override_invalid/targets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"test_target": {
"core": "Cortex-M0",
"extra_labels": [],
"features": [],
"default_lib": "std",
"supported_toolchains": ["GCC_ARM"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"test_target": {
"lib1.config1": 12,
"exception_msg": "Invalid config range for lib1.config1 = 12 (macro name: \"MBED_CONF_LIB1_CONFIG1\"), is not in the required range: [0:10]"
}
}