14.6 Implementing data views

Along with threads, OS awareness can provide arbitrary tabular data, which the debugger shows in the RTOS Data view.

The corresponding callback on the API is getDataModel(). It must return an instance of the Java interface com.arm.debug.extension.datamodel.IDataModel, which sources can be found in com.arm.debug.extension.source_<version>.jar.
This section demonstrates how to implement a view, listing the tasks, including all available information. The following additions to the implementation creates an empty Tasks table in the RTOS Data view:
<some folder>
    /mydb
        /OS
            /myos
                /extension.xml
                /messages.properties
                /provider.py
                /contexts.py
                /tasks.py
  • provider.py
    # this script implements the Java interface IOSProvider
    from osapi import DebugSessionException
    from osapi import Model
    from contexts import ContextsProvider
    from tasks import Tasks
    
    def areOSSymbolsLoaded(debugger):
            […]
    
    def isOSInitialised(debugger):
            […]
    
    def getOSContextProvider():
            […]
    
    def getDataModel():
        # returns an instance of the Java interface IDataModel
        return Model("myos", [Tasks()])
  • messages.properties
    myos.title=My OS
    myos.desc=This is My OS.
    myos.help=Displays information about My OS.
    
    tasks.title=Tasks
    tasks.desc=This table shows all tasks, including uninitialized ones
    tasks.help=Displays tasks defined within the OS and their current status.
    
    tasks.id.title=Task
    tasks.id.desc=The task identifier
    tasks.name.title=Name
    tasks.name.desc=The task name
    tasks.status.title=Status
    tasks.status.desc=The task status
    tasks.priority.title=Priority
    tasks.priority.desc=The task priority
    tasks.sp.title=Stack pointer
    tasks.sp.desc=This task's stack address
  • tasks.py
    from osapi import Table
    from osapi import createField
    from osapi import DECIMAL, TEXT, ADDRESS
    
    # this class implements the Java interface IDataModelTable
    class Tasks(Table):
        def __init__(self):
            id = "tasks"    
            fields = [createField(id, "id", DECIMAL),
                      createField(id, "name", TEXT),
                      createField(id, "status", TEXT),
                      createField(id, "priority", DECIMAL),
                      createField(id, "sp", ADDRESS)]
            Table.__init__(self, id, fields)
    
        def getRecords(self, debugger):
            records = [] # todo
    Functions createField and Table.__init__() automatically build up the keys to look for at run-time in the messages.properties file. Any key that is not found in messages.properties is printed as is.
    The above modifications create a new empty Tasks table:
    Figure 14-8 myos Empty Tasks table
    myos Empty Tasks table

    To populate the table, getRecords() in tasks.py must be implemented:
    from osapi import Table
    from osapi import createField
    from osapi import createNumberCell, createTextCell, createAddressCell
    from osapi import DECIMAL, TEXT, ADDRESS
    
    # this class implements the Java interface IDataModelTable
    class Tasks(Table):
        def __init__(self):
            […]
    
        def readTask(self, task, first):
            members = task.getStructureMembers()
            id = members["id"].readAsNumber()
    
            if (members["status"].readAsNumber() == 0):
                status = "Uninitialized"
                name = None
                sp = None
                priority = None
            else:
                if (first):
                    status = "Running"
                else:
                    status = "Ready"
    
                name = members["name"].readAsNullTerminatedString()
                sp = members["sp"].readAsAddress()
                priority = members["priority"].readAsNumber()
    
            cells = [createNumberCell(id),
                     createTextCell(name),
                     createTextCell(status),
                     createNumberCell(priority),
                     createAddressCell(sp)]
            
            return self.createRecord(cells)
            
        def getRecords(self, debugger):
            records = []
            tasks = debugger.evaluateExpression("tasks").getArrayElements()
            first = True
            
            for task in tasks:
                records.append(self.readTask(task, first))
                first = False
                    
            return records
    With this implementation, the Tasks table now shows the following values:
    Figure 14-9 myos populated Tasks table
    myos populated Tasks table

    Note

    The debugger command info myos tasks prints the same information in the Commands view.
Non-ConfidentialPDF file icon PDF versionARM DUI0446W
Copyright © 2010-2015 ARM. All rights reserved.