YT-LINK并不怎么好用,受限制比较大,以下是我的解决方案
-
YTLINK这个初衷是为了降低开发者开发难度,但是汽车行业 现在都有BOOT,对于连接件脚本里逻辑代码,或者用户自定义导出符号,就显得力不从心。
比如我的工程是BM BT APP三个工程,打算复用链接脚本:我在COnfig TOOL上折腾了许久,还是不行,最后没办法放弃了,开始自定义脚本。以下是我工程的链接脚本,放出来:#!armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m7 -xc #define __BootManagerImageStartAddress__ 0x2000000 #define __BootManagerImageMaxSize__ 128*1024 #define __BootImageStartAddress__ __BootManagerImageStartAddress__ + __BootManagerImageMaxSize__ + 0x800 /*这0x800是给打包工具留的*/ #define __BootImageMaxSize__ 256*1024 -0x800 #define __AppImageStartAddress__ __BootImageStartAddress__ + __BootImageMaxSize__ +0x800 #define __AppImageMaxSize__ (1024*1024) - __AppImageStartAddress__ - 0x800 #define __AppImageMaxEndAddress__ __AppImageStartAddress__ + __AppImageMaxSize__ #define __CodeFlashStartAddress__ __AppImageStartAddress__ #define __CodeFlashMaxSize__ __AppImageMaxSize__ BootManagerImage __BootManagerImageStartAddress__ { BootManagerImageStart __BootManagerImageStartAddress__ FIXED EMPTY 0 { } } BootImage __BootImageStartAddress__ { BootImageStart __BootImageStartAddress__ FIXED EMPTY 0 { } } LR_BVT_0 __CodeFlashStartAddress__ { AppImageStart __CodeFlashStartAddress__ FIXED EMPTY 0 { } bvt_header_region_start AlignExpr(+0,4) FIXED EMPTY 0 { } bvt_header_region +0 NOCOMPRESS { *(.bvt_header) } bvt_header_region_end +0 EMPTY 0 { } sb_config_group_region_start AlignExpr(+0,4) FIXED EMPTY 0 { } sb_config_group_region +0 NOCOMPRESS { *(.sb_config_group) } sb_config_group_region_end +0 EMPTY 0 { } sb_config_section_region_start AlignExpr(+0,16) FIXED EMPTY 0 { } sb_config_section_region +0 NOCOMPRESS { *(.sb_config_section) } sb_config_section_region_end +0 EMPTY 0 { } sb_cmac_region_start AlignExpr(+0,16) FIXED EMPTY 0 { } sb_cmac_region +0 NOCOMPRESS { *(.sb_cmac) } sb_cmac_region_end +0 EMPTY 0 { } BVT_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_BVT_0) <= 0x800) LR_IVT_0 __CodeFlashStartAddress__ + 0x800 { IVT_start __CodeFlashStartAddress__ + 0x800 FIXED EMPTY 0 { } isr_vector_region_start +0 FIXED EMPTY 0 { } isr_vector_region +0 NOCOMPRESS { *(.isr_vector) } isr_vector_region_end +0 EMPTY 0 { } IVT_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_IVT_0) <= 1024) LR_TEXT_0 __CodeFlashStartAddress__ + 0xC00 { TEXT_start __CodeFlashStartAddress__ + 0xC00 FIXED EMPTY 0 { } text_region_start +0 FIXED EMPTY 0 { } text_region +0 NOCOMPRESS { *(.text*) } text_region_end +0 EMPTY 0 { } rodata_region_start +0 FIXED EMPTY 0 { } rodata_region +0 NOCOMPRESS { *(.rodata*) } rodata_region_end +0 EMPTY 0 { } TEXT_end +0 EMPTY 0 { } ARM_start +0 FIXED EMPTY 0 { } ARM.exidx_region_start +0 FIXED EMPTY 0 { } ARM.exidx_region +0 NOCOMPRESS { *(.ARM.exidx*) } ARM.exidx_region_end +0 EMPTY 0 { } ARM_end +0 EMPTY 0 { } CODE_RAM_start AlignExpr(0x400,4) EMPTY 0 { } code_ram_region_start AlignExpr(+0,4) EMPTY 0 { } code_ram_region +0 NOCOMPRESS { *(.code_ram) } code_ram_region_end +0 EMPTY 0 { } CODE_RAM_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_TEXT_0) <= 0x09F400) LR_IVT_RAM_0 0x0 { IVT_RAM_start AlignExpr(+0,1024) EMPTY 0 { } IVT_RAM AlignExpr(+0,1024) EMPTY 0x400 { } IVT_RAM_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_IVT_RAM_0) <= 0x400) LR_OS_HEAP_ITCM_0 0x2400 { OS_HEAP_ITCM_start +0 EMPTY 0 { } OS_HEAP_ITCM_region_start +0 EMPTY 0 { } OS_HEAP_ITCM_region +0 NOCOMPRESS { *(.OS_HEAP_ITCM) } OS_HEAP_ITCM_region_end +0 EMPTY 0 { } OS_HEAP_ITCM_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_OS_HEAP_ITCM_0) <= 0x5C00) LR_STACK_0 0x20000000 { STACK_start +0 EMPTY 0 { } STACK +0 EMPTY 0x2000 { } STACK_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_STACK_0) <= 0x2000) LR_Os_HEAP_DTCM_0 0x20002000 { OS_HEAP_DTCM_start +0 EMPTY 0 { } OS_HEAP_DTCM +0 EMPTY 0 { } OS_HEAP_DTCM_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_Os_HEAP_DTCM_0) <= 0x1E000) LR_RAM_0 0x20020000 { BSS_start +0 EMPTY 0 { } bss_region_start +0 EMPTY 0 { } bss_region +0 NOCOMPRESS { *(.bss*) } bss_region_end +0 EMPTY 0 { } BSS_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_RAM_0) <= 0x3FF00) LR_BOOT_APP_COM_RAM_0 0x2005ff00 { BOOT_APP_COM_RAM_start +0 EMPTY 0 { } BOOT_APP_COM_BSS_region_start +0 EMPTY 0 { } BOOT_APP_COM_BSS_region +0 NOCOMPRESS { *(.BOOT_APP_COM_BSS) } BOOT_APP_COM_BSS_region_end +0 EMPTY 0 { } BOOT_APP_COM_RAM_end +0 EMPTY 0 { } } ScatterAssert(ImageLength(LR_BOOT_APP_COM_RAM_0) <= 0x100) LR_TEXT_1 0x2000c00 + ImageLength(LR_TEXT_0) { DATA_RAM_start AlignExpr(ImageLimit(BSS_end),4) EMPTY 0 { } data_region_start +0 EMPTY 0 { } data_region +0 NOCOMPRESS { *(.data*) } data_region_end +0 EMPTY 0 { } DATA_RAM_end +0 EMPTY 0 { } } ScatterAssert( 0x09F400 >= (0 + ImageLength(LR_TEXT_0))) ScatterAssert(ImageLength(LR_TEXT_1) <= 0x09F400-(0 + ImageLength(LR_TEXT_0))) LR_RAM_1 0x20020000 + ImageLength(LR_RAM_0) { OS_HEAP_RAM_start AlignExpr(ImageLimit(DATA_RAM_end),4) EMPTY 0 { } OS_HEAP_RAM AlignExpr(ImageLimit(DATA_RAM_end),4) EMPTY 0 { } OS_HEAP_RAM_end AlignExpr(+0,4) EMPTY 0 { } } ScatterAssert( 0x3FF00 >= (0 + ImageLength(LR_RAM_0))) ScatterAssert(ImageLength(LR_RAM_1) <= 0x3FF00-(0 + ImageLength(LR_RAM_0)))
KEIL工程的,由于要做到代码复用,所以用了#! armclang的扩展,具体链接:https://developer.arm.com/documentation/ka002282/latest/
后话,目前来说链接脚本哪家都有或多或少的问题,稍微比较好用的也只能是GCC了,以下是我的S32K的链接脚本:
/*================================================================================================== * Project : RTD AUTOSAR 4.7 * Platform : CORTEXM * Peripheral : * Dependencies : none * * Autosar Version : 4.7.0 * Autosar Revision : ASR_REL_4_7_REV_0000 * Autosar Conf.Variant : * SW Version : 3.0.0 * Build Version : S32K3_RTD_3_0_0_D2303_ASR_REL_4_7_REV_0000_20230331 * * (c) Copyright 2020 - 2023 NXP Semiconductors * All Rights Reserved. * * NXP Confidential. This software is owned or controlled by NXP and may only be * used strictly in accordance with the applicable license terms. By expressly * accepting such terms or by downloading, installing, activating and/or otherwise * using the software, you are agreeing that you have read, and that you agree to * comply with and are bound by, such license terms. If you do not agree to be * bound by the applicable license terms, then you may not retain, install, * activate or otherwise use the software. ==================================================================================================*/ /* * Target device: This linker is demo and it is using for device S32K312 only. It is not part of the production code deliverables. * Target core: ARM cortex M7 * Linker need to align with MPU default setup in system.c */ /* * GCC Linker Command File: * 0x00000000 0x00007FFF 32768 ITCM * 0x20000000 0x2000FFFF 65536 DTCM * 0x00400000 0x005FFFFF 2097152 Program Flash * 0x10000000 0x1001FFFF 131072 Data Flash * 0x20400000 0x20417FFF 98304 SRAM_0 * Last 176 KB of CODE_FLASH reserved by HSE Firmware * standby_data section should contain only uninitialized data */ HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x00000200; __STANDBY_RAM_LIMIT_END = 0x20407FFF; /* 32Kbyte for standby ram */ ENTRY(Reset_Handler) __BootManagerImageStartAddress__ = 0x00400000; __BootManagerImageMaxSize__ = 128K; __BootImageStartAddress__ = __BootManagerImageStartAddress__ + __BootManagerImageMaxSize__ + 0x800;/*这0x800是给打包工具留的*/ __BootImageMaxSize__ = 256K -0x800; __AppImageStartAddress__ = __BootImageStartAddress__ + __BootImageMaxSize__ +0x800; __AppImageMaxSize__ = 768K - 0x800; __AppImageMaxEndAddress__ = __AppImageStartAddress__ + __AppImageMaxSize__ ; __DataFlashStartAddress__ = 0x10000000 ; __DataFlashEndAddress__ = 0x00020000 ; __CodeFlashStartAddress__ = __AppImageStartAddress__; __CodeFlashMaxSize__ = __AppImageMaxSize__; MEMORY { int_pflash : ORIGIN = __CodeFlashStartAddress__, LENGTH = __CodeFlashMaxSize__ /* 2048KB - 176KB (sBAF + HSE)*/ int_dflash : ORIGIN = 0x10000000, LENGTH = 0x00020000 /* 128KB */ int_itcm : ORIGIN = 0x00000000, LENGTH = 0x00008000 /* 32KB */ dtcm_msp_stack : ORIGIN = 0x20000000, LENGTH = 0x00001000 /*4KB Interrupt Stack Size*/ dtcm_sram : ORIGIN = 0x20001000, LENGTH = 0x0000F000 /* 除了给中断栈之外所有的dtcm*/ SRAM_0 : ORIGIN = 0x20400000, LENGTH = 0x17F00 /* SRAM所有的大小*/ BootAppComSram : ORIGIN = 0x20417F00, LENGTH = 0x100 /*BOOT和APP交互用的RAM,上电不需要初始化*/ ram_rsvd2 : ORIGIN = 0x20418000, LENGTH = 0 /* End of SRAM */ } _estack = ORIGIN(dtcm_msp_stack) + LENGTH(dtcm_msp_stack); /* 把dtcm+0x1000处的地址作为中断栈的栈顶 */ ITCM_START = ORIGIN(int_itcm) ; ITCM_END = ORIGIN(int_itcm) + LENGTH(int_itcm); DTCM_START = ORIGIN(dtcm_msp_stack); DTCM_END = ORIGIN(dtcm_sram) + LENGTH(dtcm_sram); SRAM0_START = ORIGIN(SRAM_0) ; SRAM0_END = ORIGIN(SRAM_0) + LENGTH(SRAM_0); __BootAppComSramStart__ = ORIGIN(BootAppComSram); SECTIONS { .pflash : { KEEP(*(.boot_header)) . = ALIGN(2048); __text_start = .; __interrupts_init_start = .; KEEP(*(.intc_vector)) . = ALIGN(4); __interrupts_init_end = .; KEEP(*(.core_loop)) . = ALIGN(4); *(.startup) . = ALIGN(4); *(.systeminit) . = ALIGN(4); *(.text.startup) . = ALIGN(4); *(.text) *(.text*) *(EXCLUDE_FILE (*C40_Ip.o) .text) . = ALIGN(4); *(EXCLUDE_FILE (*C40_Ip.o) .mcal_text) . = ALIGN(4); *(.acmcu_code_rom) . = ALIGN(4); __acfls_code_rom_start = .; *(.acfls_code_rom) . = ALIGN(4); __acfls_code_rom_end = .; KEEP(*(.init)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); *(.rodata) *(.rodata*) . = ALIGN(4); embedxrpc_service_start = .; KEEP(*(.embedxrpc_service)) embedxrpc_service_end = .; . = ALIGN(4); } > int_pflash ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >int_pflash .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >int_pflash .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >int_pflash .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >int_pflash .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >int_pflash .int_vector : { . = ALIGN(2048); __interrupts_ram_start = .; . += __interrupts_init_end - __interrupts_init_start; . = ALIGN(4); __interrupts_ram_end = .; } > dtcm_sram __RAM_INTERRUPT_START = __interrupts_ram_start; _sidata = LOADADDR(.data); .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ *(.RamFunc) /* .RamFunc sections */ *(.RamFunc*) /* .RamFunc* sections */ . = ALIGN(4); KEEP(*C40_Ip.o(.text*)) KEEP(*C40_Ip.o(.mcal_text)) . = ALIGN(4); *(.mcal_data) . = ALIGN(4); *(.ramcode) . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } > dtcm_sram AT>int_pflash .bss : { . = ALIGN(4); _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); *(.mcal_bss) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; . = ALIGN(4); __OS_HEAP0_START = .; PROVIDE ( end = . ); PROVIDE ( _end = . ); } > dtcm_sram __OS_HEAP0_END = ORIGIN(dtcm_sram) + LENGTH(dtcm_sram); __OS_HEAP1_START = ORIGIN(SRAM_0) ; __OS_HEAP1_END = ORIGIN(SRAM_0) + LENGTH(SRAM_0); Fls_ACEraseRomStart = __acfls_code_rom_start; Fls_ACEraseRomEnd = __acfls_code_rom_end; Fls_ACEraseSize = (__acfls_code_rom_end - __acfls_code_rom_start) / 4; /* Copy 4 bytes at a time*/ Fls_ACWriteRomStart = __acfls_code_rom_start; Fls_ACWriteRomEnd = __acfls_code_rom_end; Fls_ACWriteSize = (__acfls_code_rom_end - __acfls_code_rom_start) / 4; /* Copy 4 bytes at a time*/ __ENTRY_VTABLE = __interrupts_init_start; __CORE0_VTOR = __interrupts_init_start; __CORE1_VTOR = __CORE0_VTOR; __CORE2_VTOR = __CORE0_VTOR; }
如果云途想做简化链接脚本,可以实现一个Python/C#/JS类,执行用户脚本,得到有多少个memory,每个memory有多少个Group,每个Group有多少个Section等等,用户可以这么写:
var bvt_header_secction=new section(); bvt_header_secction.Name = "*(.bvt_header)"; bvt_header_secction.ForceLength= 0x800; var sb_config_group=new section(); sb_config_group.Name = "*(.sb_config_group)" var sb_config_section=new section(); sb_config_section.Name= "*(.sb_config_section)"; ... var pflash0=new pflash(YTM32.YTM32B1HA10.PFLASH0START); pflash0.AddSections(bvt_header_secction);//bvt_header_secction.由于ForceLength不为0,所以pflash0内部地址累加器(pflash0.AddressAccumulator)是pflash0.Base+0x800 pflash0.AddSections(sb_config_section); ... LinkerHost.ExportSymbol("MySymbol",pflash0.AddressAccumulator);//导出当前符号 if(LinkerHost.IsDefined("BUILD_APP")) //通过COnfigTool界面配置的 pflash0.AddressAccumulator + = 0x666; //用户打算跳过0x666个字节。 Chip.AddMemory(pflash0); Chip.AddMemory(pflash1); Chip.AddMemory(dtcm); ..... return Chip;
ConfigTOOL宿主机那边只要获取到Chip,就可以生成IAR,GCC等等的脚本了。
-
可以先看看:
https://forum.ytmicro.com/topic/111/boot-app-的简单-demo?=1739587358163
https://forum.ytmicro.com/topic/320/yt-link使用手册?=1739587710514理论上你想实现的功能,在YT-LINK上都能配置出来。
发帖前请查看
帮助没办法联网的电脑使用YCT
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...