initial commit

This commit is contained in:
proddy
2020-07-05 18:29:08 +02:00
parent 26b201ea2f
commit c5933e8c14
739 changed files with 86566 additions and 20952 deletions

6
scripts/analyze_stackdmp.py Executable file → Normal file
View File

@@ -17,8 +17,10 @@ import os
# 3fffffb0: feefeffe feefeffe 3ffe8558 40100b01
# <<<stack<<<
call(['python', 'scripts/decoder.py ', '-s', '-e', os.getcwd()+"/.pio/build/debug/firmware_debug_1_9_1b3.elf", 'scripts/stackdmp.txt'])
call(['python', 'scripts/decoder.py ', '-s', '-e', os.getcwd()+"/.pio/build/esp12e/firmware.elf", 'scripts/stackdmp.txt'])
# example for linux:
# % cd EMS-ESP
# % python scripts/decoder_linux.py -s -e .pio/build/debug/firmware_d1_mini.elf scripts/stackdmp.txt
# % python scripts/decoder_linux.py -s -e .pio/build/esp12e/firmware.elf scripts/stackdmp.txt
# python decoder_linux.py -s -e ../.pio/build/esp8266-debug/firmware.elf stackdmp.txt

22
scripts/build.sh Executable file → Normal file
View File

@@ -55,24 +55,6 @@ set_default_environments() {
environments=$available
}
build_webui() {
cd ./tools/webfilesbuilder
# Build system uses gulpscript.js to build web interface
if [ ! -e node_modules/gulp/bin/gulp.js ]; then
echo "--------------------------------------------------------------"
echo "Installing dependencies..."
npm ci
fi
# Recreate web interface - "node ./tools/webfilesbuilder/node_modules/gulp/bin/gulp.js --cwd ./tools/webfilesbuilder"
echo "--------------------------------------------------------------"
echo "Building web interface..."
node node_modules/gulp/bin/gulp.js || exit
cd ../..
}
build_environments() {
echo "--------------------------------------------------------------"
echo "Building firmware images..."
@@ -95,7 +77,7 @@ build_environments() {
destination=firmware
version_file=./src/version.h
version=$(grep -E '^#define APP_VERSION' $version_file | awk '{print $3}' | sed 's/"//g')
version=$(grep -E '^#define EMSESP_APP_VERSION' $version_file | awk '{print $3}' | sed 's/"//g')
if ${TRAVIS:-false}; then
git_revision=${TRAVIS_COMMIT::7}
@@ -183,5 +165,5 @@ echo "* TRAVIS_TAG = $TRAVIS_TAG"
echo "* TRAVIS_BRANCH = $TRAVIS_BRANCH"
echo "* TRAVIS_BUILD_STAGE_NAME = $TRAVIS_BUILD_STAGE_NAME"
build_webui
build_environments

View File

@@ -0,0 +1,34 @@
from pathlib import Path
from shutil import copytree
from shutil import rmtree
from subprocess import check_output, Popen, PIPE, STDOUT, CalledProcessError
from os import chdir
Import("env")
def flagExists(flag):
buildFlags = env.ParseFlags(env["BUILD_FLAGS"])
for define in buildFlags.get("CPPDEFINES"):
if (define == flag or (isinstance(define, list) and define[0] == flag)):
return True
def buildWeb():
chdir("interface")
print("Building interface with npm")
try:
env.Execute("npm install")
env.Execute("npm run build")
buildPath = Path("build")
wwwPath = Path("../data/www")
if wwwPath.exists() and wwwPath.is_dir():
rmtree(wwwPath)
if not flagExists("PROGMEM_WWW"):
print("Copying interface to data directory")
copytree(buildPath, wwwPath)
finally:
chdir("..")
if (len(BUILD_TARGETS) == 0 or "upload" in BUILD_TARGETS):
buildWeb()
else:
print("Skipping build interface step for target(s): " + ", ".join(BUILD_TARGETS))

0
scripts/clean_fw.py Executable file → Normal file
View File

2
scripts/decoder.py Executable file → Normal file
View File

@@ -290,7 +290,7 @@ if __name__ == "__main__":
file = open(args.file, "r")
addr2line = os.path.join(os.path.abspath(os.path.expanduser(args.tool)),
"bin/xtensa-" + PLATFORMS[args.platform] + "-elf-addr2line")
"bin/xtensa-" + PLATFORMS[args.platform] + "-elf-addr2line.exe")
if not os.path.exists(addr2line):
print("ERROR: addr2line not found (" + addr2line + ")")

343
scripts/espota.py Normal file
View File

@@ -0,0 +1,343 @@
#!/usr/bin/env python3
#
# Original espota.py by Ivan Grokhotkov:
# https://gist.github.com/igrr/d35ab8446922179dc58c
#
# Modified since 2015-09-18 from Pascal Gollor (https://github.com/pgollor)
# Modified since 2015-11-09 from Hristo Gochkov (https://github.com/me-no-dev)
# Modified since 2016-01-03 from Matthew O'Gorman (https://githumb.com/mogorman)
#
# This script will push an OTA update to the ESP
# use it like: python3 espota.py -i <ESP_IP_address> -I <Host_IP_address> -p <ESP_port> -P <Host_port> [-a password] -f <sketch.bin>
# Or to upload SPIFFS image:
# python3 espota.py -i <ESP_IP_address> -I <Host_IP_address> -p <ESP_port> -P <HOST_port> [-a password] -s -f <spiffs.bin>
#
# Changes
# 2015-09-18:
# - Add option parser.
# - Add logging.
# - Send command to controller to differ between flashing and transmitting SPIFFS image.
#
# Changes
# 2015-11-09:
# - Added digest authentication
# - Enhanced error tracking and reporting
#
# Changes
# 2016-01-03:
# - Added more options to parser.
#
from __future__ import print_function
import socket
import sys
import os
import optparse
import logging
import hashlib
import random
# Commands
FLASH = 0
SPIFFS = 100
AUTH = 200
PROGRESS = False
# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
if (PROGRESS):
barLength = 60 # Modify this to change the length of the progress bar
status = ""
if isinstance(progress, int):
progress = float(progress)
if not isinstance(progress, float):
progress = 0
status = "error: progress var must be float\r\n"
if progress < 0:
progress = 0
status = "Halt...\r\n"
if progress >= 1:
progress = 1
status = "Done...\r\n"
block = int(round(barLength*progress))
text = "\rUploading: [{0}] {1}% {2}".format( "="*block + " "*(barLength-block), int(progress*100), status)
sys.stderr.write(text)
sys.stderr.flush()
else:
sys.stderr.write('.')
sys.stderr.flush()
def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, command = FLASH):
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (localAddr, localPort)
logging.info('Starting on %s:%s', str(server_address[0]), str(server_address[1]))
try:
sock.bind(server_address)
sock.listen(1)
except:
logging.error("Listen Failed")
return 1
# Check whether Signed Update is used.
if ( os.path.isfile(filename + '.signed') ):
filename = filename + '.signed'
file_check_msg = 'Detected Signed Update. %s will be uploaded instead.' % (filename)
sys.stderr.write(file_check_msg + '\n')
sys.stderr.flush()
logging.info(file_check_msg)
content_size = os.path.getsize(filename)
f = open(filename,'rb')
file_md5 = hashlib.md5(f.read()).hexdigest()
f.close()
logging.info('Upload size: %d', content_size)
message = '%d %d %d %s\n' % (command, localPort, content_size, file_md5)
# Wait for a connection
logging.info('Sending invitation to: %s', remoteAddr)
sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
remote_address = (remoteAddr, int(remotePort))
sent = sock2.sendto(message.encode(), remote_address)
sock2.settimeout(10)
try:
data = sock2.recv(128).decode()
except:
logging.error('No Answer')
sock2.close()
return 1
if (data != "OK"):
if(data.startswith('AUTH')):
nonce = data.split()[1]
cnonce_text = '%s%u%s%s' % (filename, content_size, file_md5, remoteAddr)
cnonce = hashlib.md5(cnonce_text.encode()).hexdigest()
passmd5 = hashlib.md5(password.encode()).hexdigest()
result_text = '%s:%s:%s' % (passmd5 ,nonce, cnonce)
result = hashlib.md5(result_text.encode()).hexdigest()
sys.stderr.write('Authenticating...')
sys.stderr.flush()
message = '%d %s %s\n' % (AUTH, cnonce, result)
sock2.sendto(message.encode(), remote_address)
sock2.settimeout(10)
try:
data = sock2.recv(32).decode()
except:
sys.stderr.write('FAIL\n')
logging.error('No Answer to our Authentication')
sock2.close()
return 1
if (data != "OK"):
sys.stderr.write('FAIL\n')
logging.error('%s', data)
sock2.close()
sys.exit(1)
return 1
sys.stderr.write('OK\n')
else:
logging.error('Bad Answer: %s', data)
sock2.close()
return 1
sock2.close()
logging.info('Waiting for device...')
try:
sock.settimeout(10)
connection, client_address = sock.accept()
sock.settimeout(None)
connection.settimeout(None)
except:
logging.error('No response from device')
sock.close()
return 1
received_ok = False
try:
f = open(filename, "rb")
if (PROGRESS):
update_progress(0)
else:
sys.stderr.write('Uploading')
sys.stderr.flush()
offset = 0
while True:
chunk = f.read(1460)
if not chunk: break
offset += len(chunk)
update_progress(offset/float(content_size))
connection.settimeout(10)
try:
connection.sendall(chunk)
if connection.recv(32).decode().find('O') >= 0:
# connection will receive only digits or 'OK'
received_ok = True
except:
sys.stderr.write('\n')
logging.error('Error Uploading')
connection.close()
f.close()
sock.close()
return 1
sys.stderr.write('\n')
logging.info('Waiting for result...')
# libraries/ArduinoOTA/ArduinoOTA.cpp L311 L320
# only sends digits or 'OK'. We must not not close
# the connection before receiving the 'O' of 'OK'
try:
connection.settimeout(60)
received_ok = False
received_error = False
while not (received_ok or received_error):
reply = connection.recv(64).decode()
# Look for either the "E" in ERROR or the "O" in OK response
# Check for "E" first, since both strings contain "O"
if reply.find('E') >= 0:
sys.stderr.write('\n')
logging.error('%s', reply)
received_error = True
elif reply.find('O') >= 0:
logging.info('Result: OK')
received_ok = True
connection.close()
f.close()
sock.close()
if received_ok:
return 0
return 1
except:
logging.error('No Result!')
connection.close()
f.close()
sock.close()
return 1
finally:
connection.close()
f.close()
sock.close()
return 1
# end serve
def parser(unparsed_args):
parser = optparse.OptionParser(
usage = "%prog [options]",
description = "Transmit image over the air to the esp8266 module with OTA support."
)
# destination ip and port
group = optparse.OptionGroup(parser, "Destination")
group.add_option("-i", "--ip",
dest = "esp_ip",
action = "store",
help = "ESP8266 IP Address.",
default = False
)
group.add_option("-I", "--host_ip",
dest = "host_ip",
action = "store",
help = "Host IP Address.",
default = "0.0.0.0"
)
group.add_option("-p", "--port",
dest = "esp_port",
type = "int",
help = "ESP8266 ota Port. Default 8266",
default = 8266
)
group.add_option("-P", "--host_port",
dest = "host_port",
type = "int",
help = "Host server ota Port. Default random 10000-60000",
default = random.randint(10000,60000)
)
parser.add_option_group(group)
# auth
group = optparse.OptionGroup(parser, "Authentication")
group.add_option("-a", "--auth",
dest = "auth",
help = "Set authentication password.",
action = "store",
default = ""
)
parser.add_option_group(group)
# image
group = optparse.OptionGroup(parser, "Image")
group.add_option("-f", "--file",
dest = "image",
help = "Image file.",
metavar="FILE",
default = None
)
group.add_option("-s", "--spiffs",
dest = "spiffs",
action = "store_true",
help = "Use this option to transmit a SPIFFS image and do not flash the module.",
default = False
)
parser.add_option_group(group)
# output group
group = optparse.OptionGroup(parser, "Output")
group.add_option("-d", "--debug",
dest = "debug",
help = "Show debug output. And override loglevel with debug.",
action = "store_true",
default = False
)
group.add_option("-r", "--progress",
dest = "progress",
help = "Show progress output. Does not work for ArduinoIDE",
action = "store_true",
default = False
)
parser.add_option_group(group)
(options, args) = parser.parse_args(unparsed_args)
return options
# end parser
def main(args):
# get options
options = parser(args)
# adapt log level
loglevel = logging.WARNING
if (options.debug):
loglevel = logging.DEBUG
# end if
# logging
logging.basicConfig(level = loglevel, format = '%(asctime)-8s [%(levelname)s]: %(message)s', datefmt = '%H:%M:%S')
logging.debug("Options: %s", str(options))
# check options
global PROGRESS
PROGRESS = options.progress
if (not options.esp_ip or not options.image):
logging.critical("Not enough arguments.")
return 1
# end if
command = FLASH
if (options.spiffs):
command = SPIFFS
# end if
return serve(options.esp_ip, options.host_ip, options.esp_port, options.host_port, options.auth, options.image, command)
# end main
if __name__ == '__main__':
sys.exit(main(sys.argv))
# end if

383
scripts/memanalyzer.py Normal file
View File

@@ -0,0 +1,383 @@
#!/usr/bin/env python3
# pylint: disable=C0301,C0114,C0116,W0511
# coding=utf-8
# -------------------------------------------------------------------------------
# based on ESPurna module memory analyser by xose.perez@gmail.com
#
# Rewritten for python-3 and changed to use "size" instead of "objdump"
# Based on https://github.com/esp8266/Arduino/pull/6525
# by Maxim Prokhorov <prokhorov.max@outlook.com>
#
# Based on:
# https://github.com/letscontrolit/ESPEasy/blob/mega/memanalyzer.py
# by psy0rz <edwin@datux.nl>
# https://raw.githubusercontent.com/SmingHub/Sming/develop/tools/memanalyzer.py
# by Slavey Karadzhov <slav@attachix.com>
# https://github.com/Sermus/ESP8266_memory_analyzer
# by Andrey Filimonov
#
# -------------------------------------------------------------------------------
#
# When using Windows with non-default installation at the C:\.platformio,
# you would need to specify toolchain path manually. For example:
#
# $ py -3 scripts\memanalyzer.py --toolchain-prefix C:\.platformio\packages\toolchain-xtensa\bin\xtensa-lx106-elf- <args>
#
# You could also change the path to platformio binary in a similar fashion:
# $ py -3 scripts\memanalyzer.py --platformio-prefix C:\Users\Max\platformio-penv\Scripts\
#
# -------------------------------------------------------------------------------
import argparse
import os
import re
import subprocess
import sys
from collections import OrderedDict
from subprocess import getstatusoutput
__version__ = (0, 3)
# -------------------------------------------------------------------------------
TOTAL_IRAM = 32786
TOTAL_DRAM = 81920
DEFAULT_ENV = "esp12e"
TOOLCHAIN_PREFIX = "~/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-"
PLATFORMIO_PREFIX = ""
SECTIONS = OrderedDict(
[
(".data", "Initialized Data (RAM)"),
(".rodata", "ReadOnly Data (RAM)"),
(".bss", "Uninitialized Data (RAM)"),
(".text", "Cached Code (IRAM)"),
(".irom0.text", "Uncached Code (SPI)"),
]
)
DESCRIPTION = "Memory Analyzer v{}".format(
".".join(str(x) for x in __version__)
)
# -------------------------------------------------------------------------------
def size_binary_path(prefix):
return "{}size".format(os.path.expanduser(prefix))
def file_size(file):
try:
return os.stat(file).st_size
except OSError:
return 0
def analyse_memory(size, elf_file):
proc = subprocess.Popen(
[size, "-A", elf_file], stdout=subprocess.PIPE, universal_newlines=True
)
lines = proc.stdout.readlines()
values = {}
for line in lines:
words = line.split()
for name in SECTIONS.keys():
if line.startswith(name):
value = values.setdefault(name, 0)
value += int(words[1])
values[name] = value
break
return values
def run(prefix, env, modules, debug):
flags = " ".join("-D{}_SUPPORT={:d}".format(k, v) for k, v in modules.items())
os_env = os.environ.copy()
os_env["PLATFORMIO_SRC_BUILD_FLAGS"] = flags
os_env["PLATFORMIO_BUILD_CACHE_DIR"] = "test/pio_cache"
if debug:
print("Selected flags: {}".format(flags))
command = [os.path.join(prefix, "platformio"), "run"]
if not debug:
command.append("--silent")
command.extend(["--environment", env])
output = None if debug else subprocess.DEVNULL
try:
subprocess.check_call(
command, shell=False, env=os_env, stdout=output, stderr=output
)
except subprocess.CalledProcessError:
print(" - Command failed: {}".format(command))
print(" - Selected flags: {}".format(flags))
sys.exit(1)
def get_available_modules():
modules = []
for line in open("lib/framework/services.h"):
match = re.search(r"(\w*)_SUPPORT", line)
if match:
modules.append((match.group(1), 0))
modules.sort(key=lambda item: item[0])
return OrderedDict(modules)
def parse_commandline_args():
parser = argparse.ArgumentParser(
description=DESCRIPTION, formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument(
"-e", "--environment", help="platformio environment to use", default=DEFAULT_ENV
)
parser.add_argument(
"--toolchain-prefix",
help="where to find the xtensa toolchain binaries",
default=TOOLCHAIN_PREFIX,
)
parser.add_argument(
"--platformio-prefix",
help="where to find the platformio executable",
default=PLATFORMIO_PREFIX,
)
parser.add_argument(
"-c",
"--core",
help="use core as base configuration instead of default",
action="store_true",
default=False,
)
parser.add_argument(
"-l",
"--list",
help="list available modules",
action="store_true",
default=False,
)
parser.add_argument("-d", "--debug", action="store_true", default=False)
parser.add_argument(
"modules", nargs="*", help="Modules to test (use ALL to test them all)"
)
return parser.parse_args()
def size_binary_exists(args):
status, _ = getstatusoutput(size_binary_path(args.toolchain_prefix))
if status != 1:
print("size not found, please check that the --toolchain-prefix is correct")
sys.exit(1)
def get_modules(args):
# Load list of all modules
available_modules = get_available_modules()
if args.list:
print("List of available modules:\n")
for module in available_modules:
print("* " + module)
print()
sys.exit(0)
modules = []
if args.modules:
if "ALL" in args.modules:
modules.extend(available_modules.keys())
else:
modules.extend(args.modules)
modules.sort()
# Check test modules exist
for module in modules:
if module not in available_modules:
print("Module {} not found".format(module))
sys.exit(2)
# Either use all of modules or specified subset
if args.core:
modules = available_modules
else:
modules = OrderedDict((x, 0) for x in modules)
configuration = "CORE" if args.core else "DEFAULT"
return configuration, modules
# -------------------------------------------------------------------------------
class Analyser:
"""Run platformio and print info about the resulting binary."""
OUTPUT_FORMAT = "{:<20}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}|{:<15}"
DELIMETERS = OUTPUT_FORMAT.format(
"-" * 20, "-" * 15, "-" * 15, "-" * 15, "-" * 15, "-" * 15, "-" * 15, "-" * 15
)
FIRMWARE_FORMAT = ".pio/build/{env}/firmware.{suffix}"
class _Enable:
def __init__(self, analyser, module=None):
self.analyser = analyser
self.module = module
def __enter__(self):
if not self.module:
for name in self.analyser.modules:
self.analyser.modules[name] = 1
else:
self.analyser.modules[self.module] = 1
return self.analyser
def __exit__(self, *args, **kwargs):
if not self.module:
for name in self.analyser.modules:
self.analyser.modules[name] = 0
else:
self.analyser.modules[self.module] = 0
analyser = None
module = None
def __init__(self, args, modules):
self._debug = args.debug
self._platformio_prefix = args.platformio_prefix
self._toolchain_prefix = args.toolchain_prefix
self._environment = args.environment
self.modules = modules
self.baseline = None
def enable(self, module=None):
return self._Enable(self, module)
def print(self, *args):
print(self.OUTPUT_FORMAT.format(*args))
def print_delimiters(self):
print(self.DELIMETERS)
def begin(self, name):
self.print(
"Module",
"Cache IRAM",
"Init RAM",
"R.O. RAM",
"Uninit RAM",
"Available RAM",
"Flash ROM",
"Binary size",
)
self.print(
"",
".text + .text1",
".data",
".rodata",
".bss",
"heap + stack",
".irom0.text",
"",
)
self.print_delimiters()
self.baseline = self.run()
self.print_values(name, self.baseline)
def print_values(self, header, values):
self.print(
header,
values[".text"],
values[".data"],
values[".rodata"],
values[".bss"],
values["free"],
values[".irom0.text"],
values["size"],
)
def print_compare(self, header, values):
self.print(
header,
values[".text"] - self.baseline[".text"],
values[".data"] - self.baseline[".data"],
values[".rodata"] - self.baseline[".rodata"],
values[".bss"] - self.baseline[".bss"],
values["free"] - self.baseline["free"],
values[".irom0.text"] - self.baseline[".irom0.text"],
values["size"] - self.baseline["size"],
)
def run(self):
run(self._platformio_prefix, self._environment, self.modules, self._debug)
elf_path = self.FIRMWARE_FORMAT.format(env=self._environment, suffix="elf")
bin_path = self.FIRMWARE_FORMAT.format(env=self._environment, suffix="bin")
values = analyse_memory(
size_binary_path(self._toolchain_prefix), elf_path
)
free = 80 * 1024 - values[".data"] - values[".rodata"] - values[".bss"]
free = free + (16 - free % 16)
values["free"] = free
values["size"] = file_size(bin_path)
return values
def main(args):
# Check xtensa-lx106-elf-size is in the path
size_binary_exists(args)
# Which modules to test?
configuration, modules = get_modules(args)
# print_values init message
print('Selected environment "{}"'.format(args.environment), end="")
if modules:
print(" with modules: {}".format(" ".join(modules.keys())))
else:
print()
print()
print("Analyzing {} configuration".format(configuration))
print()
# Build the core without any modules to get base memory usage
analyser = Analyser(args, modules)
analyser.begin(configuration)
# Test each module separately
results = {}
for module in analyser.modules:
with analyser.enable(module):
results[module] = analyser.run()
analyser.print_compare(module, results[module])
# Test all modules
if analyser.modules:
with analyser.enable():
total = analyser.run()
analyser.print_delimiters()
if len(analyser.modules) > 1:
analyser.print_compare("ALL MODULES", total)
analyser.print_values("TOTAL", total)
if __name__ == "__main__":
main(parse_commandline_args())

4
scripts/ota.sh Normal file
View File

@@ -0,0 +1,4 @@
# python espota.py -i 10.10.10.189 --port 8267 --auth neo -f ../.pio/build/debug/firmware.bin
python espota.py --debug --progress -i 10.10.10.100 -f ../.pio/build/debug/firmware.bin

View File

@@ -1,54 +0,0 @@
#!/usr/bin/env python
from subprocess import call
import os
import re
Import("env")
def build_web():
print("** Building web...")
env.Execute(
"node ./tools/webfilesbuilder/node_modules/gulp/bin/gulp.js --silent --cwd ./tools/webfilesbuilder")
def code_check(source, target, env):
print("** Starting cppcheck...")
call(["cppcheck", os.getcwd()+"/.", "--force", "--enable=all"])
print("\n** Finished cppcheck...\n")
print("\n** Starting cpplint...")
call(["cpplint", "--extensions=ino,cpp,h", "--filter=-legal/copyright,-build/include,-whitespace",
"--linelength=120", "--recursive", "src", "lib/myESP"])
print("\n** Finished cpplint...")
# build web files
build_web()
# extract application details
bag = {}
exprs = [
(re.compile(r'^#define APP_VERSION\s+"(\S+)"'), 'app_version'),
(re.compile(r'^#define APP_NAME\s+"(\S+)"'), 'app_name'),
(re.compile(r'^#define APP_HOSTNAME\s+"(\S+)"'), 'app_hostname')
]
with open('./src/version.h', 'r') as f:
for l in f.readlines():
for expr, var in exprs:
m = expr.match(l)
if m and len(m.groups()) > 0:
bag[var] = m.group(1)
with open('./src/ems-esp.cpp', 'r') as f:
for l in f.readlines():
for expr, var in exprs:
m = expr.match(l)
if m and len(m.groups()) > 0:
bag[var] = m.group(1)
app_version = bag.get('app_version')
app_name = bag.get('app_name')
app_hostname = bag.get('app_hostname')
board = env['BOARD']
branch = env['PIOENV']
# build filename, replacing . with _ for the version
env.Replace(PROGNAME=app_name + "-" +
app_version.replace(".", "_") + "-" + board)

View File

@@ -1,34 +0,0 @@
>>>stack>>>
3ffffdc0: 3fff472c 00000001 3ffec811 40224020
3ffffdd0: 3fff472c 00000019 3fff8acd 0000001b
3ffffde0: 3fff4a5c 0000072a 0000072a 402113c8
3ffffdf0: 3ffec4b5 3fff44d8 3fff8ab4 402117f0
3ffffe00: 3fff8ab4 3fff44d8 3fff472c 4022d20a
3ffffe10: 00000000 40209737 3fff472c 4022d1f8
3ffffe20: 3ffec4b5 3fff44d8 3fff8ab4 00000003
3ffffe30: 00000002 3fff4884 3fff44d8 40246fb8
3ffffe40: 3fff8ca0 ff000000 00004000 4020fb00
3ffffe50: 3fff8ca0 ff000000 3fff44d8 4024f9d5
3ffffe60: 4020d0d0 3fff4884 3fff44d8 00000003
3ffffe70: 00000002 3fff4884 3fff44d8 4020aa5c
3ffffe80: 45455b20 4d4f5250 4545205d 4d4f5250
3ffffe90: 63655320 20726f74 6c6f6f70 7a697320
3ffffea0: 73692065 202c3420 20646e61 75206e69
3ffffeb0: 61206573 203a6572 39313031 31303120
3ffffec0: 30312038 31203731 20363130 00000000
3ffffed0: 6f626552 6120746f 72657466 63757320
3ffffee0: 73736563 206c7566 2041544f 61647075
3ffffef0: 36006574 00000000 00000000 00000000
3fffff00: 00000000 00000007 3ffe8304 40227977
3fffff10: 0000000d 00000001 3fff44d8 3fff47b0
3fffff20: 3fff8e64 00000001 3fff44d8 4020c9e1
3fffff30: 0000006d 3fff4740 0000000d 4021813e
3fffff40: 0000006d 3fff4740 3fff472c 3fff47b0
3fffff50: 0000000d 3fff472c 3fff44d8 4020cfbd
3fffff60: 0000000d 3fff4a1c 3ffe97b8 3fff49c0
3fffff70: 3fff44d8 3fff2adc 3fff44c8 3fff49c0
3fffff80: 3fffdad0 3fff2adc 3fff44d8 4020d090
3fffff90: 3fffdad0 00000000 3fff2adc 40205cbc
3fffffa0: 3fffdad0 00000000 3fff4990 4020f088
3fffffb0: feefeffe feefeffe 3ffe97b8 401006f1
<<<stack<<<