From e56b6e4bd75c7ccec69f20b17c1e2d48b7c0892c Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Thu, 29 Sep 2022 11:52:22 +0200 Subject: Ethos-U PMU monitor Add Python script demonstrating how to download performance data from device. Write baremetal PMU events to Event Recorder ring buffer and increase the systick sample rate. Change-Id: Ib73c56100a8de2d7b74c455d8f80cda0b59383da --- scripts/ethosu_monitor.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100755 scripts/ethosu_monitor.py (limited to 'scripts/ethosu_monitor.py') diff --git a/scripts/ethosu_monitor.py b/scripts/ethosu_monitor.py new file mode 100755 index 0000000..60f0bdf --- /dev/null +++ b/scripts/ethosu_monitor.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 + +# +# SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the License); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an AS IS BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from ethosumonitor.inputs import * +from ethosumonitor.outputs import * +from sys import stderr, exit + +def eventLoop(input: InputInterface, output: OutputInterface): + count = 0 + + try: + while(True): + for record in input.readEventRecord(): + output.writeEventRecord(record) + count = count + 1 + except KeyboardInterrupt: + stderr.write(f'count={count}, input={input}\n') + pass + except EOFError: + pass + + output.flush() + +def getDAPLink(args): + return InputDAPLink(args.elf) + +def getMem(args): + return InputMem(args.elf, args.memory_map) + +def getFile(args): + return InputFile(args.file) + +def getOutput(args): + if args.output_format == 'binary': + return OutputBinary(args.output) + else: + return OutputJson(args.output) + +def addOutputArguments(parser): + parser.add_argument('--output-format', choices=['binary', 'json'], default='json', help='Output format.') + parser.add_argument('-o', '--output', default='/dev/stdout', help='Output file.') + +def main(): + import argparse + + parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, + description='Ethos-U monitor downloading profiling data.', + epilog=''' +Event Recorder: + The Event Recorder library is used to write performance data to a ring buffer + in memory. The ring buffer has a limited size and must be continuously + streamed to a host machine before it overflows. + + This script demonstrates how to stream performance data using DAPLink or + /dev/mem. Support for other technologies can be added implementing the + InputInterface class in inputs.py. +''') + subparsers = parser.add_subparsers() + + subparser = subparsers.add_parser('daplink', + formatter_class=argparse.RawDescriptionHelpFormatter, + description='Download performance data using DAPLink.', + epilog=''' +DAPLink: + Arm Mbed DAPLink is an open source project that enables programming and + debugging application software running on an Arm Cortex CPU. A host machine + can connect to the target device using for example USB or JTAG. + + This script demonstrates how DAPLink can be used to stream Event Recorder + data from a target device. The ELF file passed to the script must be the + same application that is running on the device, and is used to find the + location of the Event Recorder ring buffer. + + $ ethosu_monitor.py daplink --target mps3_an540 myapplication.elf +''') + subparser.set_defaults(getInput=getDAPLink) + subparser.add_argument('--target', default='mps3_an540', help='DAPLink target platform.') + subparser.add_argument('elf', help='Elf file running on the target.') + addOutputArguments(subparser) + + subparser = subparsers.add_parser('memory', + formatter_class=argparse.RawDescriptionHelpFormatter, + description='Download performance data using /dev/mem.', + epilog=''' +/dev/mem: + For a Linux based system the Event Recorder buffer should be stored in shared + memory accessible from Linux. This allows Linux to read device the Event + Recorder ring buffer using /dev/mem. + + The address of the Event Recorder ring buffer is found parsing the ELF + file. Because the device and Linux do not share the same address space a + memory map is required to translate device addresses into host addresses. + Please see sample.json for reference. + + $ ethosu_monitor.py memory --memory-map config.json myapplication.elf +''') + subparser.set_defaults(getInput=getMem) + subparser.add_argument('--memory-map', required=True, help='JSON file describing physical memory map of target.') + subparser.add_argument('elf', help='Elf file running on the target.') + addOutputArguments(subparser) + + subparser = subparsers.add_parser('file', + formatter_class=argparse.RawDescriptionHelpFormatter, + description='Replay performance data stored in binary file.', + epilog=''' +file: + Event Recorder data can be written in binary format for later processing. + This will likely have less latency than the default JSON format, reducing + the risk over ring buffer overflows. + + $ ethosu_monitor.py daplink --output-format binary --output samples.bin myapplication.elf + + The binary data can later be unpacked to JSON. + + $ ethosu_monitor.py file samples.bin --output-format json +''') + subparser.set_defaults(getInput=getFile) + subparser.add_argument('file', help='Binary file containing recorded performance data.') + addOutputArguments(subparser) + + args = parser.parse_args() + + if 'getInput' not in args: + parser.print_help() + exit(2) + + input = args.getInput(args) + output = getOutput(args) + eventLoop(input, output) + +if __name__ == '__main__': + main() -- cgit v1.2.1