Skip to content

Commit 3324f9e

Browse files
authored
Add DFU verification (#35)
***NO_CI***
1 parent e5ed788 commit 3324f9e

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
4+
namespace nanoFramework.Tools.FirmwareFlasher
5+
{
6+
/// <summary>
7+
/// Verification of DFU write failed.
8+
/// </summary>
9+
[Serializable]
10+
internal class DfuVerificationFailedException : Exception
11+
{
12+
public DfuVerificationFailedException()
13+
{
14+
}
15+
16+
public DfuVerificationFailedException(string message) : base(message)
17+
{
18+
}
19+
20+
public DfuVerificationFailedException(string message, Exception innerException) : base(message, innerException)
21+
{
22+
}
23+
24+
protected DfuVerificationFailedException(SerializationInfo info, StreamingContext context) : base(info, context)
25+
{
26+
}
27+
}
28+
}

source/nanoFirmwareFlasher/StDfu.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,14 @@ internal static extern uint STDFU_Open(
345345
[MarshalAs(UnmanagedType.LPStr)]string szDevicePath,
346346
out IntPtr hDevice);
347347

348+
[DllImport(@"stdfu\STDFU.dll", EntryPoint = "STDFU_Upload", CharSet = CharSet.Ansi)]
349+
internal static extern uint STDFU_Upload(
350+
ref IntPtr hDevice,
351+
[MarshalAs(UnmanagedType.LPArray)]byte[] pBuffer,
352+
uint nBytes,
353+
ushort nBlocks);
354+
355+
348356

349357
#endregion
350358

@@ -947,6 +955,36 @@ internal static void WriteBlock(
947955
}
948956
}
949957

958+
internal static void ReadBlock(
959+
IntPtr hDevice,
960+
uint address,
961+
byte[] data,
962+
uint blockNumber)
963+
{
964+
DfuStatus dfuStatus = new DfuStatus();
965+
966+
if (0 == blockNumber)
967+
{
968+
SetAddressPointer(hDevice, address);
969+
}
970+
971+
STDFU_GetStatus(ref hDevice, ref dfuStatus);
972+
while (dfuStatus.bState != STATE_DFU_IDLE)
973+
{
974+
STDFU_ClrStatus(ref hDevice);
975+
STDFU_GetStatus(ref hDevice, ref dfuStatus);
976+
}
977+
978+
STDFU_Upload(ref hDevice, data, (uint)data.Length, (ushort)(blockNumber + 2));
979+
980+
STDFU_GetStatus(ref hDevice, ref dfuStatus);
981+
while (dfuStatus.bState != STATE_DFU_UPLOAD_IDLE)
982+
{
983+
STDFU_ClrStatus(ref hDevice);
984+
STDFU_GetStatus(ref hDevice, ref dfuStatus);
985+
}
986+
}
987+
950988
private static void SetAddressPointer(
951989
IntPtr hDevice,
952990
uint address)

source/nanoFirmwareFlasher/StmDfuDevice.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ public void FlashDfuFile(string filePath)
237237
Console.Write("Flashing device...");
238238
}
239239

240+
// write flash
240241
for (int elementIndex = 0; elementIndex < dfuTarget.DfuElements.Length; ++elementIndex)
241242
{
242243
StDfu.DfuElement dfuElement = dfuTarget.DfuElements[elementIndex];
@@ -256,6 +257,44 @@ public void FlashDfuFile(string filePath)
256257
Console.WriteLine(" OK");
257258
}
258259

260+
if (Verbosity >= VerbosityLevel.Normal)
261+
{
262+
Console.Write("Verifying flash...");
263+
}
264+
265+
// read back for confirmation
266+
for (int elementIndex = 0; elementIndex < dfuTarget.DfuElements.Length; ++elementIndex)
267+
{
268+
StDfu.DfuElement dfuElement = dfuTarget.DfuElements[elementIndex];
269+
270+
// read the data in MaxWriteBlockSize blocks
271+
for (uint blockNumber = 0; blockNumber <= (uint)dfuElement.Data.Length / _maxWriteBlockSize; blockNumber++)
272+
{
273+
byte[] readBuffer = new byte[_maxWriteBlockSize];
274+
StDfu.ReadBlock(_hDevice, dfuElement.Address, readBuffer, blockNumber);
275+
276+
// get data for the current block
277+
byte[] buffer = dfuElement.Data.Skip((int)(_maxWriteBlockSize * blockNumber)).Take(_maxWriteBlockSize).ToArray();
278+
279+
// exit condition has to be tied with the buffer length because the data for the last block
280+
// can be shorter than the block max size
281+
for(int index = 0; index < buffer.Length; index++)
282+
{
283+
if(readBuffer[index] != buffer[index])
284+
{
285+
Console.WriteLine("");
286+
Console.WriteLine($"Error verifying flash write. Check failed for block address 0x{dfuElement.Address + blockNumber * _maxWriteBlockSize:X8}.");
287+
throw new DfuVerificationFailedException();
288+
}
289+
}
290+
}
291+
}
292+
293+
if (Verbosity >= VerbosityLevel.Normal)
294+
{
295+
Console.WriteLine(" OK");
296+
}
297+
259298
if (Verbosity >= VerbosityLevel.Normal)
260299
{
261300
Console.Write("Launching nanoBooter...");

0 commit comments

Comments
 (0)