Skip to content
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

Fingerprint configuration #21321

Merged
merged 42 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7835558
Add fingerprinting for the configuration
X-Ryl669 Feb 24, 2021
c624d58
Merge branch 'bugfix-2.0.x' into fingerprint
X-Ryl669 Mar 11, 2021
4772650
Add support for generating a JSON dictionary from the Configuration f…
X-Ryl669 Mar 11, 2021
a76483f
Add support for rebuilding the configuration file from the config.json
X-Ryl669 Mar 11, 2021
3a5b3ae
Now supports more input header and remembers which from which header …
X-Ryl669 Mar 11, 2021
34709e1
Don't filter CUSTOM_MACHINE_NAME
X-Ryl669 Mar 11, 2021
b72fe09
Add Version to the build so it's possible to figure out the source co…
X-Ryl669 Mar 12, 2021
c44d42f
Less verbose version saving to avoid useless storage of data we don't…
X-Ryl669 Mar 12, 2021
5c4fa13
Add Git reference if present
X-Ryl669 Mar 12, 2021
d220f8a
Update common-dependencies.py
thinkyhead Mar 12, 2021
2f360dc
Remove the entropy computation stuff. If someone wants it, it can rev…
X-Ryl669 Mar 12, 2021
44ac98b
Cache the preprocessor's commands when it's possible
X-Ryl669 Mar 12, 2021
7bf1913
Add support for saving the configuration to the firmware and writing …
X-Ryl669 Mar 12, 2021
1f39e84
Remove macro resolving. Tested that the generated configuration file …
X-Ryl669 Mar 12, 2021
b6f5c60
Merge branch 'bugfix-2.0.x' into fingerprint
X-Ryl669 Mar 12, 2021
d803d58
Fix AVR missing progmem section
X-Ryl669 Mar 12, 2021
aea2f1f
Another idea to fix building issue
X-Ryl669 Mar 12, 2021
3240461
Make sure the building environment is always clean
X-Ryl669 Mar 12, 2021
cda6260
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into pr/21321
thinkyhead Mar 23, 2021
e0696bf
Fix rambo build
thinkyhead Mar 23, 2021
a4cad37
Fix python errors
X-Ryl669 Mar 23, 2021
57848aa
Merge branch 'bugfix-2.0.x' into fingerprint
X-Ryl669 Mar 23, 2021
fd673b2
Silent warning when running tests
X-Ryl669 Mar 23, 2021
b01b674
Fix build issue
X-Ryl669 Mar 23, 2021
2557233
Missed fixing a warning in test code
X-Ryl669 Mar 23, 2021
86d3186
Giving up: Using a plain old C array here
X-Ryl669 Mar 23, 2021
84f33e0
Dumb me
X-Ryl669 Mar 23, 2021
b3a08b7
Make the output of the regeneration tool identic to the source file, …
X-Ryl669 Mar 23, 2021
27ca70c
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into pr/21321
thinkyhead Mar 29, 2021
7ea02de
Be positive, add M115 capability
thinkyhead Mar 29, 2021
404de0d
Split scripts up a bit
thinkyhead Mar 29, 2021
4381349
one-liner
thinkyhead Mar 29, 2021
3e8bd84
Make the feature opt-out instead of opt-in
X-Ryl669 Mar 30, 2021
0cbbdc7
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into pr/21321
thinkyhead Apr 3, 2021
44f6164
Opt in for AVR but opt out for others
X-Ryl669 Apr 6, 2021
cdbfc80
Fix CI error
X-Ryl669 Apr 6, 2021
0a4cd2a
Merge branch 'bugfix-2.0.x' into fingerprint
X-Ryl669 Aug 10, 2021
68f1a1a
Adding documentation for the feature
X-Ryl669 Aug 10, 2021
d3cdfc1
Merge 'bugfix-2.0.x' into pr/21321
thinkyhead Dec 14, 2021
b6eea0f
optimal minimal
thinkyhead Dec 14, 2021
c1291b4
move up for easier compare
thinkyhead Dec 14, 2021
baecb97
various adjustments
thinkyhead Dec 14, 2021
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
# Generated files
_Version.h
bdf2u8g
marlin_config.json
mczip.h
thinkyhead marked this conversation as resolved.
Show resolved Hide resolved
*.gen

#
# OS
Expand Down
8 changes: 8 additions & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,14 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif

/**
* Enable this option if you have more than ~3K of unused flash space.
* Marlin will embed all settings in the firmware binary as compressed data.
* Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'.
* See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'.
*/
//#define CONFIGURATION_EMBEDDING

thinkyhead marked this conversation as resolved.
Show resolved Hide resolved
// Add an optimized binary file transfer mode, initiated with 'M28 B1'
//#define BINARY_FILE_TRANSFER

Expand Down
18 changes: 18 additions & 0 deletions Marlin/src/gcode/eeprom/M500-M504.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#include "../../core/serial.h"
#include "../../inc/MarlinConfig.h"

#if ENABLED(CONFIGURATION_EMBEDDING)
#include "../../sd/SdBaseFile.h"
#include "../../mczip.h"
#endif

/**
* M500: Store settings in EEPROM
*/
Expand All @@ -50,9 +55,22 @@ void GcodeSuite::M502() {

/**
* M503: print settings currently in memory
*
* With CONFIGURATION_EMBEDDING:
* C<flag> : Save the full Marlin configuration to SD Card as "mc.zip"
*/
void GcodeSuite::M503() {
(void)settings.report(!parser.boolval('S', true));

#if ENABLED(CONFIGURATION_EMBEDDING)
if (parser.seen_test('C')) {
SdBaseFile file;
const uint16_t size = sizeof(mc_zip);
// Need to create the config size on the SD card
if (file.open("mc.zip", O_WRITE|O_CREAT) && file.write(pgm_read_ptr(mc_zip), size) != -1 && file.close())
SERIAL_ECHO_MSG("Configuration saved as 'mc.zip'");
}
#endif
}

#endif // !DISABLE_M503
Expand Down
28 changes: 21 additions & 7 deletions Marlin/src/gcode/host/M115.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "../../inc/MarlinConfig.h"
#include "../queue.h" // for getting the command port


#if ENABLED(M115_GEOMETRY_REPORT)
#include "../../module/motion.h"
#endif
Expand All @@ -33,13 +32,25 @@
#include "../../feature/caselight.h"
#endif

//#define MINIMAL_CAP_LINES // Don't even mention the disabled capabilities

#if ENABLED(EXTENDED_CAPABILITIES_REPORT)
static void cap_line(FSTR_P const name, bool ena=false) {
SERIAL_ECHOPGM("Cap:");
SERIAL_ECHOF(name);
SERIAL_CHAR(':', '0' + ena);
SERIAL_EOL();
}
#if ENABLED(MINIMAL_CAP_LINES)
#define cap_line(S,C) if (C) _cap_line(S)
static void _cap_line(FSTR_P const name) {
SERIAL_ECHOPGM("Cap:");
SERIAL_ECHOF(name);
SERIAL_ECHOLNPGM(":1");
}
#else
#define cap_line(V...) _cap_line(V)
static void _cap_line(FSTR_P const name, bool ena=false) {
SERIAL_ECHOPGM("Cap:");
SERIAL_ECHOF(name);
SERIAL_CHAR(':', '0' + ena);
SERIAL_EOL();
}
#endif
#endif

/**
Expand Down Expand Up @@ -167,6 +178,9 @@ void GcodeSuite::M115() {
// MEATPACK Compression
cap_line(F("MEATPACK"), SERIAL_IMPL.has_feature(port, SerialFeature::MeatPack));

// CONFIG_EXPORT
cap_line(F("CONFIG_EXPORT"), ENABLED(CONFIG_EMBED_AND_SAVE_TO_SD));

// Machine Geometry
#if ENABLED(M115_GEOMETRY_REPORT)
const xyz_pos_t bmin = { 0, 0, 0 },
Expand Down
6 changes: 6 additions & 0 deletions Marlin/src/inc/Conditionals_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1004,3 +1004,9 @@
#if EITHER(MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2)
#define HAS_MEATPACK 1
#endif

// AVR are (usually) too limited in resources to store the configuration into the binary
#if !defined(FORCE_CONFIG_EMBED) && (defined(__AVR__) || DISABLED(SDSUPPORT) || EITHER(SDCARD_READONLY, DISABLE_M503))
#undef CONFIGURATION_EMBEDDING
#define CANNOT_EMBED_CONFIGURATION defined(__AVR__)
#endif
4 changes: 4 additions & 0 deletions Marlin/src/inc/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,7 @@
#elif !USE_SENSORLESS && ENABLED(USES_DIAG_PINS)
#warning "Driver DIAG pins must be physically removed unless SENSORLESS_HOMING is enabled. (See https://bit.ly/2ZPRlt0)"
#endif

#if CANNOT_EMBED_CONFIGURATION
#warning "Disabled CONFIGURATION_EMBEDDING because the target usually has less flash storage. Define FORCE_CONFIG_EMBED to override."
#endif
2 changes: 1 addition & 1 deletion buildroot/bin/restore_configs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

git checkout Marlin/Configuration*.h 2>/dev/null
git checkout Marlin/src/pins/ramps/pins_RAMPS.h 2>/dev/null
rm -f Marlin/_Bootscreen.h Marlin/_Statusscreen.h
rm -f Marlin/_Bootscreen.h Marlin/_Statusscreen.h marlin_config.json .pio/build/mc.zip
X-Ryl669 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
if pioutil.is_pio_build():
from os.path import join, isfile
import shutil
from pprint import pprint

Import("env")

Expand Down
Empty file.
87 changes: 11 additions & 76 deletions buildroot/share/PlatformIO/scripts/common-dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,63 +192,6 @@ def apply_features_config():
lib_ignore = env.GetProjectOption('lib_ignore') + [feat['lib_ignore']]
set_env_field('lib_ignore', lib_ignore)

#
# Find a compiler, considering the OS
#
ENV_BUILD_PATH = os.path.join(env.Dictionary('PROJECT_BUILD_DIR'), env['PIOENV'])
GCC_PATH_CACHE = os.path.join(ENV_BUILD_PATH, ".gcc_path")
def search_compiler():
try:
filepath = env.GetProjectOption('custom_gcc')
blab("Getting compiler from env")
return filepath
except:
pass

if os.path.exists(GCC_PATH_CACHE):
with open(GCC_PATH_CACHE, 'r') as f:
return f.read()

# Find the current platform compiler by searching the $PATH
# which will be in a platformio toolchain bin folder
path_regex = re.escape(env['PROJECT_PACKAGES_DIR'])

# See if the environment provides a default compiler
try:
gcc = env.GetProjectOption('custom_deps_gcc')
except:
gcc = "g++"

if env['PLATFORM'] == 'win32':
path_separator = ';'
path_regex += r'.*\\bin'
gcc += ".exe"
else:
path_separator = ':'
path_regex += r'/.+/bin'

# Search for the compiler
for pathdir in env['ENV']['PATH'].split(path_separator):
if not re.search(path_regex, pathdir, re.IGNORECASE):
continue
for filepath in os.listdir(pathdir):
if not filepath.endswith(gcc):
continue
# Use entire path to not rely on env PATH
filepath = os.path.sep.join([pathdir, filepath])
# Cache the g++ path to no search always
if os.path.exists(ENV_BUILD_PATH):
with open(GCC_PATH_CACHE, 'w+') as f:
f.write(filepath)

return filepath

filepath = env.get('CXX')
if filepath == 'CC':
filepath = gcc
blab("Couldn't find a compiler! Fallback to %s" % filepath)
return filepath

#
# Use the compiler to get a list of all enabled features
#
Expand All @@ -257,25 +200,8 @@ def load_marlin_features():
return

# Process defines
build_flags = env.get('BUILD_FLAGS')
build_flags = env.ParseFlagsExtended(build_flags)

cxx = search_compiler()
cmd = ['"' + cxx + '"']

# Build flags from board.json
#if 'BOARD' in env:
# cmd += [env.BoardConfig().get("build.extra_flags")]
for s in build_flags['CPPDEFINES']:
if isinstance(s, tuple):
cmd += ['-D' + s[0] + '=' + str(s[1])]
else:
cmd += ['-D' + s]

cmd += ['-D__MARLIN_DEPS__ -w -dM -E -x c++ buildroot/share/PlatformIO/scripts/common-dependencies.h']
cmd = ' '.join(cmd)
blab(cmd, 4)
define_list = subprocess.check_output(cmd, shell=True).splitlines()
from preprocessor import run_preprocessor
define_list = run_preprocessor(env)
marlin_features = {}
for define in define_list:
feature = define[8:].strip().decode().split(' ')
Expand Down Expand Up @@ -310,9 +236,18 @@ def MarlinFeatureIsEnabled(env, feature):
except:
pass

#
# Add a method for other PIO scripts to query enabled features
#
env.AddMethod(MarlinFeatureIsEnabled)

#
# Add dependencies for enabled Marlin features
#
apply_features_config()
force_ignore_unused_libs()

#print(env.Dump())

from signature import compute_build_signature
compute_build_signature(env)
69 changes: 69 additions & 0 deletions buildroot/share/PlatformIO/scripts/mc-apply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python
#
# Create a Configuration from marlin_config.json
#
import json
import sys
import shutil
import re

opt_output = '--opt' in sys.argv
output_suffix = '.sh' if opt_output else '' if '--bare-output' in sys.argv else '.gen'

try:
with open('marlin_config.json', 'r') as infile:
conf = json.load(infile)
for key in conf:
# We don't care about the hash when restoring here
if key == '__INITIAL_HASH':
continue
if key == 'VERSION':
for k, v in sorted(conf[key].items()):
print(k + ': ' + v)
continue
# The key is the file name, so let's build it now
outfile = open('Marlin/' + key + output_suffix, 'w')
for k, v in sorted(conf[key].items()):
# Make define line now
if opt_output:
if v != '':
if '"' in v:
v = "'%s'" % v
elif ' ' in v:
v = '"%s"' % v
define = 'opt_set ' + k + ' ' + v + '\n'
else:
define = 'opt_enable ' + k + '\n'
else:
define = '#define ' + k + ' ' + v + '\n'
outfile.write(define)
outfile.close()

# Try to apply changes to the actual configuration file (in order to keep useful comments)
if output_suffix != '':
# Move the existing configuration so it doesn't interfere
shutil.move('Marlin/' + key, 'Marlin/' + key + '.orig')
infile_lines = open('Marlin/' + key + '.orig', 'r').read().split('\n')
outfile = open('Marlin/' + key, 'w')
for line in infile_lines:
sline = line.strip(" \t\n\r")
if sline[:7] == "#define":
# Extract the key here (we don't care about the value)
kv = sline[8:].strip().split(' ')
if kv[0] in conf[key]:
outfile.write('#define ' + kv[0] + ' ' + conf[key][kv[0]] + '\n')
# Remove the key from the dict, so we can still write all missing keys at the end of the file
del conf[key][kv[0]]
else:
outfile.write(line + '\n')
else:
outfile.write(line + '\n')
# Process any remaining defines here
for k, v in sorted(conf[key].items()):
define = '#define ' + k + ' ' + v + '\n'
outfile.write(define)
outfile.close()

print('Output configuration written to: ' + 'Marlin/' + key + output_suffix)
except:
print('No marlin_config.json found.')
Loading