cancel
Showing results for 
Search instead for 
Did you mean: 

Clocking questions + ccm

gullik
Associate II
Posted on November 11, 2013 at 14:18

I have just ported one of my systems over to the STM32F4Discovery board. It is a small OS + TCP/IP. However, I stumbled on a few things:

I need to have a 8 khz interrupt for audio sampling. I think I have clocks OK, 8 Mhz HSE, PLLM=8, N=336, P=2, Q=7, but I have to assume TIM2 clock is 84 Mhz, to get down to 8 khz, pre=420, period=25. Do I actually have the bus at 84 Mhz, 42 is maximum allowed? Or is the peripheral clock different from BUSclock?

2. Why does the ld examples never use the 64 kbyte CCM? I guess it could be used as heap + stack at an advantage, but everybody seems to skip this area. Also is it slower / faster than ''ordinary'' ram?

#stm32f4
7 REPLIES 7
Posted on November 11, 2013 at 15:29

1) Review the clock tree, the TIMCLKx is typically APBx clock *2 unless the APB is not divided down, when it is *1. The Period and Prescaler are N-1 values.

2) Never/Everybody? You just haven't looked at many, or the right examples. You can't run code from CCM, DMA to it, or use bit-banding against it. Good for stacks, and variables. Many examples don't use it because it complicates them, and the placement of section/segments therein.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
gullik
Associate II
Posted on November 11, 2013 at 16:35

Well, I have pg 212 from rm0090, and as far as I can understand I have 168 Mhz out of the mux in the middle. But the AHB prescaler has TWO outputs, and below the APBx prescaler there is a strange box (multiplier??) with a cryptic statement ''if(APBx presc = 1x1 else x2'' that I would love to understand...

That box feeds APBx timer clocks.....maybethe statement should be: ''If you have programmed your APB prescaler to 1, multiply by 1, else if you prescaled by 2 we will multiply by 2, so you still get 84''

Puzzled....

However, the whole thing works now, and the TIM2 source must be 84 Mhz, since I now have correct 8 khz with timer2 (420,25) where I had (210,25) before.....but I would still want to know if I did it right or just managed to ''hack'' it to do what I want....

gullik
Associate II
Posted on November 11, 2013 at 17:05

Well, Thanks Clive,

It does help discussing this, the puzzling thing is the ''multiplier'' I missed that. Now it makes sense, I have APB1 driving TIM2, it is prescaled by 4, so bus frequency is 42 Mhz, but since I am dividing with something != 1, I get my 42 multiplied by 2, and voila, 84 Mhz. My understanding is the ''bus'' still runs at 42.

About the CCM, well as you pointed out I am new to the STM32, and have only spent < 24 hours learning the tools, debug, the chip and finding bugs in the templates 🙂 But I am happy, making progress...

Cheers

Posted on November 11, 2013 at 18:10

This is one of the linker scripts used in one of the GNU/GCC projects using Yagarto 4.6.x/4.7.x

/*
Linker script for STM32F40x Chip Specific - sourcer32@gmail.com
*/
/* include the common STM32F40x sub-script */
INCLUDE ''STM32F4_COMMON.ld''
/* Memory Spaces Definitions */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
AUX (xrw) : ORIGIN = 0x2001C000, LENGTH = 16K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1M
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K /* also change _estack below */
}
/* highest address of the user mode stack */
_estack = 0x10010000;
/* Sections Definitions */
SECTIONS
{
/* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */
.flashtext :
{
. = ALIGN(4);
*(.flashtext) /* Startup code */
. = ALIGN(4);
} >FLASH
/* the program code is stored in the .text section, which goes to Flash */
.text :
{
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_etext = .;
/* This is used by the startup in order to initialize the .data secion */
_sidata = _etext;
} >FLASH
/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >RAM
/* This is the uninitialized data section */
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* This is the user stack section
This is just to check that there is enough RAM left for the User mode stack
It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;
. = . + _Minimum_Stack_Size ;
. = ALIGN(4);
_eusrstack = . ;
} >CCM
__exidx_start = .;
__exidx_end = .;
/* after that it's only debugging information. */
/* remove the debugging information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

The ROM system loader in the 2MB parts does have expectations of the stack residing in the 0x20000000 region, as part of it's bank switching validation code. The CCM is usable at startup as the CCMRAM clock is enabled by default. Generally speaking I think that linker scripts, and scatter files, are things that need a clear floor planing and management approach, so should be tailored to specific needs rather than as a one size fits all. This is especially the case with the various STM32F4xxXX models with multiple FLASH/RAM configurations.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
gullik
Associate II
Posted on November 12, 2013 at 01:43

Tnx,

I guess the reason many scripts don't use the entire ram is that then you can get into problems using it with peripherals. Else, your example is fine, put all user processes stack into ccm, relieves most of that concern, and frees up heap for everyone....

The stm32f4 is a nice powerful chip, and although I was a bit intimidated by the lack of ST dev tools for a while , I am now running the gnu toolchain + stlink, and it all behaves as could be expected.

Beeing born with assembler / binary code, the (current) lack of an ide is not bothersome, the gdb is good, and the most valuable tool....and it even has screen mode to help keep focus....

Amel NASRI
ST Employee
Posted on November 12, 2013 at 10:02

I was a bit intimidated by the lack of ST dev tools for a while

What dev tools are you expecting? Could you please explain?

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

gullik
Associate II
Posted on November 12, 2013 at 11:21

Well, I have used MicroChip MPLAB-X on linux before, and that is a ''almost-free'' way of getting from idea to proof-of-concept. The reason I have attempted to switch to STM32 is primarily the Discovery board, where I get a proto board + a debugger essentially for free, a wise decision from ST. The ''stopper'' with ST is the lack of an elementary development environment.

Since I now have a well working toolbox based on unrestricted open source tools, I have no excuse not to evaluate my ideas and designs, and then the little Discovery board becomes extremely attractive.

I plan to use many of these for projects ranging from SDR radio (decent A/D + D/A + HW FP), to control appliances. I made a small webserver in 2 hours, just adding a breadboard foundation with an ethernet I/F + a few sensor pins. I.e. ''Quick & Dirty''. Maybe a bit of rambling, but in essence: ''Enough s/w + h/w support to make me think I could *build* something and focus on that task, rather than buying lots of computers, operating systems, pods, compilers before I even can start working.''