Example #1
0
        // This method is called to sent to Visual Studio debugging to Mono
        public static void ForwardVisualStudioDataToMono(byte[] debuggerData, MeadowSerialDevice meadow, int userData)
        {
            // Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}-MDM-Forwarding {debuggerData.Length} bytes to Mono via hcom");
            _meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_DEBUGGING_DEBUGGER_DATA;

            new SendTargetData(meadow).BuildAndSendSimpleData(debuggerData, _meadowRequestType, (uint)userData);
        }
Example #2
0
        public static void WriteFileToFlash(MeadowSerialDevice meadow, string fileName, string targetFileName = null,
                                            int partition = 0)
        {
            meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_START_FILE_TRANSFER;

            if (string.IsNullOrWhiteSpace(targetFileName))
            {
                targetFileName = Path.GetFileName(fileName);
            }

            // For the STM32F7 on meadow, we need source file and destination file names.
            string[] csvArray = fileName.Split(',');
            if (csvArray.Length == 1)
            {
                // No CSV, just the source file name. So we'll assume the targetFileName is correct
                TransmitFileInfoToExtFlash(meadow, meadowRequestType, fileName, targetFileName, partition, 0, false, true);
            }
            else
            {
                // At this point, the fileName field should contain a CSV string containing the source
                // and destionation file names, always in an even number.
                if (csvArray.Length % 2 != 0)
                {
                    Console.WriteLine("Please provide a CSV input with file names \"source, destination, source, destination\"");
                    return;
                }

                for (int i = 0; i < csvArray.Length; i += 2)
                {
                    // Send files one-by-one
                    TransmitFileInfoToExtFlash(meadow, meadowRequestType, csvArray[i].Trim(), csvArray[i + 1].Trim(),
                                               partition, 0, false);
                }
            }
        }
Example #3
0
        //==========================================================================
        // This is most of the mandatory part of every non-data packet
        private int BuildMeadowBoundSimpleCommand(HcomMeadowRequestType requestType,
                                                  UInt32 userData, ref byte[] messageBytes)
        {
            // Note: Could use the StructLayout attribute to build
            int offset = 0;

            // Two byte seq numb
            Array.Copy(BitConverter.GetBytes((UInt16)HCOM_PROTOCOL_COMMAND_SEQ_NUMBER), 0,
                       messageBytes, offset, sizeof(UInt16));
            offset += sizeof(UInt16);

            // Protocol version
            Array.Copy(BitConverter.GetBytes((UInt16)HCOM_PROTOCOL_CURRENT_VERSION_NUMBER), 0, messageBytes, offset, sizeof(UInt16));
            offset += sizeof(UInt16);

            // Command type (2 bytes)
            Array.Copy(BitConverter.GetBytes((UInt16)requestType), 0, messageBytes, offset, sizeof(UInt16));
            offset += sizeof(UInt16);

            // Extra Data
            Array.Copy(BitConverter.GetBytes((UInt16)HCOM_PROTOCOL_EXTRA_DATA_DEFAULT_VALUE), 0, messageBytes, offset, sizeof(UInt16));
            offset += sizeof(UInt16);

            // User Data
            Array.Copy(BitConverter.GetBytes((UInt32)userData), 0, messageBytes, offset, sizeof(UInt32));
            offset += sizeof(UInt32);

            return(offset);
        }
Example #4
0
        //==========================================================================
        // Build and send a "simple" message with only a header
        internal void BuildAndSendSimpleCommand(HcomMeadowRequestType requestType, UInt32 userData)
        {
            var messageBytes = new byte[HCOM_PROTOCOL_COMMAND_REQUIRED_HEADER_LENGTH];

            // Populate the header
            BuildMeadowBoundSimpleCommand(requestType, userData, ref messageBytes);
            EncodeAndSendPacket(messageBytes, 0, HCOM_PROTOCOL_COMMAND_REQUIRED_HEADER_LENGTH);
        }
        private static void TransmitFileInfoToExtFlash(MeadowSerialDevice meadow,
                                                       HcomMeadowRequestType requestType, string sourceFileName,
                                                       string targetFileName, int partition, uint mcuAddr,
                                                       bool deleteFile, bool lastInSeries = false)
        {
            var sw = new Stopwatch();

            var sendTargetData = new SendTargetData(meadow, false);

            try
            {
                //----------------------------------------------
                if (deleteFile == true)
                {
                    // No data packets, no end-of-file message and no mcu address
                    sendTargetData.BuildAndSendFileRelatedCommand(requestType,
                                                                  (UInt32)partition, 0, 0, 0, string.Empty, sourceFileName);
                    return;
                }

                // If ESP32 file we must also send the MD5 has of the file
                string md5Hash = string.Empty;
                if (mcuAddr != 0)
                {
                    using (var md5 = MD5.Create())
                    {
                        using (var stream = File.OpenRead(sourceFileName))
                        {
                            var hash = md5.ComputeHash(stream);
                            md5Hash = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
                        }
                    }
                }

                // Open, read and close the data file
                var fileBytes  = File.ReadAllBytes(sourceFileName);
                var fileCrc32  = CrcTools.Crc32part(fileBytes, fileBytes.Length, 0);
                var fileLength = fileBytes.Length;

                sw.Start();
                sw.Restart();

                sendTargetData.SendTheEntireFile(requestType, targetFileName, (uint)partition,
                                                 fileBytes, mcuAddr, fileCrc32, md5Hash, lastInSeries);

                sw.Stop();

                if (sendTargetData.Verbose)
                {
                    Console.WriteLine($"It took {sw.ElapsedMilliseconds:N0} millisec to send {fileLength:N0} bytes. FileCrc:{fileCrc32:x08}");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"TransmitFileInfoToExtFlash threw :{ex}");
                throw;
            }
        }
 public FileCommandBuilder(HcomMeadowRequestType requestType)
 {
     RequestType = requestType;
     if (_predicates.ContainsKey(RequestType))
     {
         CompletionPredicate = _predicates[RequestType];
         ResponsePredicate   = _predicates[RequestType];
     }
 }
Example #7
0
        public void SendTheEntireFile(HcomMeadowRequestType requestType, string destFileName,
                                      uint partitionId, byte[] fileBytes, UInt32 mcuAddr, UInt32 payloadCrc32,
                                      string md5Hash, bool lastInSeries)
        {
            _packetCrc32 = 0;

            try
            {
                // Build and send the header
                BuildAndSendFileRelatedCommand(requestType,
                                               partitionId, (UInt32)fileBytes.Length, payloadCrc32,
                                               mcuAddr, md5Hash, destFileName);

                //--------------------------------------------------------------
                // Build each data packet
                int    fileBufOffset = 0;
                int    numbToSend;
                UInt16 sequenceNumber = 1;

                while (fileBufOffset <= fileBytes.Length - 1)           // equal would mean past the end
                {
                    if ((fileBufOffset + MeadowDeviceManager.MaxAllowableDataBlock) > (fileBytes.Length - 1))
                    {
                        numbToSend = fileBytes.Length - fileBufOffset;  // almost done, last packet
                    }
                    else
                    {
                        numbToSend = MeadowDeviceManager.MaxAllowableDataBlock;
                    }

                    BuildAndSendDataPacketRequest(fileBytes, fileBufOffset, numbToSend, sequenceNumber);
                    fileBufOffset += numbToSend;

                    sequenceNumber++;
                    //if (sequenceNumber % 1000 == 0)
                    //	Console.WriteLine("Have sent {0:N0} bytes out of {1:N0} in {2:N0} packets",
                    //		fileBufOffset, fileBytes.Length, sequenceNumber);
                }

                //--------------------------------------------------------------
                // Build and send the trailer
                BuildAndSendSimpleCommand(HcomMeadowRequestType.HCOM_MDOW_REQUEST_END_FILE_TRANSFER,
                                          lastInSeries ? (uint)1 : (uint)0); // set UserData

                // bufferOffset should point to the byte after the last byte
                Debug.Assert(fileBufOffset == fileBytes.Length);
                if (Verbose)
                {
                    Console.WriteLine($"Total bytes sent {fileBufOffset:N0} in {sequenceNumber:N0} packets. PacketCRC:{_packetCrc32:x08}");
                }
            }
            catch (Exception except)
            {
                Debug.WriteLine("Exception sending to Meadow:{0}", except);
                throw;
            }
        }
        public static async Task ProcessCommand(MeadowSerialDevice meadow, HcomMeadowRequestType requestType,
                                                Predicate <MeadowMessageEventArgs> filter, uint userData = 0, bool doAcceptedCheck = true, int timeoutMs = 10000)
        {
            await new SendTargetData(meadow).SendSimpleCommand(requestType, userData, doAcceptedCheck);
            var result = await WaitForResponseMessage(meadow, filter, timeoutMs);

            if (!result)
            {
                throw new MeadowDeviceManagerException(requestType);
            }
        }
Example #9
0
        public static void PartitionFileSystem(MeadowSerialDevice meadow, int numberOfPartitions = 2)
        {
            if (numberOfPartitions < 1 || numberOfPartitions > 8)
            {
                throw new IndexOutOfRangeException("Number of partitions must be between 1 & 8 inclusive");
            }

            meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_PARTITION_FLASH_FS;

            new SendTargetData(meadow).SendSimpleCommand(meadowRequestType, (uint)numberOfPartitions);
        }
Example #10
0
        //providing a numeric (0 = none, 1 = info and 2 = debug)
        public static void SetTraceLevel(MeadowSerialDevice meadow, int level)
        {
            if (level < 0 || level > 3)
            {
                throw new System.ArgumentOutOfRangeException(nameof(level), "Trace level must be between 0 & 3 inclusive");
            }

            _meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_CHANGE_TRACE_LEVEL;

            new SendTargetData(meadow).SendSimpleCommand(_meadowRequestType, (uint)level);
        }
Example #11
0
        public static async Task <string> GetDeviceSerialNumber(MeadowSerialDevice meadow, int timeoutMs = 1000)
        {
            _meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_GET_DEVICE_INFORMATION;
            await new SendTargetData(meadow).SendSimpleCommand(_meadowRequestType);
            var result = await WaitForResponseMessage(meadow, p => p.MessageType == MeadowMessageType.DeviceInfo, millisecondDelay : timeoutMs);

            if (result.isSuccessful)
            {
                return(ParseDeviceInfo(result.message, "Serial Number: ", ","));
            }

            return(string.Empty);
        }
Example #12
0
        //==========================================================================
        // Build and send a "simple" message with data
        // Added for Visual Studio Debugging
        internal void BuildAndSendSimpleData(byte[] additionalData, HcomMeadowRequestType requestType, UInt32 userData)
        {
            int totalMsgLength = additionalData.Length + HCOM_PROTOCOL_COMMAND_REQUIRED_HEADER_LENGTH;
            var messageBytes   = new byte[totalMsgLength];

            // Populate the header
            BuildMeadowBoundSimpleCommand(requestType, userData, ref messageBytes);

            // Copy the payload into the message
            Array.Copy(additionalData, 0, messageBytes,
                       HCOM_PROTOCOL_COMMAND_REQUIRED_HEADER_LENGTH, additionalData.Length);

            EncodeAndSendPacket(messageBytes, 0, totalMsgLength);
        }
Example #13
0
        //==========================================================================
        internal void BuildAndSendFileRelatedCommand(HcomMeadowRequestType requestType,
                                                     UInt32 userData, UInt32 fileSize, UInt32 fileCheckSum, UInt32 mcuAddr,
                                                     string md5Hash, string destFileName)
        {
            // Future: Try to use the StructLayout attribute
            Debug.Assert(md5Hash.Length == 0 || md5Hash.Length == HCOM_PROTOCOL_REQUEST_MD5_HASH_LENGTH);

            // Allocate the correctly size message buffers
            byte[] targetFileName     = Encoding.UTF8.GetBytes(destFileName);       // Using UTF-8 works for ASCII but should be Unicode in nuttx
            byte[] md5HashBytes       = Encoding.UTF8.GetBytes(md5Hash);
            int    optionalDataLength = sizeof(UInt32) + sizeof(UInt32) + sizeof(UInt32) +
                                        HCOM_PROTOCOL_REQUEST_MD5_HASH_LENGTH + targetFileName.Length;

            byte[] messageBytes = new byte[HCOM_PROTOCOL_COMMAND_REQUIRED_HEADER_LENGTH + optionalDataLength];

            // Add the required header
            int offset = BuildMeadowBoundSimpleCommand(requestType, userData, ref messageBytes);

            // File Size
            Array.Copy(BitConverter.GetBytes(fileSize), 0, messageBytes, offset, sizeof(UInt32));
            offset += sizeof(UInt32);

            // CRC32 checksum or delete file partition number
            Array.Copy(BitConverter.GetBytes(fileCheckSum), 0, messageBytes, offset, sizeof(UInt32));
            offset += sizeof(UInt32);

            // MCU address for this file. Used for ESP32 file downloads
            Array.Copy(BitConverter.GetBytes(mcuAddr), 0, messageBytes, offset, sizeof(UInt32));
            offset += sizeof(UInt32);

            // Include ESP32 MD5 hash if it's needed
            if (string.IsNullOrEmpty(md5Hash))
            {
                Array.Clear(messageBytes, offset, HCOM_PROTOCOL_REQUEST_MD5_HASH_LENGTH);
            }
            else
            {
                Array.Copy(md5HashBytes, 0, messageBytes, offset, HCOM_PROTOCOL_REQUEST_MD5_HASH_LENGTH);
            }
            offset += HCOM_PROTOCOL_REQUEST_MD5_HASH_LENGTH;

            // Destination File Name
            Array.Copy(targetFileName, 0, messageBytes, offset, targetFileName.Length);
            offset += targetFileName.Length;

            Debug.Assert(offset == optionalDataLength + HCOM_PROTOCOL_COMMAND_REQUIRED_HEADER_LENGTH);
            EncodeAndSendPacket(messageBytes, 0, offset);
        }
Example #14
0
        public static async Task <bool> WriteFileToFlash(MeadowSerialDevice meadow, string fileName, string targetFileName = null,
                                                         int partition = 0)
        {
            meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_START_FILE_TRANSFER;

            if (string.IsNullOrWhiteSpace(targetFileName))
            {
                targetFileName = Path.GetFileName(fileName);
            }

            // For the STM32F7 on meadow, we need source file and destination file names.
            string[] csvArray = fileName.Split(',');
            if (csvArray.Length == 1)
            {
                await Task.WhenAll(
                    Task.Run(() => TransmitFileInfoToExtFlash(meadow, meadowRequestType, fileName, targetFileName, partition, 0, false, true)),
                    MeadowDeviceManager.WaitForResponseMessage(meadow, x => x.MessageType == MeadowMessageType.Concluded));

                // No CSV, just the source file name. So we'll assume the targetFileName is correct
                //TransmitFileInfoToExtFlash(meadow, meadowRequestType, fileName, targetFileName, partition, 0, false, true);
                return(true);
            }
            else
            {
                // At this point, the fileName field should contain a CSV string containing the source
                // and destionation file names, always in an even number.
                if (csvArray.Length % 2 != 0)
                {
                    Console.WriteLine("Please provide a CSV input with file names \"source, destination, source, destination\"");
                    return(false);
                }

                for (int i = 0; i < csvArray.Length; i += 2)
                {
                    // Send files one-by-one
                    bool lastFile = i == csvArray.Length - 2 ? true : false;
                    TransmitFileInfoToExtFlash(meadow, meadowRequestType, csvArray[i].Trim(), csvArray[i + 1].Trim(),
                                               partition, 0, false, lastFile);
                }
            }
            return(false);
        }
Example #15
0
 public Command(HcomMeadowRequestType requestType,
                TimeSpan timeout,
                uint userData,
                byte[]?data,
                Predicate <MeadowMessageEventArgs> responsePredicate,
                Predicate <MeadowMessageEventArgs> completionPredicate,
                EventHandler <MeadowMessageEventArgs>?responseHandler,
                bool isAcknowledged,
                string commandBuilder)
 {
     RequestType         = requestType;
     Timeout             = timeout;
     UserData            = userData;
     Data                = data;
     ResponsePredicate   = responsePredicate;
     CompletionPredicate = completionPredicate;
     ResponseHandler     = responseHandler;
     IsAcknowledged      = isAcknowledged;
     CommandBuilder      = commandBuilder;
 }
Example #16
0
        //==========================================================================
        internal async Task <bool> SendSimpleCommand(HcomMeadowRequestType requestType, uint userData = 0, bool doAcceptedCheck = true)
        {
            var tcs      = new TaskCompletionSource <bool>();
            var received = false;

            if (!doAcceptedCheck)
            {
                BuildAndSendSimpleCommand(requestType, userData);
                return(true);
            }

            EventHandler <MeadowMessageEventArgs> handler = (s, e) =>
            {
                if (e.MessageType == MeadowMessageType.Accepted)
                {
                    received = true;
                    tcs.SetResult(true);
                }
            };

            if (_device.DataProcessor != null)
            {
                _device.DataProcessor.OnReceiveData += handler;
            }

            BuildAndSendSimpleCommand(requestType, userData);

            await Task.WhenAny(new Task[] { tcs.Task, Task.Delay(10000) });

            if (_device.DataProcessor != null)
            {
                _device.DataProcessor.OnReceiveData -= handler;
            }

            if (!received)
            {
                throw new Exception("Command not accepted.");
            }
            return(received);
        }
Example #17
0
        // Enter StartDebugging mode.
        public static async Task StartDebugging(MeadowSerialDevice meadow, int vsDebugPort)
        {
            // Tell meadow to start it's debugging server, after restarting.
            _meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_MONO_START_DBG_SESSION;
            await new SendTargetData(meadow).SendSimpleCommand(_meadowRequestType);

            // The previous command caused Meadow to restart. Therefore, we must reestablish
            // Meadow communication.
            meadow.AttemptToReconnectToMeadow();

            // Create an instance of the TCP socket send/receiver class and
            // start it receiving.
            if (vsDebugPort == 0)
            {
                Console.WriteLine($"Without '--VSDebugPort' being specified, will assume Visual Studio 2019 using default port {DefaultVS2019DebugPort}");
                vsDebugPort = DefaultVS2019DebugPort;
            }

            // Start the local Meadow.CLI debugging server
            debuggingServer = new DebuggingServer(vsDebugPort);
            debuggingServer.StartListening(meadow);
        }
Example #18
0
 internal FileCommand(HcomMeadowRequestType requestType,
                      TimeSpan timeout,
                      string sourceFileName,
                      string destinationFileName,
                      string?md5Hash,
                      uint crc32,
                      int fileSize,
                      uint partition,
                      uint mcuAddress,
                      byte[]?fileBytes,
                      Predicate <MeadowMessageEventArgs> responseHandler,
                      Predicate <MeadowMessageEventArgs> completionHandler,
                      string commandBuilder)
     : base(requestType, timeout, partition, null, responseHandler, completionHandler, null, true, commandBuilder)
 {
     SourceFileName      = sourceFileName;
     DestinationFileName = destinationFileName;
     Md5Hash             = md5Hash ?? string.Empty;
     Crc32      = crc32;
     FileSize   = fileSize;
     Partition  = partition;
     McuAddress = mcuAddress;
     FileBytes  = fileBytes;
 }
 public static async Task <bool> GetDeviceInfo(MeadowSerialDevice meadow, int timeoutMs = 1000)
 {
     _meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_GET_DEVICE_INFORMATION;
     await new SendTargetData(meadow).SendSimpleCommand(_meadowRequestType);
     return(await WaitForResponseMessage(meadow, p => p.MessageType == MeadowMessageType.DeviceInfo, millisecondDelay : timeoutMs));
 }
Example #20
0
        public static void VerifyErasedFlash(MeadowSerialDevice meadow)
        {
            meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_VERIFY_ERASED_FLASH;

            new SendTargetData(meadow).SendSimpleCommand(meadowRequestType);
        }
Example #21
0
        // fileName - is the name of the file on this host PC
        // targetFileName - is the name of the file on the F7
        public static async Task WriteFileToEspFlash(MeadowSerialDevice meadow, string fileName,
                                                     string targetFileName = null, int partition = 0, string mcuDestAddr = null)
        {
            meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_START_ESP_FILE_TRANSFER;

            // For the ESP32 on the meadow, we don't need the target file name, we just need the
            // MCU's destination address and the file's binary.
            // Assume if no mcuDestAddr that the fileName is a CSV with both file names and Mcu Addr
            if (mcuDestAddr != null)
            {
                // Since the mcuDestAddr is used we'll assume the fileName field just contains
                // a single file.
                if (string.IsNullOrWhiteSpace(targetFileName))
                {
                    // While not used by the ESP32 it cost nothing to send it and can help
                    // with debugging
                    targetFileName = Path.GetFileName(fileName);
                }

                // Convert mcuDestAddr from a string to a 32-bit unsigned int, but first
                // insure it starts with 0x
                UInt32 mcuAddr = 0;
                if (mcuDestAddr.StartsWith("0x") || mcuDestAddr.StartsWith("0X"))
                {
                    mcuAddr = UInt32.Parse(mcuDestAddr.Substring(2), System.Globalization.NumberStyles.HexNumber);
                }
                else
                {
                    Console.WriteLine($"The '--McuDestAddr' argument must be followed with an address in the form '0x1800'");
                    return;
                }

                await Task.WhenAll(
                    Task.Run(() => TransmitFileInfoToExtFlash(meadow, meadowRequestType, fileName, targetFileName, partition, mcuAddr, false, true)),
                    MeadowDeviceManager.WaitForResponseMessage(meadow, x => x.MessageType == MeadowMessageType.Concluded));
            }
            else
            {
                // At this point, the fileName field should contain a CSV string containing the destination
                // addresses followed by file's location within the host's file system.
                // E.g. "0x8000, C:\Blink\partition-table.bin, 0x1000, C:\Blink\bootloader.bin, 0x10000, C:\Blink\blink.bin"
                string[] fileElement = fileName.Split(',');
                if (fileElement.Length % 2 != 0)
                {
                    Console.WriteLine("Please provide a CSV input with \"address, fileName, address, fileName\"");
                    return;
                }

                UInt32 mcuAddr;
                for (int i = 0; i < fileElement.Length; i += 2)
                {
                    // Trim any white space from this mcu addr and file name
                    fileElement[i]     = fileElement[i].Trim();
                    fileElement[i + 1] = fileElement[i + 1].Trim();

                    if (fileElement[i].StartsWith("0x") || fileElement[i].StartsWith("0X"))
                    {
                        // Fill in the Mcu Addr
                        mcuAddr = UInt32.Parse(fileElement[i].Substring(2), System.Globalization.NumberStyles.HexNumber);
                    }
                    else
                    {
                        Console.WriteLine("Please provide a CSV input with addresses like 0x1234");
                        return;
                    }
                    // Meadow.CLI --Esp32WriteFile --SerialPort Com26 --File
                    // "0x8000, C:\Download\Esp32\Hello\partition-table.bin, 0x1000, C:\Download\Esp32\Hello\bootloader.bin, 0x10000, C:\Download\Esp32\Hello\hello-world.bin"
                    // File Path and Name
                    targetFileName = Path.GetFileName(fileElement[i + 1]);
                    bool lastFile = i == fileElement.Length - 2 ? true : false;

                    // this may need need to be awaited?
                    TransmitFileInfoToExtFlash(meadow, meadowRequestType, fileElement[i + 1], targetFileName, partition, mcuAddr, false, lastFile);
                }
            }
        }
Example #22
0
 //==========================================================================
 internal void SendSimpleCommand(HcomMeadowRequestType requestType, uint userData = 0)
 {
     BuildAndSendSimpleCommand(requestType, userData);
 }
Example #23
0
 public static void InitializeFileSystem(MeadowSerialDevice meadow, int partition)
 {
     meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_INITIALIZE_FLASH_FS;
     new SendTargetData(meadow).SendSimpleCommand(meadowRequestType, (uint)partition);
 }
Example #24
0
 public static void CreateFileSystem(MeadowSerialDevice meadow)
 {
     meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_CREATE_ENTIRE_FLASH_FS;
     new SendTargetData(meadow).SendSimpleCommand(meadowRequestType);
 }
 public MeadowDeviceManagerException(HcomMeadowRequestType hcomMeadowRequestType, Exception?innerException)  : base(null, innerException)
 {
     HcomMeadowRequestType = hcomMeadowRequestType;
 }
 public SimpleCommandBuilder(HcomMeadowRequestType requestType)
 {
     RequestType = requestType;
     Timeout     = DefaultTimeout;
 }
 public MeadowDeviceManagerException(HcomMeadowRequestType hcomMeadowRequestType)
 {
     HcomMeadowRequestType = hcomMeadowRequestType;
 }
 public static async Task ProcessCommand(MeadowSerialDevice meadow, HcomMeadowRequestType requestType,
                                         MeadowMessageType responseMessageType = MeadowMessageType.Concluded, uint userData = 0, bool doAcceptedCheck = true, int timeoutMs = 10000)
 {
     await ProcessCommand(meadow, requestType, e => e.MessageType == responseMessageType, userData, doAcceptedCheck, timeoutMs);
 }
 // This method is called to sent to Visual Studio debugging to Mono
 public static void ForwardVisualStudioDataToMono(byte[] debuggingData, MeadowSerialDevice meadow, int userData)
 {
     _meadowRequestType = HcomMeadowRequestType.HCOM_MDOW_REQUEST_DEBUGGER_MSG;
     new SendTargetData(meadow).BuildAndSendSimpleData(debuggingData, _meadowRequestType, (uint)userData);
 }
Example #30
0
        public void SendTheEntireFile(HcomMeadowRequestType requestType, string destFileName,
                                      uint partitionId, byte[] fileBytes, UInt32 mcuAddr, UInt32 payloadCrc32,
                                      string md5Hash, bool lastInSeries)
        {
            _packetCrc32 = 0;

            try
            {
                // Build and send the header
                BuildAndSendFileRelatedCommand(requestType,
                                               partitionId, (UInt32)fileBytes.Length, payloadCrc32,
                                               mcuAddr, md5Hash, destFileName);

                //--------------------------------------------------------------
                if (requestType == HcomMeadowRequestType.HCOM_MDOW_REQUEST_START_ESP_FILE_TRANSFER)
                {
                    Console.Write("Erasing ESP32 Flash...");
                    // For the ESP32 file download, the proceeding command will erase
                    // the ESP32 on chip flash memory before we can download. If the
                    // file is large enough, the time to erase the flash will prevent
                    // data from being downloaded and the 'semaphore timeout' error
                    // will cause the CLI to disconnect.
                    if ((UInt32)fileBytes.Length > 1024 * 200)
                    {
                        // Using 6 ms / kbyte
                        int eraseDelay = (6 * fileBytes.Length) / 1000;
                        // Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}-Large file download delay:{eraseDelay} mSec");
                        System.Threading.Thread.Sleep(eraseDelay);
                    }
                    Console.WriteLine("done.");
                }

                // Build each data packet
                int    fileBufOffset = 0;
                int    numbToSend;
                UInt16 sequenceNumber = 1;

                // don't echo the device responses
                _device.LocalEcho = false;

                WriteProgress(-1);
                while (fileBufOffset <= fileBytes.Length - 1)           // equal would mean past the end
                {
                    if ((fileBufOffset + MeadowDeviceManager.MaxAllowableDataBlock) > (fileBytes.Length - 1))
                    {
                        numbToSend = fileBytes.Length - fileBufOffset;  // almost done, last packet
                    }
                    else
                    {
                        numbToSend = MeadowDeviceManager.MaxAllowableDataBlock;
                    }

                    BuildAndSendDataPacketRequest(fileBytes, fileBufOffset, numbToSend, sequenceNumber);

                    var progress = fileBufOffset * 100 / fileBytes.Length;
                    WriteProgress(progress);

                    fileBufOffset += numbToSend;

                    sequenceNumber++;
                }
                WriteProgress(101);

                // echo the device responses
                Thread.Sleep(250); // if we're too fast, we'll finish and the device will still echo a little
                _device.LocalEcho = true;

                //--------------------------------------------------------------
                // Build and send the correct trailer
                switch (requestType)
                {
                // Provide the correct message end depending on the reason the file
                // is being downloaded to the F7 file system.
                case HcomMeadowRequestType.HCOM_MDOW_REQUEST_START_FILE_TRANSFER:
                    BuildAndSendSimpleCommand(HcomMeadowRequestType.HCOM_MDOW_REQUEST_END_FILE_TRANSFER,
                                              lastInSeries ? (uint)1 : (uint)0); // set UserData
                    break;

                case HcomMeadowRequestType.HCOM_MDOW_REQUEST_MONO_UPDATE_RUNTIME:
                    BuildAndSendSimpleCommand(HcomMeadowRequestType.HCOM_MDOW_REQUEST_MONO_UPDATE_FILE_END,
                                              lastInSeries ? (uint)1 : (uint)0); // set UserData
                    break;

                case HcomMeadowRequestType.HCOM_MDOW_REQUEST_START_ESP_FILE_TRANSFER:
                    BuildAndSendSimpleCommand(HcomMeadowRequestType.HCOM_MDOW_REQUEST_END_ESP_FILE_TRANSFER,
                                              lastInSeries ? (uint)1 : (uint)0); // set UserData
                    break;

                default:
                    Console.WriteLine($"File end Meadow request type of {requestType} not defined");
                    break;
                }

                // bufferOffset should point to the byte after the last byte
                Debug.Assert(fileBufOffset == fileBytes.Length);
                if (Verbose)
                {
                    Console.WriteLine($"Total bytes sent {fileBufOffset:N0} in {sequenceNumber:N0} packets. PacketCRC:{_packetCrc32:x08}");
                }
            }
            catch (Exception except)
            {
                Debug.WriteLine("{DateTime.Now:HH:mm:ss.fff}-Exception sending to Meadow:{0}", except);
                throw;
            }
        }