|
|
FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [August 2011 Threads] Linker Script for C++ on SAM7Posted by sven-de on August 2, 2011 Hi, along my journey into embedded OO I stumbled upon another problem: The linker script doesn't supply a .ctors-section and won't link global objects. I consulted these two ressources: http://www.state-machine.com/arm/Building_bare-metal_ARM_with_GNU.pdfhttp://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html#at91_cppBut at the end of the day I realised, that I'd really need some time to understand how linker-script, startup and low-level-init work within as well as together. So I just copied this between prog: and .data: .ctors : { PROVIDE(__ctors_start__ = .); KEEP(*(SORT(.ctors.*))) KEEP(*(.ctors)) PROVIDE(__ctors_end__ = .); } >flash
.dtors : { PROVIDE(__dtors_start__ = .); KEEP(*(SORT(.dtors.*))) KEEP(*(.dtors)) PROVIDE(__dtors_end__ = .); } >flash But got more errors. I've a weak understanding what the code in the two above ressources does, but have absolutely no clue about those (sparsely commented) files supplied with FreeRTOS. So I tend to swap atmel-rom.ld, boot.s und syscalls.c with those from the second ressource. Is that possible, or do they currently contain anything specific to FreeRTOS I have to take care of? Or are there even more files involved, such as Cstartup_SAM7.c and Cstartup.s79 in SRCAtmel? Is there any other way to achieve this without having to go deeply into GNU ld, and start-up procedures?
RE: Linker Script for C++ on SAM7Posted by Richard on August 2, 2011 The linker script has nothing FreeRTOS specific as far as I know.
The start up file must set up a stack for both Supervisor and IRQ modes, as a minimum (FIQ too if you use that), and install vPortYieldProcessor() as the SWI interrupt handler.
There has been lots of discussion here on the topic of C++ in the past, and some C++ projects posted to the FreeRTOS Interactive site too. http://interactive.freertos.org
Regards.
RE: Linker Script for C++ on SAM7Posted by sven-de on August 2, 2011 Richard, your response time makes me once again forget, that you aren't earning a single dime with this support (except those few bucks I paid for the eBook). Thanks!
I suppose with "start up file" you mean boot.s which apparently sets vPortYieldProcessor() as SoftwareInterrupt. But there's another file ./SrcAtmel/Cstartup.s97 which does the same. May I assume, since it's not linked, called or compiled anywhere, that this one is obsolete?
I was a bit confused to find LowLevelInit()-funtion in ./SrcAtmel/Cstartup_SAM7.c. All documentation I read until now treats low-level-init and startup-code as two different things - perhaps the naming could be changed with the next update of this demo.
Am I right, that syscalls.c has nothing to do with this? In 2009 you said that FreeRTOS doesn't even use of any of it's functions...
When this is my lucky day Richard Damon will soon come around the corner and post a platinum grade linker-script for C++ ;-)
RE: Linker Script for C++ on SAM7Posted by Richard on August 2, 2011 Which directory are you getting these files from? Just from the file name, I would say that Cstartup.s97 is probably an (old) IAR V.4x source file, and therefore should not be built with GCC. It is a long time since I did any SAM7 stuff, but I think the demos in the FreeRTOS download are for IAR, unless I did an Eclipse version at some time too.
Regards.
RE: Linker Script for C++ on SAM7Posted by sven-de on August 2, 2011 Yes, I'm using the GCC/Eclipse demo which has SrcAtmel/ right in RTOSDemo/. And your guess is probably right since the head-comment in Cstartup.s97 mentions IAR.
RE: Linker Script for C++ on SAM7Posted by Richard on August 2, 2011 Yes - ignore the .s79 file then - it is just part of the standard files received from Atmel, but not used in that particular demo.
Regards.
RE: Linker Script for C++ on SAM7Posted by sven-de on August 8, 2011 Hi, currently I'm swopping the demo's linker-script and startup-code with the aforementioned code by Martin Thomas (second link). While doing this I stumbled upon this section in the original linker-script of the SAM7 GCC-Demo: prog : { *(.text) *(.rodata) *(.rodata*) *(.glue_7) *(.glue_7t) } >flash It's the prog that puzzles me. From other linkerscripts I'd expect an .text (note the dot) in it's location instead. Since I couldn't find anything about this on the net, I assume it's some sort of custom section (which doesn't matter as long it's places in the right location). But is there any reason for not using the common .text here? (sorry for questions this far from the actual rtos)
RE: Linker Script for C++ on SAM7Posted by Johan Christiansen on August 9, 2011 Here's a script that works for C++. OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) ENTRY(_start)
MEMORY { sram : ORIGIN = 0x00000000,LENGTH = 0x1000 rom : ORIGIN = 0x40000000,LENGTH = 0x400000 flash : ORIGIN = 0x48000000,LENGTH = 0x400000 ram : ORIGIN = 0x50100000,LENGTH = 0x100000 }
SECTIONS {
. = 0; _sfixed = .;
.text : { KEEP(*(.init)) . = 0x100; KEEP(*(.jump)) *(.text) *(.text.*) *(.rodata*) . = ALIGN(8); PROVIDE (__init_array_start = .); KEEP(*(.init_array)) PROVIDE (__init_array_end = .); } >rom
.ARM.extab (NOLOAD) : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >rom __exidx_start = .; .ARM.exidx (NOLOAD) : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom __exidx_end = .; _efixed = .;
.data : { _data_lma = LOADADDR(.data); _data_start = .; *(.ramfunc) *(.data) *(.data.*) _data_end = .; } >ram AT> rom .sram 0x40 : { _sram_lma = LOADADDR(.sram); _sram_start = .; *(.sram.text) *(.sram.data) _sram_end = .; } >sram AT> rom
.bss (NOLOAD) : { _szero = .; *(.bss) *(.bss.*) . = ALIGN(8); _ezero = .; } >ram __heap_start__ = .; __heap_end__ = 0x50200000 - 8 - 40000; .ram_persist __heap_end__ (NOLOAD) : { *(.ram_persist) } > ram _sstack = 0x50200000 - 8;
} [/code
Then before starting a C++ function, or even before main do this:
/* C++ static constructors */ extern void (*__init_array_start []) (void) __attribute__((weak)); extern void (*__init_array_end []) (void) __attribute__((weak)); int count = __init_array_end - __init_array_start, i; for (i = 0; i < count; i++) __init_array_start();
RE: Linker Script for C++ on SAM7Posted by sven-de on September 5, 2011 Thank you all for your kind help. I finally took the abovementioned files from Martin Thomas an merged them mit the demo from FreeRTOS.org. Acutally I completely replaced the linker script, kept CstartupSAM7.c and just joined the two startup-files boot.s and Cstartup.S which resulted in the code below. It's working. /*------------------------------------------------------------------------------ //*- ATMEL Microcontroller Software Support - ROUSSET - //*----------------------------------------------------------------------------- //* The software is delivered "AS IS" without warranty or condition of any //* kind, either express, implied or statutory. This includes without //* limitation any warranty or condition with respect to merchantability or //* fitness for any particular purpose, or against the infringements of //* intellectual property rights of others. //*----------------------------------------------------------------------------- //*- File source : Cstartup.s //*- Object : Generic CStartup for KEIL and GCC //*- Compilation flag : None //* //*- 1.0 18/Oct/04 JPP : Creation //*- 1.1 21/Feb/05 JPP : Set Interrupt //*- 1.1 01/Apr/05 JPP : save SPSR //* //* This file (along with the linker script and Cstartup_SAM7.c) was taken from //* Martin Thomas due to it's support for C++. Originally it also allowed to //* place parts of code as well as the vectors in ROM. This functionality was //* removed by Sven Gruener in Aug/2011 while adapting it to FreeRTOS //*---------------------------------------------------------------------------*/
.print "ROM-Version: Vectors at start of Code, just variables in RAM"
/*----------------------------------------------------------------------------- //*- Exception vectors //*-------------------- //*- These vectors can be read at address 0 or at RAM address //*- They ABSOLUTELY requires to be in relative addresssing mode in order to //*- guarantee a valid jump. For the moment, all are just looping. //*- If an exception occurs before remap, this would result in an infinite loop. //*- To ensure if a exeption occurs before start application to infinite loop. //*--------------------------------------------------------------------------*/
.print "Vectors in section .vectorg -> .text" .section .vectorg, "ax"
LDR PC,Reset_Addr/* 0x00 Reset handler */ LDR PC,Undef_Addr/* 0x04 Undefined Instruction */ LDR PC,SWI_Addr/* 0x08 Software Interrupt */ LDR PC,PAbt_Addr/* 0x0C Prefetch Abort */ LDR PC,DAbt_Addr/* 0x10 Data Abort */ NOP /* 0x14 reserved */ LDR PC,[PC,#-0xF20]/* 0x18 IRQ */ LDRPC,FIQ_Addr/* 0x1c FIQ */
Reset_Addr:.wordInitReset Undef_Addr:.wordUndef_Handler SWI_Addr:.wordvPortYieldProcessor /* in portISR.c */ PAbt_Addr:.wordPAbt_Handler DAbt_Addr:.wordDAbt_Handler /*IRQ_Addr:.wordIRQ_Handler_Entry*/ FIQ_Addr:.wordFIQ_Handler
Undef_Handler:BUndef_Handler PAbt_Handler:BPAbt_Handler DAbt_Handler:BDAbt_Handler FIQ_Handler:BFIQ_Handler
/*--- End of exception vectors ----------------------------------------------*/
.arm .section .init, "ax" .global _startup .func _startup
_startup: reset:
.RAM_TOP: .word__TOP_STACK
InitReset:
/*----------------------------------------------------------------------------- /*- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit /*---------------------------------------------------------------------------*/ /*- minumum C initialization, call AT91F_LowLevelInit( void) */ .extern AT91F_LowLevelInit
ldr sp, .RAM_TOP/* temporary stack in internal RAM (**) */
/*--Call Low level init function in ABSOLUTE through the Interworking*/ ldrr0,=AT91F_LowLevelInit movlr, pc bxr0
/*------------------------------------------------------------------------------ //*- Stack size and location Definition //*------------------------------------ //*- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using //*- the vectoring. This assume that the IRQ management. //*- The Interrupt Stack must be adjusted depending on the interrupt handlers. //*- The System stack size is not defined and is limited by the free internal //*- SRAM. //*---------------------------------------------------------------------------*/
/* Stack Sizes */ .equ UND_STACK_SIZE, 0x00000004 .equ ABT_STACK_SIZE, 0x00000004 .equ FIQ_STACK_SIZE, 0x00000004 .equ IRQ_STACK_SIZE, 0X00000400 .equ SVC_STACK_SIZE, 0x00000400
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */ .equ MODE_USR, 0x10 /* User Mode */ .equ MODE_FIQ, 0x11 /* FIQ Mode */ .equ MODE_IRQ, 0x12 /* IRQ Mode */ .equ MODE_SVC, 0x13 /* Supervisor Mode */ .equ MODE_ABT, 0x17 /* Abort Mode */ .equ MODE_UND, 0x1B /* Undefined Mode */ .equ MODE_SYS, 0x1F /* System Mode */
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
/*------------------------------------------------------------------------------ //*- Setup the stack for each mode //*-------------------------------*/ mov r0, sp /* see (**) */
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */ mov sp, r0 sub r0, r0, #UND_STACK_SIZE msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */ mov sp, r0 sub r0, r0, #ABT_STACK_SIZE msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */ mov sp, r0 sub r0, r0, #FIQ_STACK_SIZE msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */ mov sp, r0 sub r0, r0, #IRQ_STACK_SIZE msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */ mov sp, r0 sub r0, r0, #SVC_STACK_SIZE msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */ mov sp, r0
/* We want to start in supervisor mode. Operation will switch to system mode when the first task starts. */ msr CPSR_c, #MODE_SVC|I_BIT|F_BIT
mov sp, r0/* Init stack Sup */
/*------------------------------------------------------------------------------ //*- Relocation of .data section (ROM->RAM) //*---------------------------------------*/ /* Relocate .data section (Copy from ROM to RAM) This will also copy the .vectmapped and .fastrun */ LDR R1, =_etext LDR R2, =_data LDR R3, =_edata LoopRel: CMP R2, R3 LDRLO R0, [R1], #4 STRLO R0, [R2], #4 BLO LoopRel
/*------------------------------------------------------------------------------ //*- Clear .bss section (Zero init) //*-------------------------------*/ MOV R0, #0 LDR R1, =__bss_start__ LDR R2, =__bss_end__ LoopZI: CMP R1, R2 STRLO R0, [R1], #4 BLO LoopZI
/*------------------------------------------------------------------------------ //*- call C++ constructors of global objects //*----------------------------------------*/ LDR r0, =__ctors_start__ LDR r1, =__ctors_end__ ctor_loop: CMP r0, r1 BEQ ctor_end LDR r2, [r0], #4 STMFD sp!, {r0-r1} MOV lr, pc /*MOV pc, r2 */ BX r2 /* mthomas 8/2006 */ LDMFD sp!, {r0-r1} B ctor_loop ctor_end:
/*------------------------------------------------------------------------------ //*- call main() //*------------*/ ldrlr,=exit ldrr0,=main bxr0
.size _startup, . - _startup .endfunc
/* "exit" dummy added by mthomas to avoid sbrk write read etc. needed by the newlib default "exit" */ .global exit .func exit exit: b . .size exit, . - exit .endfunc
/*----------------------------------------------------------------------------*/ .end
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|