2015-03-12 05:15 AM
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 #ccm-stack-usb2015-03-12 08:04 AM
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.
Using local/auto variables on the stack for DMA operations is generally frowned upon. You'd have to walk the code to see where problems might be coming from. Perhaps things like descriptors, I've seen other reports of certain F4's not being able to DMA to USB from flash.Review the .MAP file, and change local variables that can be safely moved to SRAM using a static directive for the buffer.
2015-03-12 08:40 AM
I'm not
consciously
using any DMA transfer. Does the ST USB HAL use any DMA transfer at all? Or do you mean that maybe it puts some kind of buffer in the stack? Since only the stack is located at the CCM, I thought that all local variables would be located at the RAM, because the are put in the heap. Does the compiler use the stack for local variables? I'm also using FATFS, and I'm possitive that there a 4KB variable at the RAM, but I'm not sure if it uses the stack for some other buffering.2015-03-12 11:27 AM
I thought that all local variables would be located at the RAM, because the are put in the heap. Does the compiler use the stack for local variables?
Local/Auto variables are on the stack, not the heap. You'd have to explicitly malloc() space on the heap. Static allocations will come from whatever memory they are define to come from, and typically live below the heap.You'll need to walk the HAL code, I'm not offering to do that.