I've read through the MCU_Kinetis_Compiler.pdf document and other links on the web and having problems with the syntax needed with the Kinetis GCC compiler to re-direct RAM allocaiton to different sections specified by the linker file.
How this came about:
I now have the TWR-MEM board operating, but the mmem is slow. I want my emac buffers and ADC buffers to use the internal SRAM, but all other memory to use the slower mmem.
Now I have my linker file modified to specify all memory to use the mmem. This was easy to do with the linker file modified as follows:
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001E0
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0
m_data (RW) : ORIGIN = 0x60000000, LENGTH = 0x00080000
m_data_00000000 (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001E000
m_data_20000000 (RW) : ORIGIN = 0x2000E000, LENGTH = 0x00002000
m_cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
}
But my confusion now is the #pragma syntax needed in my source code to direct various buffers to use sections: m_data_00000000 and m_data_20000000.
Now I happen to have my network buffers declared as follows:
{
{ 16, 128 },
{ 33, 512 },
};
I thought it would be as simple as adding the following:
#pragma DATA_SECTION(in_bufq,"m_data_20000000")
But I get the following compiler warning, and my allocation is not where I expect it.
D:/Freescale/CW MCU v10.4/MCU/ARM_GCC_Support/ewl/EWL_C/include/ctime:307:0: warning: ignoring #pragma options align [-Wunknown-pragmas]
../Sources/userdata.c:229:0: warning: ignoring #pragma DATA_SECTION [-Wunknown-pragmas]
Any suggestions on what the correct syntax should be to instruct the tool chain to allocate my buffers to the memory location I want them located in?
Thanks
已解决! 转到解答。
Hello Terry:
In your linker file you should have something like the next:
___m_data_20000000_ROMStart = ___ROM_AT + SIZEOF(.data);
.m_data_20000000 : AT(___m_data_20000000_ROMStart)
{
. = ALIGN(4);
___m_data_20000000_RAMStart = .;
*(.m_data_20000000) /* This is an User defined section */
___m_data_20000000_RAMEnd = .;
. = ALIGN(4);
} > m_data_20000000
___m_data_20000000_ROMSize = ___m_data_20000000_RAMEnd - ___m_data_20000000_RAMStart;
If that is the case, you can locate your data structure with the next code:
typedef struct
{
unsigned int bufNumber;
unsigned int bufSize;
}NET_BUFQ;
__attribute__ ((section(".m_data_20000000"))) NET_BUFQ in_bufq[] =
{
{ 16, 128 },
{ 33, 512 },
};
Just a few comments to clarify:
- GuiConst_INT8U is a variable from a custom example, so you won't find it in your code.
- __declspec directive works for Freescale Compiler, but in this case you are using GCC compiler, and you need to use __attribute__ instead.
:smileyalert: You read MCU_Kinetis_Compiler.pdf from CodeWarrior 10.4, which includes information about both Freescale and GCC compilers. In CodeWarrior 10.5 there are separate documents: MCU_Kinetis_Compiler.pdf and MCU_Kinetis_GCC.pdf.
When working with GCC tools, you can refer to the next files for more details:
- C:\Freescale\CW MCU v10.4\Cross_Tools\arm-none-eabi-gcc-4_7_3\share\doc\gcc-arm-none-eabi\pdf\ld.pdf
- C:\Freescale\CW MCU v10.4\Cross_Tools\arm-none-eabi-gcc-4_7_3\share\doc\gcc-arm-none-eabi\pdf\gcc\gcc.pdf
Hope you find this useful
/Jorge Gonzalez
Customer can refer below info about define variable in dedicated memory range:
LCF file:
MEMORY {
display (RW) : ORIGIN = 0x60100000, LENGTH = 0x00020000
}
SECTIONS {
___display_ROMStart = ___display_ram_ROMStart + SIZEOF(.display_ram);
.display : AT(___display_ROMStart)
{
. = ALIGN(4);
___display_RAMStart = .;
*(.display) /* This is an User defined section */
___display_RAMEnd = .;
. = ALIGN(4);
} > display
___display_ROMSize = ___display_RAMEnd - ___display_RAMStart;
C file:
#pragma define_section my_ram2 ".display" abs32 RW
__declspec(section "my_ram2") GuiConst_INT8U Display[511];
Wish it helps.
Hi Ma
Your description helps but I'm still having problems connecting my C code to the linker script.
In my case my linker script is as follows. I would like to place my high speed buffer into memory location = m_data_20000000.
MEMORY {
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001E0
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0
m_data (RW) : ORIGIN = 0x60000000, LENGTH = 0x00080000
m_data_00000000 (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
m_data_20000000 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
m_cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
}
In the C code I have the following questions:
#pragma define_section high_speed_buffer_storage ".m_data_20000000" abs32 RW
//question: can you tell me what the named section abs32 represents? Does it matter what I place here?
__declspec(section "high_speed_buffer_storage ") GuiConst_INT8U Display[511];
// question: I've search my code and I cannot find any reference to GuiConst_INT8U.
// This look like its a variable type definition. Where is this defined?
What syntax is needed for my case of __declspec line to assign mybuffer to the memory section high_speed_buffer_storage?
My variable type is: in_bufq
My buffer is as follows:
typedef struct
{
int32_t bufNumber;
int32_t bufSize;
}NET_BUFQ;
#pragma define_section high_speed_buffer_storage ".m_data_20000000" abs32 RW
__declspec(section "high_speed_buffer_storage") NET_BUFQ in_bufq[3];
NET_BUFQ in_bufq[] =
{
{ 16, 128 },
{ 33, 512 },
};
The compiler output is as follows:
D:/Freescale/CW MCU v10.4/MCU/ARM_GCC_Support/ewl/EWL_C/include/ctime:45:0: warning: ignoring #pragma options align [-Wunknown-pragmas]
D:/Freescale/CW MCU v10.4/MCU/ARM_GCC_Support/ewl/EWL_C/include/ctime:307:0: warning: ignoring #pragma options align [-Wunknown-pragmas]
../Sources/userdata.c:230:0: warning: ignoring #pragma define_section high_speed_buffer_storage [-Wunknown-pragmas]
../Sources/userdata.c:231:20: error: expected ')' before string constant
mingw32-make: *** [Sources/userdata.o] Error 1
What am I doing wrong?
Hello Terry:
In your linker file you should have something like the next:
___m_data_20000000_ROMStart = ___ROM_AT + SIZEOF(.data);
.m_data_20000000 : AT(___m_data_20000000_ROMStart)
{
. = ALIGN(4);
___m_data_20000000_RAMStart = .;
*(.m_data_20000000) /* This is an User defined section */
___m_data_20000000_RAMEnd = .;
. = ALIGN(4);
} > m_data_20000000
___m_data_20000000_ROMSize = ___m_data_20000000_RAMEnd - ___m_data_20000000_RAMStart;
If that is the case, you can locate your data structure with the next code:
typedef struct
{
unsigned int bufNumber;
unsigned int bufSize;
}NET_BUFQ;
__attribute__ ((section(".m_data_20000000"))) NET_BUFQ in_bufq[] =
{
{ 16, 128 },
{ 33, 512 },
};
Just a few comments to clarify:
- GuiConst_INT8U is a variable from a custom example, so you won't find it in your code.
- __declspec directive works for Freescale Compiler, but in this case you are using GCC compiler, and you need to use __attribute__ instead.
:smileyalert: You read MCU_Kinetis_Compiler.pdf from CodeWarrior 10.4, which includes information about both Freescale and GCC compilers. In CodeWarrior 10.5 there are separate documents: MCU_Kinetis_Compiler.pdf and MCU_Kinetis_GCC.pdf.
When working with GCC tools, you can refer to the next files for more details:
- C:\Freescale\CW MCU v10.4\Cross_Tools\arm-none-eabi-gcc-4_7_3\share\doc\gcc-arm-none-eabi\pdf\ld.pdf
- C:\Freescale\CW MCU v10.4\Cross_Tools\arm-none-eabi-gcc-4_7_3\share\doc\gcc-arm-none-eabi\pdf\gcc\gcc.pdf
Hope you find this useful
/Jorge Gonzalez