Add Code
This commit is contained in:
BIN
code/.venv/bin/__pycache__/bin2hex.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/bin2hex.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/esp_rfc2217_server.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/esp_rfc2217_server.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/espefuse.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/espefuse.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/espsecure.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/espsecure.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/esptool.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/esptool.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hex2bin.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hex2bin.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hex2dump.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hex2dump.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hexdiff.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hexdiff.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hexinfo.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hexinfo.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hexmerge.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hexmerge.cpython-312.pyc
Normal file
Binary file not shown.
87
code/.venv/bin/activate
Normal file
87
code/.venv/bin/activate
Normal file
@@ -0,0 +1,87 @@
|
||||
# This file must be used with "source bin/activate" *from bash*
|
||||
# you cannot run it directly
|
||||
|
||||
|
||||
if [ "${BASH_SOURCE-}" = "$0" ]; then
|
||||
echo "You must source this script: \$ source $0" >&2
|
||||
exit 33
|
||||
fi
|
||||
|
||||
deactivate () {
|
||||
unset -f pydoc >/dev/null 2>&1 || true
|
||||
|
||||
# reset old environment variables
|
||||
# ! [ -z ${VAR+_} ] returns true if VAR is declared at all
|
||||
if ! [ -z "${_OLD_VIRTUAL_PATH:+_}" ] ; then
|
||||
PATH="$_OLD_VIRTUAL_PATH"
|
||||
export PATH
|
||||
unset _OLD_VIRTUAL_PATH
|
||||
fi
|
||||
if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then
|
||||
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
|
||||
export PYTHONHOME
|
||||
unset _OLD_VIRTUAL_PYTHONHOME
|
||||
fi
|
||||
|
||||
# The hash command must be called to get it to forget past
|
||||
# commands. Without forgetting past commands the $PATH changes
|
||||
# we made may not be respected
|
||||
hash -r 2>/dev/null
|
||||
|
||||
if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then
|
||||
PS1="$_OLD_VIRTUAL_PS1"
|
||||
export PS1
|
||||
unset _OLD_VIRTUAL_PS1
|
||||
fi
|
||||
|
||||
unset VIRTUAL_ENV
|
||||
unset VIRTUAL_ENV_PROMPT
|
||||
if [ ! "${1-}" = "nondestructive" ] ; then
|
||||
# Self destruct!
|
||||
unset -f deactivate
|
||||
fi
|
||||
}
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate nondestructive
|
||||
|
||||
VIRTUAL_ENV='/home/rhetenor/Projects/esp/python/.venv'
|
||||
if ([ "$OSTYPE" = "cygwin" ] || [ "$OSTYPE" = "msys" ]) && $(command -v cygpath &> /dev/null) ; then
|
||||
VIRTUAL_ENV=$(cygpath -u "$VIRTUAL_ENV")
|
||||
fi
|
||||
export VIRTUAL_ENV
|
||||
|
||||
_OLD_VIRTUAL_PATH="$PATH"
|
||||
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||
export PATH
|
||||
|
||||
if [ "x" != x ] ; then
|
||||
VIRTUAL_ENV_PROMPT=""
|
||||
else
|
||||
VIRTUAL_ENV_PROMPT=$(basename "$VIRTUAL_ENV")
|
||||
fi
|
||||
export VIRTUAL_ENV_PROMPT
|
||||
|
||||
# unset PYTHONHOME if set
|
||||
if ! [ -z "${PYTHONHOME+_}" ] ; then
|
||||
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
|
||||
unset PYTHONHOME
|
||||
fi
|
||||
|
||||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then
|
||||
_OLD_VIRTUAL_PS1="${PS1-}"
|
||||
PS1="(${VIRTUAL_ENV_PROMPT}) ${PS1-}"
|
||||
export PS1
|
||||
fi
|
||||
|
||||
# Make sure to unalias pydoc if it's already there
|
||||
alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true
|
||||
|
||||
pydoc () {
|
||||
python -m pydoc "$@"
|
||||
}
|
||||
|
||||
# The hash command must be called to get it to forget past
|
||||
# commands. Without forgetting past commands the $PATH changes
|
||||
# we made may not be respected
|
||||
hash -r 2>/dev/null || true
|
||||
55
code/.venv/bin/activate.csh
Normal file
55
code/.venv/bin/activate.csh
Normal file
@@ -0,0 +1,55 @@
|
||||
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||
# You cannot run it directly.
|
||||
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||
|
||||
set newline='\
|
||||
'
|
||||
|
||||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
setenv VIRTUAL_ENV '/home/rhetenor/Projects/esp/python/.venv'
|
||||
|
||||
set _OLD_VIRTUAL_PATH="$PATH:q"
|
||||
setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q"
|
||||
|
||||
|
||||
|
||||
if ('' != "") then
|
||||
setenv VIRTUAL_ENV_PROMPT ''
|
||||
else
|
||||
setenv VIRTUAL_ENV_PROMPT "$VIRTUAL_ENV:t:q"
|
||||
endif
|
||||
|
||||
if ( $?VIRTUAL_ENV_DISABLE_PROMPT ) then
|
||||
if ( $VIRTUAL_ENV_DISABLE_PROMPT == "" ) then
|
||||
set do_prompt = "1"
|
||||
else
|
||||
set do_prompt = "0"
|
||||
endif
|
||||
else
|
||||
set do_prompt = "1"
|
||||
endif
|
||||
|
||||
if ( $do_prompt == "1" ) then
|
||||
# Could be in a non-interactive environment,
|
||||
# in which case, $prompt is undefined and we wouldn't
|
||||
# care about the prompt anyway.
|
||||
if ( $?prompt ) then
|
||||
set _OLD_VIRTUAL_PROMPT="$prompt:q"
|
||||
if ( "$prompt:q" =~ *"$newline:q"* ) then
|
||||
:
|
||||
else
|
||||
set prompt = '('"$VIRTUAL_ENV_PROMPT:q"') '"$prompt:q"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
unset env_name
|
||||
unset do_prompt
|
||||
|
||||
alias pydoc python -m pydoc
|
||||
|
||||
rehash
|
||||
103
code/.venv/bin/activate.fish
Normal file
103
code/.venv/bin/activate.fish
Normal file
@@ -0,0 +1,103 @@
|
||||
# This file must be used using `source bin/activate.fish` *within a running fish ( http://fishshell.com ) session*.
|
||||
# Do not run it directly.
|
||||
|
||||
function _bashify_path -d "Converts a fish path to something bash can recognize"
|
||||
set fishy_path $argv
|
||||
set bashy_path $fishy_path[1]
|
||||
for path_part in $fishy_path[2..-1]
|
||||
set bashy_path "$bashy_path:$path_part"
|
||||
end
|
||||
echo $bashy_path
|
||||
end
|
||||
|
||||
function _fishify_path -d "Converts a bash path to something fish can recognize"
|
||||
echo $argv | tr ':' '\n'
|
||||
end
|
||||
|
||||
function deactivate -d 'Exit virtualenv mode and return to the normal environment.'
|
||||
# reset old environment variables
|
||||
if test -n "$_OLD_VIRTUAL_PATH"
|
||||
# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling
|
||||
if test (echo $FISH_VERSION | head -c 1) -lt 3
|
||||
set -gx PATH (_fishify_path "$_OLD_VIRTUAL_PATH")
|
||||
else
|
||||
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||
end
|
||||
set -e _OLD_VIRTUAL_PATH
|
||||
end
|
||||
|
||||
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||
set -gx PYTHONHOME "$_OLD_VIRTUAL_PYTHONHOME"
|
||||
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||
end
|
||||
|
||||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||
and functions -q _old_fish_prompt
|
||||
# Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`.
|
||||
set -l fish_function_path
|
||||
|
||||
# Erase virtualenv's `fish_prompt` and restore the original.
|
||||
functions -e fish_prompt
|
||||
functions -c _old_fish_prompt fish_prompt
|
||||
functions -e _old_fish_prompt
|
||||
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||
end
|
||||
|
||||
set -e VIRTUAL_ENV
|
||||
set -e VIRTUAL_ENV_PROMPT
|
||||
|
||||
if test "$argv[1]" != 'nondestructive'
|
||||
# Self-destruct!
|
||||
functions -e pydoc
|
||||
functions -e deactivate
|
||||
functions -e _bashify_path
|
||||
functions -e _fishify_path
|
||||
end
|
||||
end
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
set -gx VIRTUAL_ENV '/home/rhetenor/Projects/esp/python/.venv'
|
||||
|
||||
# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling
|
||||
if test (echo $FISH_VERSION | head -c 1) -lt 3
|
||||
set -gx _OLD_VIRTUAL_PATH (_bashify_path $PATH)
|
||||
else
|
||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||
end
|
||||
set -gx PATH "$VIRTUAL_ENV"'/bin' $PATH
|
||||
|
||||
# Prompt override provided?
|
||||
# If not, just use the environment name.
|
||||
if test -n ''
|
||||
set -gx VIRTUAL_ENV_PROMPT ''
|
||||
else
|
||||
set -gx VIRTUAL_ENV_PROMPT (basename "$VIRTUAL_ENV")
|
||||
end
|
||||
|
||||
# Unset `$PYTHONHOME` if set.
|
||||
if set -q PYTHONHOME
|
||||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||
set -e PYTHONHOME
|
||||
end
|
||||
|
||||
function pydoc
|
||||
python -m pydoc $argv
|
||||
end
|
||||
|
||||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||
# Copy the current `fish_prompt` function as `_old_fish_prompt`.
|
||||
functions -c fish_prompt _old_fish_prompt
|
||||
|
||||
function fish_prompt
|
||||
# Run the user's prompt first; it might depend on (pipe)status.
|
||||
set -l prompt (_old_fish_prompt)
|
||||
|
||||
printf '(%s) ' $VIRTUAL_ENV_PROMPT
|
||||
|
||||
string join -- \n $prompt # handle multi-line prompts
|
||||
end
|
||||
|
||||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||
end
|
||||
96
code/.venv/bin/activate.nu
Normal file
96
code/.venv/bin/activate.nu
Normal file
@@ -0,0 +1,96 @@
|
||||
# virtualenv activation module
|
||||
# Activate with `overlay use activate.nu`
|
||||
# Deactivate with `deactivate`, as usual
|
||||
#
|
||||
# To customize the overlay name, you can call `overlay use activate.nu as foo`,
|
||||
# but then simply `deactivate` won't work because it is just an alias to hide
|
||||
# the "activate" overlay. You'd need to call `overlay hide foo` manually.
|
||||
|
||||
export-env {
|
||||
def is-string [x] {
|
||||
($x | describe) == 'string'
|
||||
}
|
||||
|
||||
def has-env [...names] {
|
||||
$names | each {|n|
|
||||
$n in $env
|
||||
} | all {|i| $i == true}
|
||||
}
|
||||
|
||||
# Emulates a `test -z`, but btter as it handles e.g 'false'
|
||||
def is-env-true [name: string] {
|
||||
if (has-env $name) {
|
||||
# Try to parse 'true', '0', '1', and fail if not convertible
|
||||
let parsed = (do -i { $env | get $name | into bool })
|
||||
if ($parsed | describe) == 'bool' {
|
||||
$parsed
|
||||
} else {
|
||||
not ($env | get -i $name | is-empty)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
let virtual_env = '/home/rhetenor/Projects/esp/python/.venv'
|
||||
let bin = 'bin'
|
||||
|
||||
let is_windows = ($nu.os-info.family) == 'windows'
|
||||
let path_name = (if (has-env 'Path') {
|
||||
'Path'
|
||||
} else {
|
||||
'PATH'
|
||||
}
|
||||
)
|
||||
|
||||
let venv_path = ([$virtual_env $bin] | path join)
|
||||
let new_path = ($env | get $path_name | prepend $venv_path)
|
||||
|
||||
# If there is no default prompt, then use the env name instead
|
||||
let virtual_env_prompt = (if ('' | is-empty) {
|
||||
($virtual_env | path basename)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let new_env = {
|
||||
$path_name : $new_path
|
||||
VIRTUAL_ENV : $virtual_env
|
||||
VIRTUAL_ENV_PROMPT : $virtual_env_prompt
|
||||
}
|
||||
|
||||
let new_env = (if (is-env-true 'VIRTUAL_ENV_DISABLE_PROMPT') {
|
||||
$new_env
|
||||
} else {
|
||||
# Creating the new prompt for the session
|
||||
let virtual_prefix = $'(char lparen)($virtual_env_prompt)(char rparen) '
|
||||
|
||||
# Back up the old prompt builder
|
||||
let old_prompt_command = (if (has-env 'PROMPT_COMMAND') {
|
||||
$env.PROMPT_COMMAND
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let new_prompt = (if (has-env 'PROMPT_COMMAND') {
|
||||
if 'closure' in ($old_prompt_command | describe) {
|
||||
{|| $'($virtual_prefix)(do $old_prompt_command)' }
|
||||
} else {
|
||||
{|| $'($virtual_prefix)($old_prompt_command)' }
|
||||
}
|
||||
} else {
|
||||
{|| $'($virtual_prefix)' }
|
||||
})
|
||||
|
||||
$new_env | merge {
|
||||
PROMPT_COMMAND : $new_prompt
|
||||
VIRTUAL_PREFIX : $virtual_prefix
|
||||
}
|
||||
})
|
||||
|
||||
# Environment variables that will be loaded as the virtual env
|
||||
load-env $new_env
|
||||
}
|
||||
|
||||
export alias pydoc = python -m pydoc
|
||||
export alias deactivate = overlay hide activate
|
||||
61
code/.venv/bin/activate.ps1
Normal file
61
code/.venv/bin/activate.ps1
Normal file
@@ -0,0 +1,61 @@
|
||||
$script:THIS_PATH = $myinvocation.mycommand.path
|
||||
$script:BASE_DIR = Split-Path (Resolve-Path "$THIS_PATH/..") -Parent
|
||||
|
||||
function global:deactivate([switch] $NonDestructive) {
|
||||
if (Test-Path variable:_OLD_VIRTUAL_PATH) {
|
||||
$env:PATH = $variable:_OLD_VIRTUAL_PATH
|
||||
Remove-Variable "_OLD_VIRTUAL_PATH" -Scope global
|
||||
}
|
||||
|
||||
if (Test-Path function:_old_virtual_prompt) {
|
||||
$function:prompt = $function:_old_virtual_prompt
|
||||
Remove-Item function:\_old_virtual_prompt
|
||||
}
|
||||
|
||||
if ($env:VIRTUAL_ENV) {
|
||||
Remove-Item env:VIRTUAL_ENV -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if ($env:VIRTUAL_ENV_PROMPT) {
|
||||
Remove-Item env:VIRTUAL_ENV_PROMPT -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if (!$NonDestructive) {
|
||||
# Self destruct!
|
||||
Remove-Item function:deactivate
|
||||
Remove-Item function:pydoc
|
||||
}
|
||||
}
|
||||
|
||||
function global:pydoc {
|
||||
python -m pydoc $args
|
||||
}
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate -nondestructive
|
||||
|
||||
$VIRTUAL_ENV = $BASE_DIR
|
||||
$env:VIRTUAL_ENV = $VIRTUAL_ENV
|
||||
|
||||
if ("" -ne "") {
|
||||
$env:VIRTUAL_ENV_PROMPT = ""
|
||||
}
|
||||
else {
|
||||
$env:VIRTUAL_ENV_PROMPT = $( Split-Path $env:VIRTUAL_ENV -Leaf )
|
||||
}
|
||||
|
||||
New-Variable -Scope global -Name _OLD_VIRTUAL_PATH -Value $env:PATH
|
||||
|
||||
$env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH
|
||||
if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
||||
function global:_old_virtual_prompt {
|
||||
""
|
||||
}
|
||||
$function:_old_virtual_prompt = $function:prompt
|
||||
|
||||
function global:prompt {
|
||||
# Add the custom prefix to the existing prompt
|
||||
$previous_prompt_value = & $function:_old_virtual_prompt
|
||||
("(" + $env:VIRTUAL_ENV_PROMPT + ") " + $previous_prompt_value)
|
||||
}
|
||||
}
|
||||
38
code/.venv/bin/activate_this.py
Normal file
38
code/.venv/bin/activate_this.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
Activate virtualenv for current interpreter:
|
||||
|
||||
import runpy
|
||||
runpy.run_path(this_file)
|
||||
|
||||
This can be used when you must use an existing Python interpreter, not the virtualenv bin/python.
|
||||
""" # noqa: D415
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import site
|
||||
import sys
|
||||
|
||||
try:
|
||||
abs_file = os.path.abspath(__file__)
|
||||
except NameError as exc:
|
||||
msg = "You must use import runpy; runpy.run_path(this_file)"
|
||||
raise AssertionError(msg) from exc
|
||||
|
||||
bin_dir = os.path.dirname(abs_file)
|
||||
base = bin_dir[: -len("bin") - 1] # strip away the bin part from the __file__, plus the path separator
|
||||
|
||||
# prepend bin to PATH (this file is inside the bin directory)
|
||||
os.environ["PATH"] = os.pathsep.join([bin_dir, *os.environ.get("PATH", "").split(os.pathsep)])
|
||||
os.environ["VIRTUAL_ENV"] = base # virtual env is right above bin directory
|
||||
os.environ["VIRTUAL_ENV_PROMPT"] = "" or os.path.basename(base) # noqa: SIM222
|
||||
|
||||
# add the virtual environments libraries to the host python import mechanism
|
||||
prev_length = len(sys.path)
|
||||
for lib in "../lib/python3.12/site-packages".split(os.pathsep):
|
||||
path = os.path.realpath(os.path.join(bin_dir, lib))
|
||||
site.addsitedir(path.decode("utf-8") if "" else path)
|
||||
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
|
||||
|
||||
sys.real_prefix = sys.prefix
|
||||
sys.prefix = base
|
||||
115
code/.venv/bin/bin2hex.py
Executable file
115
code/.venv/bin/bin2hex.py
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''Intel HEX file format bin2hex convertor utility.'''
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
usage = '''Bin2Hex convertor utility.
|
||||
Usage:
|
||||
python bin2hex.py [options] INFILE [OUTFILE]
|
||||
|
||||
Arguments:
|
||||
INFILE name of bin file for processing.
|
||||
Use '-' for reading from stdin.
|
||||
|
||||
OUTFILE name of output file. If omitted then output
|
||||
will be writing to stdout.
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
--offset=N offset for loading bin file (default: 0).
|
||||
'''
|
||||
|
||||
offset = 0
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hv",
|
||||
["help", "version", "offset="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
sys.exit(0)
|
||||
elif o in ("--offset"):
|
||||
base = 10
|
||||
if a[:2].lower() == '0x':
|
||||
base = 16
|
||||
try:
|
||||
offset = int(a, base)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad offset value')
|
||||
|
||||
if not args:
|
||||
raise getopt.GetoptError('Input file is not specified')
|
||||
|
||||
if len(args) > 2:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
from intelhex import compat
|
||||
|
||||
fin = args[0]
|
||||
if fin == '-':
|
||||
# read from stdin
|
||||
fin = compat.get_binary_stdin()
|
||||
elif not os.path.isfile(fin):
|
||||
txt = "ERROR: File not found: %s" % fin # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 2:
|
||||
fout = args[1]
|
||||
else:
|
||||
# write to stdout
|
||||
fout = sys.stdout # compat.get_binary_stdout()
|
||||
|
||||
from intelhex import bin2hex
|
||||
sys.exit(bin2hex(fin, fout, offset))
|
||||
311
code/.venv/bin/esp_rfc2217_server.py
Executable file
311
code/.venv/bin/esp_rfc2217_server.py
Executable file
@@ -0,0 +1,311 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# SPDX-FileCopyrightText: 2009-2015 Chris Liechti
|
||||
# SPDX-FileContributor: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# Redirect data from a TCP/IP connection to a serial port and vice versa using RFC 2217.
|
||||
#
|
||||
# This is a modified version of rfc2217_server.py provided by the pyserial package
|
||||
# (pythonhosted.org/pyserial/examples.html#single-port-tcp-ip-serial-bridge-rfc-2217).
|
||||
# It uses a custom PortManager to properly apply the RTS & DTR signals
|
||||
# for reseting ESP chips.
|
||||
#
|
||||
# Run the following command on the server side to make
|
||||
# connection between /dev/ttyUSB1 and TCP port 4000:
|
||||
#
|
||||
# python esp_rfc2217_server.py -p 4000 /dev/ttyUSB1
|
||||
#
|
||||
# Esptool can connect to the ESP device through that server as it is
|
||||
# demonstrated in the following example:
|
||||
#
|
||||
# esptool.py --port rfc2217://localhost:4000?ign_set_control flash_id
|
||||
#
|
||||
###################################################################################
|
||||
# redirect data from a TCP/IP connection to a serial port and vice versa
|
||||
# using RFC 2217
|
||||
#
|
||||
# (C) 2009-2015 Chris Liechti <cliechti@gmx.net>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
from esptool.config import load_config_file
|
||||
from esptool.reset import (
|
||||
ClassicReset,
|
||||
CustomReset,
|
||||
DEFAULT_RESET_DELAY,
|
||||
HardReset,
|
||||
UnixTightReset,
|
||||
)
|
||||
|
||||
import serial
|
||||
import serial.rfc2217
|
||||
from serial.rfc2217 import (
|
||||
COM_PORT_OPTION,
|
||||
SET_CONTROL,
|
||||
SET_CONTROL_DTR_OFF,
|
||||
SET_CONTROL_DTR_ON,
|
||||
SET_CONTROL_RTS_OFF,
|
||||
SET_CONTROL_RTS_ON,
|
||||
)
|
||||
|
||||
cfg, _ = load_config_file(verbose=True)
|
||||
cfg = cfg["esptool"]
|
||||
|
||||
|
||||
class EspPortManager(serial.rfc2217.PortManager):
|
||||
"""
|
||||
The beginning of the reset sequence is detected and the proper reset sequence
|
||||
is applied in a thread. The rest of the reset sequence received is just ignored
|
||||
and not sent to the serial port.
|
||||
"""
|
||||
|
||||
def __init__(self, serial_port, connection, esp32r0_delay, logger=None):
|
||||
self.esp32r0_delay = esp32r0_delay
|
||||
self.is_download_mode = False
|
||||
super(EspPortManager, self).__init__(serial_port, connection, logger)
|
||||
|
||||
def _telnet_process_subnegotiation(self, suboption):
|
||||
if suboption[0:1] == COM_PORT_OPTION and suboption[1:2] == SET_CONTROL:
|
||||
if suboption[2:3] == SET_CONTROL_DTR_OFF:
|
||||
self.is_download_mode = False
|
||||
self.serial.dtr = False
|
||||
return
|
||||
elif suboption[2:3] == SET_CONTROL_RTS_OFF and not self.is_download_mode:
|
||||
reset_thread = threading.Thread(target=self._hard_reset_thread)
|
||||
reset_thread.daemon = True
|
||||
reset_thread.name = "hard_reset_thread"
|
||||
reset_thread.start()
|
||||
return
|
||||
elif suboption[2:3] == SET_CONTROL_DTR_ON and not self.is_download_mode:
|
||||
self.is_download_mode = True
|
||||
reset_thread = threading.Thread(target=self._reset_thread)
|
||||
reset_thread.daemon = True
|
||||
reset_thread.name = "reset_thread"
|
||||
reset_thread.start()
|
||||
return
|
||||
elif suboption[2:3] in [
|
||||
SET_CONTROL_DTR_ON,
|
||||
SET_CONTROL_RTS_ON,
|
||||
SET_CONTROL_RTS_OFF,
|
||||
]:
|
||||
return
|
||||
# only in cases not handled above do the original implementation in PortManager
|
||||
super(EspPortManager, self)._telnet_process_subnegotiation(suboption)
|
||||
|
||||
def _hard_reset_thread(self):
|
||||
"""
|
||||
The reset logic used for hard resetting the chip.
|
||||
"""
|
||||
if self.logger:
|
||||
self.logger.info("Activating hard reset in thread")
|
||||
HardReset(self.serial)()
|
||||
|
||||
def _reset_thread(self):
|
||||
"""
|
||||
The reset logic is used from esptool.py because the RTS and DTR signals
|
||||
cannot be retransmitted through RFC 2217 with proper timing.
|
||||
"""
|
||||
if self.logger:
|
||||
self.logger.info("Activating reset in thread")
|
||||
|
||||
delay = DEFAULT_RESET_DELAY
|
||||
if self.esp32r0_delay:
|
||||
delay += 0.5
|
||||
|
||||
cfg_custom_reset_sequence = cfg.get("custom_reset_sequence")
|
||||
if cfg_custom_reset_sequence is not None:
|
||||
CustomReset(self.serial, cfg_custom_reset_sequence)()
|
||||
elif os.name != "nt":
|
||||
UnixTightReset(self.serial, delay)()
|
||||
else:
|
||||
ClassicReset(self.serial, delay)()
|
||||
|
||||
|
||||
class Redirector(object):
|
||||
def __init__(self, serial_instance, socket, debug=False, esp32r0delay=False):
|
||||
self.serial = serial_instance
|
||||
self.socket = socket
|
||||
self._write_lock = threading.Lock()
|
||||
self.rfc2217 = EspPortManager(
|
||||
self.serial,
|
||||
self,
|
||||
esp32r0delay,
|
||||
logger=logging.getLogger("rfc2217.server") if debug else None,
|
||||
)
|
||||
self.log = logging.getLogger("redirector")
|
||||
|
||||
def statusline_poller(self):
|
||||
self.log.debug("status line poll thread started")
|
||||
while self.alive:
|
||||
time.sleep(1)
|
||||
self.rfc2217.check_modem_lines()
|
||||
self.log.debug("status line poll thread terminated")
|
||||
|
||||
def shortcircuit(self):
|
||||
"""connect the serial port to the TCP port by copying everything
|
||||
from one side to the other"""
|
||||
self.alive = True
|
||||
self.thread_read = threading.Thread(target=self.reader)
|
||||
self.thread_read.daemon = True
|
||||
self.thread_read.name = "serial->socket"
|
||||
self.thread_read.start()
|
||||
self.thread_poll = threading.Thread(target=self.statusline_poller)
|
||||
self.thread_poll.daemon = True
|
||||
self.thread_poll.name = "status line poll"
|
||||
self.thread_poll.start()
|
||||
self.writer()
|
||||
|
||||
def reader(self):
|
||||
"""loop forever and copy serial->socket"""
|
||||
self.log.debug("reader thread started")
|
||||
while self.alive:
|
||||
try:
|
||||
data = self.serial.read(self.serial.in_waiting or 1)
|
||||
if data:
|
||||
# escape outgoing data when needed (Telnet IAC (0xff) character)
|
||||
self.write(b"".join(self.rfc2217.escape(data)))
|
||||
except socket.error as msg:
|
||||
self.log.error("{}".format(msg))
|
||||
# probably got disconnected
|
||||
break
|
||||
self.alive = False
|
||||
self.log.debug("reader thread terminated")
|
||||
|
||||
def write(self, data):
|
||||
"""thread safe socket write with no data escaping. used to send telnet stuff"""
|
||||
with self._write_lock:
|
||||
self.socket.sendall(data)
|
||||
|
||||
def writer(self):
|
||||
"""loop forever and copy socket->serial"""
|
||||
while self.alive:
|
||||
try:
|
||||
data = self.socket.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
self.serial.write(b"".join(self.rfc2217.filter(data)))
|
||||
except socket.error as msg:
|
||||
self.log.error("{}".format(msg))
|
||||
# probably got disconnected
|
||||
break
|
||||
self.stop()
|
||||
|
||||
def stop(self):
|
||||
"""Stop copying"""
|
||||
self.log.debug("stopping")
|
||||
if self.alive:
|
||||
self.alive = False
|
||||
self.thread_read.join()
|
||||
self.thread_poll.join()
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="RFC 2217 Serial to Network (TCP/IP) redirector.",
|
||||
epilog="NOTE: no security measures are implemented. "
|
||||
"Anyone can remotely connect to this service over the network.\n"
|
||||
"Only one connection at once is supported. "
|
||||
"When the connection is terminated it waits for the next connect.",
|
||||
)
|
||||
|
||||
parser.add_argument("SERIALPORT")
|
||||
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--localport",
|
||||
type=int,
|
||||
help="local TCP port, default: %(default)s",
|
||||
metavar="TCPPORT",
|
||||
default=2217,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
dest="verbosity",
|
||||
action="count",
|
||||
help="print more diagnostic messages (option can be given multiple times)",
|
||||
default=0,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--r0",
|
||||
help="Use delays necessary for ESP32 revision 0 chips",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbosity > 3:
|
||||
args.verbosity = 3
|
||||
level = (logging.WARNING, logging.INFO, logging.DEBUG, logging.NOTSET)[
|
||||
args.verbosity
|
||||
]
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
# logging.getLogger('root').setLevel(logging.INFO)
|
||||
logging.getLogger("rfc2217").setLevel(level)
|
||||
|
||||
# connect to serial port
|
||||
ser = serial.serial_for_url(args.SERIALPORT, do_not_open=True)
|
||||
ser.timeout = 3 # required so that the reader thread can exit
|
||||
# reset control line as no _remote_ "terminal" has been connected yet
|
||||
ser.dtr = False
|
||||
ser.rts = False
|
||||
|
||||
logging.info("RFC 2217 TCP/IP to Serial redirector - type Ctrl-C / BREAK to quit")
|
||||
|
||||
try:
|
||||
ser.open()
|
||||
except serial.SerialException as e:
|
||||
logging.error("Could not open serial port {}: {}".format(ser.name, e))
|
||||
sys.exit(1)
|
||||
|
||||
logging.info("Serving serial port: {}".format(ser.name))
|
||||
settings = ser.get_settings()
|
||||
|
||||
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
srv.bind(("", args.localport))
|
||||
srv.listen(1)
|
||||
logging.info("TCP/IP port: {}".format(args.localport))
|
||||
while True:
|
||||
try:
|
||||
client_socket, addr = srv.accept()
|
||||
logging.info("Connected by {}:{}".format(addr[0], addr[1]))
|
||||
client_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
ser.rts = True
|
||||
ser.dtr = True
|
||||
# enter network <-> serial loop
|
||||
r = Redirector(ser, client_socket, args.verbosity > 0, args.r0)
|
||||
try:
|
||||
r.shortcircuit()
|
||||
finally:
|
||||
logging.info("Disconnected")
|
||||
r.stop()
|
||||
client_socket.close()
|
||||
ser.dtr = False
|
||||
ser.rts = False
|
||||
# Restore port settings (may have been changed by RFC 2217
|
||||
# capable client)
|
||||
ser.apply_settings(settings)
|
||||
except KeyboardInterrupt:
|
||||
sys.stdout.write("\n")
|
||||
break
|
||||
except socket.error as msg:
|
||||
logging.error(str(msg))
|
||||
|
||||
logging.info("--- exit ---")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
37
code/.venv/bin/espefuse.py
Executable file
37
code/.venv/bin/espefuse.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This executable script is a thin wrapper around the main functionality
|
||||
# in the espefuse Python package
|
||||
|
||||
# When updating this script, please also update esptool.py and espsecure.py
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.name != "nt":
|
||||
# Linux/macOS: remove current script directory to avoid importing this file
|
||||
# as a module; we want to import the installed espefuse module instead
|
||||
with contextlib.suppress(ValueError):
|
||||
executable_dir = os.path.dirname(sys.executable)
|
||||
sys.path = [
|
||||
path
|
||||
for path in sys.path
|
||||
if not path.endswith(("/bin", "/sbin")) and path != executable_dir
|
||||
]
|
||||
|
||||
# Linux/macOS: delete imported module entry to force Python to load
|
||||
# the module from scratch; this enables importing espefuse module in
|
||||
# other Python scripts
|
||||
with contextlib.suppress(KeyError):
|
||||
del sys.modules["espefuse"]
|
||||
|
||||
import espefuse
|
||||
|
||||
if __name__ == "__main__":
|
||||
espefuse._main()
|
||||
37
code/.venv/bin/espsecure.py
Executable file
37
code/.venv/bin/espsecure.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This executable script is a thin wrapper around the main functionality
|
||||
# in the espsecure Python package
|
||||
|
||||
# When updating this script, please also update esptool.py and espefuse.py
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.name != "nt":
|
||||
# Linux/macOS: remove current script directory to avoid importing this file
|
||||
# as a module; we want to import the installed espsecure module instead
|
||||
with contextlib.suppress(ValueError):
|
||||
executable_dir = os.path.dirname(sys.executable)
|
||||
sys.path = [
|
||||
path
|
||||
for path in sys.path
|
||||
if not path.endswith(("/bin", "/sbin")) and path != executable_dir
|
||||
]
|
||||
|
||||
# Linux/macOS: delete imported module entry to force Python to load
|
||||
# the module from scratch; this enables importing espsecure module in
|
||||
# other Python scripts
|
||||
with contextlib.suppress(KeyError):
|
||||
del sys.modules["espsecure"]
|
||||
|
||||
import espsecure
|
||||
|
||||
if __name__ == "__main__":
|
||||
espsecure._main()
|
||||
37
code/.venv/bin/esptool.py
Executable file
37
code/.venv/bin/esptool.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This executable script is a thin wrapper around the main functionality
|
||||
# in the esptool Python package
|
||||
|
||||
# When updating this script, please also update espefuse.py and espsecure.py
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.name != "nt":
|
||||
# Linux/macOS: remove current script directory to avoid importing this file
|
||||
# as a module; we want to import the installed esptool module instead
|
||||
with contextlib.suppress(ValueError):
|
||||
executable_dir = os.path.dirname(sys.executable)
|
||||
sys.path = [
|
||||
path
|
||||
for path in sys.path
|
||||
if not path.endswith(("/bin", "/sbin")) and path != executable_dir
|
||||
]
|
||||
|
||||
# Linux/macOS: delete imported module entry to force Python to load
|
||||
# the module from scratch; this enables importing esptool module in
|
||||
# other Python scripts
|
||||
with contextlib.suppress(KeyError):
|
||||
del sys.modules["esptool"]
|
||||
|
||||
import esptool
|
||||
|
||||
if __name__ == "__main__":
|
||||
esptool._main()
|
||||
132
code/.venv/bin/hex2bin.py
Executable file
132
code/.venv/bin/hex2bin.py
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2005-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''Intel HEX file format hex2bin convertor utility.'''
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
usage = '''Hex2Bin convertor utility.
|
||||
Usage:
|
||||
python hex2bin.py [options] INFILE [OUTFILE]
|
||||
|
||||
Arguments:
|
||||
INFILE name of hex file for processing.
|
||||
OUTFILE name of output file. If omitted then output
|
||||
will be writing to stdout.
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-p, --pad=FF pad byte for empty spaces (ascii hex value).
|
||||
-r, --range=START:END specify address range for writing output
|
||||
(ascii hex value).
|
||||
Range can be in form 'START:' or ':END'.
|
||||
-l, --length=NNNN,
|
||||
-s, --size=NNNN size of output (decimal value).
|
||||
'''
|
||||
|
||||
pad = None
|
||||
start = None
|
||||
end = None
|
||||
size = None
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvp:r:l:s:",
|
||||
["help", "version", "pad=", "range=",
|
||||
"length=", "size="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
sys.exit(0)
|
||||
elif o in ("-p", "--pad"):
|
||||
try:
|
||||
pad = int(a, 16) & 0x0FF
|
||||
except:
|
||||
raise getopt.GetoptError('Bad pad value')
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o in ("-l", "--lenght", "-s", "--size"):
|
||||
try:
|
||||
size = int(a, 10)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad size value')
|
||||
|
||||
if start != None and end != None and size != None:
|
||||
raise getopt.GetoptError('Cannot specify START:END and SIZE simultaneously')
|
||||
|
||||
if not args:
|
||||
raise getopt.GetoptError('Hex file is not specified')
|
||||
|
||||
if len(args) > 2:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
fin = args[0]
|
||||
if not os.path.isfile(fin):
|
||||
txt = "ERROR: File not found: %s" % fin # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 2:
|
||||
fout = args[1]
|
||||
else:
|
||||
# write to stdout
|
||||
from intelhex import compat
|
||||
fout = compat.get_binary_stdout()
|
||||
|
||||
from intelhex import hex2bin
|
||||
sys.exit(hex2bin(fin, fout, start, end, size, pad))
|
||||
135
code/.venv/bin/hex2dump.py
Executable file
135
code/.venv/bin/hex2dump.py
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Show content of hex file as hexdump."""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hex2dump: show content of hex file as hexdump.
|
||||
Usage:
|
||||
python hex2dump.py [options] HEXFILE
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-r, --range=START:END specify address range for dumping
|
||||
(ascii hex value).
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--width=N dump N data bytes per line (default: 16).
|
||||
|
||||
Arguments:
|
||||
HEXFILE name of hex file for processing (use '-' to read
|
||||
from stdin)
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
DEFAULT_WIDTH = 16
|
||||
|
||||
def hex2dump(hexfile, start=None, end=None, width=DEFAULT_WIDTH):
|
||||
import intelhex
|
||||
if hexfile == '-':
|
||||
hexfile = sys.stdin
|
||||
try:
|
||||
ih = intelhex.IntelHex(hexfile)
|
||||
except (IOError, intelhex.IntelHexError):
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Error reading file: %s\n' % e)
|
||||
return 1
|
||||
if not (start is None and end is None):
|
||||
ih = ih[slice(start,end)]
|
||||
ih.dump(tofile=sys.stdout, width=width)
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
start = None
|
||||
end = None
|
||||
width = DEFAULT_WIDTH
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvp:r:",
|
||||
["help", "version", "range=", "width="])
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == "--width":
|
||||
try:
|
||||
width = int(a)
|
||||
if width < 1:
|
||||
raise ValueError
|
||||
except:
|
||||
raise getopt.GetoptError('Bad width value (%s)' % a)
|
||||
if not args:
|
||||
raise getopt.GetoptError('Hex file is not specified')
|
||||
if len(args) > 1:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(USAGE)
|
||||
return 2
|
||||
|
||||
try:
|
||||
return hex2dump(args[0], start, end, width)
|
||||
except IOError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
import errno
|
||||
if e.errno not in (0, errno.EPIPE):
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(main())
|
||||
90
code/.venv/bin/hexdiff.py
Executable file
90
code/.venv/bin/hexdiff.py
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2011-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Produce diff for 2 hex files using hex dump as string representation
|
||||
of compared data.
|
||||
"""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hexdiff: diff dumps of 2 hex files.
|
||||
Usage:
|
||||
python hexdiff.py [options] FILE1 FILE2
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(argv, 'hv', ['help', 'version'])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
if len(args) != 2:
|
||||
sys.stderr.write("ERROR: You should specify 2 files to diff.\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
fname1, fname2 = args
|
||||
|
||||
from intelhex import IntelHex, diff_dumps
|
||||
ih1 = IntelHex(fname1)
|
||||
ih2 = IntelHex(fname2)
|
||||
diff_dumps(ih1, ih2, name1=fname1, name2=fname2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
108
code/.venv/bin/hexinfo.py
Executable file
108
code/.venv/bin/hexinfo.py
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2015 Andrew Fernandes <andrew@fernandes.org>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Summarize the information in a hex file by printing the execution
|
||||
start address (if any), and the address ranges covered by the
|
||||
data (if any), in YAML format.
|
||||
"""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hexinfo: summarize a hex file's contents.
|
||||
Usage:
|
||||
python hexinfo.py [options] FILE [ FILE ... ]
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
INDENT = ' '
|
||||
INLIST = '- '
|
||||
|
||||
def summarize_yaml(fname):
|
||||
print("{:s}file: '{:s}'".format(INLIST, fname))
|
||||
from intelhex import IntelHex
|
||||
ih = IntelHex(fname)
|
||||
if ih.start_addr:
|
||||
keys = sorted(ih.start_addr.keys())
|
||||
if keys == ['CS','IP']:
|
||||
entry = ih.start_addr['CS'] * 65536 + ih.start_addr['IP']
|
||||
elif keys == ['EIP']:
|
||||
entry = ih.start_addr['EIP']
|
||||
else:
|
||||
raise RuntimeError("unknown 'IntelHex.start_addr' found")
|
||||
print("{:s}entry: 0x{:08X}".format(INDENT, entry))
|
||||
segments = ih.segments()
|
||||
if segments:
|
||||
print("{:s}data:".format(INDENT))
|
||||
for s in segments:
|
||||
print("{:s}{:s}{{ first: 0x{:08X}, last: 0x{:08X}, length: 0x{:08X} }}".format(INDENT, INLIST, s[0], s[1]-1, s[1]-s[0]))
|
||||
print("")
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(argv, 'hv', ['help', 'version'])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
if len(args) < 1:
|
||||
sys.stderr.write("ERROR: You should specify one or more files to summarize.\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
for fname in args:
|
||||
summarize_yaml(fname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
178
code/.venv/bin/hexmerge.py
Executable file
178
code/.venv/bin/hexmerge.py
Executable file
@@ -0,0 +1,178 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Merge content of several hex files into one file."""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hexmerge: merge content of hex files.
|
||||
Usage:
|
||||
python hexmerge.py [options] FILES...
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-o, --output=FILENAME output file name (emit output to stdout
|
||||
if option is not specified)
|
||||
-r, --range=START:END specify address range for output
|
||||
(ascii hex value). Both values are inclusive.
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--no-start-addr Don't write start addr to output file.
|
||||
--overlap=METHOD What to do when data in files overlapped.
|
||||
Supported variants:
|
||||
* error -- stop and show error message (default)
|
||||
* ignore -- keep data from first file that
|
||||
contains data at overlapped address
|
||||
* replace -- use data from last file that
|
||||
contains data at overlapped address
|
||||
|
||||
Arguments:
|
||||
FILES list of hex files for merging
|
||||
(use '-' to read content from stdin)
|
||||
|
||||
You can specify address range for each file in the form:
|
||||
|
||||
filename:START:END
|
||||
|
||||
See description of range option above.
|
||||
|
||||
You can omit START or END, so supported variants are:
|
||||
|
||||
filename:START: read filename and use data starting from START addr
|
||||
filename::END read filename and use data till END addr
|
||||
|
||||
Use entire file content:
|
||||
|
||||
filename
|
||||
or
|
||||
filename::
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(args=None):
|
||||
import getopt
|
||||
|
||||
output = None
|
||||
start = None
|
||||
end = None
|
||||
write_start_addr = True
|
||||
overlap = 'error'
|
||||
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(args, 'hvo:r:',
|
||||
['help', 'version',
|
||||
'output=', 'range=',
|
||||
'no-start-addr', 'overlap=',
|
||||
])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ('-o', '--output'):
|
||||
output = a
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except (ValueError, IndexError):
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == '--no-start-addr':
|
||||
write_start_addr = False
|
||||
elif o == '--overlap':
|
||||
if a in ('error', 'ignore', 'replace'):
|
||||
overlap = a
|
||||
else:
|
||||
raise getopt.GetoptError('Bad overlap value')
|
||||
|
||||
if len(args) == 0:
|
||||
raise getopt.GetoptError('You should specify file list')
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
import intelhex
|
||||
# TODO: move actual merge code into intelhex package as helper function
|
||||
# and write couple of tests for it.
|
||||
res = intelhex.IntelHex()
|
||||
|
||||
def end_addr_inclusive(addr):
|
||||
if addr is not None:
|
||||
return addr + 1
|
||||
return addr
|
||||
|
||||
for f in args:
|
||||
try:
|
||||
fname, fstart, fend = intelhex._get_file_and_addr_range(f)
|
||||
except intelhex._BadFileNotation:
|
||||
sys.stderr.write('Bad argument: "%s"\n' % f)
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
if fname == '-':
|
||||
fname = sys.stdin
|
||||
ih = intelhex.IntelHex(fname)
|
||||
if (fstart, fend) != (None, None):
|
||||
ih = ih[fstart:end_addr_inclusive(fend)]
|
||||
try:
|
||||
res.merge(ih, overlap)
|
||||
except intelhex.AddressOverlapError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Merging: '+fname+"\n")
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
return 1
|
||||
|
||||
if (start, end) != (None, None):
|
||||
res = res[start:end_addr_inclusive(end)]
|
||||
if output is None:
|
||||
output = sys.stdout
|
||||
res.write_hex_file(output, write_start_addr)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/list_serial_ports
Executable file
8
code/.venv/bin/list_serial_ports
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from utilities.list_serial_ports import lsp
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(lsp())
|
||||
8
code/.venv/bin/pip
Executable file
8
code/.venv/bin/pip
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pip-3.12
Executable file
8
code/.venv/bin/pip-3.12
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pip3
Executable file
8
code/.venv/bin/pip3
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pip3.12
Executable file
8
code/.venv/bin/pip3.12
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pyserial-miniterm
Executable file
8
code/.venv/bin/pyserial-miniterm
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from serial.tools.miniterm import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pyserial-ports
Executable file
8
code/.venv/bin/pyserial-ports
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from serial.tools.list_ports import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
1
code/.venv/bin/python
Symbolic link
1
code/.venv/bin/python
Symbolic link
@@ -0,0 +1 @@
|
||||
/usr/bin/python3.12
|
||||
1
code/.venv/bin/python3
Symbolic link
1
code/.venv/bin/python3
Symbolic link
@@ -0,0 +1 @@
|
||||
python
|
||||
1
code/.venv/bin/python3.12
Symbolic link
1
code/.venv/bin/python3.12
Symbolic link
@@ -0,0 +1 @@
|
||||
python
|
||||
162
code/.venv/bin/webreplcmd
Executable file
162
code/.venv/bin/webreplcmd
Executable file
@@ -0,0 +1,162 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import webrepl
|
||||
|
||||
examples="""webreplcmd --host 192.168.4.1 --password ulx3s ls
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s get src-remote-file.txt dest-local-file.txt
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s put src-local-file.txt dest-remote-file.txt
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s cat main.py
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s cmd 'import os; os.listdir()'
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(description='webrepl - connect to websocket webrepl',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=examples)
|
||||
parser.add_argument('--host', '-i', default=os.environ.get('WEBREPL_HOST', None), help="Host to connect to")
|
||||
parser.add_argument('--port', '-P', type=int, default=os.environ.get('WEBREPL_PORT', 8266), help="Port to connect to")
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help="Verbose information")
|
||||
parser.add_argument('--debug', '-d', action='store_true', help="Enable debugging messages")
|
||||
parser.add_argument('--password', '-p', default=os.environ.get('WEBREPL_PASSWORD', None), help="Use following password to connect")
|
||||
parser.add_argument('--before', '-B', action='append', default=os.environ.get('WEBREPL_BEFORE', None), help="command to execute before")
|
||||
parser.add_argument('--cmd', '-c', action='append', default=os.environ.get('WEBREPL_CMD', None), help="command to execute")
|
||||
parser.add_argument('--after', '-A', action='append', default=os.environ.get('WEBREPL_AFTER', None), help="command to execute after")
|
||||
parser.add_argument('commands', metavar='CMD', type=str, nargs='+',
|
||||
help='commands for repl')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.host:
|
||||
print("You need to specify host")
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
|
||||
password=''
|
||||
if not args.password:
|
||||
print("You need to specify password")
|
||||
try:
|
||||
import getpass
|
||||
password = getpass.getpass()
|
||||
except:
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
else:
|
||||
password = args.password
|
||||
|
||||
if not args.commands or len(args.commands)<1:
|
||||
print("Command is not recognized/given")
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
|
||||
repl=webrepl.Webrepl(**{})
|
||||
|
||||
if args.debug:
|
||||
repl.debug = True
|
||||
|
||||
if args.verbose:
|
||||
repl.verbose = True
|
||||
|
||||
try:
|
||||
repl.connect(args.host, args.port)
|
||||
repl.login(password)
|
||||
except Exception as e:
|
||||
print("Error connecting to host",args.host,"at port",args.port,":",e)
|
||||
sys.exit()
|
||||
|
||||
if not repl.connected:
|
||||
print("Not connected. Check your password!")
|
||||
sys.exit()
|
||||
|
||||
if args.before:
|
||||
for cmd in args.before:
|
||||
print("[i] Issuing command: "+cmd)
|
||||
try:
|
||||
r=repl.send_cmd(cmd)
|
||||
print(r.decode())
|
||||
except Exception as e:
|
||||
print("[e] Error running command:",cmd,":",e)
|
||||
|
||||
cmd = args.commands[0].lower()
|
||||
|
||||
if cmd == "ver" or cmd == "version":
|
||||
if args.verbose:
|
||||
print("[i] Getting version")
|
||||
ver=repl.get_ver()
|
||||
print("[i] Version ",ver[0], ver[1], ver[2])
|
||||
elif cmd == "list" or cmd == "ls":
|
||||
print("[i] Listing")
|
||||
r=repl.sendcmd("import os; os.listdir()")
|
||||
print(r.decode())
|
||||
elif cmd == "get" or cmd == "download":
|
||||
if len(args.commands)<3:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
source=args.commands[1]
|
||||
dest=args.commands[2]
|
||||
if args.verbose:
|
||||
print("[i] Downloading "+source+" to "+dest)
|
||||
repl.get_file(source, dest)
|
||||
elif cmd == "put" or cmd == "upload":
|
||||
if len(args.commands)<3:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
source=args.commands[1]
|
||||
dest=args.commands[2]
|
||||
if args.verbose:
|
||||
print("[i] Uploading "+source+" to "+dest)
|
||||
repl.put_file(source, dest)
|
||||
elif cmd == "del" or cmd == "rm" or cmd == "dele":
|
||||
if len(args.commands)<2:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
filename=args.commands[1]
|
||||
if args.verbose:
|
||||
print("[i] Deleting "+filename)
|
||||
r=repl.sendcmd("import os; os.remove('"+filename+"')")
|
||||
print(r.decode())
|
||||
elif cmd == "print" or cmd == "cat" or cmd == "type":
|
||||
if len(args.commands)<2:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
source=args.commands[1]
|
||||
if args.verbose:
|
||||
print("[i] Content of file",source)
|
||||
r=repl.get_file_content(source)
|
||||
print(r.decode())
|
||||
elif cmd == "command" or cmd == "cmd":
|
||||
if len(args.commands)<2:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
cmd=args.commands[1]
|
||||
if args.verbose:
|
||||
print("[i] Executing "+cmd)
|
||||
r=repl.sendcmd(cmd)
|
||||
print(r.decode())
|
||||
else:
|
||||
sys.stderr.write("Command not recognized\n")
|
||||
|
||||
if args.cmd:
|
||||
for cmd in args.cmd:
|
||||
print("[i] Issuing command: "+cmd)
|
||||
try:
|
||||
r=repl.send_cmd(cmd)
|
||||
print(r.decode())
|
||||
except Exception as e:
|
||||
print("[e] Error running command:",cmd,":",e)
|
||||
|
||||
if args.after:
|
||||
for cmd in args.after:
|
||||
print("[i] Issuing command: "+cmd)
|
||||
try:
|
||||
r=repl.send_cmd(cmd)
|
||||
print(r.decode())
|
||||
except Exception as e:
|
||||
print("[e] Error running command:",cmd,":",e)
|
||||
|
||||
if args.verbose:
|
||||
print("[i] closing REPL/WS")
|
||||
repl.disconnect()
|
||||
|
||||
Reference in New Issue
Block a user