<?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>How to detect &amp;quot;this is the first bootup of a new DFU image&amp;quot;</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/74560/how-to-detect-this-is-the-first-bootup-of-a-new-dfu-image</link><description>I have been unsuccessful attempting to perform an FDS write or update WITHIN the DFU Event handler... the update or write never completes (no FDS_EVT_WRITE or FDS_EVT_UPDATE). I&amp;#39;m wondering if that is the wrong context in which to do that. I am able to</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 30 Apr 2021 06:43:21 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/74560/how-to-detect-this-is-the-first-bootup-of-a-new-dfu-image" /><item><title>RE: How to detect "this is the first bootup of a new DFU image"</title><link>https://devzone.nordicsemi.com/thread/307599?ContentTypeID=1</link><pubDate>Fri, 30 Apr 2021 06:43:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2a70002a-a5da-4f35-88c0-427c0300dd65</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;After writing to flash you need to delay resetting until after the flash operation has completed. However, your approach may not be the best in this case depending on your interrupt priorities. I would avoid the call to&amp;nbsp;wait_for_fds_write_complete() that never returns, and instead check the&amp;nbsp;l_fds_write_pending flag when you handle the&amp;nbsp;NRF_PWR_MGMT_EVT_PREPARE_DFU event. If flash operation has not completed, return false from the&amp;nbsp;app_shutdown_handler() in that case (I do not see this part of your code so here I am referring to SDK code which might not map exactly to your code). This event will then happen again and again until you are ready (flash operation has completed), and in that case, return true so that reset can occur and the device can start in bootloader DFU mode.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to detect "this is the first bootup of a new DFU image"</title><link>https://devzone.nordicsemi.com/thread/307568?ContentTypeID=1</link><pubDate>Thu, 29 Apr 2021 22:08:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dd22623a-c8cc-4715-85c0-419d549fba8c</guid><dc:creator>jcvandegrift</dc:creator><description>&lt;p&gt;&lt;code&gt;// Note: FDS initialization is working, the boot count is updated every reboot as intended and is readable&lt;br /&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; everywhere and writable everywhere except from the DFU Handler.&lt;br /&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Any DFU (even if the code is unchanged) needs to &amp;quot;notify&amp;quot; the robot at the next reboot that the reboot is the result of a DFU even if the update failed.&lt;br /&gt;//&lt;br /&gt;&lt;br /&gt;//// Tertill DFU Handler&lt;br /&gt;&lt;br /&gt;static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch (event)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Device is preparing to enter bootloader mode.&amp;quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Tertill - Version #1 - update FDS record earlier in DFU sequence&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clear_boot_count_c(); // robot will shut itself off at next reboot, post-DFU action must be OFF&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case BLE_DFU_EVT_BOOTLOADER_ENTER:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Device will enter bootloader mode.&amp;quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Tertill - Version #2 - update FDS record later in DFU sequence&lt;br /&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clear_boot_count_c(); // robot will shut itself off at next reboot, post-DFU action must be OFF&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_ERROR(&amp;quot;Request to enter bootloader mode failed asynchroneously.&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case BLE_DFU_EVT_RESPONSE_SEND_ERROR:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_ERROR(&amp;quot;Request to send a response to client failed.&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; APP_ERROR_CHECK(false);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_ERROR(&amp;quot;Unhandled event from ble_dfu_buttonless: %d&amp;quot;, event);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//// Tertill FDS Code&lt;br /&gt;&lt;br /&gt;// Simple event handler to handle errors during initialization.&lt;br /&gt;static void fds_evt_handler(fds_evt_t const * p_evt)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Event: %s received (%s)&amp;quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_evt_str[p_evt-&amp;gt;id],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_err_str[p_evt-&amp;gt;result]);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch (p_evt-&amp;gt;id) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case FDS_EVT_INIT:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (p_evt-&amp;gt;result == FDS_SUCCESS) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_fds_initialized = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case FDS_EVT_UPDATE:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case FDS_EVT_WRITE:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (p_evt-&amp;gt;result == FDS_SUCCESS) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Record ID:\t0x%04x&amp;quot;,&amp;nbsp; p_evt-&amp;gt;write.record_id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;File ID:\t0x%04x&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp; p_evt-&amp;gt;write.file_id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Record key:\t0x%04x&amp;quot;, p_evt-&amp;gt;write.record_key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_fds_write_pending = false; // application sets this to true before initiating any write or update&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case FDS_EVT_DEL_RECORD:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (p_evt-&amp;gt;result == FDS_SUCCESS)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Record ID:\t0x%04x&amp;quot;,&amp;nbsp; p_evt-&amp;gt;del.record_id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;File ID:\t0x%04x&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp; p_evt-&amp;gt;del.file_id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;Record key:\t0x%04x&amp;quot;, p_evt-&amp;gt;del.record_key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_delete_all.pending = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void set_fds_write_pending()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_fds_write_pending = true; // application sets this to true, handler changes to false upon completion&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void wait_for_fds_write_complete(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (l_fds_write_pending) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void) sd_app_evt_wait();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// FDS Write, Update, and Read Long methods&lt;br /&gt;&lt;br /&gt;int Fds::write_long(uint16_t file_id, uint16_t record_key, uint32_t value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_record_desc_t record_desc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_record_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; record;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Wait for any previous write to complete&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_for_fds_write_complete();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Static copy of input&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static uint32_t value_copy = value;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Clear the descriptor&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;record_desc, 0x00, sizeof(fds_record_desc_t));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Fill in the record into&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.file_id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = file_id;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.key&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = record_key;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.data.p_data&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;amp;value_copy;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.data.length_words = (sizeof(value_copy) + 3) / 4; // round up to longs&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Mark write in progress, then start write&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set_fds_write_pending();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code = fds_record_write(&amp;amp;record_desc, &amp;amp;record);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( ret_code == FDS_SUCCESS ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NRF_LOG_INFO(&amp;quot;write_long() PASS\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // return 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NRF_LOG_INFO(&amp;quot;write_long() FAIL\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int Fds::update_long(uint16_t file_id, uint16_t record_key, uint32_t value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_record_desc_t record_desc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_record_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; record;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_find_token_t&amp;nbsp; ftok;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Wait for any previous write to complete&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_for_fds_write_complete();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Static copy of input&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static uint32_t value_copy = value;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Clear the descriptor and find token&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;record_desc, 0x00, sizeof(fds_record_desc_t));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;ftok&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , 0x00, sizeof(fds_find_token_t ));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Find the record&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code = fds_record_find(file_id, record_key, &amp;amp;record_desc, &amp;amp;ftok);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( ret_code == FDS_SUCCESS ) {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Fill in the record info&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.file_id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = file_id;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.key&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = record_key;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.data.p_data&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;amp;value_copy;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; record.data.length_words = (sizeof(value_copy) + 3) / 4; // round up to longs&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Mark write in progress, then start write&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set_fds_write_pending();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code = fds_record_update(&amp;amp;record_desc, &amp;amp;record);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( ret_code == FDS_SUCCESS ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NRF_LOG_INFO(&amp;quot;update_long() PASS\r\n&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // return 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;update_long() find pass, update FAIL\r\n&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NRF_LOG_INFO(&amp;quot;update_long() find FAIL\r\n&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int Fds::read_long(uint16_t file_id, uint16_t record_key, uint32_t *p_value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_find_token_t&amp;nbsp;&amp;nbsp;&amp;nbsp; ftok;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_flash_record_t&amp;nbsp; flash_record;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_record_desc_t&amp;nbsp;&amp;nbsp; record_desc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_code_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_ret_code;&lt;br /&gt;#if 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Wait for any previous write to complete&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_for_fds_write_complete();&lt;br /&gt;#endif&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset( &amp;amp;ftok&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; , 0x00, sizeof(fds_find_token_t&amp;nbsp; ) );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset( &amp;amp;flash_record, 0x00, sizeof(fds_flash_record_t) );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset( &amp;amp;record_desc , 0x00, sizeof(fds_record_desc_t ) );&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_ret_code = fds_record_find(file_id, record_key, &amp;amp;record_desc, &amp;amp;ftok);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( FDS_SUCCESS == fds_ret_code ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_ret_code = fds_record_open(&amp;amp;record_desc, &amp;amp;flash_record);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( FDS_SUCCESS == fds_ret_code ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *p_value = *((uint32_t *)(flash_record.p_data));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fds_record_close(&amp;amp;record_desc);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NRF_LOG_INFO(&amp;quot;read_long() PASS\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;read_long() find pass, read FAIL\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NRF_LOG_INFO(&amp;quot;read_long() find FAIL\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// When DFU is about to happen we do this to clear the boot count.&lt;br /&gt;// Clear Boot Count File/Record value from &amp;quot;C&amp;quot; or CPPfs&lt;br /&gt;// the extern &amp;quot;C&amp;quot; version of clear count&lt;br /&gt;void clear_boot_count_c()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; robot-&amp;gt;fds.clear_boot_count();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Class member version of clear count&lt;br /&gt;void Fds::clear_boot_count()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint16_t file_id = 0xb007; // &amp;quot;boot&amp;quot;-like&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint16_t rec_id&amp;nbsp; = 0x1234; // &amp;quot;count&amp;quot;-like&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; res;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Read the boot count, this always works and the value is correct&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool exists = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; res = read_long(file_id, rec_id, &amp;amp;m_boot_cnt);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( res == -1 ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;boot count CAN&amp;#39;T FIND\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else if ( res == -2 ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;boot count found but CAN&amp;#39;T READ\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;boot count: %d\r\n&amp;quot;, m_boot_cnt); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exists = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // what&amp;#39;s above works, what&amp;#39;s below does not work in DFU Handler context but does work after FDS setup&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Zero the boot count, this tells the next reboot that a DFU just happened.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_boot_cnt = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( exists ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; res = update_long(file_id, rec_id, m_boot_cnt);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( res == -1 ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;update_long() CAN&amp;#39;T FIND\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else if ( res == -2 ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;update_long() found but CAN&amp;#39;T UPDATE\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; res = write_long(file_id, rec_id, m_boot_cnt);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( res != 0 ) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NRF_LOG_INFO(&amp;quot;write_long() CAN&amp;#39;T WRITE\r\n&amp;quot;); NRF_LOG_FLUSH();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_for_fds_write_complete(); // This NEVER returns, implying the update or write never finishes&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to detect "this is the first bootup of a new DFU image"</title><link>https://devzone.nordicsemi.com/thread/307457?ContentTypeID=1</link><pubDate>Thu, 29 Apr 2021 11:43:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:98eaf48f-a8df-41d9-bb6b-c576acf2cab7</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi Jeff,&lt;/p&gt;
&lt;p&gt;Which DFU event handler do you refer to, and how do you make FDS calls from there? Please elaborate and show some code.&lt;/p&gt;
[quote user=""]My immediate goal is to detect that a reboot is post-DFU and do something unique. In general I&amp;#39;d like to store more state across any planned reboot, DFU, WDT, or other.[/quote]
&lt;p&gt;Just looking at this goal another approach could be to include a special version number of similar in the firmware you upgrade to, and also maintain this version in FDS. So every time the application starts you read the firmware version and compare with the version you have stored in FDS. If it is the same do nothing. If not you will know that this is the first boot after DFU update, and you also update the FDS record so that the next time it will be the same.&lt;/p&gt;
&lt;p&gt;Einar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>