private static bool parseInput(string instr) { //parse commands entered on std in if (instr.Equals("reset")) { //reset command, send a reset to current node if (sNodeid) { dc.flushData(); CanNMT cpn = new CanNMT(); cpn.doReset(dc, nodeid); } else { if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); } } } else if (instr.Equals("start")) { //start command, send a start to current node if (sNodeid) { CanNMT cpn = new CanNMT(); cpn.doStart(dc, nodeid); } else { if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); } } } else if (instr.StartsWith("go")) { //downloading command bool dlBios = false; bool error = true; if (instr.Equals("go bios")) { //if bios should be downloaded dlBios = true; error = false; } else if (instr.Equals("go")) { //is an application should be downloaded error = false; } if (!sNodeid) { if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); } error = true; } if (!sHexfile) { if (DEBUG_LEVEL>0) { Console.WriteLine("No hexfile has been specified"); } error = true; } CanNMT cpn = new CanNMT(); if (!error && aReset) { //commandline arguments specified that a reset should be done before download //send a reset command (and wait for feedback) if (!cpn.doReset(dc, nodeid)) { if (DEBUG_LEVEL>0) { Console.WriteLine("Target node did not respond to reset"); } error = true; } } if (!error) { //send application dc.flushData(); dl = new Downloader(hf, dc, nodeid, dlBios); if (!dl.go()) { if (DEBUG_LEVEL>0) { Console.WriteLine("Error occured during download"); } error = true; } } if (!error && aStart) { //commandline arguments specified that a start should be done after download //start applikation cpn.doStart(dc, nodeid); } } else if (instr.StartsWith("load")) { //load hexfile or reload current hexfile if (instr.Length > 5) { //second argument is a hexfile, this file should be loaded hexfile = instr.Substring(5); if (hf.loadHex(hexfile)) { sHexfile = true; if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); } } else { if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be loaded"); } } } else { //reload current hexfile. if a hexfile already has been specified if (sHexfile) { if (hf.loadHex(hexfile)) { if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile reloaded"); } } else { if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be reloaded"); } } } else { if (DEBUG_LEVEL>0) { Console.WriteLine("No hexfile has been specified"); } } } } else if (instr.StartsWith("node")) { //change nodeid if (instr.Length > 5) { //second argument is nodeid string node = instr.Substring(5); parseNodeId(node); } if (DEBUG_LEVEL>1) { Console.WriteLine("NodeId is 0x"+ String.Format("{0:x2}", nodeid)); } } else if (instr.Equals("help")) { printHelp(); } else if (instr.Equals("exit") || instr.Equals("quit") || instr.Equals("q")) { return false; } else { Console.WriteLine("Unknown command."); } return true; }
static bool sNodeid = false; //true when a nodeid has been parsed #endregion Fields #region Methods static void Main(string[] args) { bool error = false; if (args.Length < 4) { //if to few arguments then print info and quit printSyntax(); error = true; } if (!error) { //parse commandline arguments CommandLine=new Arguments(args); //check single arguments if (CommandLine["b"] == "true") { aBios = true; } if (CommandLine["r"] == "true") { aReset = true; } if (CommandLine["s"] == "true") { aStart = true; } if (CommandLine["t"] == "true") { aTerminal = true; } //check hexfile argument hexfile = CommandLine["f"]; if (hexfile != null) { sHexfile = true; } if (!aTerminal && !sHexfile && !aReset && !aStart) { if (DEBUG_LEVEL>0) { Console.WriteLine("When not in terminal mode a hexfile, a reset or a start parameter must be supplied, I quit"); } error = true; } //check nodeid argument string node = CommandLine["n"]; if (node != null) { if (!parseNodeId(node)) { error = true; } } if (!aTerminal && !sNodeid) { if (DEBUG_LEVEL>0) { Console.WriteLine("When not in terminal mode a nodeid must be supplied, I quit"); } error = true; } //check host and port arguments host = CommandLine["h"]; string sPort = CommandLine["p"]; if ((host == null) || (sPort.Length == 0)) { if (DEBUG_LEVEL>0) { printSyntax(); } error = true; } else { try { port = int.Parse(sPort); } catch { if (DEBUG_LEVEL>0) { Console.WriteLine("Was not able to parse port, I quit"); } error = true; } } } if (!error) { //commandline feedback output if (DEBUG_LEVEL>2) { Console.WriteLine("canDude settings:"); if (sNodeid) { Console.WriteLine("Nodeaddress: 0x" + String.Format("{0:x2}", nodeid)); } Console.WriteLine("Host: {0}:{1}", host, port); if (hexfile != null) { Console.WriteLine("Hexfile: {0}", hexfile); } Console.Write("Parameters: "); if (aBios) { Console.Write("Bios "); } if (aReset) { Console.Write("Reset "); } if (aStart) { Console.Write("Start "); } if (aTerminal) { Console.Write("Terminal"); } Console.WriteLine(""); } } if (!error) { //connect to candaemon dc = new DaemonConnection(); if (dc.init(host, port)) { if (DEBUG_LEVEL>1) { Console.WriteLine("Connected to candaemon"); } } else { if (DEBUG_LEVEL>0) { Console.WriteLine("Connection to candaemon could not be established, I quit"); } error = true; } } if (!error && aTerminal) { //terminal mode (==interactive mode) bool success = true; //load hexfile if one has been specified as commandline argument hf = new HexFile(); if (sHexfile && success) { if (hf.loadHex(hexfile)) { if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); } } else { success = false; } } if (success) { if (DEBUG_LEVEL>1) { Console.WriteLine(""); printHelp(); //print available commands Console.WriteLine(""); } string instr; do { Console.Write("> "); //a command has been executed, print a new console char instr = Console.ReadLine(); //read std in } while (parseInput(instr)); //parse a line from std in //exit command } } if (!error && !aTerminal) { //not terminal mode bool success = true; if (sHexfile) { //load hexfile (a hexfile must be supplied as commandline argument) hf = new HexFile(); if (hf.loadHex(hexfile)) { if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); } } else { success = false; if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be loaded, I quit"); } } } //if a hexfile is loaded then start autodownloading sequence if (success) { bool autosuccess = true; CanNMT cpn = new CanNMT(); if (aReset) { //send a reset command (and wait for feedback) if (!cpn.doReset(dc, nodeid)) { if (DEBUG_LEVEL>0) { Console.WriteLine("Target node did not respond to reset, I quit"); } autosuccess = false; } } if (sHexfile && autosuccess) { //send application dl = new Downloader(hf, dc, nodeid, aBios); if (!dl.go()) { if (DEBUG_LEVEL>0) { Console.WriteLine("Error occured during download"); } autosuccess = false; } } if (autosuccess && aStart) { //start application cpn.doStart(dc, nodeid); } } } if (dc != null) { //stop tcp client thread dc.stop(); } }
public bool downloader() { dState pgs = dState.SEND_START; int t = 0; int t2 = 0; CanPacket outCm = null; CanPacket cm = null; byte[] data = new byte[8]; uint byteSent = 0; ulong currentAddress = 0; bool done = false; bool errorOccured = false; try { if (isBiosUpdate) { dlOffset = hf.getAddrLower(); //Console.WriteLine(dlOffset); //dlOffset = 200; } CanNMT cpn = new CanNMT(); cpn.setReceiver(receiveID); bool hasMessage = false; while (!done) { Thread.Sleep(1); switch (pgs) { case dState.SEND_START: // Send boot start packet to target. // and wait for ack. currentAddress = hf.getAddrLower(); //data[RID_INDEX] = TARGET_ID; data[ADDR0_INDEX] = (byte)((currentAddress-dlOffset) & 0x0000FF); data[ADDR1_INDEX] = (byte)(((currentAddress-dlOffset) & 0x00FF00) >> 8); data[ADDR2_INDEX] = (byte)(((currentAddress-dlOffset) & 0xFF0000) >> 16); data[ADDR3_INDEX] = 0; //outCm = new CanPacket(CAN_NMT, CAN_NMT_PGM_START, MY_ID, receiveID, 4, data); outCm = cpn.getPgmStartPacket(data); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; pgs = dState.WAIT_ACK_PRG; timeStart = Environment.TickCount; break; case dState.WAIT_ACK_PRG: // Check for timeout, resend start packet in that case.. if ((Environment.TickCount - t) > TIMEOUT_MS) { Console.WriteLine("Timeout while waiting for start prg ack."); errorOccured = true; pgs = dState.SEND_RESET; } //Thread.Sleep(1); // If received ack. hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_PGM_ACK) { // Start sending program data.. byteSent = 0; pgs = dState.SEND_PGM_DATA; } else if (cpnin.getType() == CAN_NMT_PGM_NACK ) { // else .. Console.WriteLine("Nack on CAN_NMT_PGM_START."); errorOccured = true; pgs = dState.SEND_RESET; } } } break; case dState.SEND_PGM_DATA: //Console.WriteLine("byteSent = "+byteSent); Console.Write("."); // Send program data. byte datalength = 2; for (ulong i = 0; i < 6; i++) { // Populate data. data[i+2] = hf.getByte(currentAddress + i + byteSent); if (currentAddress + i + byteSent > hf.getAddrUpper()) { break; //then done } datalength++; } data[0] = (byte)(byteSent & 0x00FF); data[1] = (byte)((byteSent & 0xFF00) >> 8); outCm = cpn.getPgmDataPacket(data, datalength); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; byteSent += 6; pgs = dState.WAIT_ACK_DATA; break; case dState.WAIT_ACK_DATA: // Wait for pgm ack. if ((Environment.TickCount - t) > TIMEOUT_MS) { // Woops, error. Console.WriteLine("Timeout while waiting for data ack."); errorOccured = true; pgs = dState.SEND_RESET; } else if ((Environment.TickCount - t2) > TIMEOUT_SHORT_MS) { // Woops, error. Console.Write(":"); byteSent -= 6; pgs = dState.SEND_PGM_DATA; break; } //Thread.Sleep(1); // If received ack. hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_PGM_ACK) { //currentAddress += 2; // Check if end. if (currentAddress + byteSent > hf.getAddrUpper()) { // Yes, we are done, send done. pgs = dState.SEND_DONE; } else { // More to write. //byteSent = 0; pgs = dState.SEND_PGM_DATA; } } else if (cpnin.getType() == CAN_NMT_PGM_NACK ) { // else .. Console.WriteLine("Nack on CAN_NMT_PGM_DATA."); errorOccured = true; pgs = dState.SEND_RESET; } } } break; case dState.SEND_DONE: // Send done outCm = cpn.getPgmEndPacket(); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; pgs = dState.WAIT_DONE; break; case dState.WAIT_DONE: // Check for timeout, resend done packet in that case.. if ((Environment.TickCount - t) > TIMEOUT_MS) { Console.WriteLine("Timeout while waiting for end prg ack."); errorOccured = true; pgs = dState.SEND_RESET; } //Thread.Sleep(1); hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_PGM_ACK) { Console.WriteLine(""); // int crc = calcCRC(hf); if (cm.getDataLength() == 2) { byte[] cmdata = cm.getData(); if ((cmdata[0] == (crc & 0xFF)) && (cmdata[1] == (crc>>8))) { if (!isBiosUpdate) { Console.WriteLine("Done, successfully programmed application."); pgs = dState.SEND_RESET; } else { Console.WriteLine("Done, successfully programmed bios to application space."); pgs = dState.SEND_BIOS_UPDATE; } } else { string nodecrc = String.Format("{0:x4}", (int)cmdata[0] + (int)(cmdata[1]<<8)); nodecrc = "0x"+nodecrc; string realcrc = String.Format("{0:x4}", (int)(crc & 0xFF) + (int)(crc & 0xFF00)); realcrc = "0x"+realcrc; Console.WriteLine("CRC failed. Node sent CRC "+nodecrc+" but should be "+realcrc+"."); errorOccured = true; pgs = dState.SEND_RESET; } byteSent = 0; } //Console.WriteLine("crc: " + crc + " " + (crc>>8) + " " + (crc & 0xFF)); //Console.WriteLine("ACKpkg with CRC: " + cm.ToString()); // } else if (cpnin.getType() == CAN_NMT_PGM_NACK) { // else resend addr.. Console.WriteLine("Nack on CAN_NMT_PGM_END."); errorOccured = true; pgs = dState.SEND_RESET; } } } break; case dState.SEND_BIOS_UPDATE: data[0] = (byte)(0 & 0x00FF); data[1] = (byte)((0 & 0xFF00) >> 8); data[2] = (byte)(dlOffset & 0x00FF); data[3] = (byte)((dlOffset & 0xFF00) >> 8); data[4] = (byte)((hf.getAddrUpper()-hf.getAddrLower()+1) & 0x00FF); data[5] = (byte)(((hf.getAddrUpper()-hf.getAddrLower()+1) & 0xFF00) >> 8); outCm = cpn.getPgmCopyPacket(data); Console.WriteLine("Now say a prayer, moving bios"); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; pgs = dState.WAIT_BOOT; //pgs = dState.DONE; break; case dState.WAIT_BOOT: // Wait for node reset answer (boot msg). if ((Environment.TickCount - t) > 3*TIMEOUT_MS) { // Woops, error. Console.WriteLine("Timeout while waiting for node to boot."); errorOccured = true; pgs = dState.SEND_DONE; } //Thread.Sleep(1); // If received boot msg. hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_BIOS_START) { pgs = dState.SEND_EMPTY_START; } else { // else .. } } } break; case dState.SEND_EMPTY_START: // Send boot start packet to target. // and wait for ack. //data[RID_INDEX] = TARGET_ID; data[ADDR0_INDEX] = (byte)((0) & 0x0000FF); data[ADDR1_INDEX] = (byte)(((0) & 0x00FF00) >> 8); data[ADDR2_INDEX] = (byte)(((0) & 0xFF0000) >> 16); data[ADDR3_INDEX] = 0; //outCm = new CanPacket(CAN_NMT, CAN_NMT_PGM_START, MY_ID, receiveID, 4, data); outCm = cpn.getPgmStartPacket(data); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; pgs = dState.WAIT_ACK_PRG_EMPTY; timeStart = Environment.TickCount; break; case dState.WAIT_ACK_PRG_EMPTY: // Check for timeout, resend start packet in that case.. if ((Environment.TickCount - t) > 3*TIMEOUT_MS) { Console.WriteLine("Timeout while waiting for start prg ack."); errorOccured = true; pgs = dState.SEND_RESET; } //Thread.Sleep(1); // If received ack. hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_PGM_ACK) { // Start sending program data.. byteSent = 0; pgs = dState.SEND_EMPTY_DATA; } else if (cpnin.getType() == CAN_NMT_PGM_NACK ) { // else .. Console.WriteLine("Nack on CAN_NMT_PGM_START."); errorOccured = true; pgs = dState.SEND_RESET; } } } break; case dState.SEND_EMPTY_DATA: // Send program data. data[0] = 0; data[1] = 0; data[2] = 0xff; data[3] = 0xff; outCm = cpn.getPgmDataPacket(data, 4); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; byteSent += 6; pgs = dState.WAIT_ACK_EMPTY_DATA; break; case dState.WAIT_ACK_EMPTY_DATA: // Wait for pgm ack. if ((Environment.TickCount - t) > 2*TIMEOUT_MS) { // Woops, error. Console.WriteLine("Timeout while waiting for data ack."); errorOccured = true; pgs = dState.SEND_RESET; } //Thread.Sleep(1); // If received ack. hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_PGM_ACK) { pgs = dState.SEND_DONE_EMPTY; } else if (cpnin.getType() == CAN_NMT_PGM_NACK ) { // else .. Console.WriteLine("Nack on CAN_NMT_PGM_DATA."); errorOccured = true; pgs = dState.SEND_RESET; } } } break; case dState.SEND_DONE_EMPTY: // Send done outCm = cpn.getPgmEndPacket(); dc.sendCanPacket(outCm); t = Environment.TickCount; t2 = Environment.TickCount; pgs = dState.WAIT_DONE_EMPTY; break; case dState.WAIT_DONE_EMPTY: // Check for timeout, resend done packet in that case.. if ((Environment.TickCount - t) > TIMEOUT_MS) { Console.WriteLine("Timeout while waiting for end prg ack."); errorOccured = true; pgs = dState.SEND_RESET; } //Thread.Sleep(1); hasMessage = dc.getData(out cm); if (hasMessage) { CanNMT cpnin = new CanNMT(cm); if (cpnin.isNMTPacket() && (cpnin.getSender() == receiveID)) { // If no error if (cpnin.getType() == CAN_NMT_PGM_ACK) { Console.WriteLine(""); // Console.WriteLine("Done, successfully cleaned application flash."); pgs = dState.SEND_RESET; } else if (cpnin.getType() == CAN_NMT_PGM_NACK) { // else resend addr.. Console.WriteLine("Nack on CAN_NMT_PGM_END."); errorOccured = true; pgs = dState.SEND_RESET; } } } break; case dState.SEND_RESET: // Send reset cpn.doReset(dc, receiveID); t = Environment.TickCount; t2 = Environment.TickCount; pgs = dState.DONE; break; case dState.DONE: done = true; //down.Abort(); if (!errorOccured) { long tsecs = ((Environment.TickCount - timeStart) / 1000); double bitRate = hf.getLength() / ((double)(Environment.TickCount - timeStart) / 1000.0); if (tsecs <= 0) tsecs = 1; long mins = tsecs / 60; long secs = tsecs % 60; string pad = ""; if (secs < 10) { pad = "0"; } Console.WriteLine("Time spent: " + mins + ":" + pad + secs + ", " + Math.Round(bitRate, 2) + " bytes/s"); } //Console.Write("> "); break; } } } catch(Exception) { Console.WriteLine("Exception occured"); //Console.WriteLine(e); //skriva ut antal bytes skrivna vore bra här, kanske nån annan form av hjälp för debug, något gick snett liksom } return !errorOccured; }