OpenFlashLoader w/ 128Mbit external SPI flash ; more than 512 sectors?

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • OpenFlashLoader w/ 128Mbit external SPI flash ; more than 512 sectors?

    I am attempting to implement the OpenFlashLoader for a 128MBit SPI serial NOR flash.

    This is a common architecture that I use in my design, so being able to read a full image and then program a full image via JFlash would be *great*. I presently have to "ferry" data into the flash chip ~512Kbyte at a time via the main micro flash and the serial flash image converted into C arrays. :S

    And since many of the 8-pin serial NOR flash chips have a common set of basic read/write commands, this should cover a large range of parts.

    However, in FlashOS.h in the OpenFlashLoader template package, I see that the maximum number of sectors is set to 512.
    These flashes use a 4K sector size, so for anything above a 2Mbit flash, we would exceed the maximum number of sectors, or only the first 2Mbit would be addressable.

    Is this a hard limit? Is there any workaround?
  • Hello,

    Thank you for your inquiry.
    Which SPI Flash are you looking to add specifically?
    Currently the 512 sectors is a hardcap. However sector size does not necessarily mean sector size of Flash vendors.
    Every Flash vendor calls something different "sector size".
    In our case it is the maximum number of different sector sizes available.
    So if your device has 4k ,16k and 64k sectors the number of sectors would be 3. If you have only 4k sectors it is 1.

    For your flash loader to work all you need to do is to specify the Flash specific values are explained in the Wiki article.
    We have numerous Flashes in our support list that are larger than 128 MBit which also work without any issues.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • I am adding support for GD25Q128CSIG and MX25L12835F chips. A fair number of other parts should fall under the same command set, too, which appears to be common for these 8-pin serial flash parts.

    So, it looks like I misunderstood what that structure was really defining?
    Per your description, it sounds like it is describing the types of geometry in the flash, rather than an enumeration of each sector present.

    The chips do have a uniform geometry of 4KB "sectors" (minimum erase quanta), but then also 32KB and 64KB "blocks", with unique erase commands for each size.
    These are all overlapping, so then it seems I will have to choose if I want to set it up as a uniform 4K/32K/64K device.

    > For your flash loader to work all you need to do is to specify the Flash specific values

    Well, I need to specify the flash values AND implement the read/write/erase/blank-check functions, right? That's the part that takes some effort & debugging. Note that I am using these in single-lane SPI mode with a Cortex M micro, not memory-mapped QSPI mode.
    If that part was already done for me, that would be great ...
  • Hello,

    The MX chip is already on our supported SPI chips page: segger.com/products/debug-prob…es/supported-spi-flashes/
    The GD chip might work out-of-the box as the smaller and larger derivates are also supported.
    How are you programming the Flash. Directly or indirectly? wiki.segger.com/Programming_External_SPI_Flashes
    If directly just make sure your target device you have connected to your external Flash is on our support list listed as "External QSPI Flash": segger.com/downloads/supported-devices.php


    Which target device are you using?


    apullin wrote:

    If that part was already done for me, that would be great ...
    No problem. We offer this as a service. In that case NREs would apply. Would that be of interest for you?

    Best regards,

    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Our target device is an STM32F412.

    For the setup I am looking at, I don't believe J-Flash SPI will apply: we only have an SWD connection to the micro available, and for a variety of reasons, adding another station/jig that would do J-Link->SPI port directly to our current design & process isn't an option.

    But I would like to zero in on a good solution here, since this will likely become the standard for how I do manufacturing in the future!

    My understanding was that to use J-Flash in a JLink->micro->sflash setup, it requires the flash to be memory mapped by the micro.
    In my case, on the M4, I believe that would require using the Q-SPI peripheral, which I am presently not using.
    (the QSPI periph pinout *may* overlap with the standard SPI pinout I already have; tbd)

    Just plain SPI to the flash chip, and a low-level firmware driver. It appears that this is not a setup that is supported by any existing Segger solutions, other than an OpenFlashLoader implementation.

    So:
    The target setup that I am looking at would take that low-level simple SPI driver, implement the read/write/erase for the chip in the OpenFlashLoader template, in FlashPrg.c and the corresponding geometry in FlashDev.h .

    The hope is that I would eventually have a single J-Flash project that would:
    1) Load the OFL ramcode
    2) Use that to write through the 16MB (or just the non-empty part) image to the SPI flash.
    3) Load the F4 micro's main flash

    > NREs

    Maybe. If I get totally dead-ended on this, I'll request a quote.
  • @SEGGER - Nino , I have some further questions about this.

    Does the OpenFlashLoader template generate RAMCodes that are supposed to work with JFlash, to be specified with the "Use custom RAMCode" option?
    Looking at the documentation and some of the details, it seems like maybe it is not?

    For example, the template is provided with instructions to generate an ELF, but then the "Use custom RAMCode" only allows for hex, srec, bin, etc.
    And I don't see any way that the DLL could call into a binary or hex file, since it wouldn't know the function locations.
  • Hello,

    That is explained here: wiki.segger.com/Adding_Support…a_Precompiled_Flashloader

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • The FAQ is kind of misleading at this point. There is no separate compare function but a compare is performed prior programming.
    We are already in progress of updating the Open Flashloader sections to make such things more clear. The updated page will contain some kind of flow diagrams to show which functions are called under which circumstances.
    If a Veriy() is implemented, this function is used for the compare step. If the function is not implemented, the DLL compares the content by reading it back.

    Best regards
    Erik

    PS: Open Flashloader based algorithms are not supposed to be included through the J-Flash -> "Use custom RAMCode" option but through the JLinkDevices.xml as described on the page referenced by Nino.
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • @SEGGER - Erik ah, thanks.

    I am inching closer to this working ... but unfortunately, the "Release" build does not work in Segger Studio.
    I am not that familiar with the Segger IDE, so maybe I am missing something obvious.

    When I build the Release build, I get the error:
    Output/Release/Exe/flash_loader.elf section `.text.libc.__int64_udivmod' will not fit in region `UNPLACED_SECTIONS'

    Looking at the generated linker script, it is reporting that the length of the UNPLACED_SECTIONS is zero:
    UNPLACED_SECTIONS (wx) : ORIGIN = 0x100000000, LENGTH = 0

    Looking at Placement_release.xml, there are only sections for PrgCode, PrgData, DevDscr.
    I will definitely need code and functions from libc to be linked in ...

    The Debug build works fine and passes the example write/read test when running/debugging from the IDE.
    When I try to run JLinkExe using the debug build elf, I get the error:
    ****** Error: Algo error: Cannot not find "PrgData" section.
    which is not unexpected, if there is some kind of section remapping or redirection going on between the debug and release build.
  • Hello,

    Please understand that this is no support forum so responses from our team might be delayed.

    We are not aware of any issues with the reported matter. Building both the Debug and Release version from the default project from our Wiki is working as intended.
    Could you provide us with your project so we can try to reproduce the behaviour?

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Zip file is attached.

    Notably, if I modify the plain template with only the change to use uint64_t or, as just an example, a sqrtf() in one of the OFL functions (like EraseSector), then I will get the same link error when building in the Release config, but not the Debug config.
    Files
    • flash_loader.zip

      (573.29 kB, downloaded 542 times, last: )

    The post was edited 1 time, last by apullin ().

  • Hello,

    Unfortunately the provided project seems not to be portable. Attached is the error message we get when trying to open it.
    Could you provide a portable one?
    Nevertheless we assume that the gcc linker is not working correctly when using certain library functions and tries to link them per default to .text section which of course is not available in the release build.
    As the current workaround we suggest not using such library functions and use local helper functions instead.
    We will discuss this internally if gcc linker can be influenced here somehow to allow the usage of such functions for section placements without .text.

    Best regards,
    Nino
    Images
    • Capture.PNG

      19.96 kB, 927×403, viewed 571 times
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Whoops ... that was because I added in the original template project (out-of-source) so I could do side by side comparisons.

    New version is attached with that project removed, so now it should work.

    I am not certain what is causing code that can't ultimately be linked to be pulled in. It looks like udivmod for a uint64_t type is what cannot find a home?
    Can uint64_t types and/or modulos not be used, since they don't map directly to instructions and have to pull in a math function from libc?
    That is a fairly daunting requirement...

    I have an inkling that this will just take an edit to the generated linker script, or maybe there is a way to do it via Segger specific linker XML, by having PrgCode retain all the .text, .text.*, .rodata, .rodata.*, and other sections, and having PrgData keep .data, .bss.

    I can apparently work around some of the link errors by re-including thumb_crt0.s in the the build, and modifying the generated linker script to include necessary sections; modified flash_loader.ld also attached.

    However, I am still stuck with the remaining error/warning:
    warning: section `PrgData' type changed to PROGBITS
    and the ELF file is not generated.
    Files
  • Hello,

    Thank you for providing the example projects.
    We investigated further and found as expected that the issue is related to the third party HAL drivers which keep getting linked to .text instead of section PrgCode.
    You could try to work around by defining the sections as follows:

    Source Code

    1. <ProgramSection alignment="4" load="Yes" name="PrgCode" inputsections="*(PrgCode PrgCode.* .text .text.*)" />
    However this could lead to follow up issues.
    We do not recommend using external libraries for Flash loader creation as they mostly require that a full SystemInit has been executed which is not the case for Flash loader RAMcode. So we suggest keeping it as simple as possible and only using the files given by the template project and implement all Flash Controller init in the Init() function.

    Alternatively we could offer you to implement the Flash loader. In that case NREs would apply.
    Would you be interested in such an offer?

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Eh I am getting closer with we lap we do here. No need to go to contract just yet.

    So, using that option, plus a few more, I can get the project to build.
    This is what my Placement_release.xml contains:

    XML Source Code

    1. <!DOCTYPE Linker_Placement_File>
    2. <Root name="RAM Section Placement">
    3. <MemorySegment name="RAM">
    4. <ProgramSection alignment="4" load="Yes" name="PrgCode" keep="Yes" inputsections="*(PrgCode PrgCode.* .text .text.* .rodata.*)" />
    5. <ProgramSection alignment="4" load="Yes" name="PrgData" keep="Yes" inputsections="*(PrgData PrgData.* .data .data.*)" />
    6. <ProgramSection alignment="4" load="Yes" name="DevDscr" keep="Yes"/>
    7. <ProgramSection alignment="4" load="No" name=".bss" />
    8. <ProgramSection alignment="4" load="No" name=".tbss" />
    9. <ProgramSection alignment="4" load="No" name=".non_init" />
    10. <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
    11. <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
    12. <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
    13. </MemorySegment>
    14. </Root>
    Display All
    Obviously, this is not quite right because it is pulling in the entire CRT, setup, stack and heap regions, etc.
    I will revise and try to take out all the CRT and use just the bare minimum of setup. But we will need clocks to be set up and running for this to work ... the same would be true of a QSPI setup, so I assume there must be a way to make this work even if it requires the setup of an on-chip peripheral.

    But it does now build and report 160K RAM usage, which would work with our 256K RAM target.

    And I have amended the JLinkDevices.xml file with:

    XML Source Code

    1. <Device>
    2. <ChipInfo Vendor="GENERIC" Name="SPIFlashLoader" WorkRAMAddr="0x20026e8f" WorkRAMSize="0x19070" Core="JLINK_CORE_CORTEX_M4"/>
    3. <FlashBankInfo Name="128MbSPIFlash" BaseAddr="0x00000000" MaxSize="0x1000000" Loader="Devices/Generic/SPIFlashLoader/flash_loader.elf" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1" />
    4. </Device>
    Unfortunately, when I try to connect with JLinkExe in Linux, I get the error:
    No valid device has been selected.

    Or from Windows, using JFlash, I can see `SPIFlashLoader` in the device selection box, but when trying to connect, I get:
    ERROR: Failed to set device.
  • Hello,


    apullin wrote:

    Unfortunately, when I try to connect with JLinkExe in Linux, I get the error:
    You need to specify the exact device you are using to program the SPI Flashes. Just like the example in the Wiki.

    apullin wrote:

    Our target device is an STM32F412.
    This would be the device you need to set under Chipinfo, Vendor is ST.

    Keep in mind that any code placed outside of the sections PrgCode, PrgData and DevDescr are not within Arm specification for Flash loaders and will most likely be ignored during Flash download which could lead to failure.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hrm, OK. I did misunderstand the approach, and I thought I needed to define a new representative device, rather than just add a new FlashBank to the existing part.

    Oddly, the JLinkDevices.xml file did not already have an entry in it for the STM32F412VE.
    But I upgraded to the JLink package 6.34b, which does now have an entry there for STM32F412VE, including a loader for a memory mapped QSPI.

    I added the line for the flash bank info into that <Device> entry:
    <FlashBankInfo Name="128MbSPIFlash" BaseAddr="0x00000000" MaxSize="0x1000000" Loader="Devices/ST/STM32F4/ST_STM32F412V_serial_NOR_external.elf" LoaderType="FLASH_ALGO_TYPE_OPEN"/>

    However, I still get the "No valid device has been selected" error in OSX.
    Making the same change to the XML in Windows, opening the STM32F412VE device in JFlash project does report "Internal Bank 2" (1 is the existing QSPI definition), but with no size listed, and the "Failed to set device" error when connecting.

    It seems a little unclear how I should be implementing the OFL project given the issues you've helped me with above.
    The HAL is needed because there is a lot of chip specific setup to set the internal oscillator and PPL, set up the system clocks, then the GPIO and SPI peripheral, and then actually actuate the peripheral.
    My last attempt is that I am trying to bring over the bare minimum required footprint of code from the HAL into the OFL template project.
  • Hello,

    This thread will be continued via our official support channels.
    It will be closed now.

    Best regards,
    Nino
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.