-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathterminal.py
134 lines (107 loc) · 4.14 KB
/
terminal.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#
# Copyright (c) 2020-2021 Arm Limited and Contributors. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
"""Serial terminal implementation based on pyserial.tools.miniterm.
The Mbed serial terminal makes the following modifications to the default Miniterm.
* Custom help menu text
* Constrained set of menu keys
* CTRL-H to show help
* CTRL-B sends serial break to the target
To start the terminal clients should call the "run" function, this is the entry point to the module.
"""
from typing import Any
from serial import Serial
from serial.tools.miniterm import Miniterm
def run(port: str, baud: int, echo: bool = True) -> None:
"""Run the serial terminal.
This function is blocking as it waits for the terminal thread to finish executing before returning.
Args:
port: The serial port to open a terminal on.
baud: Serial baud rate.
echo: Echo user input back to the console.
"""
term = SerialTerminal(Serial(port=port, baudrate=str(baud)), echo=echo)
term.start()
try:
term.join(True)
except KeyboardInterrupt:
pass
finally:
term.join()
term.close()
class SerialTerminal(Miniterm):
"""An implementation of Miniterm that implements the additional Mbed terminal functionality.
Overrides the `writer` method to implement modified menu key handling behaviour.
Overrides the Miniterm::get_help_text method to return the Mbed custom help text.
Adds a `reset` method so users can send a reset signal to the device.
"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Set the rx/tx encoding and special characters."""
super().__init__(*args, **kwargs)
self.exit_character = CTRL_C
self.menu_character = CTRL_T
self.reset_character = CTRL_B
self.help_character = CTRL_H
self.set_rx_encoding("UTF-8")
self.set_tx_encoding("UTF-8")
def reset(self) -> None:
"""Send a reset signal."""
self.serial.sendBreak()
def get_help_text(self) -> str:
"""Return the text displayed when the user requests help."""
return HELP_TEXT
def writer(self) -> None:
"""Implements terminal behaviour."""
menu_active = False
while self.alive:
try:
input_key = self.console.getkey()
except KeyboardInterrupt:
input_key = self.exit_character
if (menu_active and input_key in VALID_MENU_KEYS) or (input_key == self.help_character):
self.handle_menu_key(input_key)
menu_active = False
elif input_key == self.menu_character:
menu_active = True
elif input_key == self.reset_character:
self.reset()
elif input_key == self.exit_character:
self.stop()
break
else:
self._write_transformed_char(input_key)
if self.echo:
self._echo_transformed_char(input_key)
def _write_transformed_char(self, text: str) -> None:
for transformation in self.tx_transformations:
text = transformation.tx(text)
self.serial.write(self.tx_encoder.encode(text))
def _echo_transformed_char(self, text: str) -> None:
for transformation in self.tx_transformations:
text = transformation.echo(text)
self.console.write(text)
CTRL_B = "\x02"
CTRL_C = "\x03"
CTRL_H = "\x08"
CTRL_T = "\x14"
VALID_MENU_KEYS = ("p", "b", "\t", "\x01", "\x04", "\x05", "\x06", "\x0c", CTRL_C, CTRL_T)
HELP_TEXT = """--- Mbed Serial Terminal
--- Based on miniterm from pySerial
---
--- Ctrl+b Send Break (reset target)
--- Ctrl+c Exit terminal
--- Ctrl+h Help
--- Ctrl+t Menu escape key, followed by:
--- p Change COM port
--- b Change baudrate
--- Tab Show detailed terminal info
--- Ctrl+a Change encoding (default UTF-8)
--- Ctrl+f Edit filters
--- Ctrl+e Toggle local echo
--- Ctrl+l Toggle EOL
--- Ctrl+r Toggle RTS
--- Ctrl+d Toggle DTR
--- Ctrl+c Send control character to remote
--- Ctrl+t Send control character to remote
"""