<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>GPREGRET register causing data corruption when set during custom use-case</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/111136/gpregret-register-causing-data-corruption-when-set-during-custom-use-case</link><description>Hi all. I am using nRF5 SDK 15.0.0 and the S140 SoftDevice v6.0.0 to develop on an nRF52840. Due to software infrastructure constraints, I am unable to implement DFU using Nordic-provided tools. Instead I rely on a custom dual-bank update process that</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 17 May 2024 19:09:19 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/111136/gpregret-register-causing-data-corruption-when-set-during-custom-use-case" /><item><title>RE: GPREGRET register causing data corruption when set during custom use-case</title><link>https://devzone.nordicsemi.com/thread/484834?ContentTypeID=1</link><pubDate>Fri, 17 May 2024 19:09:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c953ed68-1c0e-43f9-a153-c4a946650908</guid><dc:creator>rbmarcus</dc:creator><description>&lt;p&gt;Thank you for confirming that the GPREGRET register should not affect flash on reboot with my custom bootloader. I tested again today and analyzed the binary blob at each step of the process, and it is indeed unrelated to GPREGRET. I hadn&amp;#39;t been giving enough time for the fstorage init and store calls to process, so I would get occasional corruption. I tested the 4 trials mentioned in my first post a handful more times, and the error rate between them is completely random. After gating fstorage calls behind a flag set by the callback handler, I am now able to safely transfer the blob without error.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m concerned about this current transfer method, so I will be exploring alternative options for OTA DFU. Thank you again for the information you provided.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPREGRET register causing data corruption when set during custom use-case</title><link>https://devzone.nordicsemi.com/thread/483237?ContentTypeID=1</link><pubDate>Tue, 14 May 2024 11:27:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fe9c04cc-fcad-43b3-85dd-5762f3e676c9</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;The GPREGRET registers are meant to be retained through soft resets, as shown in the table here: &lt;a title="Reset behavior" href="https://infocenter.nordicsemi.com/topic/ps_nrf52840/power.html?cp=5_0_0_4_2_5_7#concept_res_behav"&gt;Reset behavior&lt;/a&gt;. We also use these registers in our SDK examples to enable the application to signal the bootloader to enter DFU mode following a soft reset.&lt;/p&gt;
[quote user=""]What does setting GPREGRET trigger after a reboot, aside from holding the values that were set?[/quote]
&lt;p&gt;These are just general-purpose retention registers and will not have any effect unless the application or bootloader is actually using them. The SoftDevice/MBR does not use them.&amp;nbsp;&lt;/p&gt;
[quote user=""]How can I prevent the flash region where my binary blob is stored from being modified, unless done so directly in custom code via the bootloader main[/quote]
&lt;p&gt;I&amp;#39;m not sure what could be corrupting the data. What kind of corruption are you seeing? Is there any pattern, or does it seem&amp;nbsp;arbitrary? You can use nrfjprog to inspect the memory.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;$ nrfjprog --memrd 0x70000 --n 0x70000 &amp;gt; dfu_slot.txt&lt;/pre&gt;&lt;/p&gt;
[quote user=""]Are there any other registers I can use to pass a flag to the bootloader without triggering any SDK functionality?[/quote]
&lt;p&gt;I&amp;#39;m not sure what SDK functionality it could be since you are using a custom bootloader. If there is, you should be able to find references to it by searching through your bootloader and application project for &amp;#39;gpregret&amp;#39;.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPREGRET register causing data corruption when set during custom use-case</title><link>https://devzone.nordicsemi.com/thread/483144?ContentTypeID=1</link><pubDate>Tue, 14 May 2024 02:50:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:31e1ca8f-5ab4-452e-84fc-fee533359c57</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;So .. I tested this, albeit on an nRF52833 &amp;#39;cos I couldn&amp;#39;t be bothered to switch to an nRF52840. Data sheet indicates identical performance, soft reset retains registers .. after 100 soft resets (no errata, power on, no debugger attached):&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Results: mResetCount = 100, SRAM_OkCount = 100, GPREGRET_OkCount = 100, GPREGRET2_OkCount = 100&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Place following data in section .noinit so it doesn&amp;#39;t get wiped on a reset
#pragma default_variable_attributes = @ &amp;quot;.noinit&amp;quot;
  // Valid data indication for this data
  static volatile uint32_t mIamInitialized    __attribute__((section(&amp;quot;.noinit&amp;quot;)));
  static volatile uint32_t mDummyGPREGRET     __attribute__((section(&amp;quot;.noinit&amp;quot;)));
  static volatile uint32_t GPREGRET_OkCount   __attribute__((section(&amp;quot;.noinit&amp;quot;)));
  static volatile uint32_t GPREGRET2_OkCount  __attribute__((section(&amp;quot;.noinit&amp;quot;)));
  static volatile uint32_t SRAM_OkCount       __attribute__((section(&amp;quot;.noinit&amp;quot;)));
  static volatile uint32_t mResetCount        __attribute__((section(&amp;quot;.noinit&amp;quot;)));
#pragma default_variable_attributes =
// End - Place following data in section .noinit so it doesn&amp;#39;t get wiped on a reset

#define MAGIC_8BIT_CODE1  96
#define MAGIC_8BIT_CODE2  23
#define MAGIC_8BIT_CODE3 102
  void TestGPREGRET(void)
  {
     char InfoPacket[120] = &amp;quot;&amp;quot;;
     mResetCount++;
     if (mDummyGPREGRET == MAGIC_8BIT_CODE1)
     {
        SRAM_OkCount++;
     }
     if (NRF_POWER-&amp;gt;GPREGRET == MAGIC_8BIT_CODE2)
     {
        GPREGRET_OkCount++;
     }
     if (NRF_POWER-&amp;gt;GPREGRET2 == MAGIC_8BIT_CODE3)
     {
        GPREGRET2_OkCount++;
     }
     // See if data is valid - Use unique device ID as the valid signature
     if (mIamInitialized != NRF_FICR-&amp;gt;DEVICEID[0])
     {
        // Indicated data is now valid - Use unique device ID as the valid signature
        mIamInitialized = NRF_FICR-&amp;gt;DEVICEID[0];
        mResetCount       = 0;
        SRAM_OkCount      = 0;
        GPREGRET_OkCount  = 0;
        GPREGRET2_OkCount = 0;
        mDummyGPREGRET       = MAGIC_8BIT_CODE1;
        NRF_POWER-&amp;gt;GPREGRET  = MAGIC_8BIT_CODE2;
        NRF_POWER-&amp;gt;GPREGRET2 = MAGIC_8BIT_CODE3;
     }
     if (mResetCount &amp;lt; 100)
     {
        // Trigger another reset
        NVIC_SystemReset();
     }
     // break after all the reset tests, log results
     // Results: mResetCount = 100, SRAM_OkCount = 100, GPREGRET_OkCount = 100, GPREGRET2_OkCount = 100
     snprintf(InfoPacket, sizeof(InfoPacket)-1, &amp;quot;Results: mResetCount = %u, SRAM_OkCount = %u, GPREGRET_OkCount = %u, GPREGRET2_OkCount = %u\r\n&amp;quot;, mResetCount, SRAM_OkCount, GPREGRET_OkCount, GPREGRET2_OkCount);
     uartSend(InfoPacket, strlen(InfoPacket));
     while(1) ;
  }
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>