{"id":2189,"date":"2023-12-17T05:33:55","date_gmt":"2023-12-17T05:33:55","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2189"},"modified":"2023-12-17T09:16:12","modified_gmt":"2023-12-17T09:16:12","slug":"w25qxx-in-spi-with-external-loader-part-3-external-loader-development","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2189","title":{"rendered":"W25QXX in SPI with External Loader Part 3: External Loader development"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"443\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-1024x443.png\" alt=\"\" class=\"wp-image-2190\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-1024x443.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-300x130.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-768x332.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-1536x664.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-1150x497.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-750x324.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-400x173.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2-250x108.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/external-loader-diagram-2.png 1674w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In the third part of external loader, we shall develop the external loader and test it.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Getting the required files.<\/li><li>Modify the file.<\/li><li>Building the external loader.<\/li><li>Testing the external loader.<\/li><li>Project download.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Getting the required files.<\/h2>\n\n\n\n<p>ST offers the required files on their repository on Github which can be downloaded from <a href=\"https:\/\/github.com\/STMicroelectronics\/stm32-external-loader\/tree\/contrib\/Loader_Files\/other%20devices\" data-type=\"URL\" data-id=\"https:\/\/github.com\/STMicroelectronics\/stm32-external-loader\/tree\/contrib\/Loader_Files\/other%20devices\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Download all four files.<\/p>\n\n\n\n<p>Copy Dev_Inf.h to inc folder.<\/p>\n\n\n\n<p>Copy both Dev_Inf.c and Loader_Src.c to src folder.<\/p>\n\n\n\n<p>Copy linker.ld to main to main project folder.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>The setup as following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"558\" height=\"826\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_07-47-42.jpg\" alt=\"\" class=\"wp-image-2191\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_07-47-42.jpg 558w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_07-47-42-203x300.jpg 203w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_07-47-42-400x592.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_07-47-42-250x370.jpg 250w\" sizes=\"(max-width: 558px) 100vw, 558px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">11. Modify the files:<\/h2>\n\n\n\n<p>Open the Dev_Inf.c source file and include the W25QXX.h header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;W25Qxx.h&quot;<\/pre><\/div>\n\n\n\n<p>In the data structure, give the external loader a name like this:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">&quot;W25Q32_ExternalLoader_SPI_F411RE&quot;<\/pre><\/div>\n\n\n\n<p>Specify the address to be used, in this case, 0xC0000000 (You can leave it for the default one since it is mapped to QSPI or any other address, just make sure it is not being used by any other peripheral).<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">0xC0000000<\/pre><\/div>\n\n\n\n<p>Make sure the initial content is 0xFF<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, open the Loader_Src.c source file and include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;W25Qxx.h&quot;\n#include &quot;stm32f4xx.h&quot;\n#include &quot;SPI1.h&quot;\n#include &quot;delay.h&quot;<\/pre><\/div>\n\n\n\n<p>In Init function, replace the content of the function with the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">*(uint32_t*)0xE000EDF0 = 0xA05F0000; \/\/enable interrupts in debug\n\n\n    SystemInit();\n\n    \/* ADAPTATION TO THE DEVICE\n     *\n     * change VTOR setting for H7 device\n     * SCB-&gt;VTOR = 0x24000000 | 0x200;\n     *\n     * change VTOR setting for other devices\n     * SCB-&gt;VTOR = 0x20000000 | 0x200;\n     *\n     * *\/\n\n    SCB-&gt;VTOR = 0x20000000 | 0x200;\n\n    __set_PRIMASK(0); \/\/enable interrupts\n\n\tSPI1_Pins_Init();\n\tW25QXX_CS_Pins_Init();\n\tSPI1_Config();\n\tdelay_init(16000000);\n\n    flash_Reset();\n\n    __set_PRIMASK(1); \/\/disable interrupts\n    return LOADER_OK;<\/pre><\/div>\n\n\n\n<p>During the initialization, we are initialize the SPI, pins, delay and reset the flash to ensure stability.<\/p>\n\n\n\n<p>Modify the read\/write function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">int Write(uint32_t Address, uint32_t Size, uint8_t* buffer) {\n\n    __set_PRIMASK(0); \/\/enable interrupts\n\n    flash_WriteMemory(buffer, Address, Size);\n\n    __set_PRIMASK(1); \/\/disable interrupts\n    return LOADER_OK;\n}\n\nint Read (uint32_t Address, uint32_t Size, uint8_t* buffer){\n    __set_PRIMASK(0); \/\/enable interrupts\n\n\tflash_ReadMemory(Address, Size, buffer);\n\n    __set_PRIMASK(1); \/\/disable interrupts\n\treturn 1;\n}\n<\/pre><\/div>\n\n\n\n<p>Note: we are maintaining the same name of the function to ensure that external loader will work.<\/p>\n\n\n\n<p>For sector erase:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">int SectorErase(uint32_t EraseStartAddress, uint32_t EraseEndAddress) {\n\n    __set_PRIMASK(0); \/\/enable interrupts\n\n    flash_SectorErase(EraseStartAddress, EraseEndAddress);\n\n    __set_PRIMASK(1); \/\/disable interrupts\n    return LOADER_OK;\n}<\/pre><\/div>\n\n\n\n<p>For mass erase:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">int MassErase(void) {\n\n    __set_PRIMASK(0); \/\/enable interrupts\n\n    flash_ChipErase();\n\n    __set_PRIMASK(1); \/\/disable interrupts\n    return LOADER_OK;\n}<\/pre><\/div>\n\n\n\n<p>Check sum function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint32_t CheckSum(uint32_t StartAddress, uint32_t Size, uint32_t InitVal) {\n    uint8_t missalignementAddress = StartAddress % 4;\n    uint8_t missalignementSize = Size;\n    int cnt;\n    uint32_t Val;\n\n    StartAddress -= StartAddress % 4;\n    Size += (Size % 4 == 0) ? 0 : 4 - (Size % 4);\n\n    for (cnt = 0; cnt &lt; Size; cnt += 4) {\n        Val = *(uint32_t*) StartAddress;\n        if (missalignementAddress) {\n            switch (missalignementAddress) {\n                case 1:\n                    InitVal += (uint8_t) (Val &gt;&gt; 8 &amp; 0xff);\n                    InitVal += (uint8_t) (Val &gt;&gt; 16 &amp; 0xff);\n                    InitVal += (uint8_t) (Val &gt;&gt; 24 &amp; 0xff);\n                    missalignementAddress -= 1;\n                    break;\n                case 2:\n                    InitVal += (uint8_t) (Val &gt;&gt; 16 &amp; 0xff);\n                    InitVal += (uint8_t) (Val &gt;&gt; 24 &amp; 0xff);\n                    missalignementAddress -= 2;\n                    break;\n                case 3:\n                    InitVal += (uint8_t) (Val &gt;&gt; 24 &amp; 0xff);\n                    missalignementAddress -= 3;\n                    break;\n            }\n        } else if ((Size - missalignementSize) % 4 &amp;&amp; (Size - cnt) &lt;= 4) {\n            switch (Size - missalignementSize) {\n                case 1:\n                    InitVal += (uint8_t) Val;\n                    InitVal += (uint8_t) (Val &gt;&gt; 8 &amp; 0xff);\n                    InitVal += (uint8_t) (Val &gt;&gt; 16 &amp; 0xff);\n                    missalignementSize -= 1;\n                    break;\n                case 2:\n                    InitVal += (uint8_t) Val;\n                    InitVal += (uint8_t) (Val &gt;&gt; 8 &amp; 0xff);\n                    missalignementSize -= 2;\n                    break;\n                case 3:\n                    InitVal += (uint8_t) Val;\n                    missalignementSize -= 3;\n                    break;\n            }\n        } else {\n            InitVal += (uint8_t) Val;\n            InitVal += (uint8_t) (Val &gt;&gt; 8 &amp; 0xff);\n            InitVal += (uint8_t) (Val &gt;&gt; 16 &amp; 0xff);\n            InitVal += (uint8_t) (Val &gt;&gt; 24 &amp; 0xff);\n        }\n        StartAddress += 4;\n    }\n\n    return (InitVal);\n}<\/pre><\/div>\n\n\n\n<p>Finally the verify function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint64_t Verify (uint32_t MemoryAddr, uint32_t RAMBufferAddr, uint32_t Size, uint32_t missalignement){\n\t__set_PRIMASK(0); \/\/enable interrupts\n\t\n\tuint32_t VerifiedData = 0, InitVal = 0;\n    uint64_t checksum;\n    Size *= 4;\n\n\tuint8_t Buffer[2];\n\tuint32_t posBuf;\n\n\tchecksum = CheckSum((uint32_t)MemoryAddr + (missalignement &amp; 0xf), Size - ((missalignement &gt;&gt; 16) &amp; 0xF), InitVal);\n\n\twhile (Size&gt;VerifiedData)\n\t{\n\t\tflash_ReadMemory(MemoryAddr+VerifiedData, 2, Buffer);\n\n\t\tposBuf=0;\n\t\twhile ((Size&gt;VerifiedData) &amp;&amp; (posBuf&lt;1024)) {\n\t\t\tif (Buffer[posBuf] != *((uint8_t*)RAMBufferAddr+VerifiedData))\n\t\t\t{\n\t\t\t\t__set_PRIMASK(1); \/\/disable interrupts\n\t\t\t\treturn ((checksum&lt;&lt;32) + MemoryAddr+VerifiedData);\n\t\t\t}\n\t\t\tposBuf++;\n\t\t\tVerifiedData++;\n\t\t}\n\t}\n\t__set_PRIMASK(1); \/\/disable interrupts\n\treturn (checksum&lt;&lt;32);\n}\n<\/pre><\/div>\n\n\n\n<p>Now compiler the code and it should say compiled successfully.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">11. Building the External Loader:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, right click on the project and select properties:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"706\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-1024x706.jpg\" alt=\"\" class=\"wp-image-2192\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-1024x706.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-300x207.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-768x530.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-1536x1059.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-2048x1412.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-1150x793.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-750x517.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-400x276.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-06-13-250x172.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>In C\/C++ settings, MCU GCC Linker, General, select the linker script provided by ST.<\/p>\n\n\n\n<p>Also, uncheck discard unused sections.<\/p>\n\n\n\n<p>After that, in Build steps:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"706\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-1024x706.jpg\" alt=\"\" class=\"wp-image-2193\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-1024x706.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-300x207.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-768x530.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-1536x1059.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-2048x1412.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-1150x793.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-750x517.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-400x276.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-08-32-250x172.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>Add the following for the post build:<\/p>\n\n\n\n<p>For macOS users:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">cp &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;..\/${BuildArtifactFileBaseName}.stldr&quot;<\/pre><\/div>\n\n\n\n<p>For windows user:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">cmd.exe \/C copy \/Y &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;..\\${BuildArtifactFileBaseName}.stldr&quot;<\/pre><\/div>\n\n\n\n<p>Press Apply and close.<\/p>\n\n\n\n<p>Compile the code and you should see the new linker script file as following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"558\" height=\"858\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-10-56.jpg\" alt=\"\" class=\"wp-image-2194\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-10-56.jpg 558w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-10-56-195x300.jpg 195w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-10-56-400x615.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-10-56-250x384.jpg 250w\" sizes=\"(max-width: 558px) 100vw, 558px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, copy the file to STM32CubeProg to the following path:<\/p>\n\n\n\n<p>For windows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\ExternalLoader<\/pre><\/div>\n\n\n\n<p>For macOS users:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/Applications\/STMicroelectronics\/STM32Cube\/STM32CubeProgrammer\/STM32CubeProgrammer.app\/Contents\/MacOs\/bin<\/pre><\/div>\n\n\n\n<p>Right click on the app and select show package contents.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">12. Testing the external Loader:<\/h2>\n\n\n\n<p>Open STM32CubeProg and select external loader:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"664\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-1024x664.jpg\" alt=\"\" class=\"wp-image-2195\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-1024x664.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-300x195.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-768x498.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-1536x996.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-2048x1328.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-1150x746.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-750x486.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-400x259.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-15-45-250x162.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, connect the MCU, select External Loader and you should see our external loader.<\/p>\n\n\n\n<p>Next, go <a href=\"https:\/\/onlinefiletools.com\/generate-random-binary-file\" data-type=\"URL\" data-id=\"https:\/\/onlinefiletools.com\/generate-random-binary-file\" target=\"_blank\" rel=\"noreferrer noopener\">this website<\/a> and to generate random binary bin file according to your W25QXX size (4MB in this case):<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Open erase and programming from STM32CubeProgrammer, select the random generated bin file, and enter the correct the address as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-1024x598.jpg\" alt=\"\" class=\"wp-image-2196\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-1024x598.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-300x175.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-768x448.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-1536x897.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-2048x1196.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-1150x671.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-750x438.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-400x233.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-23-19-250x146.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>It will take a while to write the data (due to slow nature of SPI).<\/p>\n\n\n\n<p>After flashing and verifying the flash, you should get the following two messages:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-1024x598.jpg\" alt=\"\" class=\"wp-image-2197\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-1024x598.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-300x175.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-768x448.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-1536x897.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-2048x1196.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-1150x671.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-750x438.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-400x233.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/2023-12-17_08-30-32-250x146.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Congratulations, the external loader is working like a charm.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">13. Project download:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>\/you may download the project from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/ExternalLoader_F411RE-1.zip\">ExternalLoader_F411RE-1<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/12\/ExternalLoader_F411RE-1.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the third part of external loader, we shall develop the external loader and test it. In this guide, we shall cover the following: Getting the required files. Modify the file. Building the external loader. Testing the external loader. Project download. 10. Getting the required files. ST offers the required files on their repository on [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,11,12],"tags":[],"class_list":["post-2189","post","type-post","status-publish","format-standard","hentry","category-data-structures","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2189"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2189"}],"version-history":[{"count":3,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2189\/revisions"}],"predecessor-version":[{"id":2201,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2189\/revisions\/2201"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}