The “Failed to call GENERATE_APP” error when building a Vitis project for the Cortex-M1 processor can be frustrating, but is usually caused by a few common issues. Here are some things to try when encountering this error:
Ensure the BSP is configured properly
The Board Support Package (BSP) contains crucial configuration information for building projects for a specific board. Double check that the correct BSP is set in your Vitis project properties. The BSP version should also match the version of Vitis you are using.
Open the BSP settings and verify the M1 processor variant is set properly. For example, the CM1 variant should be selected for the CM1 core on the Xilinx Kria KV260 board.
If applicable, check that the M1 TCM memory sizes are configured correctly in the BSP. The linker needs accurate values for the M1 TCM sizes.
Finally, regenerate the BSP if necessary to incorporate any changes. Regenerating the BSP will update the M1 linker script with the correct memory regions.
Use the proper M1 linker script
The linker script contains the memory layout and regions for the target processor. The Vitis build process dynamically generates this script based on your BSP settings.
However, if the BSP is not set up properly or regenerated, an outdated linker script may be used resulting in a GENERATE_APP failure. You can find the full path to the linker script in the build errors.
To use the proper M1 linker script:
- Delete any existing linker script added to your project
- Regenerate the BSP to update the memory settings
- Let Vitis dynamically generate the linker script instead of manually adding one
Check clock configurations
The M1 processor requires proper clock initialization done in the BSP system project. If the clocks are not configured correctly, you may see GENERATE_APP errors due to the M1 failing to start up properly.
Open the system project and confirm the following in xparameters.h:
- Proper clock frequencies are set for M1_CLK
- The register for enabling the clock is set to 1 (enabled)
Additionally, check the clock configurations in the driver xm1_clk.c file. The clocks need to be initialized and started early on before any use of the M1 processor.
Initialize DDR memory
For systems using external DDR memory, the M1 linker script assumes DDR is enabled and available. However, if DDR initialization is not done in the BSP, the M1 may not have access to that memory region.
In the BSP, ensure DDR initialization is done in xil_mmu.c before any use of external memory. The DDR controller, PHY, and address mapping must be initialized.
You can also try limiting the M1 to only use on-chip memory by removing external DDR from the M1 linker script. This can determine if a DDR initialization issue is the cause.
Enable caches
If enabling instruction or data caching on the M1, the appropriate cache initialization sequences must be done in the BSP system project.
Check xil_cache.c to ensure cache enabling functions are called for the M1 during early initialization. This includes any required cache flushing and invalidations to reset the cache controllers.
If caches are enabled for the M1 without proper initialization, it can lead to undefined behavior and GENERATE_APP errors.
Triple check compiler/assembler flags
The Vitis compiler uses specific flags for building projects for the Cortex-M1 that differ from the Cortex-A series. Make sure the compiler flags are properly set in your project properties:
- -mcpu=cortex-m1
- -mthumb
- -mfloat-abi=soft
The assembler flags should include:
- -mcpu=cortex-m1
Using incorrect compiler/assembler flags can result in invalid M1 instructions causing errors during project build.
Verify early runtime initialization
The generated project makefile contains an auto-generated crt0.S file. This handles early runtime initialization like stack setup and calling constructors before main().
Check that the crt0.S file is building properly without errors. Also verify the crt0.o file is being linked into the final executable.
Problems with the crt0 code can cause issues very early on before main(), leading to GENERATE_APP errors.
Check for static memory allocations
The M1 linker script only allocates memory for the stack and heap. It does not allocate space for global or static variables.
Scan through your application code and identify any large global or static data allocations. These must be placed into dedicated memory sections.
For example, add the attribute “section” “.bss.xyz” or “.data.xyz” to the variable definition. Then update the linker script to define those memory regions.
Increase stack size
In some cases, GENERATE_APP errors may be caused by the application stack overflowing into invalid memory. This can happen if using recursion or allocating large buffers on the stack.
Try incrementally increasing the stack size in the M1 linker script. The default stack size is usually small (4-8 KB). Make it larger (16-32 KB) if needed.
Also move large stack allocations to the heap using malloc() instead to reduce stack usage.
Check QEMU and Vitis alignment
When using QEMU emulation, make sure the QEMU version aligns with Vitis. Mismatched versions can cause incompatibility issues.
In particular, if generating projects using Vitis 2022.1, you must use QEMU 6.2.0 which supports Cortex-M emulation.
Try updating QEMU or reverting your Vitis installation if versions are misaligned. Also try hardware emulation if possible.
Review compile optimization settings
High levels of compiler optimization can sometimes expose bugs or issues in code that otherwise work fine at lower optimization levels.
Try reducing the optimization down from -O3 to -O2 or -O1. Check if that allows the application to build and link successfully.
Optimizer bugs are also a possibility that could cause bad code generation. It is best to keep optimization at -O2 level for Cortex-M.
Verify C runtime library compatibility
The C runtime library version must be compatible with the toolchain. Using a mismatched C runtime can cause odd errors.
The safest option is to let Vitis automatically link in the matching C runtime instead of manually adding one.
If adding it manually, verify it works with the GCC ARM Embedded version used by Vitis for Cortex-M.
Check compiler license access
The Vitis tools require access to licenses for the ARM compiler provided by Vitis. This is in addition to the Vitis license.
Verify the Cortex-M1 compiler license is properly configured and accessible to Vitis.
Without the license, the compiler may fail with errors or produce invalid output resulting in GENERATE_APP failures.
Increase unified memory capacity
When using unified memory with an external allocation, make sure the allocated capacity is sufficient for your application’s needs.
If the allocation is too small, it can result in memory access errors that manifest as GENERATE_APP failures.
Try increasing the unified memory allocation size until any errors are resolved.
Summary
The “Failed to call GENERATE_APP” error can definitely be frustrating but is usually caused by one of these common issues:
- Incorrect BSP configuration
- Invalid linker script
- Problems with clock initialization
- Missing DDR initialization
- Issues with cache enabling
- Incorrect compiler/assembler options
- Early runtime crt0.S problems
- Static memory usage errors
- Stack overflow
- QEMU and Vitis version mismatch
- Aggressive compiler optimizations
- Incorrect C runtime library
- Lack of compiler license
- Insufficient unified memory
Methodically checking each of these areas can help uncover the root cause and get past the GENERATE_APP error when building M1 projects with Vitis.