📄 mspcodewatcher.java
字号:
} public MspMote getMote() { return mspMote; } public Breakpoint getLastTriggered() { return lastBreakpoint; } /** * Breakpoint wrapper class. * May contain breakpoint meta data such source code file and line number. * * @author Fredrik Osterlind */ class Breakpoint { private CPUMonitor cpuMonitor = null; private File codeFile = null; private Integer lineNr = null; private Integer address = null; private MspMote mspMote = null; /** * Create new uninitialized breakpoint. Used with setConfigXML(). */ public Breakpoint(MspMote mote) { this.mspMote = mote; } /** * Creates new breakpoint wrapper at given address. * * @param address Executable address * @param mote MSP mote */ public Breakpoint(Integer address, MspMote mote) { this.mspMote = mote; cpuMonitor = new CPUMonitor() { public void cpuAction(int type, int adr, int data) { breakpointReached(Breakpoint.this); } }; mspMote.getCPU().setBreakPoint(address, cpuMonitor); this.address = address; } /** * Creates new breakpoint wrapper at given address with given meta data. * * @param codeFile Source code file * @param lineNr Source code file line number * @param address Executable address * @param mote MSP mote */ public Breakpoint(File codeFile, Integer lineNr, Integer address, MspMote mote) { this(address, mote); this.codeFile = codeFile; this.lineNr = lineNr; } /** * @return MSP mote */ public MspMote getMote() { return mspMote; } /** * @return Source code file */ public File getCodeFile() { return codeFile; } /** * @return Source code file line number */ public Integer getLineNumber() { return lineNr; } /** * @return Executable address */ public Integer getExecutableAddress() { return address; } private void unregisterBreakpoint() { mspMote.getCPU().setBreakPoint(address, null); } public Collection<Element> getConfigXML() { Vector<Element> config = new Vector<Element>(); Element element; element = new Element("address"); element.setText(address.toString()); config.add(element); if (codeFile != null) { element = new Element("codefile"); codeFile = GUI.stripAbsoluteContikiPath(codeFile); element.setText(codeFile.getPath().replaceAll("\\\\", "/")); config.add(element); } if (lineNr != null) { element = new Element("line"); element.setText(lineNr.toString()); config.add(element); } return config; } public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) { for (Element element : configXML) { if (element.getName().equals("codefile")) { codeFile = new File(element.getText()); if (!codeFile.exists()) { return false; } } else if (element.getName().equals("line")) { lineNr = Integer.parseInt(element.getText()); } else if (element.getName().equals("address")) { address = Integer.parseInt(element.getText()); } } if (address == null) { return false; } cpuMonitor = new CPUMonitor() { public void cpuAction(int type, int adr, int data) { breakpointReached(Breakpoint.this); } }; mspMote.getCPU().setBreakPoint(address, cpuMonitor); return true; } } /** * Tries to, using debugging information from firmware file, calculate the executable address of given meta data. * * @param codeFile Source code file * @param lineNr Source code file line number * @return Executable address or null if not found */ public Integer getExecutableAddressOf(File codeFile, int lineNr) { if (codeFile == null || lineNr < 0) { return null; } // Match file names Enumeration fileEnum = debuggingInfo.keys(); while (fileEnum.hasMoreElements()) { File file = (File) fileEnum.nextElement(); if (file != null && file.getName().equals(codeFile.getName())) { /* Found source code file */ Hashtable<Integer, Integer> lineTable = debuggingInfo.get(file); Enumeration lineEnum = lineTable.keys(); while (lineEnum.hasMoreElements()) { Integer line = (Integer) lineEnum.nextElement(); if (line != null && line.intValue() == lineNr) { /* Found line address */ return lineTable.get(line); } } // TODO Return null here to only allow unique source files } } return null; } public Collection<Element> getConfigXML() { Vector<Element> config = new Vector<Element>(); Element element; for (Breakpoint breakpoint: breakpoints) { element = new Element("breakpoint"); Collection breakpointXML = breakpoint.getConfigXML(); if (breakpointXML != null) { element.addContent(breakpointXML); config.add(element); } } return config; } public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) { for (Element element : configXML) { if (element.getName().equals("breakpoint")) { Breakpoint breakpoint = new Breakpoint(mspMote); boolean ret = breakpoint.setConfigXML(element.getChildren(), visAvailable); if (!ret) { return false; } breakpoints.add(breakpoint); lastBreakpoint = null; } } return true; } } private void updateInfo() { // Update instructions view instructionsUI.updateRegs(); instructionsUI.repaint(); // Try locate source file updateCurrentSourceCodeFile(); if (currentCodeFile == null) { return; } displaySourceFile(currentCodeFile, currentLineNumber); codeUI.repaint(); if (currentCodeFile != null) { currentFileButton.setText(currentCodeFile.getName() + ":" + currentLineNumber); } else { currentFileButton.setText("[unknown]"); } fileComboBox.setSelectedIndex(0); } public void closePlugin() { mySimulation.deleteObserver(simObserver); while (breakpoints.getBreakpoints().size() > 0) { breakpoints.removeBreakpoint(breakpoints.getBreakpoints().firstElement().getExecutableAddress()); } } private void updateCurrentSourceCodeFile() { currentCodeFile = null; try { DebugInfo debugInfo = mspMote.getELF().getDebugInfo(mspMote.getCPU().reg[MSP430.PC]); if (debugInfo == null) { return; } /* Nasty Cygwin-Windows fix */ String path = debugInfo.getPath(); if (path == null) { return; } if (path.contains("/cygdrive/")) { int index = path.indexOf("/cygdrive/"); char driveCharacter = path.charAt(index+10); path = path.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/"); } currentCodeFile = new File(path, debugInfo.getFile()); currentLineNumber = debugInfo.getLine(); } catch (Exception e) { logger.fatal("Exception: " + e); currentCodeFile = null; currentLineNumber = -1; } } private File[] getAllSourceFileNames() { String[] sourceFiles = mspMote.getELF().getDebug().getSourceFiles(); Vector<File> files = new Vector<File>(); for (String sourceFile: sourceFiles) { /* Nasty Cygwin-Windows fix */ if (sourceFile.contains("/cygdrive/")) { int index = sourceFile.indexOf("/cygdrive/"); char driveCharacter = sourceFile.charAt(index+10); sourceFile = sourceFile.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/"); } File file = new File(sourceFile); if (!GUI.isVisualizedInApplet()) { if (!file.exists() || !file.isFile()) { logger.warn("Can't locate source file, skipping: " + file.getPath()); } else { files.add(file); } } else { /* Accept all files without existence check */ files.add(file); } } File[] filesArray = new File[files.size()]; for (int i=0; i < filesArray.length; i++) { filesArray[i] = files.get(i); } return filesArray; } private Hashtable<File, Hashtable<Integer, Integer>> getFirmwareDebugInfo() { /* Fetch all executable addresses */ ArrayList<Integer> addresses = mspMote.getELF().getDebug().getExecutableAddresses(); Hashtable<File, Hashtable<Integer, Integer>> fileToLineHash = new Hashtable<File, Hashtable<Integer, Integer>>(); for (int address: addresses) { DebugInfo info = mspMote.getELF().getDebugInfo(address); if (info != null && info.getPath() != null && info.getFile() != null && info.getLine() >= 0) { /* Nasty Cygwin-Windows fix */ String path = info.getPath(); if (path.contains("/cygdrive/")) { int index = path.indexOf("/cygdrive/"); char driveCharacter = path.charAt(index+10); path = path.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/"); } File file = new File(path, info.getFile()); Hashtable<Integer, Integer> lineToAddrHash = fileToLineHash.get(file); if (lineToAddrHash == null) { lineToAddrHash = new Hashtable<Integer, Integer>(); fileToLineHash.put(file, lineToAddrHash); } lineToAddrHash.put(info.getLine(), address); } } return fileToLineHash; } /** * Tries to open and read given text file. * * @param textFile File * @return Line-by-line text in file */ public static Vector<String> readTextFile(URL textFile) throws IOException { URLConnection urlConnection = textFile.openConnection(); urlConnection.setDoInput(true); urlConnection.setUseCaches(false); Vector<String> data = new Vector<String>(); BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); String line; while ((line = reader.readLine()) != null) { data.add(line); } return data; } /** * Tries to open and read given text file. * * @param textFile File * @return Line-by-line text in file */ public static Vector<String> readTextFile(File textFile) { if (GUI.isVisualizedInApplet()) { /* Download from web server instead */ String path = textFile.getPath(); /* Extract Contiki build path */ String contikiBuildPath = GUI.getExternalToolsSetting("PATH_CONTIKI_BUILD"); String contikiWebPath = GUI.getExternalToolsSetting("PATH_CONTIKI_WEB"); if (!path.startsWith(contikiBuildPath)) { return null; } try { /* Replace Contiki parent path with web server code base */ path = contikiWebPath + '/' + path.substring(contikiBuildPath.length()); path = path.replace('\\', '/'); URL url = new URL(GUI.getAppletCodeBase(), path); return readTextFile(url); } catch (MalformedURLException e) { logger.warn("Failure to read source code: " + e); return null; } catch (IOException e) { logger.warn("Failure to read source code: " + e); return null; } } try { BufferedReader in = new BufferedReader( new FileReader(textFile)); String line; Vector<String> textData = new Vector<String>(); while ((line = in.readLine()) != null) { textData.add(line); } in.close(); return textData; } catch (Exception e) { return null; } } public Collection<Element> getConfigXML() { return breakpoints.getConfigXML(); } public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) { return breakpoints.setConfigXML(configXML, visAvailable); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -