<?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>speed up flash programming time</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/63522/speed-up-flash-programming-time</link><description>Hi, 
 We are using Jlink and nrfjprog to program the nRF52832 flash via SWD interface. We have a combined hex file which is about 512k and takes about 12 seconds to flash it. 
 I tried to change the clock and seems not effective at all. I also search</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Sat, 05 Dec 2020 07:44:54 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/63522/speed-up-flash-programming-time" /><item><title>RE: speed up flash programming time</title><link>https://devzone.nordicsemi.com/thread/283404?ContentTypeID=1</link><pubDate>Sat, 05 Dec 2020 07:44:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f1052961-66c4-42df-a5f9-d7ec8edc073e</guid><dc:creator>Korn&amp;#233;l Schadl</dc:creator><description>&lt;p&gt;I had a similar problem and solved it by mass-updating devices through&amp;nbsp;the native RADIO peripheral.&lt;/p&gt;
&lt;p&gt;The approach&amp;nbsp;is that&amp;nbsp;a preprogrammed firmware (called updater) is periodically waking up and listening on a channel to see if there are update packages in the air. If there are, it starts&amp;nbsp;capturing and writing them to the flash, taking note of which offset+length ranges&amp;nbsp;were received. Once it has all&amp;nbsp;ranges received, it&amp;nbsp;resets the entry point to the starting address and reboots. (The wakeup and listening interval is adjusted in the updater based on whether the device has an on/off switch, or if it comes with a battery and it is on after&amp;nbsp;leaving the assembly house, etc.)&lt;/p&gt;
&lt;p&gt;Another device that is located at your facility has the actual target firmware and an additional one (called distributor) that is constantly looping over the target firmware&amp;#39;s flash areas (in its own flash), assembles&amp;nbsp;the update packages, and broadcasts them. A package contains an offset, the&amp;nbsp;chunk size, and the payload (e.g. in 128-byte chunks). You will also have to transmit the overall firmware size and ideally an overall hash (e.g. crc32) as a start or end packet.&lt;/p&gt;
&lt;p&gt;Ideally, you implement the transmission so that there are no ACK packages sent from the updaters, to avoid collisions on the channels, and also have some&amp;nbsp;security measures implemented to&amp;nbsp;minimize&amp;nbsp;the risk of unintended updates (e.g. you can place a public key in the updater and sign all packages in the distributor).&lt;/p&gt;
&lt;p&gt;Not sending ACK&amp;nbsp;responses is not an issue, as the distributor continuously loops through its firmware chunks, and if the updater doesn&amp;#39;t catch one, it will likely do in the next round.&lt;/p&gt;
&lt;p&gt;The updater/distributor`s&amp;nbsp;linker&amp;nbsp;could use&amp;nbsp;a similar layout (below is&amp;nbsp;an example for nRF52840):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;MEMORY
{
&amp;#160; &amp;#160; FLASH (rx) : ORIGIN = 0x000fc000, LENGTH = 0x02000
&amp;#160; &amp;#160; RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;For nRF52832 it would look the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;MEMORY
{
    FLASH (rx) : ORIGIN = 0x0007c000, LENGTH = 0x02000
    RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x10000
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In your case, I would have one distributor (on one end of the channels)&amp;nbsp;for the test firmware, another&amp;nbsp;few for receiving test results along with the device id (on different channels), and a third one on the other end of the channels that distributes the&amp;nbsp;final firmware.&lt;/p&gt;
&lt;p&gt;The test firmware would send its test results on a random channel selected from a predefined&amp;nbsp;list (which is where the&amp;nbsp;test listeners watch) and would wait for an ACK. If the ACK arrived, it goes ahead with updating to the final firmware.&lt;/p&gt;
&lt;p&gt;With this approach (at least regarding the update procedure) you are theoretically limited&amp;nbsp;by the number of devices that can physically fit&amp;nbsp;in the area you are broadcasting your firmwares in, without shadowing the signal too much, and&amp;nbsp;by the number of collisions, the transmission of test results, and test-result-ACKs&amp;nbsp;cause (which is easier to scale).&lt;/p&gt;
&lt;p&gt;Some additional thoughts:&lt;br /&gt;- Besides the overall hash of the&amp;nbsp;firmware you send at the beginning or end of a distributor loop cycle, it makes sense to&amp;nbsp;use 3 byte CRCs per packet (using the NRF_RADIO&amp;#39;s registers), to further lower the risk of corruption in the final transmitted firmware. If a corruption is detected by the updater using the final hash,&amp;nbsp;it should just re-receive all update packages from the beginning.&lt;br /&gt;-&amp;nbsp;If you are worried about transmitting the firmware OTA in your local area, you can pseudo-encrypt it using the public key that is already in the updater (along with some other logic), or for better security, you can do an initial handshake with an additional device for a fixed key exchange (that can also be regenerated periodically) and use AES-128 or similar.&lt;br /&gt;- It might sound funny, but if the key exchange and test-result transmissions&amp;nbsp;become a significant bottleneck, you can just put all devices on a moving belt (or cart for that matter)&amp;nbsp;and move them from one place to&amp;nbsp;another, where there are multiple distributors/key-exchangers/test-result-grabbers along the way.&lt;br /&gt;&lt;br /&gt;Also, a 512k hex file is not that big,&amp;nbsp;for the bytes transferred, rather look for the&amp;nbsp;size of the bin file (that is what actually lives on the flash).&lt;/p&gt;
&lt;p&gt;Below&amp;nbsp;is an excerpt of code that copies the flash content from one area to another (in&amp;nbsp;the aforementioned approach you don&amp;#39;t have to copy from A to B, but it can be a good starting point):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;storage_init();

if (storage.firmware_ready_to_copy) {
    uint32_t crc = crc32_compute((uint8_t *) BANK_1_START, storage.firmware_size, 0);

    if (crc == storage.firmware_crc) {
        uint32_t i, pages = (storage.firmware_size + (CODE_PAGE_SIZE - 1)) / CODE_PAGE_SIZE;

        do {
            for (i = 0; i &amp;lt; pages; i++) {
                nrf_gpio_pin_clear(PIN_LED02);
                nrf_nvmc_page_erase((uint32_t) (BANK_0_START + i * CODE_PAGE_SIZE));
                nrf_gpio_pin_set(PIN_LED02);
                nrf_nvmc_write_words(BANK_0_START + i * CODE_PAGE_SIZE, (const uint32_t *) (BANK_1_START + i * CODE_PAGE_SIZE), CODE_PAGE_SIZE / sizeof(uint32_t));
            }
        } while (crc32_compute((uint8_t *) BANK_0_START, storage.firmware_size, 0) != crc);
    }

    storage.firmware_ready_to_copy = 0;

    storage_save();
}

NVIC_SystemReset();
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You can start an app from a given address on the bus with cpu_start():&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void __attribute__ ((noinline)) start_app(uint32_t addr) {
    __asm volatile(
    &amp;quot;ldr   r0, [%0]\n&amp;quot;
    &amp;quot;msr   msp, r0\n&amp;quot;
    &amp;quot;ldr   r0, [%0, #0x04]\n&amp;quot;
    &amp;quot;movs  r4, #0xFF\n&amp;quot;
    &amp;quot;sxtb  r4, r4\n&amp;quot;
    &amp;quot;mrs   r5, IPSR\n&amp;quot;
    &amp;quot;cmp   r5, #0x00\n&amp;quot;
    &amp;quot;bne   isr_abort\n&amp;quot;
    &amp;quot;mov   lr, r4\n&amp;quot;
    &amp;quot;bx    r0\n&amp;quot;

    &amp;quot;isr_abort:  \n&amp;quot;
    &amp;quot;mov   r5, r4\n&amp;quot;
    &amp;quot;mov   r6, r0\n&amp;quot;
    &amp;quot;movs  r7, #0x21\n&amp;quot;
    &amp;quot;rev   r7, r7\n&amp;quot;
    &amp;quot;push  {r4-r7}\n&amp;quot;
    &amp;quot;movs  r4, #0x00\n&amp;quot;
    &amp;quot;movs  r5, #0x00\n&amp;quot;
    &amp;quot;movs  r6, #0x00\n&amp;quot;
    &amp;quot;movs  r7, #0x00\n&amp;quot;
    &amp;quot;push  {r4-r7}\n&amp;quot;
    &amp;quot;movs  r0, #0xF9\n&amp;quot;
    &amp;quot;sxtb  r0, r0\n&amp;quot;
    &amp;quot;bx    r0\n&amp;quot;
    &amp;quot;.align\n&amp;quot;
    ::
    &amp;quot;r&amp;quot;(addr):
    &amp;quot;r0&amp;quot;, &amp;quot;r4&amp;quot;, &amp;quot;r5&amp;quot;, &amp;quot;r6&amp;quot;, &amp;quot;r7&amp;quot;);
}

void cpu_start(uint32_t address) {
    NVIC-&amp;gt;ICER[0] = 0xFFFFFFFF;
#if defined(__NRF_NVIC_ISER_COUNT) &amp;amp;&amp;amp; __NRF_NVIC_ISER_COUNT == 2
    NVIC-&amp;gt;ICER[1] = 0xFFFFFFFF;
#endif

    start_app(address);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hope that helps,&lt;/p&gt;
&lt;p&gt;Korn&amp;eacute;l&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: speed up flash programming time</title><link>https://devzone.nordicsemi.com/thread/259118?ContentTypeID=1</link><pubDate>Thu, 09 Jul 2020 09:14:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8a40d996-ac6b-4bc3-88c9-530d41a1c607</guid><dc:creator>George Leung</dc:creator><description>&lt;p&gt;This is not&amp;nbsp;practical for our case. The test code is much smaller than the app code.&lt;/p&gt;
&lt;p&gt;Anyway we want to know any tricks could reduce the programming time? Is it already up to limited and no room to improve. Is there any Jtag tool apart from Jlink may help on this?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: speed up flash programming time</title><link>https://devzone.nordicsemi.com/thread/259102?ContentTypeID=1</link><pubDate>Thu, 09 Jul 2020 08:22:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c054322a-9b93-45b7-9da5-afc676e2a41c</guid><dc:creator>awneil</dc:creator><description>&lt;p&gt;It could be pre-programmed with the test code.&lt;/p&gt;
&lt;p&gt;That would halve your &lt;em&gt;total&lt;/em&gt; programming time ...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: speed up flash programming time</title><link>https://devzone.nordicsemi.com/thread/259074?ContentTypeID=1</link><pubDate>Thu, 09 Jul 2020 06:21:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fa8fdf31-b585-4e5b-b231-729265c0646e</guid><dc:creator>George Leung</dc:creator><description>&lt;p&gt;We have a PCBA test firmware and an application firmware, so the chip will be programmed twice. So it cannot be pre-programmed.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: speed up flash programming time</title><link>https://devzone.nordicsemi.com/thread/259009?ContentTypeID=1</link><pubDate>Wed, 08 Jul 2020 13:37:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b3e778f2-54ee-4e67-9807-cbba4f57e1b3</guid><dc:creator>awneil</dc:creator><description>[quote userid="9458" url="~/f/nordic-q-a/63522/speed-up-flash-programming-time"]Our production is quite large (&amp;gt;100k per quarter),[/quote]
&lt;p&gt;Perhaps you could consider getting the chips programmed&amp;nbsp;by your supplier ... ?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>