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