6 Replies Latest reply on Mar 26, 2020 10:41 PM by BrBr_1320441

    Secure DFU failure on large applications




      I have been trying to get secure DFU working with a UART transport layer and am having some issues. I believe I have a safe memory layout at this point, but it would appear I am trying to write to read only memory still.


      I am basing my work on CE222802 on CYBLE-416045-2. I am using PDL 3.0.4 because the suggested version of 3.0.1 will not work with CYBLE-416045-2, and upgrading to 3.1+ causes lots of backwards compatibility issues.


      Anyway, with the standard project and PDL 3.0.4 (and one header change needed for a difference between PDL 3.0.1 and 3.0.4), everything works.


      However, my actual application needs much more memory (both flash and ram) than this example project allocates for App1.


      So, I am starting with just the flash memory tables, and I modified it as such in both app0 and app1 in the common linker script.


          flash_app0_core0  (rx)  : ORIGIN = 0x10000000, LENGTH = 0x10000

          flash_app0_core1  (rx)  : ORIGIN = 0x10010000, LENGTH = 0x10000

          flash_app1_core0  (rx)  : ORIGIN = 0x10040000, LENGTH = 0x20000

          flash_app1_core1  (rx)  : ORIGIN = 0x10060000, LENGTH = 0x80000



          flash_storage     (rw)  : ORIGIN = 0x100E0000, LENGTH = 0x1000

          flash_boot_meta   (rw)  : ORIGIN = 0x100FFA00, LENGTH = 0x400


      All other variables are exactly the same. Bolded values are the ones I actually changed from the default in CE222802.


      When I do this, after around 350 seconds (towards the end of the process) I receive an error in the bootloader host tool: "The flash row is not valid for the selected array"


      If I reduce LENGTH(flash_app1_core1) (I tested at 0x4000), then it works. It did not work with length of 0x6000 though.


      I am not sure why this wouldn't be right. I cant see any obvious memory overlaps.


      Thanks for any help

        • 1. Re: Secure DFU failure on large applications

          As a follow up -- I believe I have at least identified the cause.


          It would appear the secure dfu sample CE222802  (which I am using as a base), first uploads the image to a temporary location and then moves it after validation.


          The temporary location chosen is 0x10080000. So it is writing the application and will reach the flash_storage region after 0x6000 bytes. This would make sense why it reached the very end but failed when I set it to 0x6000, but worked at 0x5000 length.


          So, as a test I changed the temporary image location in bootload_user.c to &__cy_app1_verify_start.


          And with that, the application completes bootloading successfully!


          But Im still not done, because it appears that it isn't loading the bootloadable correctly at this point. I wonder if it is failing to validate for some reason?


          Is there a better way to actually disable the temporary image placement? I am perfectly okay with the loader corrupting the application in this case, so long as the bootloader is still functional.

          • 2. Re: Secure DFU failure on large applications

            It looks there is no simple way to disable the temporary image placement in CE222802, unless to modify the specific project code.

            Instead, CE213903 use a direct loading method to store image in a perpetual address. You can refer to this code to modify CE222802.


            Just for remaind, one major differenrce between the two projects is the handling in bootload_user.c / dfu_user.c -> Cy_Bootload_WriteData() / Cy_Dfu_WriteData().

            Another one is the appId marked in CE222802 app1 linker files is 2, to recognize the received image to store in a temporary place  -


            /* Bootloader SDK specific: sets an app Id */

            __cy_app_id = 2;


            Hope this helps.

            • 3. Re: Secure DFU failure on large applications

              Great, thanks. I will follow up with that today and hopefully have something working soon.


              Another question I have related to this:


              When I build an application with Creator I of course get 4 total hex files for CM0+/CM4 core on App0/1. In a production environment, should I be using something like Cypress Programmer or OpenOCD to program all four of those seprately? And would that be equivalent to programming the bootloader and bootloading the bootloadable? Basically I am trying to avoid needing to bootload in a prod environment because it takes forever and is a separate test. I would rather flash both in the same step.



              • 4. Re: Secure DFU failure on large applications

                After refactoring based on CE213903  I am now correctly bootloading without temporary image placement.


                I was also able to verify that flashing the four hex files was good enough to load both the bootloader and bootloadable application.


                Should I be flashing the normal hex file or the signed one for the bootloader and/or application? It doesn't appear to work when flashing the signed hex files that are generated from the mcu elf tool.

                • 5. Re: Secure DFU failure on large applications

                  You should flash the normal hex file.

                  In addition, it's feasible to generate a merged hex file of both app0 and app1 to simplify the flash process. Please refer to the steps described in the following KBA - Generate Combined Hex File for PSoC 6 MCU Basic Device Firmware Update - KBA227138

                  • 6. Re: Secure DFU failure on large applications

                    Great, thank you!


                    That led me to the documentation for cymcuelftool and I now am able to generate a single image for both cores and both apps.


                    I think I have this working now.