summaryrefslogtreecommitdiff
path: root/.gitlab-ci/bare-metal/serial_buffer.py
diff options
context:
space:
mode:
Diffstat (limited to '.gitlab-ci/bare-metal/serial_buffer.py')
-rwxr-xr-x.gitlab-ci/bare-metal/serial_buffer.py185
1 files changed, 0 insertions, 185 deletions
diff --git a/.gitlab-ci/bare-metal/serial_buffer.py b/.gitlab-ci/bare-metal/serial_buffer.py
deleted file mode 100755
index b21ce6e6ef1..00000000000
--- a/.gitlab-ci/bare-metal/serial_buffer.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright © 2020 Google LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice (including the next
-# paragraph) shall be included in all copies or substantial portions of the
-# Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-import argparse
-from datetime import datetime, timezone
-import queue
-import serial
-import threading
-import time
-
-
-class SerialBuffer:
- def __init__(self, dev, filename, prefix, timeout=None, line_queue=None):
- self.filename = filename
- self.dev = dev
-
- if dev:
- self.f = open(filename, "wb+")
- self.serial = serial.Serial(dev, 115200, timeout=timeout)
- else:
- self.f = open(filename, "rb")
- self.serial = None
-
- self.byte_queue = queue.Queue()
- # allow multiple SerialBuffers to share a line queue so you can merge
- # servo's CPU and EC streams into one thing to watch the boot/test
- # progress on.
- if line_queue:
- self.line_queue = line_queue
- else:
- self.line_queue = queue.Queue()
- self.prefix = prefix
- self.timeout = timeout
- self.sentinel = object()
- self.closing = False
-
- if self.dev:
- self.read_thread = threading.Thread(
- target=self.serial_read_thread_loop, daemon=True)
- else:
- self.read_thread = threading.Thread(
- target=self.serial_file_read_thread_loop, daemon=True)
- self.read_thread.start()
-
- self.lines_thread = threading.Thread(
- target=self.serial_lines_thread_loop, daemon=True)
- self.lines_thread.start()
-
- def close(self):
- self.closing = True
- if self.serial:
- self.serial.cancel_read()
- self.read_thread.join()
- self.lines_thread.join()
- if self.serial:
- self.serial.close()
-
- # Thread that just reads the bytes from the serial device to try to keep from
- # buffer overflowing it. If nothing is received in 1 minute, it finalizes.
- def serial_read_thread_loop(self):
- greet = "Serial thread reading from %s\n" % self.dev
- self.byte_queue.put(greet.encode())
-
- while not self.closing:
- try:
- b = self.serial.read()
- if len(b) == 0:
- break
- self.byte_queue.put(b)
- except Exception as err:
- print(self.prefix + str(err))
- break
- self.byte_queue.put(self.sentinel)
-
- # Thread that just reads the bytes from the file of serial output that some
- # other process is appending to.
- def serial_file_read_thread_loop(self):
- greet = "Serial thread reading from %s\n" % self.filename
- self.byte_queue.put(greet.encode())
-
- while not self.closing:
- line = self.f.readline()
- if line:
- self.byte_queue.put(line)
- else:
- time.sleep(0.1)
- self.byte_queue.put(self.sentinel)
-
- # Thread that processes the stream of bytes to 1) log to stdout, 2) log to
- # file, 3) add to the queue of lines to be read by program logic
-
- def serial_lines_thread_loop(self):
- line = bytearray()
- while True:
- bytes = self.byte_queue.get(block=True)
-
- if bytes == self.sentinel:
- self.read_thread.join()
- self.line_queue.put(self.sentinel)
- break
-
- # Write our data to the output file if we're the ones reading from
- # the serial device
- if self.dev:
- self.f.write(bytes)
- self.f.flush()
-
- for b in bytes:
- line.append(b)
- if b == b'\n'[0]:
- line = line.decode(errors="replace")
-
- time = datetime.now().strftime('%y-%m-%d %H:%M:%S')
- print("{endc}{time} {prefix}{line}".format(
- time=time, prefix=self.prefix, line=line, endc='\033[0m'), flush=True, end='')
-
- self.line_queue.put(line)
- line = bytearray()
-
- def lines(self, timeout=None, phase=None):
- start_time = time.monotonic()
- while True:
- read_timeout = None
- if timeout:
- read_timeout = timeout - (time.monotonic() - start_time)
- if read_timeout <= 0:
- print("read timeout waiting for serial during {}".format(phase))
- self.close()
- break
-
- try:
- line = self.line_queue.get(timeout=read_timeout)
- except queue.Empty:
- print("read timeout waiting for serial during {}".format(phase))
- self.close()
- break
-
- if line == self.sentinel:
- print("End of serial output")
- self.lines_thread.join()
- break
-
- yield line
-
-
-def main():
- parser = argparse.ArgumentParser()
-
- parser.add_argument('--dev', type=str, help='Serial device')
- parser.add_argument('--file', type=str,
- help='Filename for serial output', required=True)
- parser.add_argument('--prefix', type=str,
- help='Prefix for logging serial to stdout', nargs='?')
-
- args = parser.parse_args()
-
- ser = SerialBuffer(args.dev, args.file, args.prefix or "")
- for line in ser.lines():
- # We're just using this as a logger, so eat the produced lines and drop
- # them
- pass
-
-
-if __name__ == '__main__':
- main()