logo资料库

tasking LSL 简单教程.pdf

第1页 / 共13页
第2页 / 共13页
第3页 / 共13页
第4页 / 共13页
第5页 / 共13页
第6页 / 共13页
第7页 / 共13页
第8页 / 共13页
资料共13页,剩余部分请下载后查看
LSL Sample Cases using the Control Program The aim of this document is to demonstrate the usage of the Linker Script Language while using the TriCore toolchain to locate your application. It contains examples that deal with the most commonly used aspects of the language. It first lists all questions and continues with the proposed solutions. Studying this document will take 2 hours of your time. You may skip this document if you intend to use EDE instead. In that case document “LSL Sample Cases using EDE” will suffice for most cases. Each solution consists of a proposed section layout definition - which you must place in a user module layout.lsl - and an invocation of the control program. The control program invocation will use tc1796.lsl for derivative definition and extmem.lsl for external memory definition. You can find both in the product folder include.lsl. You are encouraged to verify the results of the linker by checking the map file. You can also test most examples with CrossView Pro’s simulator execution environment using the following command line invocation: xfwtc example.elf -C tc1796 -tcfg tsim2.cfg THE QUESTIONS… 1. How do I locate a function within a specific memory definition? 2. How do I locate a function at an absolute memory offset address? 3. How do I locate a function at an absolute address? 4. I have several functions that must be located within a specific memory definition. Their order must be the order in which they were defined plus that they must be contiguous. Possible alignment gaps between these sections may not be replaced with existing sections but should simply remain gaps. How do I do this? 5. I have a function that I want to run from RAM memory. I would like the startup code to load this function in RAM prior to entering the main program. How do I do this? 6. How do I locate a variable at a fixed address without using the __at() memory qualifier? 7. I have battery-backed data. I do not want the startup code to clear it because then it will also be cleared in case of sudden reboots which I do not want. For this data I want the linker to disable the clear attribute but how? 8. I know how I can address linker labels for the stack or heap. But how can I change their size and/or start address? 9. We have a project that because of its size and complexity has been split into several logical blocks, each having their own group of engineers. All blocks are delivered to us as libraries before finally locating the entire application. We want to avoid one group of engineers accidentally using resources from other groups and therefore want a mechanism that restricts memory use to well defined memory blocks per group of engineers. No one may enter the application block of someone else nor may a block itself exceed a certain size. Each application block must be extended with a fill pattern to meet this size. Is there a way? 10. Within the memory map of our application we have specific memory parts that must be reserved. No data may be located within this range other than data that is located by means of an absolute address. Is there a way to do this in the Linker Script Language? 11. For a self-designed processor we need a way to define a Scratch-Pad RAM. Since it may only be used for executing code we want to prevent the linker from using this RAM memory for standard application data. In a way it needs to be ‘disabled’ and only those groups that we explicitly locate within it should be allowed. What internal memory definition should we use? 12. We have two groups with sections requiring contiguous ordering. The groups themselves must be contiguous but not necessarily ordered. What section layout definition do you propose we use? © 2002-2005 Altium BV 1 LSL Sample Cases using the Control Program
TASKING TRICORE TOOLSET TASKING TRICORE TOOLSET THE PROPOSED SOLUTIONS… QUESTION 1 How do I locate a function within a specific memory definition? Solution: Assume the following C-module: #include extern void _lc_ub__text_test_Sample[]; extern void _lc_ue__text_test_Sample[]; void Sample(void) { printf("_lc_ub__text_test_Sample: 0x%p\n", printf("_lc_ue__text_test_Sample: 0x%p\n", _lc_ub__text_test_Sample); _lc_ue__text_test_Sample); } void main(void) { } Sample(); Suppose you want to locate function Sample and suppose the C-module is called test.c then according to TriCore’s section naming convention (See section 3.10, compiler generated sections) Sample will be assigned to the following code section: ".text.test.Sample" Suppose Sample must be located within memory ext_c such as defined in extmem.lsl then the following section layout definition will accomplish this: section_layout ::linear { group ( run_addr = mem:ext_c ) { select ".text.test.Sample"; } } The following control program command line invocation locates the application: cctc --output=example.elf --debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --verbose test.c © 2002-2005 Altium BV 2 LSL Sample Cases using the Control Program
QUESTION 2 How do I locate a function at an absolute memory offset address? TASKING TRICORE TOOLSET Solution: Using the same C-module as with Solution 1 and assuming a memory offset of 32k the section layout definition becomes: section_layout ::linear { group ( ordered, run_addr = mem:ext_c[32k] ) { } select ".text.test.Sample"; } } Note that in addition to the memory offset a new keyword is introduced called ordered. This keyword is required because a fixed memory offset address implies a restricted address and by default groups are unrestricted. The required control program command line invocation: cctc --output=example.elf --debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --verbose test.c QUESTION 3 How do I locate a function at an absolute address? Solution: Using the same C-module as with Solution 1 and assuming an absolute address of 0xa000c000 the section layout definition becomes: section_layout ::linear { group ( ordered, run_addr = 0xA000C000 ) { } select ".text.test.Sample"; The required control program command line invocation: cctc --output=example.elf --debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --verbose test.c © 2002-2005 Altium BV 3 LSL Sample Cases using the Control Program
TASKING TRICORE TOOLSET QUESTION 4 I have several functions that must be located within a specific memory definition. Their order must be the order in which they were defined plus that they must be contiguous. Possible alignment gaps between these sections may not be replaced with existing sections but should simply remain gaps. How do I do this? Solution: Assume the following C-module called test.c: #include extern void _lc_ub__text_test_SampleB[]; extern void _lc_ue__text_test_SampleE[]; void SampleB(void) { printf("_lc_ub__text_test_SampleB: 0x%p\n", _lc_ub__text_test_SampleB); printf("_lc_ue__text_test_SampleE: 0x%p\n", _lc_ue__text_test_SampleE); } void SampleE(void) { } void main(void) { SampleB(); SampleE(); } Suppose you want to locate functions SampleB and SampleE then from Solution 1 it follows that these are assigned to the sections listed below: ".text.test.SampleB" ".text.test.SampleE" Further suppose function SampleB must be located before SampleE then the section layout definition becomes: section_layout ::linear { } } group ( ordered, contiguous, fill=0x55, run_addr = mem:ext_c ) { select ".text.test.SampleB"; select ".text.test.SampleE"; Note the use of the fill keyword. It prevents the linker from substituting alignment gaps with unrestricted sections/groups. The required control program command line invocation: cctc –-output=example.elf –-debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --verbose test.c © 2002-2005 Altium BV 4 LSL Sample Cases using the Control Program
QUESTION 5 I have a function that I want to run from RAM memory. I would like the startup code to load this function in RAM prior to entering the main program. How do I do this? Solution: Assume the following C-module called test.c: TASKING TRICORE TOOLSET ((int*)_lc_ub__text_test_Add)[0] = 0x2080540B; #include extern void _c_init(void); extern void _lc_ub__text_test_Add[]; inline void PatchAdd2Sub(void) { } inline void ReinstallAdd(void) { } __indirect int Add(const int a, const int b) { } void main(void) { return a+b; _c_init(); if ( Add(1,1) == 2 ) { if ( PatchAdd2Sub(), Add(1,1) == 0 ) { if ( ReinstallAdd(), Add(1,1) == 2 ) { } puts("success!"); } } } For this example the aim is to have Add installed in the on-chip scratch-pad memory defined as csram in the derivative definition for tc1796. Note the use of the __indirect keyword which - in this case - is required because within the tc1796 memory map the gap between external memory ext_c and internal memory csram exceeds 16 MB and can therefore not be resolved with a standard callg or jg instruction. Not using __indirect here will result in linker error messages. The proposed section layout definition: section_layout ::linear { group ( run_addr = mem:spe:csram, copy ) { } select ".text.test.Add"; } The copy keyword instructs the linker to create a copy section for the sections within its group. In this case .text.test.Add spawns into copy section [.text.test.Add] and runtime section .text.test.Add which is installed in csram. The copy section itself is still unrestricted and will be freely located in ROM memory. Note the use of spe:csram to uniquely identify csram within a © 2002-2005 Altium BV 5 LSL Sample Cases using the Control Program
TASKING TRICORE TOOLSET possible multi-core environment or from possible external memory definitions with the same name. The required control program command line invocation: cctc --output=example.elf --debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --verbose test.c QUESTION 6 How do I locate a variable at a fixed address without using the __at() memory qualifier? Solution: Assume the following C-module called test.c: extern void _lc_ub__bss_test_MMRDeviceOne[]; extern void _lc_ub__bss_test_MMRDeviceTwo[]; __far unsigned MMRDeviceOne; __far unsigned MMRDeviceTwo; void main(void) { while ( _lc_ub__bss_test_MMRDeviceOne != ((void*)0xA0080100) ); while ( _lc_ub__bss_test_MMRDeviceTwo != ((void*)0xA0080200) ); puts (“memory mapped devices have been properly located”): In this example memory mapped registers MMRDeviceOne and MMRDeviceTwo are supposed to reside at addresses 0xA0080100 and 0xA0080200 respectively. If they are not, the program will lock at either the 1st or 2nd while-statement. Locating both memory mapped registers to their designated addresses requires the following section layout definition: } } } section_layout ::linear { select ".bss.test.MMRDeviceOne"; group ( ordered, run_addr=mem:ext_d[0x100] ) { } group ( ordered, run_addr=mem:ext_d[0x200] ) { } select ".bss.test.MMRDeviceTwo"; section_layout ::linear { select ".bss.test.MMRDeviceOne"; group ( ordered, run_addr=0xA0080100 ) { } group ( ordered, run_addr=0xA0080200 ) { } select ".bss.test.MMRDeviceTwo"; Note that memory-relative addresses are used. Instead you may also use the following equivalent that implements absolute addresses: © 2002-2005 Altium BV 6 LSL Sample Cases using the Control Program
TASKING TRICORE TOOLSET The required control program command line invocation in both cases: cctc –-output=example.elf –-debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --section-per-data-object --verbose test.c Note the use of compiler command line option --section-per-data-object which is to make sure each variable is assigned a unique section name rather than one data section per module. QUESTION 7 I have battery-backed data. I do not want the startup code to clear it because then it will also be cleared in case of sudden reboots which I do not want. For this data I want the linker to disable the clear attribute but how? Solution: Assume the following C-module called test.c: #include #include char securedString[35]; extern void _lc_ub__text_libc[]; void ColdReboot(void) { } void main(void) { ((void(*)(void))_lc_ub__text_libc)(); printf("%35s\n", securedString); strcpy(securedString, "All are clear, I alone am clouded"); ColdReboot(); With every cold reboot - and the example repeatedly keeps doing so - the main program begins by printing the contents of securedString. Under normal circumstances this means nothing is printed because securedString has been cleared by the startup code. In this case securedString resides in battery backed memory (for simplicity’s sake this is assumed to be memory ext_d ) and a sudden reboot will therefore unwantingly clear its contents. To prevent this from happening use the following section layout: } } section_layout ::linear { group ( ordered, run_addr=mem:ext_d, attributes=ws ) { } select ".bss.test.securedString"; Where attributes=ws assigns the scratch attribute to all sections within that group which effectively disables clearing. The example requires the following control program command line invocation: cctc –-output=example.elf –-debug-info --cpu=tc1796 --lsl-file=layout.lsl --lsl-file=extmem.lsl --section-per-data-object --verbose test.c © 2002-2005 Altium BV 7 LSL Sample Cases using the Control Program
QUESTION 8 I know how I can address linker labels for the stack or heap. But how can I change their size and/or start address? Solution: Assume the following C-module: TASKING TRICORE TOOLSET #include extern void _lc_ub_ustack[]; extern void _lc_ue_ustack[]; extern void _lc_ub_heap[]; extern void _lc_ue_heap[]; void main(void) { printf("_lc_ub_ustack = 0x%p\n", _lc_ub_ustack); printf("_lc_ue_ustack = 0x%p\n", _lc_ue_ustack); printf("_lc_ub_heap = 0x%p\n", _lc_ub_heap); printf("_lc_ue_heap = 0x%p\n", _lc_ue_heap); } } } Further suppose this application requires a relatively small stack size of 256 bytes which must be offset to 32k of memory definition ext_d. The heap - though not used - should be 2k in size and located at an offset of 40k within the same memory. Listed below is the proposed section layout definition: section_layout ::linear { stack "ustack" ( size=256 ); group ( ordered, run_addr=mem:ext_d[32k] ) { } group ( ordered, run_addr=mem:ext_d[40k] ) { } heap "heap" ( size=2k ); If on the other hand the stack or heap location is unrestricted then the following section layout definition will suffice: section_layout ::linear { group stack "ustack" ( size=256 ); group heap "heap" ( size=2k ); The usage of the stack or heap keyword within the section layout definition is different from that of the architecture definition (tc_arch.lsl). Within the architecture definition attributes such as minimum stack or heap size, stack or heap growth, ballooning and alignment are defined. The section layout allows you to modify or extend these with group properties. For more information about the stack or heap keyword within the architecture definition please refer section 8.5.3, Defining Address Spaces in chapter Semantics of the Architecture Definition of the Reference Manual. The same keywords within the section layout definition are explained in section 8.8.3, Creating or Modifying Special Sections in chapter Semantics of the Section Layout Definition of the Reference Manual. © 2002-2005 Altium BV 8 LSL Sample Cases using the Control Program
分享到:
收藏