-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Support flashing .hex files onto any suitable External flash partition. #2512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support flashing .hex files onto any suitable External flash partition. #2512
Conversation
haslinghuis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please solve the code smells too.
59d20b3 to
36a4b77
Compare
haslinghuis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hydra you forgot some code smells, I have pointed them out to make it easier.
36a4b77 to
894b118
Compare
|
@haslinghuis I hadn't looked at the code-smells yet, the previous push was fixing the build failure. My IDE doesn't have an option for removing trailing spacing on Javascript files (it does on C/JAVA files...) Missed one, just forced pushed again to fix the other issues. |
This allows uploading not only firmware, but system, osd logos/fonts and config backups too. Additionally, the firmware partition is not always the 3rd partition on new FCs, other partitions can preceed it. A partition is 'suitable' if it matches the length of the .hex file.
894b118 to
26ec8fb
Compare
|
Kudos, SonarCloud Quality Gate passed!
|
|
@hydra which hardware is needed to test this - the merging is automated - and we need to test the PR before we can apply the |
|
@haslinghuis SPRacingH7 EXTREME/ZERO/NANO/RF/EXTREME-PX4-EDITION/CINE. I tested it on 3 of the above, each with different flash chips and DFU descriptors. Previously only EXTREME/NANO/ZERO worked. |
|
@hydra these advantages looks so good, can you suply to our Configurator Maintainers with some hardware samples to can test all your new features? |
|
Pretty sure the maintainers already have the SPRacingH7EXTREME, I recall sending a few out. |
|
@hydra we are now new maintainers for the new Configurator maintaining system: |
schugabe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flashing bf to a SPRacingH7RF works with this PR
| if (str == "@External Flash /0x90000000/1001*128Kg,3*128Kg,20*128Ka") { | ||
| str = "@External Flash /0x90000000/998*128Kg,1*128Kg,4*128Kg,21*128Ka"; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this? A bug in the FC? I don't understand how this works (the flash system). I suppose this cannot be fixed in any way and this is a workaround in the Configurator to support it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I close this because the only change was the commit, so we are already supporting this.
|
What additional testing is required in order to get the 'Tested' label added? |
|
@haslinghuis I haven't test anything. I saw @schugabe tested, figured that would be enough. Apologize, I remove the tag. |
|
To make good quality merges the code should be tested by maintainers with the needed hardware. |
|
Gotcha! |
|
AUTOMERGE: (FAIL)
|
|
if the current maintainers do not have the hardware then perhaps the old maintainers should send their hardware to them? As there is a global shortage of CPUs there are no new FCs that can be sent out. Is it not enough that the designer of the hardware and the person that initially added support for flashing to external flash chips, and other users, have tested it? The updated code is isolated from non external flash chips too. |
| self.available_flash_size = firmware_partition_size; | ||
| const firmwarePartitionSize = firmwareSectors.total_size; | ||
|
|
||
| if (firmwarePartitionSize === self.hex.bytes_total) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason for matching this by size? This seems to be contrary to the way Intel Hex files are designed to work, and not really scalable / extensible:
- what happens if there are multiple partitions of the same size;
- what happens if the hex file is shorter than the partition it should go into;
- why is this not using the address, which is the way Intel Hex is meant to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Currently first matching partition is used, by design. There are no targets like this anyway.
- Short hex results in no match, intended. All current EXST HEX images are the same size as the partition.
- I agree! The pattern of checking the size come from the non-external flash code. To be honest the whole size checking should probably just be deleted since the next step of the dfu flashing processes deals with the actual addresses. If it was up to me I would ditch .hex files and use a zipped .json file and improve the entire release and flashing process and allow multiple images/memory areas to be flashed/updated. similar to how PX4 does it. I'll be happy to delete the size checking code from both the internal and external flash use cases and make it rely on addresses only, however this would take some time and I've got other outstanding work right now. Suggest merging this stop-gap solution until time allows for further improvements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With regard to 3 above. This section can be deleted (mostly):
betaflight-configurator/src/js/protocols/stm32usbdfu.js
Lines 572 to 629 in 26ec8fb
| if (typeof chipInfo.internal_flash !== "undefined") { | |
| // internal flash | |
| self.chipInfo = chipInfo; | |
| self.flash_layout = chipInfo.internal_flash; | |
| self.available_flash_size = self.flash_layout.total_size - (self.hex.start_linear_address - self.flash_layout.start_address); | |
| GUI.log(i18n.getMessage('dfu_device_flash_info', (self.flash_layout.total_size / 1024).toString())); | |
| if (self.hex.bytes_total > self.available_flash_size) { | |
| GUI.log(i18n.getMessage('dfu_error_image_size', | |
| [(self.hex.bytes_total / 1024.0).toFixed(1), | |
| (self.available_flash_size / 1024.0).toFixed(1)])); | |
| self.cleanup(); | |
| } else { | |
| self.getFunctionalDescriptor(0, function (descriptor, resultCode) { | |
| self.transferSize = resultCode ? 2048 : descriptor.wTransferSize; | |
| console.log('Using transfer size: ' + self.transferSize); | |
| self.clearStatus(function () { | |
| self.upload_procedure(1); | |
| }); | |
| }); | |
| } | |
| } else if (typeof chipInfo.external_flash !== "undefined") { | |
| // external flash, exst images must match the size of the partition being flashed. | |
| // | |
| // since the actual addresses to be flashed are in the .hex file this is not ideal | |
| // really we just need to make sure the flash chip contains addresses/offsets that match the ones in the .hex file. | |
| self.chipInfo = chipInfo; | |
| self.flash_layout = chipInfo.external_flash; | |
| self.available_flash_size = 0; | |
| // Find a partition that matches the size of the hex. | |
| for (const firmwareSectors of self.flash_layout.sectors) { | |
| const firmwarePartitionSize = firmwareSectors.total_size; | |
| if (firmwarePartitionSize === self.hex.bytes_total) { | |
| self.available_flash_size = firmwarePartitionSize; | |
| break; | |
| } | |
| } | |
| GUI.log(i18n.getMessage('dfu_device_flash_info', (self.flash_layout.total_size / 1024).toString())); | |
| if (self.available_flash_size === 0) { | |
| GUI.log(i18n.getMessage('dfu_error_image_mismatch')); | |
| self.cleanup(); | |
| } else { | |
| self.getFunctionalDescriptor(0, function (descriptor, resultCode) { | |
| self.transferSize = resultCode ? 2048 : descriptor.wTransferSize; | |
| console.log('Using transfer size: ' + self.transferSize); | |
| self.clearStatus(function () { | |
| self.upload_procedure(2); // no option bytes to deal with | |
| }); | |
| }); | |
| } |
This section could could be improved (out of scope of this PR):
betaflight-configurator/src/js/protocols/stm32usbdfu.js
Lines 777 to 804 in 26ec8fb
| // find out which pages to erase | |
| var erase_pages = []; | |
| for (var i = 0; i < self.flash_layout.sectors.length; i++) { | |
| for (var j = 0; j < self.flash_layout.sectors[i].num_pages; j++) { | |
| if (self.options.erase_chip) { | |
| // full chip erase | |
| erase_pages.push({'sector': i, 'page': j}); | |
| } else { | |
| // local erase | |
| var page_start = self.flash_layout.sectors[i].start_address + j * self.flash_layout.sectors[i].page_size; | |
| var page_end = page_start + self.flash_layout.sectors[i].page_size - 1; | |
| for (var k = 0; k < self.hex.data.length; k++) { | |
| var starts_in_page = self.hex.data[k].address >= page_start && self.hex.data[k].address <= page_end; | |
| var end_address = self.hex.data[k].address + self.hex.data[k].bytes - 1; | |
| var ends_in_page = end_address >= page_start && end_address <= page_end; | |
| var spans_page = self.hex.data[k].address < page_start && end_address > page_end; | |
| if (starts_in_page || ends_in_page || spans_page) { | |
| var idx = erase_pages.findIndex(function (element, index, array) { | |
| return element.sector == i && element.page == j; | |
| }); | |
| if (idx == -1) | |
| erase_pages.push({'sector': i, 'page': j}); | |
| } | |
| } | |
| } | |
| } | |
| } | |
As you can see, all the addresses in the .hex are checked to see if they match an 'erasable page'. Instead of checking the size which I fully agree is wrong for both internal an external flash chips as the hex can contain non-contiguous memory addresses, the code could be updated to show 'address not found' or 'address not writable' error messages instead.
|
I'm closing this PR. I'll do another one that ditches the size checking for both internal and external flashes and relies on addresses alone which is a sensible long-term solution. |
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.
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.
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.
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.
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.
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.
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.
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.
Fix sliders disable input 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. Fix pre-existing code-smells. Indicate inactive dyn notch if looprate less 2k don't change filter type when moving filter slider Presets: remove cache for fetch Update github issues templates Fix Port Detection using VID/PID Add option for manufacturers and developers fix integrated yaw usage move code to pidtuning.js fix tuningsliders disable only if rpy Fix filter slider update Fix lowpass 1 handlers Put things back Restore Initial Settings Fix PID rows updating Work on PID Fix PID copy Remove PID validation Apply new MSP FW sliders: fix gyro and dterm ON/OF toggles FW sliders for 4.2: Mark's diff file applied FW Sliders for 4.2: Fix infinity for PD ratio and fix PD gain slider adjustin only D FE Sliders for 4.2: fixing legacy filter and PID sliders - bringing back old logic FW Sliders: bringing back SetDirty for the correct profile select blocking Fix slider calculation Remove MSP_APPLY* Fix legacy Revert CSS for PID tab Move Filter Mode element in UI Remove bitflag Remove apply byte FW sliders: symmetrical MSP commands Fix saving gyro lowpass 1 disable FW sliders: fix dterm dynamic LPF after enabling it FW sliders: fix enabled input field background FW Sliders: fix when loading PID tab with non-default expert sliders in non-expert mode
Fix sliders disable input 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. Fix pre-existing code-smells. Indicate inactive dyn notch if looprate less 2k don't change filter type when moving filter slider Presets: remove cache for fetch Update github issues templates Fix Port Detection using VID/PID Add option for manufacturers and developers fix integrated yaw usage move code to pidtuning.js fix tuningsliders disable only if rpy Fix filter slider update Fix lowpass 1 handlers Put things back Restore Initial Settings Fix PID rows updating Work on PID Fix PID copy Remove PID validation Apply new MSP FW sliders: fix gyro and dterm ON/OF toggles FW sliders for 4.2: Mark's diff file applied FW Sliders for 4.2: Fix infinity for PD ratio and fix PD gain slider adjustin only D FE Sliders for 4.2: fixing legacy filter and PID sliders - bringing back old logic FW Sliders: bringing back SetDirty for the correct profile select blocking Fix slider calculation Remove MSP_APPLY* Fix legacy Revert CSS for PID tab Move Filter Mode element in UI Remove bitflag Remove apply byte FW sliders: symmetrical MSP commands Fix saving gyro lowpass 1 disable FW sliders: fix dterm dynamic LPF after enabling it FW sliders: fix enabled input field background FW Sliders: fix when loading PID tab with non-default expert sliders in non-expert mode disable only if rpy
This allows uploading not only firmware, but system, osd logos/fonts and config backups too.
Additionally, the firmware partition is not always the 3rd partition on new FCs, other partitions can preceed it.
A partition is 'suitable' if it matches the length of the .hex file.