cancel
Showing results for 
Search instead for 
Did you mean: 

ModusToolbox PSoC 6 SDK

New Contributor II

Hello,

Can you point me to an example showing the 64MB QSPI NOR flash (present on the PSoC6 Wi-Fi BT) kit being used for additional code storage when project code exceeds 2MB flash?  If not, would you be able to make one?  Ideally, the flashing step can be seamlessly integrated into the Modus Toolbox Quick Launch pane.

Thanks!

0 Likes
Reply
1 Solution
Employee

Hi StLe_4753786​,

To be able to program the image to external flash, you should store QSPI configs to sflash.

have you checked this AN, AN228740 , section-7 ?

Thanks

View solution in original post

8 Replies
Employee

Hi stle_4753786​,

Here is an PSoC Creator code example which demonstrates execute in place with QSPI.
https://www.cypress.com/documentation/code-examples/ce224285-psoc-6-mcu-external-flash-access-xip-mo...

Hope it helps.

0 Likes
Reply
New Contributor II

Thanks, that was a quick response!

Unfortunately, I couldn't get the code to compile on Modus Toolbox 2.1.0 (which I'm using for my project on the Prototyping Kit, i.e. not the Pioneer Kit).  I had created an empty project, copied your AppNote source files to a src sub-dir, and replaced "main.c" with "main_cm4.c".  The compiler cannot find the "smif" component.  I don't see it in the Library Manager.  (Have tried serial-flash but it doesn't solve the issue).

Any idea where I can find "smif"?  Thanks!

--------------------------------------------------------------------------------------------

./src/cy_smif_memconfig.h:19:10: fatal error: smif/cy_smif_memslot.h: No such file or directory

#include "smif/cy_smif_memslot.h"

          ^~~~~~~~~~~~~~~~~~~~~~~~

libs/psoc6make/make/core/build.mk:359: recipe for target '/home/ubuntu64/work/psoc/mtw_2_1/ExtFlashXIPMode/build/CY8CPROTO-062-4343W/Debug/main_cm4.o' failed

compilation terminated.

0 Likes
Reply
Employee

Well, if you are using MTB, best approach would be to use serial-flash.lib​ Let me add little more detailed steps here below.
Unfortunately, I don;t have a direct MTB code example reference to share with you right now.  Please follow below steps to get the execute in place working on your project.


  1. Please refer this code example for using the serial-flash.lib​ API's in your project. IT demonstrates QSPI read/write using  serial-flash.lib
  2. Now, use cy_serial_flash_qspi_enable_xip() to enable/disable the XIP mode as necessary in your code.
    Example:
    cy_serial_flash_qspi_enable_xip(enable);
    my_func_for_xip(); <-- your xip code here
    cy_serial_flash_qspi_enable_xip(disable);
  3. This code example mentioned in previous post, will give you an idea of linker file placements.
    Please make the necessary changes to linker file to place your code in XIP region.

      Here is the snippet from the .ld file, that gives you a brief idea of how to place the code in XIP region (QSPI).

    /* Places the code in the Execute in Place (XIP) section. See the smif driver

    *  documentation for details.

    */

    .cy_xip :

    {

        KEEP(*(.cy_xip))

    } > xip


  Please don't use the the API;s from this example directly. It is added here to brief how to place the code in memory.
Instead just refer to main_cm4.c file and linker files only for cy_xip section placement and access.

Thanks !

New Contributor II

Thanks for the pointers.  I have created a new MTB project based on "QSPI_Flash_Read_Write" example and made slight changes to print a variable that is placed on .cy_xip.

const char hiWord[] CY_SECTION(".cy_xip") = "\r\n\rHello from the external string\r\n\r";

void main() {

    ...

    cy_serial_flash_qspi_enable_xip(true);

    printf(hiWord);

    cy_serial_flash_qspi_enable_xip(false);

    ...

}

The .ld for this example, already has the cy_xip section defined:

(./libs/TARGET_CY8CPROTO-062-4343W/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/cy8c6xxa_cm4_dual.ld)

    .cy_xip :

    {

        KEEP(*(.cy_xip))

    } > xip

The code compiled fine and I was pleased to see the .cy_xip section, with an address quite different from the other sections.

   ----------------------------------------------------

  | Section Name         |  Address      |  Size       |

   ----------------------------------------------------

  | .cy_m0p_image        |  0x10000000   |  5996       |

  | .text                |  0x10002000   |  58308      |

  | .ARM.exidx           |  0x100103c4   |  8          |

  | .copy.table          |  0x100103cc   |  24         |

  | .zero.table          |  0x100103e4   |  8          |

  | .data                |  0x080022e0   |  3832       |

  | .cy_sharedmem        |  0x080031d8   |  8          |

  | .noinit              |  0x080031e0   |  148        |

  | .bss                 |  0x08003274   |  1020       |

  | .heap                |  0x08003670   |  1028496    |

  | .cy_xip              |  0x18000000   |  37         |

   ----------------------------------------------------

However, when I tried to flash using Debug (KitProg3), an error occurred.

Screenshot from 2020-08-14 12-16-32.png

What else do I have to do?  Thanks!

0 Likes
Reply
New Contributor II

Hi, is there a workaround for the MTB flashing issue?  Thanks!

0 Likes
Reply
Employee

Hi StLe_4753786​,

To be able to program the image to external flash, you should store QSPI configs to sflash.

have you checked this AN, AN228740 , section-7 ?

Thanks

View solution in original post

New Contributor II

Thanks for the pointer!  After reading section-7, I edited (./libs/serial-flash/cy_serial_flash_prog.c), inserted the line "#define CY_ENABLE_XIP_PROGRAM".  Now I'm able to flash using MTB without error.

I'm able to define variables in .cy_xip (even very large arrays e.g. 32MB) which I'm able to memset without problem.  That part works well.

But I'm still unable to invoke a function placed in .cy_xip_code (or cy_xip).  It will crash with a processing fault (attached screenshot).  I had defined:

#pragma long_calls

void test_xip(const char* str_p);

int test_xip_no_param(void);

#pragma long_calls_off

CY_SECTION(".cy_xip_code") __attribute__((used))

void test_xip(const char* str_p)

{

  printf("test_xip: %s\r\n", str_p);

}

CY_SECTION(".cy_xip_code") __attribute__((used))

int test_xip_no_param(void)

{

  //printf("test_xip_no_param\r\n");

  int i = 2;

  return i + 1;

}

Also, in the calling code, I had preceded the function calls with cy_serial_flash_qspi_enable_xip(true) and ended with cy_serial_flash_qspi_enable_xip(false).   I have also defined the .cy_xip_code section in the .ld file.  Please see attached.

What else did I miss?   Thanks!

0 Likes
Reply
New Contributor II

I found the problem, it's because the sample code was performing an erase of the flash.  Obviously not a good idea if I have placed code there!

Attached files can read/write variables and constants, and invoke functions in the external flash using multiple sections.

   ----------------------------------------------------

  | Section Name         |  Address      |  Size       |

   ----------------------------------------------------

  | .cy_m0p_image        |  0x10000000   |  5996       |

  | .text                |  0x10002000   |  56284      |

  | .ARM.exidx           |  0x1000fbdc   |  8          |

  | .copy.table          |  0x1000fbe4   |  24         |

  | .zero.table          |  0x1000fbfc   |  8          |

  | .data                |  0x080022e0   |  3832       |

  | .cy_sharedmem        |  0x080031d8   |  8          |

  | .noinit              |  0x080031e0   |  148        |

  | .bss                 |  0x08003274   |  1020       |

  | .heap                |  0x08003670   |  1028496    |

  | .cy_sflash_user_d    |  0x16000800   |  8          |

  | .cy_toc_part2        |  0x16007c00   |  512        |

  | .cy_xip              |  0x18000000   |  3145748    |

  | .cy_xip_code         |  0x18300038   |  48         |

  | .cy_xip_code2        |  0x18300068   |  56         |

  | .cy_xip2             |  0x18300014   |  36         |

   ----------------------------------------------------

Thanks for your help!

0 Likes
Reply