Example #1
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.");
        }
        public bool BinaryCompare(MemoryMap mmread, ref uint difference_address)
        {
            if (mmread.Size != this.Size)
            {
                difference_address = uint.MaxValue; //todo other method for extracting this information
                return(false);                      // size don't match
            }

            for (uint i = 0; i < this.Size; i++)
            {
                if (mmread.mem[i] != this.mem[i])
                {
                    difference_address = i;
                    return(false);
                }
            }

            return(true);
        }
Example #3
0
        public void WriteFLASH(BootloaderClient endpoint, MemoryMap source)
        {
            Console.CursorVisible = false;

            Console.Write("   Writing FLASH 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.WriteFlashPage, payload);

                Message response = SendAndWaitForResponse(endpoint, msg_write, 2000);
            }

            Console.CursorVisible = true;
            Console.WriteLine("Done.");
        }
Example #4
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);
        }
        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();
        }
        static void ___________Main(string[] args)
        {
            Console.WriteLine("SmartTable bootloader C&C software by Tomasz Jaworski");
            random = new Random();

            //MemoryMap mm = new MemoryMap(0x10000);
            // IntelHEX16Storage st = new IntelHEX16Storage(mm);
            //  st.Load(@"d:\praca\projekty\SmartTable\atmega328p-rs485-bootloader\Debug\atmega328p_bootloader.hex");
            // mm.Dump("test.txt");


            //if (SerialPort.GetPortNames().Length == 0) {
            //    Console.WriteLine("No serial ports available, quitting...");
            //    return;
            //}

            AVRBootloaderCnC cnc = new AVRBootloaderCnC();

            cnc.SendAdvertisementToEveryDetectedPort();

            cnc.AcquireBootloaderDevices(0x20);

            // show found devices
            cnc.ShowDevices();

            Console.WriteLine("Reading bootloader version and signature");
            foreach (Device dev in cnc.Devices)
            {
                Console.WriteLine("Reading device {0:X2}... ", dev.address);

                // read bootloader version and timestamp
                string ver = "";
                cnc.ReadVersion(dev, ref ver);

                // read CPU signature
                byte[] bsig = null;
                cnc.ReadSignature(dev, out bsig);
            }


            #region DEMO 1 - Download EEPROM from all found devices

            Console.WriteLine("Reading EEPROM and Flash memories...");

            foreach (Device dev in cnc.Devices)
            {
                Console.WriteLine("Reading device {0:X2}... ", dev.address);

                // read eeprom
                MemoryMap mm = new MemoryMap(1024);
                cnc.ReadEEPROM(dev, mm);

                string fname = string.Format("eeprom_{0:X2}", dev.address);
                mm.Dump(fname + ".txt", DumpMode.Text);
                mm.Dump(fname + ".bin", DumpMode.Binary);

                // read flash
                mm = new MemoryMap(32 * 1024);
                cnc.ReadFLASH(dev, mm);

                fname = string.Format("flash_{0:X2}", dev.address);
                mm.Dump(fname + ".txt", DumpMode.Text);
                mm.Dump(fname + ".bin", DumpMode.Binary);
            }

            #endregion


            #region DEMO 2 - Increment a counter in eeprom (@ 0x0A) and in flash (@ 0x0100)

            /*
             * Console.WriteLine("Reading EEPROM and Flash memories...");
             *
             * foreach (Device dev in cnc.Devices) {
             *  Console.WriteLine("Reading device {0:X2}... ", dev.address);
             *
             *  // read eeprom
             *  MemoryMap mm = new MemoryMap(1024);
             *  cnc.ReadEEPROM(dev, mm);
             *
             *  UInt16 a = mm.ReadUInt16(10);
             *  if (a == 0xffff)
             *      a = 0;
             *  else
             *      a++;
             *  mm.Write(10, a);
             *  cnc.WriteEEPROM(dev, mm);
             *  Console.WriteLine("A=" + a.ToString());
             * }
             *
             *
             * foreach (Device dev in cnc.Devices) {
             *  Console.WriteLine("Reading device {0:X2}... ", dev.address);
             *
             *  // read eeprom
             *  MemoryMap mm = new MemoryMap(32*1024);
             *  cnc.ReadFLASH(dev, mm);
             *
             *  UInt16 a = mm.ReadUInt16(0x100);
             *  if (a == 0xffff)
             *      a = 0;
             *  else
             *      a++;
             *  mm.Write(0x100, a);
             *  cnc.WriteFLASH(dev, mm);
             *  Console.WriteLine("A=" + a.ToString());
             * }
             */


            #endregion

            #region  DEMO 3 - fill eeprom and flash with random data

            /*
             * foreach (Device dev in cnc.Devices) {
             *  // read eeprom
             *  MemoryMap mm = new MemoryMap(1024);
             *  for (uint i = 0; i < 1024; i++)
             *      mm.Write(i, (byte)random.Next());
             *
             *  cnc.WriteEEPROM(dev, mm);
             *  string fname = string.Format("eeprom_random_written_{0:X2}", dev.address);
             *  mm.Dump(fname + ".txt", DumpMode.Text);
             *  mm.Dump(fname + ".bin", DumpMode.Binary);
             *
             *  mm.Zero();
             *
             *  cnc.ReadEEPROM(dev, mm);
             *  fname = string.Format("eeprom_random_read_{0:X2}", dev.address);
             *  mm.Dump(fname + ".txt", DumpMode.Text);
             *  mm.Dump(fname + ".bin", DumpMode.Binary);
             * }
             *
             * foreach (Device dev in cnc.Devices) {
             *  // read eeprom
             *  MemoryMap mm = new MemoryMap(32*1024);
             *  for (uint i = 0; i < mm.Size; i++)
             *      mm.Write(i, (byte)random.Next());
             *
             *  cnc.WriteFLASH(dev, mm);
             *  string fname = string.Format("flash_random_written_{0:X2}", dev.address);
             *  mm.Dump(fname + ".txt", DumpMode.Text);
             *  mm.Dump(fname + ".bin", DumpMode.Binary);
             *
             *  mm.Zero();
             *
             *  cnc.ReadFLASH(dev, mm);
             *  fname = string.Format("flash_random_read_{0:X2}", dev.address);
             *  mm.Dump(fname + ".txt", DumpMode.Text);
             *  mm.Dump(fname + ".bin", DumpMode.Binary);
             * }
             */
            #endregion

            /*
             * List<SerialPort> ports = ListAndOpenSerialPorts();
             *
             * // send advertisement to all devices, co they can stay in bootloader mode
             * SendAdvertisement(ports);
             *
             * // purge buffers
             * PurgeSerialPorts(ports);
             *
             * List<Device> endpoints = new List<Device>();
             */
            /*
             * // get list of devices for each serial port
             * foreach (SerialPort sp in ports)
             *  AcquireDevicesOnSerialPort(endpoints, sp);
             *
             * // show discovered devices
             * ShowDevices(endpoints.ToArray());
             */

            //endpoints.Add(new Device(ports[0], 0x51));



            /*            MemoryMap eeprom = new MemoryMap(1024);
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom1a.txt");
             *          eeprom.Write(123, eeprom.ReadInt16(123) + 123);
             *          WriteEEPROM(endpoints[0], eeprom);
             *          VerifyEEPROM(endpoints[0], eeprom);
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom2a.txt");
             *
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom1b.txt");
             *          eeprom.Write(123, eeprom.ReadInt16(123) + 123);
             *          WriteEEPROM(endpoints[0], eeprom);
             *          VerifyEEPROM(endpoints[0], eeprom);
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom2b.txt");
             *
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom1c.txt");
             *          eeprom.Write(123, eeprom.ReadInt16(123) + 123);
             *          WriteEEPROM(endpoints[0], eeprom);
             *          eeprom.Write(400, 99);
             *          VerifyEEPROM(endpoints[0], eeprom);
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom2c.txt");
             *
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom1d.txt");
             *          eeprom.Write(123, eeprom.ReadInt16(123) + 123);
             *          WriteEEPROM(endpoints[0], eeprom);
             *          VerifyEEPROM(endpoints[0], eeprom);
             *          ReadEEPROM(endpoints[0], eeprom);
             *          eeprom.Dump("eeprom2d.txt");
             */

            //byte[] sig;
            //ReadSignature(endpoints[0], out sig);
        }
        public void LoadTasks(string taskDescriptionFile)
        {
            // Read tasks
            Jobs.JobEntryCollection collection = null;
            try
            {
                string content = File.ReadAllText(taskDescriptionFile);
                collection = JsonConvert.DeserializeObject <Jobs.JobEntryCollection>(content);
            }
            catch (IOException ioex)
            {
                throw new BootloaderException($"Job list load error: {ioex.Message}", ioex);
            }
            catch (JsonException jex)
            {
                throw new BootloaderException($"Job list parsing error: {jex.Message}", jex);
            }

            // Verify jobs
            for (int i = 0; i < collection.Jobs.Length; i++)
            {
                JobEntry task = collection.Jobs[i];
                try
                {
                    //todo: refactorize
                    if (task.JobType == JobType.WriteEepromMemory)
                    {
                        //TODO: replace fake load into fake memory with a clear verification procedure
                        MemoryMap         mm = new MemoryMap(task.ProgrammableMemorySize);
                        IntelHEX16Storage s  = new IntelHEX16Storage(mm);
                        s.Load(task.FileName);
                    }

                    if (task.JobType == JobType.WriteFlashMemory)
                    {
                        //TODO: replace fake load into fake memory with a clear verification procedure
                        MemoryMap         mm = new MemoryMap(task.ProgrammableMemorySize);
                        IntelHEX16Storage s  = new IntelHEX16Storage(mm);
                        s.Load(task.FileName);
                    }
                    if (task.JobType == JobType.ReadFlashMemory || task.JobType == JobType.ReadEepromMemory)
                    {
                        //TODO: replace fake load into fake memory with a clear verification procedure
                        //  MemoryMap mm = new MemoryMap(task.ProgrammableMemorySize);
                        // IntelHEX16Storage s = new IntelHEX16Storage(mm);
                        //s.Load(task.FileName);
                    }
                    if (task.JobType == JobType.Reboot)
                    {
                        //?
                    }
                }
                catch (Exception ex)
                {
                    throw new BootloaderException($"Job verification failed ({task.JobType}, task #{i}): {ex.Message}", ex);
                }
            }

            // Seems ok
            this.jobs = collection.Jobs;
        }