[SOLVED] JFlash overwrites incorrect pages

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] JFlash overwrites incorrect pages

    Hi,

    I'm using J-Flash with an LPC54605J512 MCU. We have a bootloader that occupies address range 0x0-0x3FFF, and the app occupies 0x4000-0x7FFFF. Whenever we try to program the app space, the J-Link seems to use a sector erase, which erases the bootloader. The flash sector size in this part is 32kB, page size is 256bytes. Page erase is available in the flash API, so why does programming force a sector erase in sector 0?

    Thanks,

    Henry
  • Hi Henry,


    The J-Link software does only utilize sector erase for this device in order to strain the flash as least as possible.
    Furthermore, the reference manual does not provide information if a sector erase is necessary after a certain amount of page erase / programming cycles.

    Since the Flash sector size is 32KB, the first sector ranges from 0x0000 - 0x8000.
    Therefore, if your Data starts at 0x4000, J-Flash will erase the first sector in order to able to program it.

    A easy solution would be to merge the bootloader in the data file which is about to be programmed. This can be done automatically by using J-Flash command line options.
    Does this work for you?


    Best regards,
    Niklas
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Niklas,

    That is OK in the production environment: we produce a unified .hex file for the factory that is a merge of the boot and the app: this works OK. The problem is that our team are working on the application, and every time the app is loaded (via GDB plugin for eclipse), the J-Link erases the boot! The boot and app are necessarily separate projects, so there isn't any way to 'merge' the 2 files.
    We can't reserve a whole sector for the bootloader (too large), and we must be able to program the application only during development.

    I can't see any info from the manufacturer to suggest that page erase is a cycle-limited operation: I'm not sure why you'd need to complete a sector erase after N page erases (I can check with the FAE if you're unsure).

    Ideally we'd like to tell the tool to perform erase at the page level, or for it to determine that a sub-sector region is being programmed, and use page erase as standard. Is this possible? If not, are there plans to support page-level erase?

    Thanks,

    Henry
  • Hi Henry,


    There is a workaround for this issue:
    [Excerpt of UM8001]



    If you add "exec monitor SetFlashDLNoRMWThreshold <size>" to your GDB client startup script, J-Link will not erase, but read-modify-write the first sector.
    Does this work for you for debugging?


    Best regards,
    Niklas
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Niklas,

    that's a nice idea, but it still doesn't solve the problem:

    1. I erase the whole device
    2. I program the boot + app
    3. I program just the app (with SetFlashDLNoRMWThresholdset to 16kB)

    The application is now invalid because the lower page hasn't been erased at all. I need the loader to do the following:
    if(sizeof(data_to_program_in_sector) < sector_size)
    {
    erase_pages_where_program_will_be_loaded()
    program_data()
    }
    else
    {
    erase_sector()
    program_data()
    }

    It seems like really odd behaviour to me that the loader decides to do a sector erase when the hex/bin doesn't have data for the whole sector, especially when a page erase operation is available. Doing just sector erases over 32kB doesn't give developers much freedom to locate separate parts of a solution. Is there any way to script the loading so that we can control the load operation?

    Thanks,

    Henry
  • Hi Niklas,

    Having re-read the documentation, I think the RMW behaviour is:
    1. Read the sector
    2. Modify the copy
    3. erase the sector
    4. Program the modified copy

    In which case your suggestion would work for our application (the bootloader would still be in the modified copy). Can you confirm this is the behaviour?

    I can't see where to add the "exec monitor SetFlashDLNoRMWThreshold <size>" command (where is the GDB client startup script located?).

    Thanks,

    Henry
  • Hello,

    Niklas is currently not in the office so i will try to answer your questions.

    It seems like really odd behaviour to me that the loader decides to do a sector erase when the hex/bin doesn't have data for the whole sector, especially when a page erase operation is available. Doing just sector erases over 32kB doesn't give developers much freedom to locate separate parts of a solution. Is there any way to script the loading so that we can control the load operation?

    The reason for this behavior is that in most devices flash is logically cut down sectors to smaller page sizes to give the user more flexibility for programming which on the other hand increases the danger of bitflips in the adjacent sectors if they are not physically separated in the flash. That is why our products do sector erases per default to ensure no biterrors happen in the remaining flash.

    Having re-read the documentation, I think the RMW behaviour is:
    1. Read the sector
    2. Modify the copy
    3. erase the sector
    4. Program the modified copy


    This is the correct behavior of the RMW command.

    I can't see where to add the "exec monitor SetFlashDLNoRMWThreshold <size>" command (where is the GDB client startup script located?).


    To answer this could you please provide us with a screenshot of your debug settings tab? So we can suggest the correct placement.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nino,

    Please see the debug configuration attached. I'd like to pass the J-Link commands directly through this config page, but I'm not against having a .gdbinit script file inside the project if required.

    Many thanks for the support,

    Henry
    Images
    • GDBSetup.png

      42.29 kB, 670×926, viewed 717 times
  • Hello Henry,

    Thank you for your feedback.
    To get the RMW exec command up and running you have to use the "commands" window in the debugger tab.
    Simply start a new line and enter: monitor exec SetFlashDLNoRMWThreshold <size>

    Which values are applicable for "size" you can find in the J-Link manual in the command strings chapter under "SetFlashDLNoRMWThreshold ".

    Best regards
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nino,

    I get the following error:

    Source Code

    1. Error in final launch sequence
    2. Failed to execute MI command:
    3. monitor exec SetFlashDLNoRMWThreshold 32768
    4. Error message from debugger back end:
    5. "monitor" command not supported by this target.


    Any idea why the 'monitor' command is unsupported?

    Thanks,

    Henry
  • Hello Henry,

    Looks like the GBD client tries to execute the command before the GBD server is connected to it.
    And only the server can interpret the "monitor" command.

    Could you try to insert the startupsequence "monitor exec..." in the startup tab, not the debugger tab?
    It is most likely that the command gets called to early and placing it in the startup tab instead should do the trick.
    Could you test this and see if the behaviour changes?

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nino,

    No luck with moving to the 'Startup' tab (see attached): no error, but the behaviour is now the same as before (the boot is overwritten). Interestingly, the boot area isn't all blank, but some of it has been touched/erased, before and after snapshots of the boot area flash attached.
    Images
    • BootAfterAppLoad.png

      28.43 kB, 409×1,378, viewed 635 times
    • BootBeforeAppLoad.png

      49 kB, 409×1,376, viewed 579 times
    • GDBStartup.png

      48.28 kB, 689×976, viewed 634 times
  • Hello Henry,

    I will try to reproduce the issue later today.
    Sorry for the delay. Lots of projects open at the moment.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hello Henry,

    i made a example project in J-Link Commander for the RMW function so you can test it out on your hardware, you can download it here:
    download.segger.com/Nino/17003…nderRMWExamplePackage.zip

    Could you please check if it is working on your hardware? What the example basically does it first erases the flash content then programs the first 4 kB of the bootloader.
    After that it skips to the application address area and activates RMW for the whole chip (in this example, 32 kB should be sufficient in your case) and writes
    a 4kB App into it. Before and after the second write we check if the bootloader area has changed. If it did not, RMW worked successfully.

    Should it have worked, please check your hardwaresetup and make sure that the app file is not writing data into the bootloader area.
    If it still does not work, could you provide us with a J-Link logfile so we can try to narrow the issue down?

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nino,

    I've attached the log file from your test: everything works great, so we know that JLink can do it.
    I noticed 2 differences between your test and my config:
    1. The value passed to SetFlashDLNoRMWThreshold is preceded by '='
    2. The value passed to SetFlashDLNoRMWThreshold is hexadecimal in the form 0x

    I set the GDB init command (in the startup tab) to:
    monitor exec SetFlashDLNoRMWThreshold = 0xFFFFFFFF

    and it works fine (the boot is left untouched), so problem solved.

    BUT: if I change it to '= 0x8000' (32kB RMW limit), it doesn't work.

    Your test works fine if I change to a 32kB limit, so I'm not sure what is the problem.

    I can use the MAX value of 0xFFFFFFFF, but I'd like to know if there is any difference, or why the behaviour is different.
    Thanks for your efforts.
    Files
    • testLog.txt

      (2.87 kB, downloaded 560 times, last: )
  • Hello Henry,

    Great to see that you are up and running again.

    BUT: if I change it to '= 0x8000' (32kB RMW limit), it doesn't work.


    It is indeed strange that the 32 kB limit works with my example + J-Link Commander but not with your project + GBD/IDE you are using.
    Could you check if the issue remains when you use the J-Link Commander to program your project?

    I can use the MAX value of 0xFFFFFFFF, but I'd like to know if there is any difference, or why the behaviour is different.


    If you make sure that you do a whole flash erase each time before first time programing the flash then it should not make any difference if you set 32 kB to RMW or the whole flash as the remaining memory will remain empty after a RMW.

    Could you provide me with a J-Link logfile when your project is getting programmed with the 32 kB RMW limit?
    Maybe we can narrow it down from there.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nino,

    Thanks for persevering....
    Could you check if the issue remains when you use the J-Link Commander to program your project?
    It works fine, with the threshold set to 0x8000: this gives me hope that it's a GDB thing, not something j-link is doing.
    Could you provide me with a J-Link logfile when your project is getting programmed with the 32 kB RMW limit?
    Log attached. I can see that the RMW command is being processed, but the result is the same as originally: that sector 0 is blank from address 0x170, and not blank but also not correct below that address.
    I completed this test by:
    1. erase the whole flash (using j-flash)
    2. program the boot
    3. program the app (does not run)
    4. examine the flash around address 0x170 (is corrupt/blank)

    Thanks,

    Henry
    Files
    • gdbLog.txt

      (11.92 kB, downloaded 561 times, last: )
  • Hello Henry,

    Is it possible that your application is larger than the remaining 16 kB in the first sector?
    If that is the case then you have to increase the RMW range to at least the size of the bootloader + app. Or to be sure (so you dont have to change anything each time your app gets larger)
    just set the whole flash to RMW (like in the example provided by me) after an initial erase.
    So just stick to 0xFFFFFFFF and you are good to go.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Nino,

    So I now understand: I thought the RMW threshold applied to the contents found in each sector, but in fact it applies to the whole image. That explains why 0x8000 (the sector size) doesn't work: the application is MUCH larger than that. However, it works in JFlash with RMW set to 32kB, which is odd.
    I think setting to the MAX value is OK, with a caveat that if your application gets smaller, and you don't perform a full erase, that a small piece of the old application is left in flash. This is OK for development: as far as I know the flash contents beyond the application are irrelevant.

    Many thanks,

    Henry
  • Hi Henry,


    So I now understand: I thought the RMW threshold applied to the contents found in each sector, but in fact it applies to the whole image.

    This is correct. If the total size of a write is < RMW value, the write will be read-modify-write. Sorry for any confusion caused.

    Good to hear that everything is working for you now.


    Best regards,
    Niklas
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.