2016-12-22 09:10 AM
Hello,
I work on a STM32F4 and I want use the CCM memory to declare my structures.
For example I want this kind of structure to be always declared in the CCM memory:
typedef struct Assign_Pot Assign_Pot;
struct Assign_Pot {
uint8_t variable1; uint8_t variable2; uint16_t variable3; };Assign_Pot* Assign_Tab[100];
I've been looking across the forum but I can't find a solution that works.
If I declare my structure like this:
struct Assign_Pot {
uint8_t variable1; uint8_t variable2; uint16_t variable3; } __attribute__ ((section('.ccm')));I have the warning: 'section' attribute does not apply to types [-Wattributes]
And the structure is not created in the CCM
Do you have some experience to share with this problem?
Thanks a lot, have a great day!
Note: this post was migrated and contained many threaded conversations, some content may be missing.2016-12-22 04:25 PM
The warning clearly tells you what's the problem: you can use the section attribute only when you declare variables, not when you create types. In other words, declaring a type (a struct tag here) only tells the compiler, what the variable looks like, not where variables of that type are going to be located, nor how many of them will be defined. OTOH if you define variable of whatever type, you tell the compiler to allocate a space in memory for that variable, so that's the right time to tell the compiler where exactly to allocate that space (normally you tell nothing and the compiler allocates it into its default space).
Nor does a pointer - either a pointer variable or a pointer type - define, where is the pointed-to object allocated, so defining pointers is not a way to tell the allocation of the pointed-to objects (you can allocate a pointer variable itself, though)
Declare a variable of struct Assign_Pot type and give it a section attribute.
JW
2016-12-22 06:42 PM
Normally the default linker configuration file (say IAR) would put the stack in the CCM if available.
As such, all local variables (struct based) declared inside a function should end up in the CCM, so developers benefits from it right away.
The main difference between main RAM and CCM is when lots of DMA transfer is going on.
DMA will take CPU cycles to read/write the main RAM. If using USB HS, SPI DMA, ADC/DAC DMA, then frequently accessed variables (or pointers) might be worth going to the CCM memory. Naturally, DMA accessed variables shouldn't be moved in the CCM. The lower the core frequency (on battery budget?) the more of a difference it could make.
Hope this help!
2016-12-23 02:31 AM
Thanks a lot for all your tips!
, If I declare myvariable of struct Assign_Pottype and give it a section attribute, for example:
Assign_Pot* Assign_Tab[100] __attribute__ ((section('.ccm')));
It will only declare the 100
pointer in the CCM, not all the variables inside the structure, isn't it?
, how can be sure that my default linker configuration file put all my 'static' or 'global' variables end up in CCM memory? For your interest you can find attached the linker file I made. In my code, only the variables declared with __attribute__ ((section('.ccm'))); are going into the CCM. ________________ Attachments : cutom_link.ld.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hz1Z&d=%2Fa%2F0X0000000bFM%2FtpDumIzm66M.y_H08VP2Os_FgbmFISqytecR4tOBk7I&asPdf=false2016-12-23 03:44 AM
,
,
I'm an IAR toolchain user, in IAR there is a linker config file *.lnk which describes the various memory segments and name them.
To force a particular source code portion to put their code or variables in a specific segment, I use a ♯ pragma ,
Each compiler and linker have their own method to get the job done, this is where digging the doc becomes handy.
2016-12-23 04:31 AM
Thank you. I use Coocox together with GNU Tools ARM Embedded, but it seems that I can't use
♯ pragma (I found this doc
)2016-12-23 05:39 AM
,
,
If I declare my ,variable of
struct Assign_Pot
type and give it a section attribute, for example:
Assign_Pot* Assign_Tab[100]
__attribute__ ((section('.ccm'))),
It will only declare the 100 ,
pointer in the CCM, not all the variables inside the structure, isn't it?
Yes, but this is basic C, nothing STM- or gcc-specific. By defining a pointer (or, here, an array of pointers) you tell the compiler to allocate space for those pointers, not for the pointed-to objects.
how can be sure that my default linker configuration file put all my 'static' or 'global' variables end up in CCM memory? For your interest you can find attached the linker file I made. In my code, only the variables declared with ,
__attribute__ ((section('.ccm'))),
are going into the CCM.Modify the linker script so that both .data and .bss output sections are placed into the ram1 region (in the same way as .ccm output section). The relevant part of GNU linker documentation is
https://sourceware.org/binutils/docs/ld/Output-Section-Description.html ♯ Output-Section-Description
.JW
2016-12-23 06:22 AM
Thanks a lot!
Do you think it's possible to set that
.data and .bss output sections are placed into the ram and ram1 region ? For example when the
ram1 is full, the other variables will be automatically placed in the ram. Because I don't want to only use the ram1 (CCM) of course.
Something like this in my linker file:
// variables with __attribute__ ((section('.ccm'))); will always be placed into the ram1 memory
.ccm (NOLOAD) :
{
. = ALIGN(4);
*(.ccm)
*(.ccm.*)
. = ALIGN(4);
} > ram1
// the other variables will be placed in both ram and ram1 memory
.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = . ;
} > ram > ram1
.bss (NOLOAD) :
{
_sbss = . ;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
} > ram > ram1
Sorry for all these beginners questions
2016-12-23 06:36 AM
The GNU linker isn't going to automatically spill or allocate memory across discontinuous memory regions, you have to micro-manage that at a function/object/section level. Or write a script.
Alternatively you could have both regions on a heap, and dynamically allocate.
On the F4 the CCM can't be used for DMA buffers, or code execution.
2016-12-23 07:56 AM
Thanks!
Now I configured my .data to always be located in the ccm, it's a good thing.
But my main problem maybe remains the same: to be able to declare my struct variables into CCM.
I'm not sure that, by declaring ma .data in ccm, my struct variables will be in the CCM, for e.g. when I do:
struct Assign_Pot {
uint8_t variable1;
uint8_t variable2;
uint16_t variable3;
};
Assign_Pot* Assign_Tab[100];