Hi all,
We are using a product based board with K60 MCU in it.. Due to insufficient memory we changed the MCU to K66. We are using Codewarrior version 10.6.4 and MQX version 4.2.2. Now i am trying to port the linker file because the old one uses Codewarrior compiler(LCF file) new one is GCC compiler(LD file). I found a porting guide but its insufficient for us.
The LCF file uses keywords such as FORCE_ACTIVE, OBJECT. I cant find the exact replacement of these in LD File.
Please help to solve this issue.
Thanks and Regards,
Anand.S
k60_linker , porting lcf filekeyword
Thank you Sebastian. For your information i want to avoid dead striping of constant values(FORCE ACTIVE keyword used) . So using volatile is not a good idea i think so...
Also how to relocate strings in external flash? Please help me..!
Thank and regards,
Anand
 Sebastian_Del_R
		
			Sebastian_Del_RHello Anand, I hope you're doing well!
To use external flash memory with the k66F, you can use its Flexbus peripheral. This peripheral can interface with external SRAM, PROM, EPROM, EEPROM and flash.
You can read more information about this peripheral in the K66 Sub-Family Reference Manual located here, specifically, you can read chapter 34 "External Bus Interface (FlexBus)".
Best regards,
Sebastian
 Sebastian_Del_R
		
			Sebastian_Del_RHello Anand, I hope you’re well,
Do you think you could please share with me the .lcf you're talking about so I can more closely see what code sections you're referring to? Or at least some of the context around these sentences you're describing?
This is to check exactly which sentences you can't find an equivalent to, because some are not needed on newer linker file versions (such as the .ld form of linker files used by the GCC compiler).
Thank you,
Best regards,
Sebastian
Thank you so much Sebastian. I am attaching the .LCF file below. Please go through it.
MEMORY
{
 # Temporarily granted more space for user app
 #vectorrom (RX): ORIGIN = 0x00083000, LENGTH = 0x00000400
 #cfmprotrom (RX): ORIGIN = 0x00083400, LENGTH = 0x00000020 
 #rom (RX): ORIGIN = 0x00083420, LENGTH = 0x0007CBE0 # Code + Const data
 vectorrom (RX): ORIGIN = 0x0004B000, LENGTH = 0x00000400
 cfmprotrom (RX): ORIGIN = 0x0004B400, LENGTH = 0x00000020 
 rom (RX): ORIGIN = 0x0004B420, LENGTH = 0x000B4BD0 # Code + Const data
 fwver_mark (RW): ORIGIN = 0x000FFFF0, LENGTH = 0x00000008 # FW Ver marker
 end_mark (RW): ORIGIN = 0x000FFFF8, LENGTH = 0x00000008 # FW End marker
 ram (RW): ORIGIN = 0x1FFF0000, LENGTH = 0x00020000 # SRAM - RW data
 #ext_ram (RW): ORIGIN = 0x60000000, LENGTH = 0x00080000 # External SRAM - RW Data
 ext_ram (RW): ORIGIN = 0x60000000, LENGTH = 0x00060000 # External SRAM - RW Data
 ext_ram_txt (RX): ORIGIN = 0x60060000, LENGTH = 0x00020000 # External SRAM - RX text
 ext_flash (RW): ORIGIN = 0x70000000, LENGTH = 0x000A0000 # External Flash - RW Data
 ext_flash_txt (RX): ORIGIN = 0x70080000, LENGTH = 0x00200000 # External Flash for txt - RX Data
# kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap)
 end_of_kd (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000
 
 # Boot stack reused by MQX Kernel data
 bstack (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200 # Boot stack
 end_bstack (RW): ORIGIN = 0x2000FC00, LENGTH = 0x00000000
}
KEEP_SECTION { .vectors_rom, .vectors_ram, .cfmconfig, .endmark , .fwvermark}
FORCE_ACTIVE {g_engString, g_engStringSize, 
 g_frenchString, g_frenchStringSize, 
 g_germanString, g_germanStringSize,
 g_spanishString, g_spanishStringSize,
 g_UIPageStoreSize,g_UIPageStoreMenu,
 g_UIPageSignature,
 g_flashUIDataEndMark}
SECTIONS
{
 __INTERNAL_SRAM_BASE = 0x1FFF0000;
 __INTERNAL_SRAM_SIZE = 0x00020000;
 __SRAM_POOL = 0x2000FFF0;
__INTERNAL_FLASH_BASE = 0x00000000;
 __INTERNAL_FLASH_SIZE = 0x00100000;
__INTERNAL_FLEXNVM_BASE = 0;
 __INTERNAL_FLEXNVM_SIZE = 0;
 
 __UNCACHED_DATA_START = 0x1FFF0000;
 __UNCACHED_DATA_SIZE = 0x00020000;
 __UNCACHED_DATA_END = 0x2000FFF0;
 
 __EXTERNAL_MRAM_BASE = 0x60000000;
 __EXTERNAL_MRAM_SIZE = 0x00080000;
 __EXTERNAL_MRAM_ROM_BASE = 0x60000000;
 __EXTERNAL_MRAM_ROM_SIZE = 0x00000000;
 __EXTERNAL_MRAM_RAM_BASE = 0x60000000;
 __EXTERNAL_MRAM_RAM_SIZE = 0x00080000;
__EXTERNAL_LCD_BASE = 0x60000000;
 __EXTERNAL_LCD_SIZE = 0x1FFFF;
 __EXTERNAL_LCD_DC_BASE = 0x60010000;
# MQX link time configurations
 __DEFAULT_PROCESSOR_NUMBER = 1;
 __DEFAULT_INTERRUPT_STACK_SIZE = 1024;
 __KERNEL_DATA_VERIFY_ENABLE = 0; # Test SDRAM read/write
# Flashx configurations
 __FLASHX_SECT_SIZE = 0x1000;
.vectors :
 {
 __VECTOR_TABLE_ROM_START = .; # Runtime vector table in sram
 *(.vectors_rom)
 . = ALIGN (0x4); 
 } > vectorrom
.cfmprotect :
 {
 *(.cfmconfig)
 . = ALIGN (0x4);
 } > cfmprotrom
.main_application :
 {
 *(KERNEL)
 *(S_BOOT)
 *(IPSUM)
 *(.text)
 *(.init)
 *(.fini)
 *(.eini)
 *(.ctors)
 *(.dtors)
 . = ALIGN(0x4);
 *(.rodata)
 . = ALIGN(0x4);
 *(.rdata)
 . = ALIGN(0x4);
 *(.exception)
 . = ALIGN(0x4);
 __exception_table_start__ = .;
 EXCEPTION
 __exception_table_end__ = .;
 __sinit__ = .;
 STATICINIT
. = ALIGN(0x4);
 __COPY_OF_DATA = .;
 } > rom
.main_application_data : AT(__COPY_OF_DATA)
 {
 . = ALIGN(128);
 __VECTOR_TABLE_RAM_START = .; # Runtime vector table in sram
 *(.vectors_ram)
. = ALIGN(512);
 __BDT_BASE = .;
 *(.usb_bdt)
 __BDT_END = .;
 
 __START_DATA = .;
 *(.data)
 __END_DATA = .;
. = ALIGN(0x4);
 __START_SDATA = .;
 *(.sdata)
 __END_SDATA = .;
 
 # Added this section for the internal flash update code to be relocated to RAM at run time 
 . = ALIGN(0x4);
 __RELOCATE_START = .;
 *(.relocate_code)
 __RELOCATE_END = .;
. = ALIGN(0x4);
 __SDA_BASE = .;
 __SDA_BASE_ = __SDA_BASE;
 . = ALIGN(16);
 } > ram
.main_application_bss :
 {
 . = ALIGN(0x10);
 __START_SBSS = .;
 *(.sbss)
 *(SCOMMON)
 __END_SBSS = .;
 
 __START_BSS = .;
 *(.bss)
 *(COMMON)
 __END_BSS = .;
 . = ALIGN(16);
 } >> ram
.kernel_data : #AT(ADDR(.main_application_bss) + SIZEOF(.main_application_bss))
 {
 __KERNEL_DATA_START = ALIGN(0x10);
 }
 .end_of_kernel_data :
 {
 __KERNEL_DATA_END = .;
 } > end_of_kd
.boot_stack :
 {
 _stack_end = .;
 } > bstack
 
 .end_of_boot_stack :
 {
 _stack_addr = .;
 __SP_INIT = .;
 __BOOT_STACK_ADDRESS = .;
 } > end_bstack
 
 __COPY_OF_EXT_RAM_DATA = __COPY_OF_DATA + SIZEOF(.main_application_data);
 .ext_ram_data : AT(__COPY_OF_EXT_RAM_DATA)
 {
 . = ALIGN(0x4);
 ___extRAMStart = .;
 *(.data_extram)
 *(.rodata_extram)
 ___extRAMEnd = .;
 . = ALIGN(16);
 } > ext_ram
 
 .ext_ram_bss :
 {
 . = ALIGN(16); 
 *(.bss_extram)
 . = ALIGN(16);
 } >> ext_ram
__UI_DATA_START = 0x00000;
 __UI_DATA_END = 0xA0000;
 __UI_DATA_LANG_ENGLISH_START = 0x00000;
 __UI_DATA_LANG_FRENCH_START = 0x10000;
 __UI_DATA_LANG_SPANISH_START = 0x20000;
 __UI_DATA_LANG_GERMAN_START = 0x30000;
 __UI_DATA_MENU_STORE_START = 0x090000;
 __UI_DATA_MENU_STORE_END = __UI_DATA_MENU_STORE_START + 0xD000; 
 __UI_MENU_SIGNATURE = __UI_DATA_MENU_STORE_END - 4;
 __UI_DATA_END_MARK = __UI_DATA_END - 4;
 
 .ext_flash_data_english : AT(__UI_DATA_LANG_ENGLISH_START + ADDR(ext_flash))
 {
 . = ALIGN(0x4); 
 OBJECT(g_engStringSize, lang_english_strings_c.obj)
 OBJECT(g_engString, lang_english_strings_c.obj) 
 . = ALIGN(16);
 } > ext_flash
 
 .ext_flash_data_french : AT(__UI_DATA_LANG_FRENCH_START + ADDR(ext_flash))
 {
 . = ALIGN(0x4); 
 OBJECT(g_frenchStringSize, lang_french_strings_c.obj)
 OBJECT(g_frenchString, lang_french_strings_c.obj) 
 . = ALIGN(16);
 } >> ext_flash
 
 .ext_flash_data_spanish : AT(__UI_DATA_LANG_SPANISH_START + ADDR(ext_flash))
 {
 . = ALIGN(0x4); 
 OBJECT(g_spanishStringSize, lang_spanish_strings_c.obj)
 OBJECT(g_spanishString, lang_spanish_strings_c.obj) 
 . = ALIGN(16);
 } >> ext_flash
 
 .ext_flash_data_german : AT(__UI_DATA_LANG_GERMAN_START + ADDR(ext_flash))
 {
 . = ALIGN(0x4); 
 OBJECT(g_germanStringSize, lang_german_strings_c.obj)
 OBJECT(g_germanString, lang_german_strings_c.obj) 
 . = ALIGN(16);
 } >> ext_flash
 
 .ext_flash_data_menustore : AT(__UI_DATA_MENU_STORE_START + ADDR(ext_flash) )
 {
 . = ALIGN(0x4);
 OBJECT(g_UIPageStoreSize, dr_menudata_c.obj) 
 OBJECT(g_UIPageStoreMenu, dr_menudata_c.obj)
 . = ALIGN(16);
 } >> ext_flash
 
 .ext_flash_data_menustore_sign : AT(__UI_MENU_SIGNATURE + ADDR(ext_flash))
 { 
 OBJECT(g_UIPageSignature, dr_menu_renderer_c.obj)
 } >> ext_flash
 
 .ext_flash_end : AT(__UI_DATA_END_MARK + ADDR(ext_flash))
 { 
 OBJECT(g_flashUIDataEndMark, spiflash_ui_data_c.obj)
 } >> ext_flash
 
 # Locate the ROM copy table into ROM after the initialized data
 _romp_at = __COPY_OF_EXT_RAM_DATA + SIZEOF(.ext_ram_data);
 .romp : AT (_romp_at)
 {
 __S_romp = _romp_at;
 WRITEW(__COPY_OF_DATA); #ROM start address
 WRITEW(ADDR(.main_application_data)); #RAM start address
 WRITEW(SIZEOF(.main_application_data)); #size
 
 # Added for copying the SRAM data to SRAM in runtime
 WRITEW(__COPY_OF_EXT_RAM_DATA); #ROM start address
 WRITEW(ADDR(.ext_ram_data)); #RAM start address
 WRITEW(SIZEOF(.ext_ram_data)); #size
 
 WRITEW(0);
 WRITEW(0);
 WRITEW(0);
 }
_flashx_start = _romp_at + SIZEOF(.romp);
# flashx working area spans across the whole rest of Flash memory
 __FLASHX_START_ADDR = ((_flashx_start + __FLASHX_SECT_SIZE - 1) / __FLASHX_SECT_SIZE) * __FLASHX_SECT_SIZE;
 __FLASHX_END_ADDR = __INTERNAL_FLASH_BASE + __INTERNAL_FLASH_SIZE;
# This is for marking the end of FW area (8 Bytes)
 .endmark :
 {
 WRITEW(0x12345678);
 } > end_mark
 
 # This is for storing FW version(8 Bytes)
 .fwvermark :
 {
 *(.fwvermark)
 } > fwver_mark
 
 /* Section created to relocate code in specific Flash address */ 
 .ext_flash_txt :
 {
 . = ALIGN(4); 
 ext_flash_txt_start = .;
 *(.section_ext_flash_txt)
 ext_flash_txt_end = .;
 . = ALIGN(4); 
 
 } > ext_flash_txt 
}
/* EOF */
 Sebastian_Del_R
		
			Sebastian_Del_RHello Anand, I hope you're well,
I've gone through your linker script and read a bit about the syntax and statements used in the .lcf format, and what I've learned is that the FORCE_ACTIVE statement prevents a function or code section from being cut from the code even if it's not being used.
An alternative to this statement would be to set the "volatile" attribute in your C code to any function you wish to keep from being optimized out of the code.
As for the OBJECT statement, I haven't found an equivalent to it in the .ld format, however, when you include the libraries containing your used functions, the compiler should be smart enough to only include the functions that you're using (except If you set them as volatile!).
Please let me know if this answers your question or if you have any other questions!
Best regards,
Sebastian
