Reputation: 317
I am developing a firmware upgrade app in C# using VisualStudio 2015. The app uses a XAML-based form and C# code. The target of the firmware upgrade is a custom board running an STM32F417 processor (ARM Cortex M4). The C# code connects with the 417, causes the 417 to jump to its bootloader (factory installed) and uses the bootloader API to load the new firmware.
After every transfer of 256 bytes (max transfer allowed), a checksum of the data and the number of bytes is sent, and an ACK byte is received from the 417 to show that everything checked out for that transfer. The transfer would fail after a couple of blocks of 256 and to test the transfer, I set up the C# code to just transfer the .hex file without any of the other checks.
I set the code to transfer the updated firmware as a .hex file. line by line. It writes data out the a serial line and is captured as text in HyperTerminal. I implemented it as a write of 256 bytes:
byte[] buffer256 = new byte[256];
// Read the file and process one line at a time
System.IO.StreamReader file = new System.IO.StreamReader(path);
while ((line = file.ReadLine()) != null)
{
line = line.Substring(1, line.Length - 1);
// Create byte array from string
var bytes = GetBytesFromByteString(line).ToArray();
// Assign values to variables from byte array
type = bytes[3];
// BLOCK WRITE TO MEMORY
if (type == 0) // data type
{
length = bytes[0];
if (byteCounter >= 255)
{
_serialPort.Write(buffer256, 0, 256);
Array.Clear(buffer256, 0, buffer256.Length);
byteCounter = 0;
}
for (int i = 0; i < length; i++)
{
buffer256[byteCounter++] = bytes[4 + i];
}
} // end BLOCK WRITE TO MEMORY
counter++;
} // end WHILE loop for loading hex file
file.Close();
And also as a write of single bytes:
byte[] buffer256 = new byte[256];
// Read the file and process one line at a time
System.IO.StreamReader file = new System.IO.StreamReader(path);
while ((line = file.ReadLine()) != null)
{
line = line.Substring(1, line.Length - 1);
// Create byte array from string
var bytes = GetBytesFromByteString(line).ToArray();
// Assign values to variables from byte array
type = bytes[3];
if (type == 0)
{
length = bytes[0];
for (int i = 0; i < length; i++)
{
_serialPort.Write(bytes, 4 + i, 1);
} // end FOR loop
}// end SINGLE BYTE WRITING
counter++;
} // end WHILE loop for loading hex file
file.Close();
In both cases, the hex file is changed by writing it using the SerialPort class. I tried various other methods, even WriteAsync in the BaseStream class on which the SerialPort class is built (overriding Stream methods).
Here is a sample (8 words) of the original .hex file (data only) compared to the received data:
Original:
00F8012B 002AF9D1 18467047 70B50646
2DF0FEFC 04680546 0A220021 304600F0
Received:
00F8012B 002AF9D1 18464670 4770B506
462DF0FE FC046805 460A2200 21304600
These are lines 49 and 50 out of 13391. The checksums for some of the blocks were also checked and were wrong. I'm pretty sure that is why the firmware upgrades are failing — the bootloader is calculating a checksum based on what it is receiving and fails when it compares it to the checksum the C# app is calculating and sending over.
My question is: if the SerialPort (and underlying Stream) is unreliable, what should I replace it with and how? Is it possible to just replace the SerialPort class, maybe with a C++ class? Or would it be better to rewrite the entire app in C++ or something else?
Upvotes: 2
Views: 802
Reputation: 2981
The SerialPort class itself isn't unreliable. I've used it successfully on the desktop and numerous CE devices. The problem could be the hardware on either end, one of the OSes, some fiddly configuration value, or some combination of any of those.
It could also be your code. I'm not sure you're doing anything wrong, but reading binary data into a string using ReadLine seems pretty weird to me. Have you verified bytes[] is correct in a debugger?
PS--If one of the hardware issues is related to timing, switching to C++ can be helpful. Interop is pretty painless for something like this, so I wouldn't bother rewriting the whole app, but I don't know your situation so couldn't say for sure.
Upvotes: 1