How to flashing firmware without erasing factory data

Hello Nordic team!
I am currently encountiering such a problem. During the production process, factory data is downloaded to the designated area in advanced through the following command:

PS D:\Factory> python .\matter\scripts\tools\nrfconnect\generate_nrfconnect_chip_factory_data.py `
>> --sn 11223344556677889900 `
>> --vendor_id 65521 `
>> --product_id 32774 `
>> --vendor_name "Nordic Semiconductor ASA" `
>> --product_name "Matter Test Device" `
>> --date 2023-01-01 `
>> --hw_ver 1 `
>> --hw_ver_str v1.0 `
>> --dac_cert .\Chip-DAC-Cert.der `
>> --dac_key .\Chip-DAC-Key.der `
>> --pai_cert .\Chip-PAI-Cert.der `
>> --spake2_it 1000 `
>> --spake2_salt U1BBS0UyUCBLZXkgU2FsdA== `
>> --discriminator 0xF00 `
>> --passcode 20252050 `
>> --generate_onboarding `
>> --out .\build `
>> --offset 0x172000 `
>> --size 0x1000 `
>> --schema .\matter\scripts\tools\nrfconnect\nrfconnect_factory_data.schema

You can see:

>> --offset 0x172000 `
>> --size 0x1000 `
The specified download area has been provided, which is obtained in pm_static_nrf54l15_cpuapp.yml:

mcuboot_primary_app:
  orig_span: &id002
  - app
  span: *id002
  address: 0xD800
  region: flash_primary
  size: 0x164800
factory_data:
  address: 0x172000
  region: flash_primary
  size: 0x1000
settings_storage:
  address: 0x173000
  region: flash_primary
  size: 0xA000

Then I used:
nrfutil device program --firmware .\build.hex --serial-number 
Successfully downloaded:

PS D:\Factory> nrfutil device program --firmware .\build.hex --serial-number xxxxxxxx
[00:00:01] ###### 100% [2/2 xxxxxxxx] Programmed

THen the problem came, I found that in vscode, I always faied to download  when I cliked Flash, as long as the generated factory hex file was downloaded before:

[10/10] Generating ../matter.ota
-- west flash: using runner nrfutil
-- runners.nrfutil: mass erase requested
-- runners.nrfutil: reset after flashing requested
-- runners.nrfutil: Flashing file: D:\Code\matter-samples\light_switch_1\build\merged.hex
Error: One or more batch tasks failed:
 * 1057775460: [Probe] Failed to attach to target: The Application core access port is protected (All) (NotAvailableBecauseProtection)


The operation was unavailable for some of the devices because they had readback protection enabled. These devices might be possible to unlock using the `recover` subcommand. See `nrfutil device recover --help` for more information.

ERROR: runners.nrfutil: Flashing failed because the target must be recovered.
  To fix, run "west flash --recover" instead.
  Note: this will recover and erase all flash memory prior to reflashing.
FATAL ERROR: command exited with status 24: nrfutil --json device x-execute-batch --batch-path 'D:\Code\matter-samples\light_switch_1\build\generated_nrfutil_batch.json' --serial-number 1057775460

 *  The terminal process terminated with exit code: 24. 
 *  Terminal will be reused by tasks, press any key to close it. 

According to prompts, then I executed west flash --recover, which was downloaded successfully, but the result was to overwrite the previously downloaded factory data hex file.

There are two case here, I don't do any configuration, just west flash --recover and the uart print the vendor information and defualt certificate provided by Nordic for each matter sample.
In the second case, I set SB_CONFIG_MATTER_FACTORY_DATA_GENERATE = n in sysbuild.conf, although no factory data is generated at compile time. But with west flash --recover, I found that the factory data was  still overwritten, because the serial output told me:

uart:~$ *** Booting My Application v2.9.0-46e3bca3919f ***
*** Using nRF Connect SDK v2.9.0-7787b2649840 ***
*** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
I: 1433 [DL]BLE address: C9:E8:4E:4E:29:60
I: 1440 [DL]CHIP task running
I: Init CHIP stack
I: 1445 [DL]OpenThread started: OK
I: 1448 [DL]Setting OpenThread device type to SLEEPY END DEVICE
E: 1454 [DL]Failed to parse factory data
E: FactoryDataProvider::Init() failed [Error: 160]
E: Exited with code a0


Why is this so important? In out production process, the certificate and vendor information are combined into a factory data hex file through a python script, wich is downloaded to the product in advance. Than I have to make sure that my product firmware does not overwrite the location of this factory data hex file.

ncs version v2.9

I followed the post titled "Flashing firmware without erasing factory data - Nordic Q&A - Nordic DevZone - Nordic DevZone" and tried it out, but it failed. I learned from the forum's AI that the CONFIG_CHIP_FACTORY_DATA_BUILD  has been deprecated, so I used SB_CONFIG_MATTER_FACTORY_DATA_GENERATE instead, but the resualt was the same. If factory data exists beforehand, I have to use west flash --revocer, which ends up overwriting the factory data. If there's existing firmware, falshing the factory data will overwrite the firmware...

 

Parents Reply
  • Hi,

    On the nRF54L15, APPROTECT will automatically be enabled upon reset, as seen in Enabling access port protection mechanism.
    An application with CONFIG_NRF_APPROTECT_USE_UICR set will disable APPROTECT when it starts, which is why our samples do not enable APPORTECT by default.

    This means that if you flash factory_data.hex and no application, then reset the device, APPROTECT will be enabled.

    A workaround is to flash a minimal application at the same time as factory_data.hex, which only sets CONFIG_NRF_APPROTECT_USE_UICR. Then, you can flash your actual application over the "placeholder" application later.

    Best regards,
    Marte

Children
  • Thanks to Marte for the detailed answer! I plan to test the method tomorrow. I will caom back annd share the results.
    Thanks again for your help!

  • Hi, Marte.
    I'm really sorry. I followed your steps, but there are still issues. My problem likely arose when creating a minimal application. Here's what I did:

    1. First, since my chip is the nrf54l15, I couldn't use `CONFIG_NRF_APPROTECT_USE_UICR`. Instead, I set `CONFIG_NRF_APPROTECT_DISABLE` to `y`.
    2. At this step, I tried two different approaches. The first was making no changes, and the second involved disabling Factory merge-related configurations:
    `CONFIG_CHIP_FACTORY_DATA=y`
    `CONFIG_CHIP_FACTORY_DATA_BUILD=n`
    `SB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y`
    `SB_CONFIG_MATTER_FACTORY_DATA_MERGE_WITH_FIRMWARE=y`
    3. For both attempts, I used the following merge methods:
    `python mergehex.py -o firmware.hex merged.hex factory.hex --overlap replace`
    `python mergehex.py -o firmware.hex factory.hex merged.hex`
    Here, `build.hex` is my factory data, `merged.hex` is the compiled minimal application file, and `firmware.hex` is the merged firmware. The path for `mergehex.py` is `zephyr\scripts\build\mergehex.py`.
    4. There were two outcomes:
    - The first case still outputs the default factory data over the serial port, with no changes.
    - The second case produces the following output:
    ```
    *** Booting My Application v2.9.0 - unknown commit ***
    *** Using nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***

    I: 1301 [DL]BLE address: C7:D6:46:A0:2D:35
    I: 1308 [DL]CHIP task running
    I: Init CHIP stack
    I: 1313 [DL]OpenThread started: OK
    I: 1316 [DL]Setting OpenThread device type to MINIMAL END DEVICE
    I: 1322 [DL]The device does not support hardware protection against write.
    E: GetEnableKey() failed [Error: 160]
    E: Exited with code a0
    uart:~$
    ```

    So, what should I do? I should mention that I prefer using command-line tools as much as possible, as this would make it easier to create a tool for manufacturers to download factory data.

    Alternatively, is my approach of separating factory data and firmware downloads uncommon? What’s the standard practice here?

    Anyway, thanks a lot for your reply.
    Best regards,
    wang
  • Hi,

    Great to hear that you found the solution!

    Please let me know if you experience any more issues related to this.

    Best regards,
    Marte

  • Hi Marte,

    I'm glad to see your reply. Now I'm stuck with another issue. Although I no longer encounter problems related to protection, I still can't figure out how to download the firmware without overwriting the previous factory data.

    As you mentioned, the minimal application is essentially a regular program that incorporates the factory data I requested—that part is fine. However, whether I flash the new firmware using VSCode or with the command `nrfutil device program --firmware .\firmware.hex --serial-number xxxx`, it always overwrites the factory data embedded in the minimal application.

    What should I do?

    Thanks for your hlep.

Related