- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
Solved! Go to Solution.
- Tags:
- qspi flash
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- 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
- 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); - 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 !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
What else do I have to do? Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, is there a workaround for the MTB flashing issue? Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!