Debug: freertos gdb plugin.
This commit is contained in:
		
							parent
							
								
									72e78dcc1b
								
							
						
					
					
						commit
						c318d54995
					
				
							
								
								
									
										107
									
								
								debug/FreeRTOS/FreeRTOS.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								debug/FreeRTOS/FreeRTOS.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | |||||||
|  | # File: FreeRTOS.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #   This file contains some python code that utilizes the GDB API | ||||||
|  | # to inspect information about the FreeRTOS internal state. The | ||||||
|  | # idea is to provide the user with the ability to inspect information | ||||||
|  | # about the tasks, queues, mutexs, etc. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | from os import path | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | directory, file = path.split(__file__) | ||||||
|  | directory = path.expanduser(directory) | ||||||
|  | directory = path.abspath(directory) | ||||||
|  | 
 | ||||||
|  | sys.path.append(directory) | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | import pprint | ||||||
|  | 
 | ||||||
|  | from FreeRTOSgdb.Types import StdTypes | ||||||
|  | from FreeRTOSgdb.List import ListInspector | ||||||
|  | from FreeRTOSgdb.GDBCommands import ShowHandleName, ShowRegistry, ShowList | ||||||
|  | from FreeRTOSgdb.GDBCommands import ShowQueueInfo | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Scheduler: | ||||||
|  |     def __init__(self): | ||||||
|  | 
 | ||||||
|  |         self._blocked = ListInspector("xSuspendedTaskList") | ||||||
|  |         self._delayed1 = ListInspector("xDelayedTaskList1") | ||||||
|  |         self._delayed2 = ListInspector("xDelayedTaskList2") | ||||||
|  |         self._readyLists = [] | ||||||
|  |         readyTasksListsStr = "pxReadyTasksLists" | ||||||
|  |         readyListsSym, methodType = gdb.lookup_symbol(readyTasksListsStr) | ||||||
|  |         if readyListsSym != None: | ||||||
|  |             readyLists = readyListsSym.value() | ||||||
|  |             minIndex, maxIndex = readyLists.type.range() | ||||||
|  |             for i in range(minIndex, maxIndex + 1): | ||||||
|  |                 readyList = readyLists[i] | ||||||
|  |                 FRReadyList = ListInspector(readyList) | ||||||
|  |                 self._readyLists.append(FRReadyList) | ||||||
|  |         else: | ||||||
|  |             print("Failed to Find Symbol: %s" % readyTasksListsStr) | ||||||
|  |             raise ValueError("Invalid Symbol!") | ||||||
|  | 
 | ||||||
|  |     def ShowTaskList(self): | ||||||
|  |         self.PrintTableHeader() | ||||||
|  |         for i, rlist in enumerate(self._readyLists): | ||||||
|  |             if i == 0: | ||||||
|  |                 items = rlist.GetElements("TCB_t", 0) | ||||||
|  |             else: | ||||||
|  |                 items = rlist.GetElements("TCB_t", 1) | ||||||
|  |             if len(items) > 0: | ||||||
|  |                 print("Ready List {%d}: Num Tasks: %d" % (i, len(items))) | ||||||
|  |                 for tcb, val in items: | ||||||
|  |                     self.PrintTaskFormatted(tcb) | ||||||
|  | 
 | ||||||
|  |         items = self._blocked.GetElements("TCB_t") | ||||||
|  |         print("Blocked List: Num Tasks: %d" % len(items)) | ||||||
|  |         for tcb, val in items: | ||||||
|  |             self.PrintTaskFormatted(tcb) | ||||||
|  | 
 | ||||||
|  |         items = self._delayed1.GetElements("TCB_t") | ||||||
|  |         print("Delayed {1}: Num Tasks: %d" % len(items)) | ||||||
|  |         for tcb, val in items: | ||||||
|  |             self.PrintTaskFormatted(tcb, val) | ||||||
|  | 
 | ||||||
|  |         items = self._delayed2.GetElements("TCB_t") | ||||||
|  |         print("Delayed {2}: Num Tasks: %d" % len(items)) | ||||||
|  |         for tcb, val in items: | ||||||
|  |             self.PrintTaskFormatted(tcb, val) | ||||||
|  | 
 | ||||||
|  |     def PrintTableHeader(self): | ||||||
|  |         print("%16s %3s %4s" % ("Name", "PRI", "STCK")) | ||||||
|  | 
 | ||||||
|  |     def PrintTaskFormatted(self, task, itemVal=None): | ||||||
|  |         topStack = task["pxTopOfStack"] | ||||||
|  |         stackBase = task["pxStack"] | ||||||
|  |         highWater = topStack - stackBase | ||||||
|  |         taskName = task["pcTaskName"].string() | ||||||
|  |         taskPriority = task["uxPriority"] | ||||||
|  |         if itemVal != None: | ||||||
|  |             print("%16s %3s %4s %5s" % (taskName, taskPriority, highWater, itemVal)) | ||||||
|  |         else: | ||||||
|  |             print("%16s %3s %4s" % (taskName, taskPriority, highWater)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ShowTaskList(gdb.Command): | ||||||
|  |     """Generate a print out of the current tasks and their states.""" | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         super(ShowTaskList, self).__init__("show Task-List", gdb.COMMAND_SUPPORT) | ||||||
|  | 
 | ||||||
|  |     def invoke(self, arg, from_tty): | ||||||
|  |         sched = Scheduler() | ||||||
|  |         sched.ShowTaskList() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ShowRegistry() | ||||||
|  | ShowList() | ||||||
|  | ShowTaskList() | ||||||
|  | ShowHandleName() | ||||||
|  | ShowQueueInfo() | ||||||
							
								
								
									
										31
									
								
								debug/FreeRTOS/FreeRTOSgdb/EventGroup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								debug/FreeRTOS/FreeRTOSgdb/EventGroup.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | # File: EventGroup.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #   This file contains the implementation of a Event Group Inspector | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | from .List import ListInspector | ||||||
|  | from .Task import TaskInspector | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class EventGroupInspector: | ||||||
|  |     EvtGrpType = gdb.lookup_type("EventGroup_t") | ||||||
|  | 
 | ||||||
|  |     def __init__(self, handle): | ||||||
|  |         """""" | ||||||
|  |         self._evtgrp = gdb.Value(handle).cast(EventGroupInspector.EvtGrpType) | ||||||
|  | 
 | ||||||
|  |     def GetTasksWaiting(self): | ||||||
|  |         """""" | ||||||
|  |         taskListObj = self._evtgrp["xTasksWaitingForBits"] | ||||||
|  |         taskList = ListInspector(taskListObj) | ||||||
|  |         return taskList.GetElements(TaskInspector.TCBType) | ||||||
|  | 
 | ||||||
|  |     def GetEventBits(self): | ||||||
|  |         """Get the Event Flag Bits | ||||||
|  |         @return L{gdb.Value} of EventBits_t | ||||||
|  |         """ | ||||||
|  |         return self._evtgrp["uxEventBits"] | ||||||
							
								
								
									
										139
									
								
								debug/FreeRTOS/FreeRTOSgdb/GDBCommands.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								debug/FreeRTOS/FreeRTOSgdb/GDBCommands.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | |||||||
|  | # File: GDBCommands.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #   This file contains the implementation of some custom | ||||||
|  | # GDB commands for Inspecting the FreeRTOS state | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | from .List import ListInspector | ||||||
|  | from .Task import TaskInspector | ||||||
|  | from .HandleRegistry import HandleRegistry | ||||||
|  | from .QueueTools import * | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ShowQueueInfo(gdb.Command): | ||||||
|  |     """Generate a print out of info about a particular | ||||||
|  |     set of queues. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         super(ShowQueueInfo, self).__init__("show Queue-Info", gdb.COMMAND_SUPPORT) | ||||||
|  | 
 | ||||||
|  |     def invoke(self, arg, from_tty): | ||||||
|  |         argv = gdb.string_to_argv(arg) | ||||||
|  | 
 | ||||||
|  |         qTypes = [] | ||||||
|  |         if len(argv) > 0: | ||||||
|  |             for a in argv: | ||||||
|  |                 try: | ||||||
|  |                     qType = QueueMode.Map[a] | ||||||
|  |                     qTypes.append(qType) | ||||||
|  |                 except KeyError: | ||||||
|  |                     print("Arg %s does not map to a Queue Type!" % a) | ||||||
|  | 
 | ||||||
|  |         reg = HandleRegistry() | ||||||
|  |         qToShow = [] | ||||||
|  |         if len(qTypes) > 0: | ||||||
|  |             # We will only print info about queues | ||||||
|  |             for qType in qTypes: | ||||||
|  |                 qObjs = reg.FilterBy(qType) | ||||||
|  |                 qToShow.extend(qObjs) | ||||||
|  |         else: | ||||||
|  |             qToShow = reg.FilterBy(None) | ||||||
|  | 
 | ||||||
|  |         print("Num Queues: %d" % len(qToShow)) | ||||||
|  |         print("%20s %4s %16s %16s" % ("NAME", "CNT", "SEND", "RECEIVE")) | ||||||
|  |         for q in qToShow: | ||||||
|  |             self.PrintQueueInfo(q) | ||||||
|  | 
 | ||||||
|  |     def PrintQueueInfo(self, q): | ||||||
|  |         """Print Info about the Queue""" | ||||||
|  |         sendList = q.GetTasksWaitingToSend() | ||||||
|  |         rxList = q.GetTasksWaitingToReceive() | ||||||
|  | 
 | ||||||
|  |         # print("TxLen: %d, RxLen: %d" % (len(sendList), len(rxList))) | ||||||
|  | 
 | ||||||
|  |         maxCount = max(len(sendList), len(rxList)) | ||||||
|  |         outputFmt = "%20s %4s %16s %16s" | ||||||
|  |         if maxCount == 0: | ||||||
|  |             print(outputFmt % (q.GetName(), q.GetQueueMessagesWaiting(), "", "")) | ||||||
|  |         else: | ||||||
|  | 
 | ||||||
|  |             for i in range(0, maxCount): | ||||||
|  |                 txName = "" | ||||||
|  |                 if i < len(sendList): | ||||||
|  |                     tcbRef, val = sendList[i] | ||||||
|  |                     tcb = TaskInspector(tcbRef) | ||||||
|  |                     txName = tcb.GetName() | ||||||
|  |                 rxName = "" | ||||||
|  |                 if i < len(rxList): | ||||||
|  |                     tcbRef, val = rxList[i] | ||||||
|  |                     tcb = TaskInspector(tcbRef) | ||||||
|  |                     rxName = tcb.GetName() | ||||||
|  | 
 | ||||||
|  |                 if i == 0: | ||||||
|  |                     print( | ||||||
|  |                         outputFmt | ||||||
|  |                         % (q.GetName(), q.GetQueueMessagesWaiting(), txName, rxName) | ||||||
|  |                     ) | ||||||
|  |                 else: | ||||||
|  |                     print(outputFmt % ("", "", txName, rxName)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ShowHandleName(gdb.Command): | ||||||
|  |     """Generate a print out of the handle by name""" | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         super(ShowHandleName, self).__init__("show Handle-Name", gdb.COMMAND_SUPPORT) | ||||||
|  | 
 | ||||||
|  |     def invoke(self, arg, from_tty): | ||||||
|  |         argv = gdb.string_to_argv(arg) | ||||||
|  |         if len(argv) != 1: | ||||||
|  |             print("Invalid Argument: Requires one handle arg") | ||||||
|  |         handle = int(argv[0], 0) | ||||||
|  |         reg = HandleRegistry() | ||||||
|  |         name = reg.GetName(handle) | ||||||
|  |         print("Handle 0x%08x: %s" % (handle, name)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ShowRegistry(gdb.Command): | ||||||
|  |     """Generate a print out of the queue handle registry""" | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         super(ShowRegistry, self).__init__("show Handle-Registry", gdb.COMMAND_SUPPORT) | ||||||
|  | 
 | ||||||
|  |     def invoke(self, arg, from_tty): | ||||||
|  |         reg = HandleRegistry() | ||||||
|  |         reg.PrintRegistry() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ShowList(gdb.Command): | ||||||
|  |     """Generate a print out of the elements in a list | ||||||
|  |     passed to this command. User must pass a symbol that | ||||||
|  |     will be looked up. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         super(ShowList, self).__init__( | ||||||
|  |             "show List-Handle", gdb.COMMAND_SUPPORT, gdb.COMPLETE_SYMBOL | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def invoke(self, arg, from_tty): | ||||||
|  |         argv = gdb.string_to_argv(arg) | ||||||
|  | 
 | ||||||
|  |         CastTypeStr = None | ||||||
|  |         if len(argv) > 0: | ||||||
|  |             symbolArg = argv[0] | ||||||
|  | 
 | ||||||
|  |         if len(argv) > 1: | ||||||
|  |             CastTypeStr = argv[1] | ||||||
|  | 
 | ||||||
|  |         listVal = ListInspector(symbolArg) | ||||||
|  | 
 | ||||||
|  |         elems = listVal.GetElements(CastTypeStr) | ||||||
|  | 
 | ||||||
|  |         for elem in elems: | ||||||
|  |             print("Elem: %s" % str(elem)) | ||||||
							
								
								
									
										84
									
								
								debug/FreeRTOS/FreeRTOSgdb/HandleRegistry.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								debug/FreeRTOS/FreeRTOSgdb/HandleRegistry.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | # File: HandleRegistry.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 06NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #   THis file contains the implementation of a class for accessing the | ||||||
|  | # handle registry. This contains a mapping of queue handles to | ||||||
|  | # strings for labeling purposes. | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | from .Types import StdTypes | ||||||
|  | from .QueueTools import * | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HandleRegistry: | ||||||
|  |     """The FreeRTOS system can be configured with a table that | ||||||
|  |     associates a name with a QueueHandle_t. | ||||||
|  |     This class can be used to access this table and | ||||||
|  |     label queue/mutex/semaphore/event groups | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, regSymbol="xQueueRegistry"): | ||||||
|  |         symbol, methodObj = gdb.lookup_symbol(regSymbol) | ||||||
|  |         self._registry = symbol.value() | ||||||
|  |         self._minIndex = 0 | ||||||
|  |         self._maxIndex = 0 | ||||||
|  |         self._minIndex, self._maxIndex = self._registry.type.range() | ||||||
|  | 
 | ||||||
|  |     def GetName(self, handle): | ||||||
|  |         """Find the string name associated with a queue | ||||||
|  |         handle if it exists in the registry | ||||||
|  |         """ | ||||||
|  |         for i in range(self._minIndex, self._maxIndex): | ||||||
|  |             elem = self._registry[i] | ||||||
|  |             h = elem["xHandle"] | ||||||
|  |             val = h.cast(StdTypes.uint32_t) | ||||||
|  |             if handle == val: | ||||||
|  |                 print("Found Entry for: %x" % handle) | ||||||
|  |                 name = elem["pcQueueName"].string() | ||||||
|  |                 return name | ||||||
|  | 
 | ||||||
|  |     def PrintRegistry(self): | ||||||
|  |         for i in range(self._minIndex, self._maxIndex): | ||||||
|  |             elem = self._registry[i] | ||||||
|  |             h = elem["xHandle"] | ||||||
|  |             if h != 0: | ||||||
|  |                 name = elem["pcQueueName"].string() | ||||||
|  |                 print("%d: %3s %16s" % (i, h, name)) | ||||||
|  | 
 | ||||||
|  |     def FilterBy(self, qMode): | ||||||
|  | 
 | ||||||
|  |         """Retrieve a List of Mutex Queue Handles""" | ||||||
|  |         resp = [] | ||||||
|  |         for i in range(self._minIndex, self._maxIndex): | ||||||
|  |             elem = self._registry[i] | ||||||
|  |             h = elem["xHandle"] | ||||||
|  |             if h != 0: | ||||||
|  |                 name = elem["pcQueueName"].string() | ||||||
|  |                 q = QueueInspector(h) | ||||||
|  |                 q.SetName(name) | ||||||
|  |                 if qMode != None: | ||||||
|  |                     qType = q.GetQueueType() | ||||||
|  |                     if qType != None: | ||||||
|  |                         if qType == qMode: | ||||||
|  |                             resp.append(q) | ||||||
|  | 
 | ||||||
|  |                     else: | ||||||
|  |                         print("qType == None") | ||||||
|  |                 else: | ||||||
|  |                     resp.append(q) | ||||||
|  | 
 | ||||||
|  |         return resp | ||||||
|  | 
 | ||||||
|  |     def GetMutexes(self): | ||||||
|  |         """Retrieve all the Mutex Objects in the Handle Registry""" | ||||||
|  |         return self.FilterBy(QueueMode.MUTEX) | ||||||
|  | 
 | ||||||
|  |     def GetSemaphores(self): | ||||||
|  |         """Retrieve all the Semaphore Objects in the Handle Registry""" | ||||||
|  |         return self.FilterBy(QueueMode.BINARY) | ||||||
|  | 
 | ||||||
|  |     def GetQueues(self): | ||||||
|  |         """Retrieve all the Queue Objects in the Handle Registry""" | ||||||
|  |         return self.FilterBy(QueueMode.QUEUE) | ||||||
							
								
								
									
										103
									
								
								debug/FreeRTOS/FreeRTOSgdb/List.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								debug/FreeRTOS/FreeRTOSgdb/List.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | # File: List.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #   This file contains the class for inspecting | ||||||
|  | # a FreeRTOS List Object | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | 
 | ||||||
|  | from .Types import StdTypes | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ListInspector: | ||||||
|  |     """FreeRTOS List Inspector Object""" | ||||||
|  | 
 | ||||||
|  |     ListType = gdb.lookup_type("List_t") | ||||||
|  | 
 | ||||||
|  |     def __init__(self, handle): | ||||||
|  |         """""" | ||||||
|  |         self._list = None | ||||||
|  |         #    print("List: Handle: %s" % handle) | ||||||
|  |         self.Assign(handle) | ||||||
|  | 
 | ||||||
|  |     def Assign(self, listObj): | ||||||
|  |         try: | ||||||
|  |             if listObj.type == ListInspector.ListType: | ||||||
|  |                 self._list = listObj | ||||||
|  |                 return | ||||||
|  |             else: | ||||||
|  |                 raise TypeError("Invalid List Object Type!") | ||||||
|  |         except Exception as exc: | ||||||
|  |             # print(" Failed to assign from List object: %s" % str(exc)) | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |         symbol, methodObj = gdb.lookup_symbol(listObj) | ||||||
|  |         if symbol != None: | ||||||
|  |             self._list = symbol.value() | ||||||
|  |         else: | ||||||
|  |             addrInt = int(listObj, 0) | ||||||
|  |             listObjPtr = gdb.Value(addrInt).cast(ListInspector.ListType.pointer()) | ||||||
|  |             self._list = listObjPtr.dereference() | ||||||
|  | 
 | ||||||
|  |     def GetElements(self, CastTypeStr=None, startElem=1): | ||||||
|  |         """Get the Elements of the list as an array of | ||||||
|  |         gdb.Value type objects. | ||||||
|  |         @param CastTypeStr string name of the type of object that | ||||||
|  |           we will cast the void *pvOwner elements of the list to. | ||||||
|  |           User can also pass a L{gdb.Type} object as the type | ||||||
|  |           If None, we will simply cast to uint32_t and print these | ||||||
|  |           as hex values. | ||||||
|  |         @param startElem This is a flag to indicate whether | ||||||
|  |            we will start getting elements starting at 0 or 1. Note | ||||||
|  |            that this is to deal with some non-consistent behavior | ||||||
|  |            of some of the TCB Task lists. | ||||||
|  |         """ | ||||||
|  |         if self._list != None: | ||||||
|  | 
 | ||||||
|  |             CastType = None | ||||||
|  |             if CastTypeStr != None: | ||||||
|  |                 if type(CastTypeStr) == str: | ||||||
|  |                     try: | ||||||
|  |                         CastType = gdb.lookup_type(CastTypeStr).pointer() | ||||||
|  |                     except: | ||||||
|  |                         print("Failed to find type: %s" % CastTypeStr) | ||||||
|  |                 elif type(CastTypeStr) == gdb.Type: | ||||||
|  |                     CastType = CastTypeStr.pointer() | ||||||
|  | 
 | ||||||
|  |             resp = [] | ||||||
|  |             numElems = self._list["uxNumberOfItems"] | ||||||
|  |             # print("List Elements: %d" % numElems) | ||||||
|  |             index = self._list["pxIndex"] | ||||||
|  | 
 | ||||||
|  |             if numElems > 0 and numElems < 200: | ||||||
|  | 
 | ||||||
|  |                 if startElem == 0: | ||||||
|  |                     curr = index | ||||||
|  |                 else: | ||||||
|  |                     curr = index["pxPrevious"] | ||||||
|  | 
 | ||||||
|  |                 for i in range(0, numElems): | ||||||
|  |                     owner = curr["pvOwner"] | ||||||
|  | 
 | ||||||
|  |                     ownerObj = None | ||||||
|  |                     if CastType != None: | ||||||
|  |                         castObjPtr = owner.cast(CastType) | ||||||
|  |                         castObj = castObjPtr.dereference() | ||||||
|  |                         ownerObj = castObj | ||||||
|  |                     else: | ||||||
|  |                         ownerUInt = owner.cast(StdTypes.uint32_t) | ||||||
|  |                         ownerObj = ownerUInt | ||||||
|  | 
 | ||||||
|  |                     itemVal = curr["xItemValue"] | ||||||
|  |                     resp.append((ownerObj, itemVal.cast(StdTypes.uint32_t))) | ||||||
|  | 
 | ||||||
|  |                     curr = curr["pxPrevious"] | ||||||
|  | 
 | ||||||
|  |             return resp | ||||||
|  | 
 | ||||||
|  |         else: | ||||||
|  |             raise ValueError("Invalid List Object - Possibly Failed to Initialize!") | ||||||
							
								
								
									
										110
									
								
								debug/FreeRTOS/FreeRTOSgdb/QueueTools.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								debug/FreeRTOS/FreeRTOSgdb/QueueTools.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | # File: Queue.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #   This file contains the implementation of a Queue Inspector | ||||||
|  | # class. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | from .List import ListInspector | ||||||
|  | from .Task import TaskInspector | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class QueueMode: | ||||||
|  |     QUEUE = 0 | ||||||
|  |     MUTEX = 1 | ||||||
|  |     COUNTING = 2 | ||||||
|  |     BINARY = 3 | ||||||
|  |     RECURSIVE = 4 | ||||||
|  | 
 | ||||||
|  |     Map = None | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def IsValid(qType): | ||||||
|  |         if ( | ||||||
|  |             qType == QueueMode.QUEUE | ||||||
|  |             or qType == QueueMode.MUTEX | ||||||
|  |             or qType == QueueMode.COUNTING | ||||||
|  |             or qType == QueueMode.BINARY | ||||||
|  |             or qType == QueueMode.RECURSIVE | ||||||
|  |         ): | ||||||
|  |             return True | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | QueueMap = { | ||||||
|  |     "mutex": QueueMode.MUTEX, | ||||||
|  |     "queue": QueueMode.QUEUE, | ||||||
|  |     "semaphore": QueueMode.BINARY, | ||||||
|  |     "counting": QueueMode.COUNTING, | ||||||
|  |     "recursive": QueueMode.RECURSIVE, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QueueMode.Map = QueueMap | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class QueueInspector: | ||||||
|  | 
 | ||||||
|  |     QueueType = gdb.lookup_type("Queue_t") | ||||||
|  | 
 | ||||||
|  |     def __init__(self, handle): | ||||||
|  |         """""" | ||||||
|  |         #    print("Queue: Handle: %s" % handle) | ||||||
|  |         self.name = None | ||||||
|  |         queueObjPtr = None | ||||||
|  |         if type(handle) == gdb.Value: | ||||||
|  |             queueObjPtr = handle.cast(QueueInspector.QueueType.pointer()) | ||||||
|  |             self._queue = queueObjPtr.dereference() | ||||||
|  |         else: | ||||||
|  |             queueObjPtr = gdb.Value(handle).cast(QueueInspector.QueueType.pointer()) | ||||||
|  |         self._queue = queueObjPtr.dereference() | ||||||
|  | 
 | ||||||
|  |     def GetName(self): | ||||||
|  |         return self.name | ||||||
|  | 
 | ||||||
|  |     def SetName(self, name): | ||||||
|  |         self.name = name | ||||||
|  | 
 | ||||||
|  |     def GetTasksWaitingToSend(self): | ||||||
|  |         """Retrieve a list of gdb.Value objects of type | ||||||
|  |         TCB that are the tasks that are currently waiting to | ||||||
|  |         send data on this queue object. | ||||||
|  |         """ | ||||||
|  |         sendList = ListInspector(self._queue["xTasksWaitingToSend"]) | ||||||
|  | 
 | ||||||
|  |         return sendList.GetElements(TaskInspector.TCBType) | ||||||
|  | 
 | ||||||
|  |     def GetTasksWaitingToReceive(self): | ||||||
|  |         """Retrieve a list of gdb.Value objects of Type | ||||||
|  |         TCB that are the tasks that are currently waiting to | ||||||
|  |         receive data on this queue object. | ||||||
|  |         """ | ||||||
|  |         rxList = ListInspector(self._queue["xTasksWaitingToReceive"]) | ||||||
|  |         return rxList.GetElements(TaskInspector.TCBType) | ||||||
|  | 
 | ||||||
|  |     def GetQueueMessagesWaiting(self): | ||||||
|  |         """Return the number of messages waiting as a | ||||||
|  |         L{gdb.Value} object | ||||||
|  |         """ | ||||||
|  |         return self._queue["uxMessagesWaiting"] | ||||||
|  | 
 | ||||||
|  |     def GetQueueType(self): | ||||||
|  |         """Return the Type of the Queue as a enumerated number""" | ||||||
|  |         try: | ||||||
|  |             qType = self._queue["ucQueueType"] | ||||||
|  |             if QueueMode.IsValid(int(qType)): | ||||||
|  |                 return qType | ||||||
|  |             else: | ||||||
|  |                 raise ValueError( | ||||||
|  |                     "Invalid Queue Type In Queue Object! Are you sure this is a Queue Handle?" | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |         except Exception as exc: | ||||||
|  |             # If the TRACE functionality of the RTOS is not enabled, | ||||||
|  |             #  then the queue type will not be availabe in the queue | ||||||
|  |             #  handle - so we return None | ||||||
|  |             print("Failed to get Type: %s" % str(exc)) | ||||||
|  |             return None | ||||||
							
								
								
									
										63
									
								
								debug/FreeRTOS/FreeRTOSgdb/Task.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								debug/FreeRTOS/FreeRTOSgdb/Task.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | # File: Task.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #  This file contains the implementation of a class to use for | ||||||
|  | # inspecting the state of a FreeRTOS Task in GDB | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TaskInspector: | ||||||
|  | 
 | ||||||
|  |     TCBType = gdb.lookup_type("TCB_t") | ||||||
|  | 
 | ||||||
|  |     def __init__(self, handle): | ||||||
|  |         self._tcb = None | ||||||
|  |         # print("Task: Pass Handle: %s" % str(handle)) | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             if handle.type == TaskInspector.TCBType: | ||||||
|  |                 self._tcb = handle | ||||||
|  |                 return | ||||||
|  |             else: | ||||||
|  |                 print("Handle Type: %s" % str(handle.type)) | ||||||
|  | 
 | ||||||
|  |         except AttributeError as aexc: | ||||||
|  |             print("Attribute Error: %s" % str(aexc)) | ||||||
|  |             pass | ||||||
|  |         except Exception as exc: | ||||||
|  |             print("Error Initializing Task Inspector: %s" % str(exc)) | ||||||
|  |             raise | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             tcbPtr = gdb.Value(handle).cast(TaskInspector.TCBType.pointer()) | ||||||
|  |             self._tcb = tcbPtr.dereference() | ||||||
|  |             return | ||||||
|  |         except Exception as exc: | ||||||
|  |             print("Failed to convert Handle Pointer: %s" % str(handle)) | ||||||
|  | 
 | ||||||
|  |         self._tcb = handle | ||||||
|  | 
 | ||||||
|  |     def GetName(self): | ||||||
|  |         if self._tcb != None: | ||||||
|  |             return self._tcb["pcTaskName"].string() | ||||||
|  |         else: | ||||||
|  |             raise ValueError("Invalid TCB") | ||||||
|  | 
 | ||||||
|  |     def GetPriority(self): | ||||||
|  |         if self._tcb != None: | ||||||
|  |             return self._tcb["uxPriority"] | ||||||
|  |         else: | ||||||
|  |             raise ValueError("Invalid TCB") | ||||||
|  | 
 | ||||||
|  |     def GetStackMargin(self): | ||||||
|  |         if self._tcb != None: | ||||||
|  |             topStack = self._tcb["pxTopOfStack"] | ||||||
|  |             stackBase = self._tcb["pxStack"] | ||||||
|  |             highWater = topStack - stackBase | ||||||
|  |             return highWater | ||||||
|  |         else: | ||||||
|  |             raise ValueError("Invalid TCB") | ||||||
							
								
								
									
										14
									
								
								debug/FreeRTOS/FreeRTOSgdb/Types.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								debug/FreeRTOS/FreeRTOSgdb/Types.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | # File: Types.py | ||||||
|  | # Author: Carl Allendorph | ||||||
|  | # Date: 05NOV2014 | ||||||
|  | # | ||||||
|  | # Description: | ||||||
|  | #    This file contains the implementation of some | ||||||
|  | # standard types | ||||||
|  | 
 | ||||||
|  | import gdb | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class StdTypes: | ||||||
|  |     uint32_t = gdb.lookup_type("uint32_t") | ||||||
|  |     uint16_t = gdb.lookup_type("uint16_t") | ||||||
							
								
								
									
										0
									
								
								debug/FreeRTOS/FreeRTOSgdb/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								debug/FreeRTOS/FreeRTOSgdb/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										340
									
								
								debug/FreeRTOS/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								debug/FreeRTOS/LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,340 @@ | |||||||
|  | GNU GENERAL PUBLIC LICENSE | ||||||
|  |                        Version 2, June 1991 | ||||||
|  | 
 | ||||||
|  |  Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> | ||||||
|  |  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||||
|  |  Everyone is permitted to copy and distribute verbatim copies | ||||||
|  |  of this license document, but changing it is not allowed. | ||||||
|  | 
 | ||||||
|  |                             Preamble | ||||||
|  | 
 | ||||||
|  |   The licenses for most software are designed to take away your | ||||||
|  | freedom to share and change it.  By contrast, the GNU General Public | ||||||
|  | License is intended to guarantee your freedom to share and change free | ||||||
|  | software--to make sure the software is free for all its users.  This | ||||||
|  | General Public License applies to most of the Free Software | ||||||
|  | Foundation's software and to any other program whose authors commit to | ||||||
|  | using it.  (Some other Free Software Foundation software is covered by | ||||||
|  | the GNU Lesser General Public License instead.)  You can apply it to | ||||||
|  | your programs, too. | ||||||
|  | 
 | ||||||
|  |   When we speak of free software, we are referring to freedom, not | ||||||
|  | price.  Our General Public Licenses are designed to make sure that you | ||||||
|  | have the freedom to distribute copies of free software (and charge for | ||||||
|  | this service if you wish), that you receive source code or can get it | ||||||
|  | if you want it, that you can change the software or use pieces of it | ||||||
|  | in new free programs; and that you know you can do these things. | ||||||
|  | 
 | ||||||
|  |   To protect your rights, we need to make restrictions that forbid | ||||||
|  | anyone to deny you these rights or to ask you to surrender the rights. | ||||||
|  | These restrictions translate to certain responsibilities for you if you | ||||||
|  | distribute copies of the software, or if you modify it. | ||||||
|  | 
 | ||||||
|  |   For example, if you distribute copies of such a program, whether | ||||||
|  | gratis or for a fee, you must give the recipients all the rights that | ||||||
|  | you have.  You must make sure that they, too, receive or can get the | ||||||
|  | source code.  And you must show them these terms so they know their | ||||||
|  | rights. | ||||||
|  | 
 | ||||||
|  |   We protect your rights with two steps: (1) copyright the software, and | ||||||
|  | (2) offer you this license which gives you legal permission to copy, | ||||||
|  | distribute and/or modify the software. | ||||||
|  | 
 | ||||||
|  |   Also, for each author's protection and ours, we want to make certain | ||||||
|  | that everyone understands that there is no warranty for this free | ||||||
|  | software.  If the software is modified by someone else and passed on, we | ||||||
|  | want its recipients to know that what they have is not the original, so | ||||||
|  | that any problems introduced by others will not reflect on the original | ||||||
|  | authors' reputations. | ||||||
|  | 
 | ||||||
|  |   Finally, any free program is threatened constantly by software | ||||||
|  | patents.  We wish to avoid the danger that redistributors of a free | ||||||
|  | program will individually obtain patent licenses, in effect making the | ||||||
|  | program proprietary.  To prevent this, we have made it clear that any | ||||||
|  | patent must be licensed for everyone's free use or not licensed at all. | ||||||
|  | 
 | ||||||
|  |   The precise terms and conditions for copying, distribution and | ||||||
|  | modification follow. | ||||||
|  | 
 | ||||||
|  |                     GNU GENERAL PUBLIC LICENSE | ||||||
|  |    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||||||
|  | 
 | ||||||
|  |   0. This License applies to any program or other work which contains | ||||||
|  | a notice placed by the copyright holder saying it may be distributed | ||||||
|  | under the terms of this General Public License.  The "Program", below, | ||||||
|  | refers to any such program or work, and a "work based on the Program" | ||||||
|  | means either the Program or any derivative work under copyright law: | ||||||
|  | that is to say, a work containing the Program or a portion of it, | ||||||
|  | either verbatim or with modifications and/or translated into another | ||||||
|  | language.  (Hereinafter, translation is included without limitation in | ||||||
|  | the term "modification".)  Each licensee is addressed as "you". | ||||||
|  | 
 | ||||||
|  | Activities other than copying, distribution and modification are not | ||||||
|  | covered by this License; they are outside its scope.  The act of | ||||||
|  | running the Program is not restricted, and the output from the Program | ||||||
|  | is covered only if its contents constitute a work based on the | ||||||
|  | Program (independent of having been made by running the Program). | ||||||
|  | Whether that is true depends on what the Program does. | ||||||
|  | 
 | ||||||
|  |   1. You may copy and distribute verbatim copies of the Program's | ||||||
|  | source code as you receive it, in any medium, provided that you | ||||||
|  | conspicuously and appropriately publish on each copy an appropriate | ||||||
|  | copyright notice and disclaimer of warranty; keep intact all the | ||||||
|  | notices that refer to this License and to the absence of any warranty; | ||||||
|  | and give any other recipients of the Program a copy of this License | ||||||
|  | along with the Program. | ||||||
|  | 
 | ||||||
|  | You may charge a fee for the physical act of transferring a copy, and | ||||||
|  | you may at your option offer warranty protection in exchange for a fee. | ||||||
|  | 
 | ||||||
|  |   2. You may modify your copy or copies of the Program or any portion | ||||||
|  | of it, thus forming a work based on the Program, and copy and | ||||||
|  | distribute such modifications or work under the terms of Section 1 | ||||||
|  | above, provided that you also meet all of these conditions: | ||||||
|  | 
 | ||||||
|  |     a) You must cause the modified files to carry prominent notices | ||||||
|  |     stating that you changed the files and the date of any change. | ||||||
|  | 
 | ||||||
|  |     b) You must cause any work that you distribute or publish, that in | ||||||
|  |     whole or in part contains or is derived from the Program or any | ||||||
|  |     part thereof, to be licensed as a whole at no charge to all third | ||||||
|  |     parties under the terms of this License. | ||||||
|  | 
 | ||||||
|  |     c) If the modified program normally reads commands interactively | ||||||
|  |     when run, you must cause it, when started running for such | ||||||
|  |     interactive use in the most ordinary way, to print or display an | ||||||
|  |     announcement including an appropriate copyright notice and a | ||||||
|  |     notice that there is no warranty (or else, saying that you provide | ||||||
|  |     a warranty) and that users may redistribute the program under | ||||||
|  |     these conditions, and telling the user how to view a copy of this | ||||||
|  |     License.  (Exception: if the Program itself is interactive but | ||||||
|  |     does not normally print such an announcement, your work based on | ||||||
|  |     the Program is not required to print an announcement.) | ||||||
|  | 
 | ||||||
|  | These requirements apply to the modified work as a whole.  If | ||||||
|  | identifiable sections of that work are not derived from the Program, | ||||||
|  | and can be reasonably considered independent and separate works in | ||||||
|  | themselves, then this License, and its terms, do not apply to those | ||||||
|  | sections when you distribute them as separate works.  But when you | ||||||
|  | distribute the same sections as part of a whole which is a work based | ||||||
|  | on the Program, the distribution of the whole must be on the terms of | ||||||
|  | this License, whose permissions for other licensees extend to the | ||||||
|  | entire whole, and thus to each and every part regardless of who wrote it. | ||||||
|  | 
 | ||||||
|  | Thus, it is not the intent of this section to claim rights or contest | ||||||
|  | your rights to work written entirely by you; rather, the intent is to | ||||||
|  | exercise the right to control the distribution of derivative or | ||||||
|  | collective works based on the Program. | ||||||
|  | 
 | ||||||
|  | In addition, mere aggregation of another work not based on the Program | ||||||
|  | with the Program (or with a work based on the Program) on a volume of | ||||||
|  | a storage or distribution medium does not bring the other work under | ||||||
|  | the scope of this License. | ||||||
|  | 
 | ||||||
|  |   3. You may copy and distribute the Program (or a work based on it, | ||||||
|  | under Section 2) in object code or executable form under the terms of | ||||||
|  | Sections 1 and 2 above provided that you also do one of the following: | ||||||
|  | 
 | ||||||
|  |     a) Accompany it with the complete corresponding machine-readable | ||||||
|  |     source code, which must be distributed under the terms of Sections | ||||||
|  |     1 and 2 above on a medium customarily used for software interchange; or, | ||||||
|  | 
 | ||||||
|  |     b) Accompany it with a written offer, valid for at least three | ||||||
|  |     years, to give any third party, for a charge no more than your | ||||||
|  |     cost of physically performing source distribution, a complete | ||||||
|  |     machine-readable copy of the corresponding source code, to be | ||||||
|  |     distributed under the terms of Sections 1 and 2 above on a medium | ||||||
|  |     customarily used for software interchange; or, | ||||||
|  | 
 | ||||||
|  |     c) Accompany it with the information you received as to the offer | ||||||
|  |     to distribute corresponding source code.  (This alternative is | ||||||
|  |     allowed only for noncommercial distribution and only if you | ||||||
|  |     received the program in object code or executable form with such | ||||||
|  |     an offer, in accord with Subsection b above.) | ||||||
|  | 
 | ||||||
|  | The source code for a work means the preferred form of the work for | ||||||
|  | making modifications to it.  For an executable work, complete source | ||||||
|  | code means all the source code for all modules it contains, plus any | ||||||
|  | associated interface definition files, plus the scripts used to | ||||||
|  | control compilation and installation of the executable.  However, as a | ||||||
|  | special exception, the source code distributed need not include | ||||||
|  | anything that is normally distributed (in either source or binary | ||||||
|  | form) with the major components (compiler, kernel, and so on) of the | ||||||
|  | operating system on which the executable runs, unless that component | ||||||
|  | itself accompanies the executable. | ||||||
|  | 
 | ||||||
|  | If distribution of executable or object code is made by offering | ||||||
|  | access to copy from a designated place, then offering equivalent | ||||||
|  | access to copy the source code from the same place counts as | ||||||
|  | distribution of the source code, even though third parties are not | ||||||
|  | compelled to copy the source along with the object code. | ||||||
|  | 
 | ||||||
|  |   4. You may not copy, modify, sublicense, or distribute the Program | ||||||
|  | except as expressly provided under this License.  Any attempt | ||||||
|  | otherwise to copy, modify, sublicense or distribute the Program is | ||||||
|  | void, and will automatically terminate your rights under this License. | ||||||
|  | However, parties who have received copies, or rights, from you under | ||||||
|  | this License will not have their licenses terminated so long as such | ||||||
|  | parties remain in full compliance. | ||||||
|  | 
 | ||||||
|  |   5. You are not required to accept this License, since you have not | ||||||
|  | signed it.  However, nothing else grants you permission to modify or | ||||||
|  | distribute the Program or its derivative works.  These actions are | ||||||
|  | prohibited by law if you do not accept this License.  Therefore, by | ||||||
|  | modifying or distributing the Program (or any work based on the | ||||||
|  | Program), you indicate your acceptance of this License to do so, and | ||||||
|  | all its terms and conditions for copying, distributing or modifying | ||||||
|  | the Program or works based on it. | ||||||
|  | 
 | ||||||
|  |   6. Each time you redistribute the Program (or any work based on the | ||||||
|  | Program), the recipient automatically receives a license from the | ||||||
|  | original licensor to copy, distribute or modify the Program subject to | ||||||
|  | these terms and conditions.  You may not impose any further | ||||||
|  | restrictions on the recipients' exercise of the rights granted herein. | ||||||
|  | You are not responsible for enforcing compliance by third parties to | ||||||
|  | this License. | ||||||
|  | 
 | ||||||
|  |   7. If, as a consequence of a court judgment or allegation of patent | ||||||
|  | infringement or for any other reason (not limited to patent issues), | ||||||
|  | conditions are imposed on you (whether by court order, agreement or | ||||||
|  | otherwise) that contradict the conditions of this License, they do not | ||||||
|  | excuse you from the conditions of this License.  If you cannot | ||||||
|  | distribute so as to satisfy simultaneously your obligations under this | ||||||
|  | License and any other pertinent obligations, then as a consequence you | ||||||
|  | may not distribute the Program at all.  For example, if a patent | ||||||
|  | license would not permit royalty-free redistribution of the Program by | ||||||
|  | all those who receive copies directly or indirectly through you, then | ||||||
|  | the only way you could satisfy both it and this License would be to | ||||||
|  | refrain entirely from distribution of the Program. | ||||||
|  | 
 | ||||||
|  | If any portion of this section is held invalid or unenforceable under | ||||||
|  | any particular circumstance, the balance of the section is intended to | ||||||
|  | apply and the section as a whole is intended to apply in other | ||||||
|  | circumstances. | ||||||
|  | 
 | ||||||
|  | It is not the purpose of this section to induce you to infringe any | ||||||
|  | patents or other property right claims or to contest validity of any | ||||||
|  | such claims; this section has the sole purpose of protecting the | ||||||
|  | integrity of the free software distribution system, which is | ||||||
|  | implemented by public license practices.  Many people have made | ||||||
|  | generous contributions to the wide range of software distributed | ||||||
|  | through that system in reliance on consistent application of that | ||||||
|  | system; it is up to the author/donor to decide if he or she is willing | ||||||
|  | to distribute software through any other system and a licensee cannot | ||||||
|  | impose that choice. | ||||||
|  | 
 | ||||||
|  | This section is intended to make thoroughly clear what is believed to | ||||||
|  | be a consequence of the rest of this License. | ||||||
|  | 
 | ||||||
|  |   8. If the distribution and/or use of the Program is restricted in | ||||||
|  | certain countries either by patents or by copyrighted interfaces, the | ||||||
|  | original copyright holder who places the Program under this License | ||||||
|  | may add an explicit geographical distribution limitation excluding | ||||||
|  | those countries, so that distribution is permitted only in or among | ||||||
|  | countries not thus excluded.  In such case, this License incorporates | ||||||
|  | the limitation as if written in the body of this License. | ||||||
|  | 
 | ||||||
|  |   9. The Free Software Foundation may publish revised and/or new versions | ||||||
|  | of the General Public License from time to time.  Such new versions will | ||||||
|  | be similar in spirit to the present version, but may differ in detail to | ||||||
|  | address new problems or concerns. | ||||||
|  | 
 | ||||||
|  | Each version is given a distinguishing version number.  If the Program | ||||||
|  | specifies a version number of this License which applies to it and "any | ||||||
|  | later version", you have the option of following the terms and conditions | ||||||
|  | either of that version or of any later version published by the Free | ||||||
|  | Software Foundation.  If the Program does not specify a version number of | ||||||
|  | this License, you may choose any version ever published by the Free Software | ||||||
|  | Foundation. | ||||||
|  | 
 | ||||||
|  |   10. If you wish to incorporate parts of the Program into other free | ||||||
|  | programs whose distribution conditions are different, write to the author | ||||||
|  | to ask for permission.  For software which is copyrighted by the Free | ||||||
|  | Software Foundation, write to the Free Software Foundation; we sometimes | ||||||
|  | make exceptions for this.  Our decision will be guided by the two goals | ||||||
|  | of preserving the free status of all derivatives of our free software and | ||||||
|  | of promoting the sharing and reuse of software generally. | ||||||
|  | 
 | ||||||
|  |                             NO WARRANTY | ||||||
|  | 
 | ||||||
|  |   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||||||
|  | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN | ||||||
|  | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||||||
|  | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||||||
|  | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||||||
|  | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS | ||||||
|  | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE | ||||||
|  | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||||||
|  | REPAIR OR CORRECTION. | ||||||
|  | 
 | ||||||
|  |   12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||||||
|  | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||||||
|  | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||||||
|  | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||||||
|  | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||||||
|  | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||||||
|  | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||||||
|  | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||||||
|  | POSSIBILITY OF SUCH DAMAGES. | ||||||
|  | 
 | ||||||
|  |                      END OF TERMS AND CONDITIONS | ||||||
|  | 
 | ||||||
|  |             How to Apply These Terms to Your New Programs | ||||||
|  | 
 | ||||||
|  |   If you develop a new program, and you want it to be of the greatest | ||||||
|  | possible use to the public, the best way to achieve this is to make it | ||||||
|  | free software which everyone can redistribute and change under these terms. | ||||||
|  | 
 | ||||||
|  |   To do so, attach the following notices to the program.  It is safest | ||||||
|  | to attach them to the start of each source file to most effectively | ||||||
|  | convey the exclusion of warranty; and each file should have at least | ||||||
|  | the "copyright" line and a pointer to where the full notice is found. | ||||||
|  | 
 | ||||||
|  |     {description} | ||||||
|  |     Copyright (C) {year}  {fullname} | ||||||
|  | 
 | ||||||
|  |     This program is free software; you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation; either version 2 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  |     You should have received a copy of the GNU General Public License along | ||||||
|  |     with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  | 
 | ||||||
|  | Also add information on how to contact you by electronic and paper mail. | ||||||
|  | 
 | ||||||
|  | If the program is interactive, make it output a short notice like this | ||||||
|  | when it starts in an interactive mode: | ||||||
|  | 
 | ||||||
|  |     Gnomovision version 69, Copyright (C) year name of author | ||||||
|  |     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||||
|  |     This is free software, and you are welcome to redistribute it | ||||||
|  |     under certain conditions; type `show c' for details. | ||||||
|  | 
 | ||||||
|  | The hypothetical commands `show w' and `show c' should show the appropriate | ||||||
|  | parts of the General Public License.  Of course, the commands you use may | ||||||
|  | be called something other than `show w' and `show c'; they could even be | ||||||
|  | mouse-clicks or menu items--whatever suits your program. | ||||||
|  | 
 | ||||||
|  | You should also get your employer (if you work as a programmer) or your | ||||||
|  | school, if any, to sign a "copyright disclaimer" for the program, if | ||||||
|  | necessary.  Here is a sample; alter the names: | ||||||
|  | 
 | ||||||
|  |   Yoyodyne, Inc., hereby disclaims all copyright interest in the program | ||||||
|  |   `Gnomovision' (which makes passes at compilers) written by James Hacker. | ||||||
|  | 
 | ||||||
|  |   {signature of Ty Coon}, 1 April 1989 | ||||||
|  |   Ty Coon, President of Vice | ||||||
|  | 
 | ||||||
|  | This General Public License does not permit incorporating your program into | ||||||
|  | proprietary programs.  If your program is a subroutine library, you may | ||||||
|  | consider it more useful to permit linking proprietary applications with the | ||||||
|  | library.  If this is what you want to do, use the GNU Lesser General | ||||||
|  | Public License instead of this License. | ||||||
|  | 
 | ||||||
							
								
								
									
										120
									
								
								debug/FreeRTOS/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								debug/FreeRTOS/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | |||||||
|  | FreeRTOS-GDB | ||||||
|  | ============ | ||||||
|  | 
 | ||||||
|  | Python API Library for inspecting FreeRTOS Objects in GDB | ||||||
|  | 
 | ||||||
|  | Basically, the FreeRTOS internal state is kind of hard to inspect  | ||||||
|  | when working with GDB. This project provides some scripts for GDB's  | ||||||
|  | Python API that make accessing some of these internals a little easier | ||||||
|  | to inspect.  | ||||||
|  | 
 | ||||||
|  | ##Requirements:  | ||||||
|  | 
 | ||||||
|  | 1. You need to have the python API enabled in your version of GDB. This is a  | ||||||
|  |     compile time option when building GDB. You should be able to do something | ||||||
|  | 	  like this:  | ||||||
|  | ``` | ||||||
|  | 	gdb> python print "Hello World"  | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | and get predictable results. If it throws an error - then you don't have  | ||||||
|  | python compiled in your version of GDB. | ||||||
|  | 
 | ||||||
|  | 2. Need to be using FreeRTOS 8.0+. This code could probably be used with FreeRTOS | ||||||
|  |     version 7.0 or previous versions, but the current code doesn't support it. | ||||||
|  | 
 | ||||||
|  | 3. You need to use the Handle Registry for Queue info to be any use. | ||||||
|  |     Note that this only works for Queue based objects and not  | ||||||
|  |     for EventGroups  | ||||||
|  | 
 | ||||||
|  | 4. You need to put the FreeRTOS-GDB/src directory on your python path:  | ||||||
|  | ``` | ||||||
|  | 	$> export PYTHONPATH=~/src/FreeRTOS-GDB/src/ | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | How To Use:  | ||||||
|  | ``` | ||||||
|  | $> gdb ./bin/program.elf  | ||||||
|  | (gdb) c  | ||||||
|  | Program runs on embedded device, sets up tasks, and queues  | ||||||
|  | <Break> | ||||||
|  | (gdb) source ~/FreeRTOS-GDB/src/FreeRTOS.py  | ||||||
|  | (gdb) show Task-List | ||||||
|  |             Name PRI STCK | ||||||
|  | Ready List {0}: Num Tasks: 1 | ||||||
|  |             IDLE   0  107 | ||||||
|  | Blocked List: Num Tasks: 11 | ||||||
|  |        EMAC Task   1  239 | ||||||
|  |       AFEC0 Task   1  295 | ||||||
|  |      LDSENS Task   1  195 | ||||||
|  |       AFEC1 Task   1  295 | ||||||
|  |  LineSample Task   1  281 | ||||||
|  |         DMAUART0   1  225 | ||||||
|  |         Log Task   1  273 | ||||||
|  |         BAT Task   1  169 | ||||||
|  |          Rx Task   1  421 | ||||||
|  |         Mng Task   2  551 | ||||||
|  |        Cell Task   1  275 | ||||||
|  | Delayed {1}: Num Tasks: 5 | ||||||
|  |          Tmr Svc   3  355 62254 | ||||||
|  |        WLAN Task   1  205 13817 | ||||||
|  |        Init Task   1  445 10015 | ||||||
|  |         LED Task   1  179  7105 | ||||||
|  |          DMACOM1   1  265  7065 | ||||||
|  | Delayed {2}: Num Tasks: 0 | ||||||
|  | 
 | ||||||
|  | (gdb) show Queue-Info mutex | ||||||
|  | Num Queues: 6 | ||||||
|  |             NAME  CNT             SEND          RECEIVE | ||||||
|  |         LOG:LOCK    1             NONE             NONE | ||||||
|  |      STREAM:LOCK    1             NONE             NONE | ||||||
|  |        TWI:MUTEX    1             NONE             NONE | ||||||
|  |      CC3000:LOCK    1             NONE             NONE | ||||||
|  |        WLAN:LOCK    0             NONE             NONE | ||||||
|  |         SPI:LOCK    1             NONE             NONE | ||||||
|  | 
 | ||||||
|  | (gdb) show Queue-Info queue | ||||||
|  | Num Queues: 14 | ||||||
|  |             NAME  CNT             SEND          RECEIVE | ||||||
|  |             TmrQ    0                           Tmr Svc | ||||||
|  |      LOG:MSGPOOL   12             NONE             NONE | ||||||
|  |         LOG:MSGQ    0                          Log Task | ||||||
|  |        TWI:QUEUE    0             NONE             NONE | ||||||
|  |        SPI:QUEUE    0             NONE             NONE | ||||||
|  |     DMAAFEC:POOL    1             NONE             NONE | ||||||
|  |    DMAAFEC:QUEUE    0                        AFEC0 Task | ||||||
|  |     DMAAFEC:POOL    1             NONE             NONE | ||||||
|  |    DMAAFEC:QUEUE    0                        AFEC1 Task | ||||||
|  |       COM:TXPOOL    3             NONE             NONE | ||||||
|  |          COM:TXQ    0             NONE             NONE | ||||||
|  |       COM:RXPOOL    5             NONE             NONE | ||||||
|  |          COM:RXQ    0             NONE             NONE | ||||||
|  |      FATFS:MUTEX    0             NONE             NONE | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | @note - the NONE's above may just be empty strings. | ||||||
|  | 
 | ||||||
|  | This code adds the following custom GDB commands:  | ||||||
|  | 
 | ||||||
|  | * show List-Handle (symbol|address) [CastType] | ||||||
|  | 	CastType is an optional argument that will cast all of the  | ||||||
|  | 	handles in a list to a particular type.  | ||||||
|  | * show Task-List | ||||||
|  | * show Handle-Registry | ||||||
|  | * show Handle-Name  (symbole|address)  | ||||||
|  | * show Queue-Info [filter] | ||||||
|  |    filter can be "queue","mutex","semaphore", "counting", "recursive" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @TODO | ||||||
|  | ===== | ||||||
|  | 
 | ||||||
|  | * With GDB's Python API - it doesn't seem to handle code is separate | ||||||
|  |     files very well.  | ||||||
|  | 
 | ||||||
|  | * Currently, the EventGroup objects don't have an inspector.  | ||||||
|  |     Work in progress - ideal solution would likely modify the struct | ||||||
|  |     of the Event Group to provide a similar piece of info that the  | ||||||
|  |     Queue handle does so that we could use the same registry. | ||||||
| @ -71,6 +71,7 @@ debug: flash | |||||||
| 	arm-none-eabi-gdb-py \
 | 	arm-none-eabi-gdb-py \
 | ||||||
| 		-ex "target extended-remote 127.0.0.1:4242" \
 | 		-ex "target extended-remote 127.0.0.1:4242" \
 | ||||||
| 		-ex "set confirm off" \
 | 		-ex "set confirm off" \
 | ||||||
|  | 		-ex "source ../debug/FreeRTOS/FreeRTOS.py" \
 | ||||||
| 		$(OBJ_DIR)/$(PROJECT).elf; \
 | 		$(OBJ_DIR)/$(PROJECT).elf; \
 | ||||||
| 	kill `cat $(OBJ_DIR)/st-util.PID`; \
 | 	kill `cat $(OBJ_DIR)/st-util.PID`; \
 | ||||||
| 	rm $(OBJ_DIR)/st-util.PID | 	rm $(OBJ_DIR)/st-util.PID | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aleksandr Kutuzov
						Aleksandr Kutuzov