blob: 60f0bdf68e82228d27e1115b923ac975c5a0febb [file] [log] [blame]
Kristofer Jonssone56b6e42022-09-29 11:52:22 +02001#!/usr/bin/env python3
2
3#
4# SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
5#
6# SPDX-License-Identifier: Apache-2.0
7#
8# Licensed under the Apache License, Version 2.0 (the License); you may
9# not use this file except in compliance with the License.
10# You may obtain a copy of the License at
11#
12# www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing, software
15# distributed under the License is distributed on an AS IS BASIS, WITHOUT
16# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17# See the License for the specific language governing permissions and
18# limitations under the License.
19#
20
21from ethosumonitor.inputs import *
22from ethosumonitor.outputs import *
23from sys import stderr, exit
24
25def eventLoop(input: InputInterface, output: OutputInterface):
26 count = 0
27
28 try:
29 while(True):
30 for record in input.readEventRecord():
31 output.writeEventRecord(record)
32 count = count + 1
33 except KeyboardInterrupt:
34 stderr.write(f'count={count}, input={input}\n')
35 pass
36 except EOFError:
37 pass
38
39 output.flush()
40
41def getDAPLink(args):
42 return InputDAPLink(args.elf)
43
44def getMem(args):
45 return InputMem(args.elf, args.memory_map)
46
47def getFile(args):
48 return InputFile(args.file)
49
50def getOutput(args):
51 if args.output_format == 'binary':
52 return OutputBinary(args.output)
53 else:
54 return OutputJson(args.output)
55
56def addOutputArguments(parser):
57 parser.add_argument('--output-format', choices=['binary', 'json'], default='json', help='Output format.')
58 parser.add_argument('-o', '--output', default='/dev/stdout', help='Output file.')
59
60def main():
61 import argparse
62
63 parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
64 description='Ethos-U monitor downloading profiling data.',
65 epilog='''
66Event Recorder:
67 The Event Recorder library is used to write performance data to a ring buffer
68 in memory. The ring buffer has a limited size and must be continuously
69 streamed to a host machine before it overflows.
70
71 This script demonstrates how to stream performance data using DAPLink or
72 /dev/mem. Support for other technologies can be added implementing the
73 InputInterface class in inputs.py.
74''')
75 subparsers = parser.add_subparsers()
76
77 subparser = subparsers.add_parser('daplink',
78 formatter_class=argparse.RawDescriptionHelpFormatter,
79 description='Download performance data using DAPLink.',
80 epilog='''
81DAPLink:
82 Arm Mbed DAPLink is an open source project that enables programming and
83 debugging application software running on an Arm Cortex CPU. A host machine
84 can connect to the target device using for example USB or JTAG.
85
86 This script demonstrates how DAPLink can be used to stream Event Recorder
87 data from a target device. The ELF file passed to the script must be the
88 same application that is running on the device, and is used to find the
89 location of the Event Recorder ring buffer.
90
91 $ ethosu_monitor.py daplink --target mps3_an540 myapplication.elf
92''')
93 subparser.set_defaults(getInput=getDAPLink)
94 subparser.add_argument('--target', default='mps3_an540', help='DAPLink target platform.')
95 subparser.add_argument('elf', help='Elf file running on the target.')
96 addOutputArguments(subparser)
97
98 subparser = subparsers.add_parser('memory',
99 formatter_class=argparse.RawDescriptionHelpFormatter,
100 description='Download performance data using /dev/mem.',
101 epilog='''
102/dev/mem:
103 For a Linux based system the Event Recorder buffer should be stored in shared
104 memory accessible from Linux. This allows Linux to read device the Event
105 Recorder ring buffer using /dev/mem.
106
107 The address of the Event Recorder ring buffer is found parsing the ELF
108 file. Because the device and Linux do not share the same address space a
109 memory map is required to translate device addresses into host addresses.
110 Please see sample.json for reference.
111
112 $ ethosu_monitor.py memory --memory-map config.json myapplication.elf
113''')
114 subparser.set_defaults(getInput=getMem)
115 subparser.add_argument('--memory-map', required=True, help='JSON file describing physical memory map of target.')
116 subparser.add_argument('elf', help='Elf file running on the target.')
117 addOutputArguments(subparser)
118
119 subparser = subparsers.add_parser('file',
120 formatter_class=argparse.RawDescriptionHelpFormatter,
121 description='Replay performance data stored in binary file.',
122 epilog='''
123file:
124 Event Recorder data can be written in binary format for later processing.
125 This will likely have less latency than the default JSON format, reducing
126 the risk over ring buffer overflows.
127
128 $ ethosu_monitor.py daplink --output-format binary --output samples.bin myapplication.elf
129
130 The binary data can later be unpacked to JSON.
131
132 $ ethosu_monitor.py file samples.bin --output-format json
133''')
134 subparser.set_defaults(getInput=getFile)
135 subparser.add_argument('file', help='Binary file containing recorded performance data.')
136 addOutputArguments(subparser)
137
138 args = parser.parse_args()
139
140 if 'getInput' not in args:
141 parser.print_help()
142 exit(2)
143
144 input = args.getInput(args)
145 output = getOutput(args)
146 eventLoop(input, output)
147
148if __name__ == '__main__':
149 main()