Skip to content

Commit 439e0a9

Browse files
committed
Verify target has all addresses found in the hex file instead of
verifying the size. As noted in PR betaflight#2512 simply verifying the size of the hex file is not extensible and is not how hex files are designed to be used. A hex file can contains many non-contiguous blocks of data. This also supports targets with any partition layout. Additionally, this provides a more flexible way of providing hex files which can now contain data for non-contiguous blocks, e.g. firmware + config or firmware + osd fonts.
1 parent ca7fdeb commit 439e0a9

File tree

2 files changed

+70
-33
lines changed

2 files changed

+70
-33
lines changed

locales/en/messages.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,10 @@
656656
"dfu_device_flash_info": {
657657
"message": "Detected device with total flash size $1 KiB"
658658
},
659-
"dfu_error_image_size": {
659+
"dfu_hex_address_errors": {
660+
"message": "<span class=\"message-negative\">Error</span>: Firmware image contains addresses not found on target device"
661+
},
662+
"dfu_error_image_size": {
660663
"message": "<span class=\"message-negative\">Error</span>: Supplied image is larger then flash available on the chip! Image: $1 KiB, limit = $2 KiB"
661664
},
662665

src/js/protocols/stm32usbdfu.js

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,47 @@ STM32DFU_protocol.prototype.verify_flash = function (first_array, second_array)
562562
return true;
563563
};
564564

565+
STM32DFU_protocol.prototype.isBlockUsable = function(startAddress, length) {
566+
var self = this;
567+
568+
let result = false;
569+
570+
let searchAddress = startAddress;
571+
let remainingLength = length;
572+
573+
let restart;
574+
do {
575+
restart = false;
576+
577+
for (const sector of self.flash_layout.sectors) {
578+
const sectorStart = sector.start_address;
579+
const sectorLength = sector.num_pages * sector.page_size;
580+
const sectorEnd = sectorStart + sectorLength - 1; // - 1 for inclusive
581+
582+
const addressInSector = (searchAddress >= sectorStart) && (searchAddress <= sectorEnd);
583+
584+
if (addressInSector) {
585+
const endAddress = searchAddress + remainingLength - 1; // - 1 for inclusive
586+
587+
const endAddressInSector = (endAddress <= sectorEnd);
588+
if (endAddressInSector) {
589+
result = true;
590+
restart = false;
591+
break;
592+
}
593+
594+
// some of the block is in this sector, search for the another sector that contains the next part of the block
595+
searchAddress = sectorEnd + 1;
596+
remainingLength -= sectorLength;
597+
restart = true;
598+
break;
599+
}
600+
}
601+
} while (restart);
602+
603+
return result;
604+
};
605+
565606
STM32DFU_protocol.prototype.upload_procedure = function (step) {
566607
var self = this;
567608

@@ -572,59 +613,52 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
572613
console.log('Failed to detect chip info, resultCode: ' + resultCode);
573614
self.cleanup();
574615
} else {
616+
let nextAction;
617+
575618
if (typeof chipInfo.internal_flash !== "undefined") {
576619
// internal flash
577-
self.chipInfo = chipInfo;
620+
nextAction = 1;
578621

622+
self.chipInfo = chipInfo;
579623
self.flash_layout = chipInfo.internal_flash;
580-
self.available_flash_size = self.flash_layout.total_size - (self.hex.start_linear_address - self.flash_layout.start_address);
581624

582-
GUI.log(i18n.getMessage('dfu_device_flash_info', (self.flash_layout.total_size / 1024).toString()));
583-
584-
if (self.hex.bytes_total > self.available_flash_size) {
585-
GUI.log(i18n.getMessage('dfu_error_image_size',
586-
[(self.hex.bytes_total / 1024.0).toFixed(1),
587-
(self.available_flash_size / 1024.0).toFixed(1)]));
588-
self.cleanup();
589-
} else {
590-
self.getFunctionalDescriptor(0, function (descriptor, resultCode) {
591-
self.transferSize = resultCode ? 2048 : descriptor.wTransferSize;
592-
console.log('Using transfer size: ' + self.transferSize);
593-
self.clearStatus(function () {
594-
self.upload_procedure(1);
595-
});
596-
});
597-
}
598625
} else if (typeof chipInfo.external_flash !== "undefined") {
599-
// external flash, flash to the 3rd partition.
626+
// external flash
627+
nextAction = 2; // no option bytes
628+
600629
self.chipInfo = chipInfo;
601630
self.flash_layout = chipInfo.external_flash;
631+
} else {
632+
console.log('Failed to detect internal or external flash');
633+
self.cleanup();
634+
}
602635

603-
var firmware_partition_index = 2;
604-
var firmware_sectors = self.flash_layout.sectors[firmware_partition_index];
605-
var firmware_partition_size = firmware_sectors.total_size;
636+
if (typeof nextAction !== "undefined") {
637+
GUI.log(i18n.getMessage('dfu_device_flash_info', (self.flash_layout.total_size / 1024).toString()));
606638

607-
self.available_flash_size = firmware_partition_size;
639+
// verify all addresses in the hex are writable.
608640

609-
GUI.log(i18n.getMessage('dfu_device_flash_info', (self.flash_layout.total_size / 1024).toString()));
641+
const unusableBlocks = [];
642+
643+
for (const block of self.hex.data) {
644+
const usable = self.isBlockUsable(block.address, block.bytes);
645+
if (!usable) {
646+
unusableBlocks.push(block);
647+
}
648+
}
610649

611-
if (self.hex.bytes_total > self.available_flash_size) {
612-
GUI.log(i18n.getMessage('dfu_error_image_size',
613-
[(self.hex.bytes_total / 1024.0).toFixed(1),
614-
(self.available_flash_size / 1024.0).toFixed(1)]));
650+
if (unusableBlocks.length > 0) {
651+
GUI.log(i18n.getMessage('dfu_hex_address_errors'));
615652
self.cleanup();
616653
} else {
617654
self.getFunctionalDescriptor(0, function (descriptor, resultCode) {
618655
self.transferSize = resultCode ? 2048 : descriptor.wTransferSize;
619656
console.log('Using transfer size: ' + self.transferSize);
620657
self.clearStatus(function () {
621-
self.upload_procedure(2); // no option bytes to deal with
658+
self.upload_procedure(nextAction);
622659
});
623660
});
624661
}
625-
} else {
626-
console.log('Failed to detect internal or external flash');
627-
self.cleanup();
628662
}
629663
}
630664
});

0 commit comments

Comments
 (0)