Add Code
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Executable
+115
@@ -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))
|
||||
Executable
+311
@@ -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()
|
||||
Executable
+37
@@ -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()
|
||||
Executable
+37
@@ -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()
|
||||
Executable
+37
@@ -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()
|
||||
Executable
+132
@@ -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))
|
||||
Executable
+135
@@ -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())
|
||||
Executable
+90
@@ -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())
|
||||
Executable
+108
@@ -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())
|
||||
Executable
+178
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Executable
+8
@@ -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())
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
/usr/bin/python3.12
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
python
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
python
|
||||
Executable
+162
@@ -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