Figured it out: it seems that the example project has its build settings set to debug. Switching to release for both bootloader (including updated row protection) and bootloadable fixed the problem. However, I still don't know why it's needed to build with release setting. Would be nice if someone can clarify.
I tried programming the code example that you have pointed out. I could not observe any difference in behavior in both the Debug and Release mode. The image below shows the total Flash consumed by the Bootloader project(Debug mode):
Here the Application consumes 18552 bytes of Flash. 18552 divided by 256 is 72.4. If I protect only 72 Flash rows then the Bootloading happens properly in both Debug and Release mode, otherwise I get the same error "The flash row is not valid for the selected array".
Both Release and Debug modes cause different level of code optimization. Release mode is generally smaller and runs faster.
It is possible to manually change the optimization for the project as well as individual files in the project. Right click on the project (or file) > Build Settings > AM GCC 5.4 > Compiler >Optimization > Optimization Level.
thank you for your response. From your description and the picture, I've an assumption where the error is:
The total number of bytes consumed is 18808, but you're only using 18552 bytes for the page calculation, so you're ignoring the 256 bytes of metadata.
Please take a look at the USB_FS bootloader example documentation PDF. Here, there's no metadata shown, which in turn caused me to use the first size value (would be 18808 bytes in your case) and gives wrong calculation result.
Could this be the error? In this case the documentation PDF has to be updated. However, it wouldn't explain why it works if both bootloader and bootloadable projects are compiled with release settings, because I did the same calculation.
May I ask you if you can verify this?
- compile with debug settings and protect including the metadata bytes
- compile with release settings and protect including the metadata bytes
For the first one, you should get the error, where the second one should work.
The update to the queries you have asked:
1) On compiling with debug settings and protecting the flash rows including the metadata (73 flash rows) I got an error. Protecting only 72 rows worked for me.
2) On compiling with release setting and protecting the flash rows including metadata (73 Flash rows) I got the same error. Protecting only 72 rows worked for me in release mode as well.
Explanation for this: The main application occupies on 72 flash rows and metadata occupies the last row of the flash. When protecting 73 rows while bootloading we get an error because the bootloadable image should be stored from the 73rd Flash row which is protected ( as Bootloader host will write the Bootloadable application just after the Bootloader project)
Can you let me know if there is a difference in the size of the project when compiled using Release mode and Debug mode. It would be easy for us to check the same if you could attach the project here. Are you using some optimization with the debug and release mode.
I am attaching the project that I have used for testing let me know if this works for you.
USBFS_Bootloader.zip 12.3 MB
thank you for reproducing the behaviour.
That's it! This explains why it's not working. So, may I ask you to update the USB_FS documentation file? Figure 1 shows an outdated output regarding the flash size information, which lead me to wrong calculation. Updating the documentation might prevent that other users will also be trapped by this
Yes, the sizes are different. Currently I'm using the default settings for debug/release. Upon project progress those settings might be modified to get even better optimization. However, with your explanation above, the initial problem is solved, thank you.
Regarding my statement that it works if I use release mode for both bootloader and application, I did the same procedure again and I wasn't able to reproduce it So, I assume that I missed to update the write protection somewhere between the different build modes on the first run. I'll keep an eye on it - if it happens again, I'll inform you.
One last question:
If, for any circumstance, it's needed to update the bootloader itself without loosing the application, what would be best way to do that? Reading through the bootloader/bootloadable component datasheet, I'm not sure which approach to choose. I think it's either "upgradeable stack" or "Dual application bootloader with combination projects". From the description the last one seems to be the choice, but it has the drawback that parts of the source code are the same.