Skip to content

Commit f6c29a7

Browse files
committed
Add initial support for PySerial Miniterm
1 parent 99e6dc1 commit f6c29a7

File tree

1 file changed

+115
-11
lines changed

1 file changed

+115
-11
lines changed

mbed/mbed.py

Lines changed: 115 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,103 @@ def formaturl(url, format="default"):
17521752
return url
17531753

17541754

1755+
def cdc(port, reset=False, sterm=False, baudrate=9600, timeout=10):
1756+
from serial import Serial, SerialException
1757+
1758+
def get_instance(*args, **kwargs):
1759+
try:
1760+
serial_port = Serial(*args, **kwargs)
1761+
serial_port.flush()
1762+
except Exception as e:
1763+
error("Unable to open serial port connection to \"%s\"" % port)
1764+
return False
1765+
return serial_port
1766+
1767+
def cdc_reset(serial_instance):
1768+
try:
1769+
serial_instance.sendBreak()
1770+
except:
1771+
try:
1772+
serial_instance.setBreak(False) # For Linux the following setBreak() is needed to release the reset signal on the target mcu.
1773+
except:
1774+
result = False
1775+
1776+
def cdc_term(serial_instance):
1777+
import serial.tools.miniterm as miniterm
1778+
1779+
term = miniterm.Miniterm(serial_instance, echo=True)
1780+
term.exit_character = '\x03'
1781+
term.menu_character = '\x14'
1782+
term.set_rx_encoding('UTF-8')
1783+
term.set_tx_encoding('UTF-8')
1784+
def cli_writer():
1785+
menu_active = False
1786+
while term.alive:
1787+
try:
1788+
c = term.console.getkey()
1789+
except KeyboardInterrupt:
1790+
c = '\x03'
1791+
if not term.alive:
1792+
break
1793+
if menu_active:
1794+
term.handle_menu_key(c)
1795+
menu_active = False
1796+
elif c == term.menu_character:
1797+
menu_active = True # next char will be for menu
1798+
elif c == '\x02' or c == '\x12': # ctrl+b/ctrl+r sendbreak
1799+
cdc_reset(term.serial)
1800+
elif c == '\x03' or c == '\x1d': # ctrl+c/ctrl+]
1801+
term.stop()
1802+
term.alive = False
1803+
break
1804+
elif c == '\x05': # ctrl+e
1805+
term.echo = not term.echo
1806+
elif c == '\x08': # ctrl+e
1807+
print term.get_help_text()
1808+
elif c == '\t': # tab/ctrl+i
1809+
term.dump_port_settings()
1810+
else:
1811+
text = c
1812+
for transformation in term.tx_transformations:
1813+
text = transformation.tx(text)
1814+
term.serial.write(term.tx_encoder.encode(text))
1815+
if term.echo:
1816+
echo_text = c
1817+
for transformation in term.tx_transformations:
1818+
echo_text = transformation.echo(echo_text)
1819+
term.console.write(echo_text)
1820+
term.writer = cli_writer
1821+
action('--- Terminal on {p.name} - {p.baudrate},{p.bytesize},{p.parity},{p.stopbits} ---\n'.format(p=term.serial))
1822+
action('--- Quit: CTRL+C | Reset: CTRL+B | Echo: CTRL+E ---')
1823+
action('--- Info: TAB | Help: Ctrl+H | Menu: Ctrl+T ---')
1824+
term.start()
1825+
try:
1826+
term.join(True)
1827+
except KeyboardInterrupt:
1828+
pass
1829+
term.join()
1830+
term.close()
1831+
1832+
result = False
1833+
serial_port = get_instance(port, baudrate=baudrate, timeout=timeout)
1834+
if serial_port:
1835+
serial_port.reset_input_buffer()
1836+
if reset:
1837+
cdc_reset(serial_port)
1838+
result = True
1839+
1840+
if sterm:
1841+
if not serial_port.is_open:
1842+
serial_port = get_instance(port, baudrate=baudrate, timeout=timeout)
1843+
try:
1844+
cdc_term(serial_port)
1845+
result = True
1846+
except:
1847+
pass
1848+
1849+
return result
1850+
1851+
17551852
# Subparser handling
17561853
parser = argparse.ArgumentParser(prog='mbed',
17571854
description="Command-line code management tool for ARM mbed OS - http://www.mbed.com\nversion %s\n\nUse 'mbed <command> -h|--help' for detailed help.\nOnline manual and guide available at https://github.com/ARMmbed/mbed-cli" % ver,
@@ -2366,12 +2463,13 @@ def status_(ignore=False):
23662463
dict(name='--build', help='Build directory. Default: build/'),
23672464
dict(name=['-c', '--clean'], action='store_true', help='Clean the build directory before compiling'),
23682465
dict(name=['-f', '--flash'], action='store_true', help='Flash the built firmware onto a connected target.'),
2466+
dict(name=['-s', '--sterm'], action='store_true', help='Open serial terminal after compiling. Can be chained with --flash'),
23692467
dict(name=['-N', '--artifact-name'], help='Name of the built program or library'),
23702468
dict(name=['-S', '--supported'], dest='supported', const=True, choices=["matrix", "toolchains", "targets"], nargs="?", help='Shows supported matrix of targets and toolchains'),
23712469
dict(name='--app-config', dest="app_config", help="Path of an app configuration file (Default is to look for 'mbed_app.json')"),
23722470
help='Compile code using the mbed build tools',
23732471
description="Compile this program using the mbed build tools.")
2374-
def compile_(toolchain=None, target=None, profile=False, compile_library=False, compile_config=False, config_prefix=None, source=False, build=False, clean=False, flash=False, artifact_name=None, supported=False, app_config=None):
2472+
def compile_(toolchain=None, target=None, profile=False, compile_library=False, compile_config=False, config_prefix=None, source=False, build=False, clean=False, flash=False, sterm=False, artifact_name=None, supported=False, app_config=None):
23752473
# Gather remaining arguments
23762474
args = remainder
23772475
# Find the root of the program
@@ -2451,23 +2549,24 @@ def compile_(toolchain=None, target=None, profile=False, compile_library=False,
24512549
+ args,
24522550
env=env)
24532551

2552+
if flash or sterm:
2553+
detected = program.detect_target()
2554+
try:
2555+
from mbed_host_tests.host_tests_toolbox import flash_dev
2556+
except (IOError, ImportError, OSError):
2557+
error("The '-f/--flash' option requires that the 'mbed-greentea' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-greentea'.", 1)
2558+
24542559
if flash:
24552560
fw_name = artifact_name if artifact_name else program.name
24562561
fw_fbase = os.path.join(build_path, fw_name)
24572562
fw_file = fw_fbase + ('.hex' if os.path.exists(fw_fbase+'.hex') else '.bin')
24582563
if not os.path.exists(fw_file):
24592564
error("Build program file (firmware) not found \"%s\"" % fw_file, 1)
2460-
detected = program.detect_target()
2461-
2462-
try:
2463-
from mbed_host_tests.host_tests_toolbox import flash_dev, reset_dev
2464-
except (IOError, ImportError, OSError):
2465-
error("The '-f/--flash' option requires that the 'mbed-greentea' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-greentea'.", 1)
2466-
24672565
if not flash_dev(detected['msd'], fw_file, program_cycle_s=2):
24682566
error("Unable to flash the target board connected to your system.", 1)
24692567

2470-
if not reset_dev(detected['port']):
2568+
if flash or sterm:
2569+
if not cdc(detected['port'], reset=flash, sterm=sterm):
24712570
error("Unable to reset the target board connected to your system.\nThis might be caused by an old interface firmware.\nPlease check the board page for new firmware.", 1)
24722571

24732572
program.set_defaults(target=target, toolchain=tchain)
@@ -2633,12 +2732,14 @@ def export(ide=None, target=None, source=False, clean=False, supported=False, ap
26332732

26342733
# Test command
26352734
@subcommand('detect',
2735+
dict(name=['-r', '--reset'], dest='reset', action='store_true', help='Reset detected targets (via SendBreak)'),
2736+
dict(name=['-s', '--sterm'], dest='sterm', action='store_true', help='Open serial terminal for detected targets'),
26362737
hidden_aliases=['det'],
26372738
help='Detect connected mbed targets/boards\n\n',
26382739
description=(
26392740
"Detects mbed targets/boards connected to this system and shows supported\n"
26402741
"toolchain matrix."))
2641-
def detect():
2742+
def detect(reset=False, sterm=False):
26422743
# Gather remaining arguments
26432744
args = remainder
26442745
# Find the root of the program
@@ -2661,7 +2762,7 @@ def detect():
26612762
if very_verbose:
26622763
error(str(e))
26632764
else:
2664-
warning("The mbed tools were not found in \"%s\". \nLimited information will be shown about connected mbed targets/boards" % program.path)
2765+
warning("The mbed OS tools were not found in \"%s\". \nLimited information will be shown about connected mbed targets/boards" % program.path)
26652766
targets = program.get_detected_targets()
26662767
if targets:
26672768
unknown_found = False
@@ -2671,10 +2772,13 @@ def detect():
26712772
action("Detected unknown target connected to \"%s\" and using com port \"%s\"" % (target['mount'], target['serial']))
26722773
else:
26732774
action("Detected \"%s\" connected to \"%s\" and using com port \"%s\"" % (target['name'], target['mount'], target['serial']))
2775+
cdc(target['serial'], reset=reset, sterm=sterm)
26742776

26752777
if unknown_found:
26762778
warning("If you're developing a new target, you can mock the device to continue your development. "
26772779
"Use 'mbedls --mock ID:NAME' to do so (see 'mbedls --help' for more information)")
2780+
else:
2781+
error("This command requires that the 'mbed-greentea' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-greentea'.", 1)
26782782

26792783

26802784
# Generic config command

0 commit comments

Comments
 (0)