コード例 #1
0
        public bool Ping(BootloaderClient dev, int timeout)
        {
            int x = this.random.Next();

            byte[] payload = BitConverter.GetBytes(x);

            Message ping_message = new Message(dev.BootloaderAddress, MessageType.Ping, payload);
            Message msg          = SendAndWaitForResponse(dev, ping_message, timeout, false);

            // check if there was a response
            if (msg == null)
            {
                return(false);
            }

            // check if the received payload size is the same as sent
            if (msg.Payload.Length != 4)
            {
                return(false);
            }

            // compare the contents
            for (int i = 0; i < 4; i++)
            {
                if (payload[i] != msg.Payload[i])
                {
                    return(false);
                }
            }

            // well, ok then
            return(true);
        }
コード例 #2
0
        public void WriteEEPROM(BootloaderClient endpoint, MemoryMap source)
        {
            Console.CursorVisible = false;

            Console.Write("   Writing EEPROM memory ({0}kB):   ", source.Size / 1024);
            ConsoleProgressBar cpb = new ConsoleProgressBar(0, source.Size);

            for (uint addr = 0; addr < source.Size; addr += 128, cpb.Progress = addr)
            {
                byte[] payload = new byte[2 + 128];
                payload[0] = (byte)(addr & 0xFF);
                payload[1] = (byte)((addr >> 8) & 0xFF);
                source.Read(addr, payload, 2, 128);

                Message msg_write = new Message(endpoint.BootloaderAddress, MessageType.WriteEepromPage, payload);

                Message response = SendAndWaitForResponse(endpoint, msg_write, 2000);
                if (response.Type != MessageType.WriteEepromPage)
                {
                    throw new CnCException("response.Type");
                }
            }

            Console.CursorVisible = true;
            Console.WriteLine("Done.");
        }
コード例 #3
0
        public void ReadBootloaderVersion(BootloaderClient dev, ref string ver)
        {
            Console.CursorVisible = false;


            Message msg_readfwver = new Message(dev.BootloaderAddress, MessageType.ReadBootloaderVersion);
            Message response      = SendAndWaitForResponse(dev, msg_readfwver, 2000);

            ver = Encoding.ASCII.GetString(response.Payload, 0, response.Payload.Length - 1);

            Console.CursorVisible = true;
            Console.WriteLine($"   Reading bootloader fw version: [{ver}]");
        }
コード例 #4
0
        public void ReadSignature(BootloaderClient endpoint, out byte[] signature)
        {
            Console.CursorVisible = false;
            signature             = null;

            Console.Write("   Reading AVR CPU signature (32b): ");

            Message msg_readsig = new Message(endpoint.BootloaderAddress, MessageType.ReadSignature);
            Message response    = SendAndWaitForResponse(endpoint, msg_readsig, 2000);

            signature = response.Payload;

            Console.CursorVisible = true;
            Console.WriteLine("   Done ({0:X2} {1:X2} {2:X2}).", signature[0], signature[2], signature[4]);
        }
コード例 #5
0
        public bool Reboot(BootloaderClient dev)
        {
            Console.Write("Rebooting {0:X2}... ", dev.BootloaderAddress);
            Message reboot_message = new Message(dev.BootloaderAddress, MessageType.Reboot);
            Message msg            = SendAndWaitForResponse(dev, reboot_message, 200, false);

            if (msg != null)
            {
                Console.WriteLine("Ok.");
            }
            else
            {
                Console.WriteLine("Failed.");
            }

            return(msg != null);
        }
コード例 #6
0
        public void ReadEEPROM(BootloaderClient endpoint, MemoryMap dest)
        {
            Console.CursorVisible = false;

            Console.Write("   Reading EEPROM memory ({0}kB):   ", dest.Size / 1024);
            ConsoleProgressBar cpb = new ConsoleProgressBar(0, dest.Size);

            for (uint addr = 0; addr < dest.Size; addr += 128, cpb.Progress = addr)
            {
                Message msg_readpage = new Message(endpoint.BootloaderAddress, MessageType.ReadEepromPage, new byte[] { (byte)(addr & 0xFF), (byte)(addr >> 8), });

                Message response = SendAndWaitForResponse(endpoint, msg_readpage, 2000);
                dest.Write(addr, response.Payload, 0, 128);
            }

            Console.CursorVisible = true;
            Console.WriteLine("Done.");
        }
コード例 #7
0
        public bool VerifyEEPROM(BootloaderClient endpoint, MemoryMap expected)
        {
            Console.CursorVisible = false;

            Console.Write("   Verifying EEPROM memory ({0}kB): ", expected.Size / 1024);
            ConsoleProgressBar cpb    = new ConsoleProgressBar(0, expected.Size);
            MemoryMap          mmread = new MemoryMap(expected.Size);

            for (uint addr = 0; addr < expected.Size; addr += 128, cpb.Progress = addr)
            {
                Message msg_readpage = new Message(endpoint.BootloaderAddress, MessageType.ReadEepromPage, new byte[] { (byte)(addr & 0xFF), (byte)(addr >> 8), });

                Message response = SendAndWaitForResponse(endpoint, msg_readpage, 2000);
                mmread.Write(addr, response.Payload, 0, 128);
            }

            UInt32 difference_address = 0;
            bool   result             = expected.BinaryCompare(mmread, ref difference_address);

            Console.CursorVisible = true;
            if (result)
            {
                Console.WriteLine("Correct.");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Failed.");
                Console.ForegroundColor = ConsoleColor.Gray;

                byte expected_byte = expected.ReadByte(difference_address);
                byte existing_byte = mmread.ReadByte(difference_address);

                throw new MemoryVerificationException("FLASH", difference_address, expected_byte, existing_byte);
            }
            return(result);
        }
コード例 #8
0
        static void Main(string[] args)
        {
            ShowIntro();

            random = new Random();

            BootloaderJobsLoader btp = new BootloaderJobsLoader();

            Console.WriteLine($"Reading task file...");
            try
            {
                btp.LoadTasks("bootloader_tasks_real.json");
            }
            catch (Exception ex)
            {
                ColorConsole.WriteLine(ConsoleColor.Red, "Error druing reading: " + ex.Message);
            }


            // Find highest bootloader id
            byte[] addresses_to_check = btp.Jobs.Where(x => x.BootloaderID.HasValue).Select(x => x.BootloaderID.Value).Distinct().ToArray();

            // Show some summary
            Console.WriteLine($"Task summary:");
            Console.WriteLine($"   Found {btp.Count} task(s).");
            Console.WriteLine($"   Highest bootloader ID: 0x{addresses_to_check.Max():X2}");
            Console.WriteLine($"   Unique bootloaders (by ID): {btp.Jobs.Select(x => x.BootloaderID).Where(x => x.HasValue).Distinct().Count()}");
            Console.WriteLine($"   Unique bootloaders: {string.Join(",", addresses_to_check.Select(x => "0x" + x.ToString("X2")).Distinct())}");

            //
            // Wait for all serial ports to be connected and identified
            AVRBootloaderCnC cnc = new AVRBootloaderCnC();

            cnc.SendAdvertisementToEveryDetectedPort();

            // Scan all available serial ports for bootloaders
            cnc.AcquireBootloaderDevicesInParallel(addresses_to_check);



            // show found devices
            cnc.ShowDevices();


            for (int job_index = 0; job_index < btp.Count; job_index++)
            {
                JobEntry          job_entry           = btp.Jobs[job_index];
                JobTypeDescriptor job_type_descriptor = JobTypeDescriptorCollection.GetDescriptor(job_entry.JobType);
                ColorConsole.WriteLine(ConsoleColor.Cyan, $"Running task {job_index}: {job_entry.JobType} for device {job_entry.CPU} ID={job_entry.BootloaderID:X2}...");

                // Get the device
                BootloaderClient device = cnc.Devices.Where(x => x.BootloaderAddress == job_entry.BootloaderID).FirstOrDefault();
                if (device == null && job_type_descriptor.IsPhysicalDeviceNeeded)
                {
                    ColorConsole.WriteLine(ConsoleColor.Yellow, "   No proper device found.");
                    continue;
                }

                if (job_entry.JobType == JobType.ReadEepromMemory)
                {
                    MemoryMap mm = new MemoryMap(job_entry.ProgrammableMemorySize);

                    cnc.ReadEEPROM(device, mm);
                    IntelHEX16Storage storage = new IntelHEX16Storage(mm);
                    storage.Save(job_entry.FileName);
                }

                if (job_entry.JobType == JobType.ReadFlashMemory)
                {
                    MemoryMap mm = new MemoryMap(job_entry.ProgrammableMemorySize);
                    cnc.ReadFLASH(device, mm);
                    IntelHEX16Storage storage = new IntelHEX16Storage(mm);
                    storage.Save(job_entry.FileName);
                }

                if (job_entry.JobType == JobType.WriteEepromMemory)
                {
                    FileInfo          fi      = new FileInfo(job_entry.FileName);
                    MemoryMap         mm      = new MemoryMap(job_entry.ProgrammableMemorySize);
                    IntelHEX16Storage storage = new IntelHEX16Storage(mm);
                    storage.Load(fi.FullName);
                    Console.WriteLine($"   File name: {fi.FullName}");
                    Console.WriteLine($"   Modified.: {fi.LastWriteTime}");
                    cnc.WriteEEPROM(device, mm);
                }


                if (job_entry.JobType == JobType.WriteFlashMemory)
                {
                    FileInfo          fi      = new FileInfo(job_entry.FileName);
                    MemoryMap         mm      = new MemoryMap(job_entry.ProgrammableMemorySize);
                    IntelHEX16Storage storage = new IntelHEX16Storage(mm);
                    storage.Load(fi.FullName);
                    Console.WriteLine($"   File name: {fi.FullName}");
                    Console.WriteLine($"   Modified.: {fi.LastWriteTime}");
                    cnc.WriteFLASH(device, mm);
                }

                if (job_entry.JobType == JobType.Reboot)
                {
                    cnc.Reboot(device);
                }

                if (job_entry.JobType == JobType.WaitForKey)
                {
                    if (!string.IsNullOrEmpty(job_entry.WaitForKeyMessage))
                    {
                        ColorConsole.PressAnyKey(job_entry.WaitForKeyMessage);
                    }
                    else
                    {
                        ColorConsole.PressAnyKey();
                    }
                }

                if (job_entry.JobType == JobType.ReadBootloaderVersion)
                {
                    string ver = "";
                    cnc.ReadBootloaderVersion(device, ref ver);
                }
            }

            ColorConsole.PressAnyKey();
        }
コード例 #9
0
        private Message SendAndWaitForResponse(BootloaderClient ep, Message request, int timeout, bool throw_timeout_exception = true, int retries = 3)
        {
            Debug.Assert(ep.BootloaderAddress == request.Address);

            MessageExtractor me = new MessageExtractor();

            byte[] buffer = new byte[1024];
            byte[] empty  = new byte[128 + 4 + 5];

            Message msg = null;

            while (retries-- >= 0)
            {
                // setup serial port
                ep.Port.DiscardInBuffer();
                ep.Port.DiscardOutBuffer();
                ep.Port.ReadTimeout = 200;

                // send data
                ep.Port.Write(request.Binary, 0, request.BinarySize);
                Thread.Sleep(0);
                //Debug.WriteLine("sent " + request.BinarySize.ToString());

                // and wait for response
                DateTime start = DateTime.Now;
                do
                {
                    int read = -1;
                    try {
                        read = ep.Port.Read(buffer, 0, buffer.Length);
                    }
                    catch (TimeoutException tex) {
                        Debug.WriteLine("TO");
                        continue; // ignore timeouts
                    }
                    catch (Exception ex) {
                        Debug.WriteLine("EX");
                        break; // shit happens
                    }

                    me.AddData(buffer, read);
                    if (me.TryExtract(ref msg, request.Address, request.Type))
                    {
                        break; // ok, got message!
                    }
                } while ((DateTime.Now - start).TotalMilliseconds <= timeout && timeout != -1);

                // if message was correctly received then stop communication
                if (msg != null)
                {
                    break;
                }
                Debug.WriteLine("RETRY");
            }
            if (msg == null && throw_timeout_exception)
            {
                throw new TimeoutException(string.Format("No response from bootloader device 0x{0:X2} on {1}", ep.BootloaderAddress, ep.Port.PortName));
            }

            return(msg);
        }