2012-01-11 02:08 AM
I've spent (too many) hours trying to figure out how to use the CCM for something useful.
And with useful I mean easy access from my code written in C. I use GNU GCC, etc (the Yagarto toolchain). At first I thought that putting some variable, array into a specified section, let's call it .ccm, (and of course the appropriate lines in the linker script) would be the solution. For example: uint8_t test[1024] __attribute__ ((section(''.cmm''))); Well, it works... Kind of... :\ I compiles and links nicely. Checking the memory map/dump of the generated ELF-file I see that the array is located @0x1000 0000 However, producing a binary image produces a LARGE 100+MB file. Doing a hex-file makes it smaller but will not load into ST-Link Utility (file too large to fit, it says) Now... That's probably due to the gap between 0x1000 FFFF and 0x2000 0000 The part in the linker script is something like (under the SECTIONS part) .ccm : { .= ALING(4); *(.ccm) .= ALIGN(4); } >CCMRAM And CCM is defined under MEMORY as CCRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K Also tried to use NOLOAD to make it NOBITS instead of PROGBITS but it still takes up space in the binary or hex-file. Removing the section with objcopy and --remove-section .ccm does nothing to help either. Isn't there anyway of makeing your own section behave like the .bss section and not taking space in the image? I hope I make sense with my problem/question. Best regards // J�rgen #stm32-stm32f4-ccm-linker-section #gcc-linker-ccm2013-06-20 02:09 PM
It's not a silver bullet.
I could describe the joys of virtual memory, where you have to pin and lock physical memory before you can DMA to it, or writing kernel mode drivers. If you even get an IRQL_NOT_LESS_OR_EQUAL blue screen, it's because some fool tried to DMA into, or access, a user memory context that switched out before the transfer completed/started. Generally it's inadvisable to DMA on the stack, due to it's transient nature, and the potential for the DMA controller settings to out live the current activity. Much hilarity ensues when the stack gets trashed by a lingering transfer.2013-06-20 03:31 PM
I think you have another troubles with SDIO, because I suceccfully used FatFs + SDIO in 2 projects, where IRAM2 (CCM) was set by default as the main RAM.
Huge IRAM1 was used only as a buffer for SD-card writing and some variables. Also I put ff,c,fatfs_drv.c, stm32f4sd.c into IRAM1.2013-06-20 06:03 PM
That's exactly the problem I had. Buffers were in CCM passed to the SD read/write functions.
2013-06-21 12:34 AM
Buffers you MUST put at big RAM, but stack and other variables, not used by DMA - in CCM.
The simplest way in KEil is to use IRAM2 (CCM) by default, buffers should be at separate file, and in this file' properties - say to use IRAM1. How to do this in GCC - I don't know.2013-10-01 05:34 AM
I try to use ccm for STemWIN gui stack.
I use CoIDE with this linker script.OUTPUT_FORMAT (''elf32-littlearm'', ''elf32-bigarm'', ''elf32-littlearm'')
/* Internal Memory Map*/
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000
}
_eram = 0x20000000 + 0x00020000;
/* Section Definitions */
SECTIONS
{
.text :
{
KEEP(*(.isr_vector .isr_vector.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
} > rom
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
__exidx_end = .;
. = ALIGN(4);
_etext = .;
_sidata = .;
.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = . ;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
_sbss = . ;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
} > ram
/* stack section */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > ram
. = ALIGN(4);
_end = . ;
}
/*********************************************************************
* Portions COPYRIGHT 2013 STMicroelectronics *
* Portions SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
** emWin V5.20 - Graphical user interface for embedded applications **
All Intellectual Property rights in the Software belongs to SEGGER.
emWin is protected by international copyright laws. Knowledge of the
source code may not be used to write a similar product. This file may
only be used in accordance with the following terms:
The software has been licensed to STMicroelectronics International
N.V. a Dutch company with a Swiss branch and its headquarters in Plan-
les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the
purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_
troller products commercialized by Licensee only, sublicensed and dis_
tributed under the terms and conditions of the End User License Agree_
ment supplied by STMicroelectronics International N.V.
Full source code is available at: www.segger.com
We appreciate your understanding and fairness.
----------------------------------------------------------------------
File : GUIConf.c
Purpose : Display controller initialization
---------------------------END-OF-HEADER------------------------------
*/
/**
******************************************************************************
* @file GUIConf.c
* @author MCD Application Team
* @version V1.0.0
* @date 22-July-2013
* @brief Display controller initialization
******************************************************************************
* @attention
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the ''License'');
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ''AS IS'' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
#include ''GUI.h''
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES (1024) * 64 // x KByte
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
/* 32 bit aligned memory area */
U32 extMem[GUI_NUMBYTES / 4] __attribute__ ((section(''.cmm'')));
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_X_Config
*
* Purpose:
* Called during the initialization process in order to set up the
* available memory for the GUI.
*/
void GUI_X_Config(void)
{
GUI_ALLOC_AssignMemory(extMem, GUI_NUMBYTES);
}
/*************************** End of file ****************************/
I put this to the ld file
.ccm (NOLOAD) :
{
.= ALING(4);
*(.ccm)
.= ALIGN(4);
} >ram1
Everything is working, but if delete the section definition from the file, then compile with no error and the program run.
The question why the program run without the section definition?
2013-10-01 06:40 AM
U32 extMem[GUI_NUMBYTES / 4] __attribute__ ((section(''.cmm'')));
CCM not CMM2013-10-01 07:10 AM
I write to ccm, but the working is the same. I hope that is working well.
This is is the map file: ccm 0x20000adc 0x10000 load address 0x0803c6a4 .ccm 0x20000adc 0x10000 ..\obj\GUIConf.o 0x20000adc extMem the linker script:OUTPUT_FORMAT (''elf32-littlearm'', ''elf32-bigarm'', ''elf32-littlearm'')
/* Internal Memory Map*/
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000
}
_eram = 0x20000000 + 0x00020000;
/* Section Definitions */
SECTIONS
{
.ccm (NOLOAD) :
{
.= ALING(4);
*(.ccm)
.= ALIGN(4);
} > ram1
.text :
{
KEEP(*(.isr_vector .isr_vector.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
} > rom
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
__exidx_end = .;
. = ALIGN(4);
_etext = .;
_sidata = .;
.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = . ;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
_sbss = . ;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
} > ram
/* stack section */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > ram
. = ALIGN(4);
_end = . ;
}
2013-10-01 08:23 AM
This worked for me (Yagarto 4.7.2)
#define GUI_NUMBYTES 10240
uint32_t extMem[GUI_NUMBYTES / 4] __attribute__ ((section(''.ccm'')));
OUTPUT_FORMAT (''elf32-littlearm'', ''elf32-bigarm'', ''elf32-littlearm'')
/* Internal Memory Map*/
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00100000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
ram1 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00010000
}
_eram = 0x20000000 + 0x00020000;
/* Section Definitions */
SECTIONS
{
.ccm (NOLOAD) :
{
. = ALIGN(4);
*(.ccm)
*(.ccm.*)
. = ALIGN(4);
} > ram1
.text :
{
KEEP(*(.isr_vector .isr_vector.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
} > rom
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
__exidx_end = .;
. = ALIGN(4);
_etext = .;
_sidata = .;
.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = . ;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
_sbss = . ;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
} > ram
/* stack section */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > ram
. = ALIGN(4);
_end = . ;
}
..
0x20020000 _eram = 0x20020000
.ccm 0x10000000 0x2800
0x10000000 . = ALIGN (0x4)
*(.ccm)
.ccm 0x10000000 0x2800 out/main.o
0x10000000 extMem
*(.ccm.*)
0x10002800 . = ALIGN (0x4)
.text 0x08000000 0xa148
*(.isr_vector .isr_vector.*)
.isr_vector 0x08000000 0x188 out/startup_stm32f401xx.o
0x08000000 g_pfnVectors
..
2013-10-03 01:18 AM
Thank you very much. One question is for linker script.
This line*(.ccm.*)
What do this line exactly?
2013-10-03 01:37 AM
> *(.ccm.*)
> What do this line exactly?
The first asterisk means ''any input file''. The second is a wildcard in the input section name, i.e. it means ''accept any input section which starts with '.ccm.'''. https://sourceware.org/binutils/docs/ld/Input-Section-Basics.html http://wiki.hup.hu/index.php/RTFM ;) JW