mirror of
				https://github.com/ARM-software/devlib.git
				synced 2025-10-31 05:53:25 +00:00 
			
		
		
		
	trace/serial_trace: Add capability to trace serial traffic
We add a TraceCollector which logs the traffic on a serial port. This can then be used to debug why a board crashes, or to extract extra information from the device whilst it is running a workload.
This commit is contained in:
		
				
					committed by
					
						 setrofim
						setrofim
					
				
			
			
				
	
			
			
			
						parent
						
							c4f6a1a85f
						
					
				
				
					commit
					6abe6067da
				
			| @@ -25,6 +25,7 @@ from devlib.derived.energy import DerivedEnergyMeasurements | |||||||
| from devlib.derived.fps import DerivedGfxInfoStats, DerivedSurfaceFlingerStats | from devlib.derived.fps import DerivedGfxInfoStats, DerivedSurfaceFlingerStats | ||||||
|  |  | ||||||
| from devlib.trace.ftrace import FtraceCollector | from devlib.trace.ftrace import FtraceCollector | ||||||
|  | from devlib.trace.serial_trace import SerialTraceCollector | ||||||
|  |  | ||||||
| from devlib.host import LocalConnection | from devlib.host import LocalConnection | ||||||
| from devlib.utils.android import AdbConnection | from devlib.utils.android import AdbConnection | ||||||
|   | |||||||
							
								
								
									
										75
									
								
								devlib/trace/serial_trace.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								devlib/trace/serial_trace.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | from pexpect.exceptions import TIMEOUT | ||||||
|  | import shutil | ||||||
|  | from tempfile import NamedTemporaryFile | ||||||
|  |  | ||||||
|  | from devlib.trace import TraceCollector | ||||||
|  | from devlib.utils.serial_port import get_connection | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class SerialTraceCollector(TraceCollector): | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def collecting(self): | ||||||
|  |         return self._collecting | ||||||
|  |  | ||||||
|  |     def __init__(self, target, serial_port, baudrate, timeout=20): | ||||||
|  |         super(SerialTraceCollector, self).__init__(target) | ||||||
|  |         self.serial_port = serial_port | ||||||
|  |         self.baudrate = baudrate | ||||||
|  |         self.timeout = timeout | ||||||
|  |  | ||||||
|  |         self._serial_target = None | ||||||
|  |         self._conn = None | ||||||
|  |         self._tmpfile = None | ||||||
|  |         self._collecting = False | ||||||
|  |  | ||||||
|  |     def reset(self): | ||||||
|  |         if self._collecting: | ||||||
|  |             raise RuntimeError("reset was called whilst collecting") | ||||||
|  |  | ||||||
|  |         if self._tmpfile: | ||||||
|  |             self._tmpfile.close() | ||||||
|  |             self._tmpfile = None | ||||||
|  |  | ||||||
|  |     def start(self): | ||||||
|  |         if self._collecting: | ||||||
|  |             raise RuntimeError("start was called whilst collecting") | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         self._tmpfile = NamedTemporaryFile() | ||||||
|  |         self._tmpfile.write("-------- Starting serial logging --------\n") | ||||||
|  |  | ||||||
|  |         self._serial_target, self._conn = get_connection(port=self.serial_port, | ||||||
|  |                                                          baudrate=self.baudrate, | ||||||
|  |                                                          timeout=self.timeout, | ||||||
|  |                                                          logfile=self._tmpfile, | ||||||
|  |                                                          init_dtr=0) | ||||||
|  |         self._collecting = True | ||||||
|  |  | ||||||
|  |     def stop(self): | ||||||
|  |         if not self._collecting: | ||||||
|  |             raise RuntimeError("stop was called whilst not collecting") | ||||||
|  |  | ||||||
|  |         # We expect the below to fail, but we need to get pexpect to | ||||||
|  |         # do something so that it interacts with the serial device, | ||||||
|  |         # and hence updates the logfile. | ||||||
|  |         try: | ||||||
|  |             self._serial_target.expect(".", timeout=1) | ||||||
|  |         except TIMEOUT: | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  |         self._serial_target.close() | ||||||
|  |         del self._conn | ||||||
|  |  | ||||||
|  |         self._tmpfile.write("-------- Stopping serial logging --------\n") | ||||||
|  |  | ||||||
|  |         self._collecting = False | ||||||
|  |  | ||||||
|  |     def get_trace(self, outfile): | ||||||
|  |         if self._collecting: | ||||||
|  |             raise RuntimeError("get_trace was called whilst collecting") | ||||||
|  |  | ||||||
|  |         shutil.copy(self._tmpfile.name, outfile) | ||||||
|  |  | ||||||
|  |         self._tmpfile.close() | ||||||
|  |         self._tmpfile = None | ||||||
| @@ -49,7 +49,7 @@ def pulse_dtr(conn, state=True, duration=0.1): | |||||||
|  |  | ||||||
|  |  | ||||||
| def get_connection(timeout, init_dtr=None, logcls=SerialLogger, | def get_connection(timeout, init_dtr=None, logcls=SerialLogger, | ||||||
|                    *args, **kwargs): |                    logfile=None, *args, **kwargs): | ||||||
|     if init_dtr is not None: |     if init_dtr is not None: | ||||||
|         kwargs['dsrdtr'] = True |         kwargs['dsrdtr'] = True | ||||||
|     try: |     try: | ||||||
| @@ -60,7 +60,7 @@ def get_connection(timeout, init_dtr=None, logcls=SerialLogger, | |||||||
|         conn.setDTR(init_dtr) |         conn.setDTR(init_dtr) | ||||||
|     conn.nonblocking() |     conn.nonblocking() | ||||||
|     conn.flushOutput() |     conn.flushOutput() | ||||||
|     target = fdpexpect.fdspawn(conn.fileno(), timeout=timeout) |     target = fdpexpect.fdspawn(conn.fileno(), timeout=timeout, logfile=logfile) | ||||||
|     target.logfile_read = logcls('read') |     target.logfile_read = logcls('read') | ||||||
|     target.logfile_send = logcls('send') |     target.logfile_send = logcls('send') | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user