Beispiel #1
0
        static int Main(string[] args)
        {
            /* install global Exception handler
             * Won't do much more than pretify'ing the error messages but better
             * fail gracefully that terribly
             */
            System.AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;

            bool errors_encountered = false;

            CommandLineParser cmd_parser = new CommandLineParser();

            if (cmd_parser.parse_command_line(args) == false)
            {
                return(RETURN_INVALID_CMDLINE);
            }

            /********************************
             * SEED EROS Bdrige mode enable/disable requests
             */

            /* SEED EROS Bridge Enable */
            if (cmd_parser.bootloader_operations.Contains(CommandLineParser.en_bootloader_operations.SEEDEROS_BRIDGEENABLE))
            {
                System.IO.Ports.SerialPort serial_port = new System.IO.Ports.SerialPort();

                serial_port.BaudRate = cmd_parser.baudrate_bps;
                serial_port.PortName = cmd_parser.port_name;
                serial_port.Encoding = Encoding.ASCII;

                try
                {
                    Console.WriteLine();
                    Console.WriteLine("> Seed Robotics Eros: Enabling bridge mode...");

                    serial_port.Open();
                    System.Threading.Thread.Sleep(cmd_parser.prewait_ms);

                    /* clear out any wrong/previous commands that might exist on the board buffer
                     * This ensures we're at a clean state of the command parser when we send the bridge enable command */
                    serial_port.Write("\r\n");
                    wait_for_reply(serial_port, cmd_parser.replytimeout_ms);
                    System.Threading.Thread.Sleep(500); /* wait another 500ms to fully receive all comms */
                    serial_port.ReadExisting();         /* read and discard */

                    /* now send the actual command */
                    /* 20 = 4 + 16 (Int bus to USB with DTR reset) */
                    serial_port.Write("commbridge 20\r\n"); /* this command is specific to the EROS firmware CONSOLE; if you
                                                             * don't have a console on the port you are trying to open, this is
                                                             * not necessary;
                                                             * It bridges the USB interface to the Internal bus, using the
                                                             * a special bridge mode built for flashing the servos
                                                             * (it will auto reset the bus on Serial connect, uses a softserial library to
                                                             * cope with the device side of TSB weird timing, etc.) */

                    wait_for_reply(serial_port, cmd_parser.replytimeout_ms);

                    if (serial_port.BytesToRead < 1)
                    {
                        Console.WriteLine("ERROR");
                        Console.WriteLine("No reply from the Seed Eros device.");
                        Console.WriteLine("(Is this Serial Port connected to a Seed Eros device? Is the device already in bridge mode?)");
                        return(RETURN_SEEDEROS_COMMAND_FAILED);
                    }
                    else
                    {
                        Console.Write("  < Reply: ");
                        while (serial_port.BytesToRead > 0)
                        {
                            Console.WriteLine(serial_port.ReadLine().ToString());
                        }
                    }

                    serial_port.Close();

                    return(0);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ERROR");
                    Console.WriteLine(ex.Message);
                    Console.WriteLine();
                    Console.WriteLine("> Pre requisite command (SeedEros) failed. Ending session.");
                    return(RETURN_SEEDEROS_COMMAND_FAILED);
                }
            }

            /* SEED EROS Bridge Disable */
            if (cmd_parser.bootloader_operations.Contains(CommandLineParser.en_bootloader_operations.SEEDEROS_BRIDGEDISABLE))
            {
                System.IO.Ports.SerialPort serial_port = new System.IO.Ports.SerialPort();

                /* to exit bridge mode, we open and close the port at 1200 bps */
                serial_port.BaudRate = 1200;
                serial_port.PortName = cmd_parser.port_name;
                serial_port.Encoding = Encoding.ASCII;

                try
                {
                    Console.WriteLine();
                    Console.Write("> Seed Robotics Eros: Sending Host request to disable bridge mode...");

                    serial_port.Open();
                    serial_port.DtrEnable = true;       /* on Mono / .Net we apparently need to explicitly set DTR */

                    System.Threading.Thread.Sleep(800); /* wait a couple of seconds */

                    serial_port.Close();
                    System.Threading.Thread.Sleep(1000); /* wait a couple of seconds */

                    Console.WriteLine(" Done.\n");
                    Console.WriteLine("  ( If your firmware supports host request to exit bridge mode, the unit's LEDs should be back to white/three colours.");
                    Console.WriteLine("    If the LED colour hasn't changed, you need to manually power cycle your unit (including disconnecting the USB cable) to resume regular operation.)");

                    return(0);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ERROR");
                    Console.WriteLine(ex.Message);
                    Console.WriteLine();
                    Console.WriteLine("> Post process command (SeedEros) failed.");
                    return(RETURN_SEEDEROS_COMMAND_FAILED);
                }
            }

            /* Emergency Erase Request
             * Emergency Erase restoresbootloader acces sin case of lost password, by wiping
             * the full FLASH and EEPROM memory areas
             */
            if (cmd_parser.bootloader_operations.Contains(CommandLineParser.en_bootloader_operations.EMERGENCY_ERASE))
            {
                Console.WriteLine();
                Console.WriteLine("WARNING: Emergency Erase deletes all Application Flash");
                Console.WriteLine("and EEPROM data, as well as Timeout and Password.");
                Console.WriteLine("No Firmware or EEPROM data will be left on the device after");
                Console.WriteLine("this operation.");
                Console.WriteLine("This provides for a clean TSB with default values.");
                Console.WriteLine();
                Console.WriteLine("IMPORTANT! An Emergency Erase DOES NOT target an individual");
                Console.WriteLine("device; if the device is connected on a BUS (Daisy chain),");
                Console.WriteLine("ALL the devices will perform the Emergency Erase.");
                Console.WriteLine();
                Console.WriteLine("This function should ONLY be used by experienced users.");
                Console.WriteLine();
                Console.Write("Do you fully understand the information above? (Y/n) ");
                if (!get_YesNo_reply())
                {
                    Console.WriteLine();
                    Console.WriteLine("Operation cancelled. Nothing was done.");
                    return(0);
                }
                Console.Write("Do you wish to continue? (Y/n) ");
                if (!get_YesNo_reply())
                {
                    Console.WriteLine();
                    Console.WriteLine("Operation cancelled. Nothing was done.");
                    return(0);
                }

                Console.WriteLine();

                TSBInterfacing tsb = new TSBInterfacing();
                if (!tsb.EmergencyErase(cmd_parser.port_name, cmd_parser.baudrate_bps, cmd_parser.prewait_ms, cmd_parser.replytimeout_ms))
                {
                    Console.WriteLine();
                    Console.WriteLine("> Error while performing Emergency Erase operation.");
                    return(RETURN_ERRORS_ENCOUNTERED);
                }
                else
                {
                    return(0);
                }
            }


            /********** Main cycle for multi-device bootloader operations **************
             * /* Cycle through the passwords specified for the bootloader */
            if (cmd_parser.bootloader_passwords.Count() == 0)
            {
                /* add a bogus entry with an empty password. Assuming user intends to start the session
                 * with no password. */
                cmd_parser.bootloader_passwords.Add("");
            }

            /* only advance to TSB if we have more commands lined up and requested at the command line */
            if (cmd_parser.bootloader_operations.Count == 0 ||
                (cmd_parser.bootloader_operations.Count == 1 && cmd_parser.bootloader_operations.Contains(CommandLineParser.en_bootloader_operations.SEEDEROS_BRIDGEDISABLE)))
            {
                Console.WriteLine();
                Console.WriteLine("> No bootloader actions specified. Ending session");
                return(0);
            }


            foreach (string pwd in cmd_parser.bootloader_passwords)
            {
                if (pwd.Length > 0)
                {
                    Console.WriteLine();
                    Console.WriteLine("> Activating bootloader for device with password: {0}", pwd);
                    Console.WriteLine();
                }
                else
                {
                    Console.WriteLine();
                    Console.WriteLine("> Activating bootloader (no device password specified)");
                    Console.WriteLine();
                }


                /* build a new instance for every new device; this ensures variables and
                 * control structures come from a clean slate, which makes sense, since we're
                 * starting a whole new session
                 */
                TSBInterfacing tsb = new TSBInterfacing();

                if (tsb.ActivateBootloader(cmd_parser.port_name, cmd_parser.baudrate_bps, cmd_parser.prewait_ms, cmd_parser.replytimeout_ms, pwd))
                {
                    /* Bootloader is active. Print all bootloader information */
                    PrintDeviceInfo(tsb);

                    if (cmd_parser.patch_daisychain_bug)
                    {
                        if (tsb.session_data_.daisychain_patch_in_lastpage == false)
                        {
                            /* forcing a LastPageWrite will write the data with the necessary
                             * patches in place to cope with this bug */

                            Console.WriteLine();
                            Console.WriteLine("> Patching for daisy chain operation", pwd);
                            Console.WriteLine();

                            tsb.LastPage_Write();
                        }
                        else
                        {
                            Console.WriteLine();
                            Console.WriteLine("> Daisy chain patch is already applied", pwd);
                            Console.WriteLine();
                        }
                    }

                    /*  check if the user asked to tag the file names.
                     *  This MUST be done here for the cases where we use multiple
                     *  passwords; in that case, we have sessins starting at different times
                     *  (initiated here) and also different passwords
                     */
                    string tag = string.Format("_{0:yyMMdd}_{0:HHmmss}", DateTime.Now);
                    if (pwd.Length > 0)
                    {
                        tag += string.Format("_{0}", pwd);
                    }

                    string eep_filename   = cmd_parser.eeprom_file_name;
                    string flash_filename = cmd_parser.flash_file_name;

                    if (cmd_parser.tag_eepromfilename_withdatetimepwd && !string.IsNullOrEmpty(cmd_parser.eeprom_file_name))
                    {
                        eep_filename = AddTagToFilename(cmd_parser.eeprom_file_name, tag);
                    }

                    if (cmd_parser.tag_flashfilename_withdatetimepwd && !string.IsNullOrEmpty(cmd_parser.flash_file_name))
                    {
                        flash_filename = AddTagToFilename(cmd_parser.flash_file_name, tag);
                    }


                    /* loop through the various operations requested */
                    foreach (CommandLineParser.en_bootloader_operations bootloader_op in cmd_parser.bootloader_operations)
                    {
                        switch (bootloader_op)
                        {
                        case CommandLineParser.en_bootloader_operations.DISPLAY_DEVICE_INFO:
                            /* do nothing; when we activated TSB it already displayed the device info */
                            break;

                        case CommandLineParser.en_bootloader_operations.EEP_ERASE:
                            if (!tsb.EEProm_Erase())
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Erasing EEProm.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.EEP_WRITE:
                            if (!tsb.EEProm_Write(eep_filename))
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Writing EEPROM.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.EEP_VERIFY:
                            if (!tsb.EEProm_Verify(eep_filename))
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Verifying EEPROM.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.EEP_READ:
                            if (!tsb.EEProm_Read(eep_filename))
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Reading EEPROM.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.FW_ERASE:
                            if (!tsb.Flash_Erase())
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Erasing Flash.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.FW_WRITE:
                            if (!tsb.Flash_Write(flash_filename))
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Writing Flash.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.FW_VERIFY:
                            if (!tsb.Flash_Verify(flash_filename))
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Verifying Flash.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.FW_READ:
                            if (!tsb.Flash_Read(flash_filename))
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error Reading Flash.");
                                errors_encountered = true;
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.PASSWORD_CHANGE:
                            /* ask the user for a password */
                            Console.WriteLine();
                            Console.Write("Please enter the new Password (max. {0} chars): ", TSBInterfacing.max_pwd_length);
                            string new_pwd = Console.ReadLine();

                            if (string.IsNullOrEmpty(new_pwd))
                            {
                                new_pwd = "";
                                Console.WriteLine("No password specified. The bootloader will be accessible without password.");
                            }
                            else if (new_pwd.Length > Tsbloader_adv.TSBInterfacing.max_pwd_length)
                            {
                                Console.WriteLine("ERROR: Password is too long. Maximum password length supported by this tool is {0} characters.", Tsbloader_adv.TSBInterfacing.max_pwd_length);
                                Console.WriteLine("> Password has not been changed.");
                            }
                            else
                            {
                                Console.WriteLine("New password will be set to: {0}", new_pwd);
                                Console.WriteLine("(if you lose your password, you may use the Emergency Erase option '-XXX')");
                            }

                            if (request_confirm())
                            {
                                tsb.session_data_.password = new_pwd;
                                if (!tsb.LastPage_Write())
                                {
                                    Console.WriteLine();
                                    Console.WriteLine("> Error writing bootloader configuration data.");
                                    errors_encountered = true;
                                }
                            }
                            break;

                        case CommandLineParser.en_bootloader_operations.TIMEOUT_CHANGE:
                            /* ask the user for a timeout */
                            int new_timeout_setting;
                            while (true)
                            {
                                Console.WriteLine();
                                Console.Write("Please enter the new Timeout setting: ");
                                string new_timeout = Console.ReadLine();

                                if (string.IsNullOrEmpty(new_timeout))
                                {
                                    Console.WriteLine("Invalid timeout specified. Timeout must be number between 8 and 255.");
                                }
                                else
                                {
                                    if (!int.TryParse(new_timeout, out new_timeout_setting))
                                    {
                                        Console.WriteLine("Invalid timeout specified. Timeout must be number between 8 and 255.");
                                    }
                                    else if (new_timeout_setting < 8 || new_timeout_setting > 255)
                                    {
                                        Console.WriteLine("Invalid timeout specified. Timeout must be number between 8 and 255.");
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }

                            /* no need to confirm this one; save immediately */
                            tsb.session_data_.timeout = (byte)new_timeout_setting;
                            if (!tsb.LastPage_Write())
                            {
                                Console.WriteLine();
                                Console.WriteLine("> Error writing bootloader configuration data.");
                                errors_encountered = true;
                            }
                            break;

                        default:
                            Console.WriteLine("ERROR: Unknown Bootloader operation in function main()");
                            return(RETURN_UNKOWN_OPTION_IN_CASE);
                        }
                    }

                    tsb.DeactivateBootloader();
                }
                else
                {
                    Console.WriteLine();
                    Console.WriteLine("> Could not activate bootloader for the selected device.");
                    tsb.DeactivateBootloader();
                    errors_encountered = true;
                }
            }



            if (errors_encountered)
            {
                Console.WriteLine();
                Console.WriteLine("> Requested operations completed with errors. Please review the error messages above.");
                return(RETURN_ERRORS_ENCOUNTERED);
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine("> All operations complete.");
                return(0);
            }
        }