############################################################################ # tools/pynuttx/rpmsg.py # # SPDX-License-Identifier: Apache-2.0 # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. The # ASF licenses this file to you 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 # # http://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. # ############################################################################ import gdb from . import utils from .lists import NxList class RPMsgDump(gdb.Command): """Dump rpmsg service""" CALLBACK_HEADER = ["rpmsg_cb_s at", "ns_match", "ns_bind"] ENDPOINT_HEADER = [ "endpoint_addr", "name", "addr", "dest_addr", "cb", "ns_bound_cb", "ns_unbind_cb", ] CALLBACK_FORAMTTER = "{:<20} {:<40} {:<40}" ENDPOINT_FORMATTER = "{:<20} {:<20} {:<12} {:<12} {:<40} {:<40} {:<40}" def __init__(self): if utils.get_symbol_value("CONFIG_RPMSG"): super(RPMsgDump, self).__init__("rpmsgdump", gdb.COMMAND_USER) def print_headers(self, headers, formatter): gdb.write(formatter.format(*headers) + "\n") gdb.write(formatter.format(*["-" * len(header) for header in headers]) + "\n") def dump_rdev_epts(self, endpoints_head): gdb.write(f"dump_rdev_epts:{endpoints_head}\n") self.print_headers(self.ENDPOINT_HEADER, self.ENDPOINT_FORMATTER) output = [] for endpoint in NxList(endpoints_head, "struct rpmsg_endpoint", "node"): output.append( self.ENDPOINT_FORMATTER.format( f"{endpoint}", f"{endpoint['name'].string()}", f"{endpoint['addr']}", f"{endpoint['dest_addr']}", f"{endpoint['cb']}", f"{endpoint['ns_bound_cb']}", f"{endpoint['ns_unbind_cb']}", ) ) gdb.write("\n".join(output) + "\n") def dump_rdev_bitmap(self, rdev): bitmap_values = [hex(bit) for bit in utils.ArrayIterator(rdev["bitmap"])] gdb.write( f"bitmap:{' '.join(bitmap_values):<20} bitmaplast: {rdev['bitmap']}\n" ) def dump_rdev(self, rdev): gdb.write(f"device:{rdev}\n") self.dump_rdev_bitmap(rdev) self.dump_rdev_epts(rdev["endpoints"]) def dump_rpmsg_cb(self): gdb.write("g_rpmsg_cb:\n") self.print_headers(self.CALLBACK_HEADER, self.CALLBACK_FORAMTTER) output = [] for cb in NxList(gdb.parse_and_eval("g_rpmsg_cb"), "struct rpmsg_cb_s", "node"): output.append( self.CALLBACK_FORAMTTER.format( str(cb), str(cb["ns_match"]), str(cb["ns_bind"]) ) ) gdb.write("\n".join(output) + "\n") def dump_rpmsg(self): gdb.write("g_rpmsg:\n") for rpmsg in NxList(gdb.parse_and_eval("g_rpmsg"), "struct rpmsg_s", "node"): self.dump_rdev(rpmsg["rdev"]) def invoke(self, args, from_tty): self.dump_rpmsg_cb() self.dump_rpmsg()