AnsweredAssumed Answered

CCM stack and USB

Question asked by sanchez.damaso on Mar 12, 2015
Latest reply on Mar 12, 2015 by Clive One
I'm using a ST32F429IG in a project in which I implement a mass storage in an external serial flash memory chip. The data transmission is made via the HAL_SPI_TransmitReceive() funtion, so no interrupt or dma transfer involved.
I decided to put the stack in the CCM memory and everything works well except the USB mass storage. I think that my linker script is correct, but I'll post it so you can check it out:

/*------------------------------------------------------------------------------
 *      Linker script for running in internal FLASH on the STM32F429IG
 *----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

/* Memory Spaces Definitions */
MEMORY
{
    ROM  (rx) : ORIGIN = 0x08000000, LENGTH = 1024K - 128K
    ROM_LANG  (rx) : ORIGIN = 0x080E0000, LENGTH = 128K
    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 192K
  CCRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   __etext
 *   __data_start__
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   __data_end__
 *   __bss_start__
 *   __bss_end__
 *   __end__
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 */


SECTIONS
{
    .rom_lang :
    {
        *(.rom_lang*)

    } > ROM_LANG

    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)

        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
         *crtbegin.o(.dtors)
         *crtbegin?.o(.dtors)
         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
         *(SORT(.dtors.*))
         *(.dtors)

        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > ROM

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > ROM

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > ROM
    __exidx_end = .;

    __etext = .;

    .data : AT (__etext)
    {
        __data_start__ = .;
        *(vtable)
        *(.data*)

        . = ALIGN(4);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(4);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);


        . = ALIGN(4);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        . = ALIGN(4);
        /* All data end */
        __data_end__ = .;

    } > RAM

    .bss (NOLOAD):
    {
        __bss_start__ = .;
        *(.bss*)
        *(COMMON)
        __bss_end__ = .;
    } > RAM

    .heap (NOLOAD):
    {
        __end__ = .;
        end = __end__;
        *(.heap*)
        __HeapLimit = .;
    } > RAM

    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (NOLOAD):
    {
        *(.stack)
    } > CCRAM

    /* Set stack top to end of CCRAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(CCRAM) + LENGTH(CCRAM);
    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
    PROVIDE(__stack = __StackTop);
}

Putting the stack in the CCM causes Windows to not detect correctly the mass storage. If I put the stack back in RAM, there's no problem at all.
I know that the CCM doesn't support DMA transfers, but I'm not sure if the HAL USB drivers make any DMA transfers using the stack.
I suppose that I can put the stack back in RAM and fill the CCM with some .bss variables, but I would like to know if anyone have found this problem or knows how to solve it.
I'm using the latest HAL version, by the way.
Thank you for your help

Outcomes