/* -- uCOS-III Thread script for Rowley CrossWorks 3.7.x for ARM -- -- Copyright (c) 2016 Tero Koskinen -- -- Permission to use, copy, modify, and distribute this software for any -- purpose with or without fee is hereby granted, provided that the above -- copyright notice and this permission notice appear in all copies. -- -- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- -- Version 1.0 - 2016-12-27 -- */ function getState(state) { if (state == 0x00) return "ready"; if (state == 0x01) return "delayed"; if (state == 0x02) return "pend"; if (state == 0x03) return "pend+timeout"; if (state == 0x04) return "suspended"; if (state == 0x05) return "suspended+delayed"; if (state == 0x06) return "suspended+pend"; if (state == 0x07) return "suspended+pend+timeout"; if (state == 0xFF) return "deleted"; return "unknown" } function getregs(x) { tcb = Debug.evaluate("*(OS_TCB *)" + x); sp = tcb.StkPtr; WScript.Echo("stack 0x"+sp.toString(16)+"\n"); var i; var a = new Array(); a[8] = TargetInterface.peekWord(sp); sp+=4; a[9] = TargetInterface.peekWord(sp); sp+=4; a[10] = TargetInterface.peekWord(sp); sp+=4; a[11] = TargetInterface.peekWord(sp); sp+=4; a[4] = TargetInterface.peekWord(sp); sp+=4; a[5] = TargetInterface.peekWord(sp); sp+=4; a[6] = TargetInterface.peekWord(sp); sp+=4; a[7] = TargetInterface.peekWord(sp); sp+=4; a[0] = TargetInterface.peekWord(sp); sp+=4; a[1] = TargetInterface.peekWord(sp); sp+=4; a[2] = TargetInterface.peekWord(sp); sp+=4; a[3] = TargetInterface.peekWord(sp); sp+=4; a[12] = TargetInterface.peekWord(sp); sp+=4; a[14] = TargetInterface.peekWord(sp); sp+=4; a[15] = TargetInterface.peekWord(sp); sp+=4; a[16] = TargetInterface.peekWord(sp); sp+=4; if (a[16] & (1<<9)) // Stack has been 8-byte aligned sp += 4; a[13] = sp; WScript.Echo("registers: "); for (i=0;i < 17;++i) { WScript.Echo("r" + i + ": " + a[i].toString(16) + " "); } WScript.Echo("\n"); return a; } function add_task(tcb_ptr, state) { var tcb, task_name, current_task, regs; task = Debug.evaluate("*(OS_TCB*)" + tcb_ptr); if (task == undefined) { WScript.Echo("task undefined! tcb_ptr: " + tcb_ptr + "\n"); return; } current_task = Debug.evaluate("OSTCBCurPtr"); tcb = tcb_ptr; task_name = Debug.evaluate("(char*)" + task.NamePtr); sp_val = task.StkPtr; // TargetInterface.getRegister("sp"); stack_left = sp_val - task.StkLimitPtr; if (tcb == current_task) { sp_val = TargetInterface.getRegister("sp"); regs = []; Threads.add(task_name, task.Prio, "executing", stack_left, []); } else { Threads.add(task_name, task.Prio, getState(task.TaskState), stack_left, tcb); } WScript.Echo("Task " + task_name + " added\n"); } function add_list(list, state) { var i, index, item, task; if (list && list.HeadPtr != 0 && list.NbrEntries>0) { index = list.HeadPtr; for (i = 0; i < list.NbrEntries; i++) { item = Debug.evaluate("*(OS_TCB*)" + index); if (index) add_task(index, state); index = item.NextPtr; if (index == 0) break; if (i > 10) break; } } else { // WScript.Echo("list empty\n"); } } function add_pend_list(list, state) { var i, index, item, task; if (list && list.HeadPtr != 0 && list.NbrEntries>0) { index = list.HeadPtr; pend_data = Debug.evaluate("*(OS_PEND_DATA*)" + index); for (i = 0; i < list.NbrEntries; i++) { tcb = Debug.evaluate("(OS_TCB*)" + pend_data.TCBPtr); if (tcb) add_task(tcb, state); index = index.NextPtr; if (index == 0) break; if (i > 40) break; } } else { // WScript.Echo("list empty\n"); } } function update() { var i, list, lists, max_priority; Threads.clear(); if( Debug.evaluate("OSTCBCurPtr") == 0 ) return; max_priority = 31; Threads.newqueue("Ready"); for (i = max_priority; i >= 0; i--) { list = Debug.evaluate("OSRdyList[" + i + "]"); if (list.NbrEntries > 0) { add_list(list, "ready"); } } Threads.newqueue("Delayed"); // Processing delayed tasks list = Debug.evaluate("(OS_TCB*)OSTickListDly.TCB_Ptr"); if (list) { while (list != 0) { item = Debug.evaluate("*(OS_TCB*) " + list); add_task(list, "delayed"); list = item.TickNextPtr; } } list = Debug.evaluate("(OS_TCB*)OSTickListTimeout.TCB_Ptr"); if (list) { while (list != 0) { item = Debug.evaluate("*(OS_TCB*) " + list); add_task(list, "delayed"); list = item.TickNextPtr; } } // Processing tasks waiting for mutex current_mutex = Debug.evaluate("*OSMutexDbgListPtr"); counter = 0; while (current_mutex) { mutex_name = Debug.evaluate("(char*)" + current_mutex.NamePtr); list = current_mutex.PendList; if (list) { if (list.NbrEntries > 0) { Threads.newqueue("Pending on mutex " + mutex_name); add_pend_list(list, "pending"); } } if (current_mutex.DbgNextPtr == 0) break; current_mutex = Debug.evaluate("*(OS_MUTEX*)" + current_mutex.DbgNextPtr); if (current_mutex == undefined) WScript.Echo("current_mutex undefined!\n"); counter++; if (counter > 100) { WScript.Echo("Infinite loop detected, breaking out\n"); break; } } } function init() { Threads.setColumns("Name", "Priority", "State", "Stack Left"); Threads.setSortByNumber("Priority"); }