# # 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, args.target, args.reset) 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('-r', '--reset', action='store_true', help='Reset target.') 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)