This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
so I stumbled about a use case which is documented in many different parts in the LTS1.3.0 compiler manual, which makes it sometimes hard to gather all the needed information at once.
I wanted to try the topic which is explained here: https://software-dl.ti.com/codegen/docs/tiarmclang/rel1_3_0_LTS/compiler_manual/linker_description/05_linker_command_files/placing-a-section-at-different-load-and-run-addresses-stdz0756565.html#stdz0756565
So in fact placing sections at a different load than run-address. Our use case is to place different code-parts each in external RAM and depending on what the program does load them in the same run-location (of course not both at once, but either the one or the other.).
I followed the example also described here: https://software-dl.ti.com/codegen/docs/tiarmclang/rel1_3_0_LTS/compiler_manual/linker_description/08_using_linker_generated_copy_tables/generating-copy-tables-with-the-table-operator-stdz0750716.html#stdz0750717
so my solution was the following:
in the linker-script:
.ovly: > MCU1_0_R5F_MEM_TEXT UNION: run > MCU1_0_R5F_MEM_TEXT { .testLog: { -l libtestLog.a } load > MCU1_0_EXTRAM_CODE, palign(8), table(TESTCODELOG) .testSignal: { -l libtestSignal.a } load > MCU1_0_EXTRAM_CODE, palign(8), table(TESTCODESIG) }
and inside the source code:
#include <cpy_tbl.h> extern COPY_TABLE TESTCODELOG; extern COPY_TABLE TESTCODESIG; /* ... */ if(useLog) { copy_in(&TESTCODELOG); new LogTest(); } else { copy_in(&TESTCODESIG); new SignalTest(); }
but it won't work.
I can see that the code will be loaded at call copy_in, but somethings wrong.
having opened the memory browser I see the following (I changed the names a bit) before the copy_in (in this case the else-branch):
0x701790A4 .L.str 0x701790A4 6362696C 62612B2B 00203A69 0x701790B0 .L__const._ZN7x6x20x21xEv.regs 0x701790B0 28001000 00000080 0x701790B8 .L.str 0x701790B8 5464654C 006B7361 0x701790C0 .L.str 0x701790C0 E2800001 E5C10014 EA000033 E59D0010 E5900010 E30B1210 E3471017 ED9F0B31 E3032CDF E3402034 EB000124 E59D1010 0x701790F0 E5D10014 E2800001 E5C10014 EA000026 E59D0010 E5900010 E30B121C E3471017 E30A2E4B E3472017 EBFEFE74 E59D1010 0x70179120 E5D10014 E2800001 E5C10014 EA00001A E59D0010 E5900010 E30B1228 E3471017 EBFF1F5A E59D1010 E5D10014 E2800001 0x70179150 E5C10014 EA000010 E59D0010 E5900010 E30B1234 E3471017 E30A2E58 E3472017 E3003539 EB0000B9 E59D1010 E5D10014 0x70179180 E2800001 E5C10014 EA000003 E59D1010 E3A00000 E5C10014 0x70179198 .L.str.13 0x70179198 EAFFFFFF EAFFFF91 E28DD018 E8BD8800 2A9D627C 404525DF 41BB999A 00000000 00000000 00000000 E92D41F0 E24DD0C0 0x701791C8 E1A0C001 E1A0E000 E59D00DC E59D10D8 E58DE0BC E58DC0B8 E1CD2BB6 E58D30B0 E5CD10AF E5CD00AE E59D00BC E58D0028 0x701791F8 E28D00AC E58D003C EBFFC99A E28D0088 E58D0024 E3A01021 EBFFD114 E59D1024 E59D0028 E3811001 E5D10014 E2800001 0x70179228 E5C10014 EA00001A E59D0010 E5900010 E30B1328 E3471017 EBFF1F32 E59D1010 E5D10014 E2800001 E5C10014 EA000010 0x70179258 E59D0010 E5900010 E30B1334 E3471017 E30A2F58 E3472017 E3003539 EB0000B9 E59D1010 0x7017927C .L__FUNCTION__._ZN7x8x3x26xIJEE12xEv 0x7017927C E5D10014 E2800001 E5C10014 EA000003 E59D1010 E3A00000 E5C10014 EAFFFFFF EAFFFF91 E28DD018 E8BD8800 2A9D627C 0x701792AC 404525DF 41BB999A 00000000 00000000 00000000 00000000 00000000 00000000 0x701792CC .L.str.17 0x701792CC 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x701792FC 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x7017932C 00000000 00000000 00000000 00000000 00000000 EB0006A6 E5900000 E58D0038 E28D00AF EB00068A E5D00000 E58D002C 0x7017935C E28D00AE 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x7017938C 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x701793BC 00000000 0x701793C0 LogTest::func() 0x701793C0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x701793F0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x70179420 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x70179450 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x70179480 E59D20B8 EBFF3D01 E28D00B4 EB00064B ED900A00 ED8D0A0D E28D00B3 EB000637 00000000 00000000 00000000 00000000 0x701794B0 00000000 00000000 00000000 00000000 E59D003C E1D330B0 EB0002C0 E3500000 0A000020 EAFFFFFF E59D002C E5900000 0x701794E0 E58D0024 E28D0064 E58D001C E28D1088 E3A02021 E58D2020 EBFE72FF E59D101C E59D2020 E28D0040 EBFE72FB E59D0024 0x70179510 E59D1040 E59D2044 E59D3048 E59DC04C 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x70179540 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x70179570 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x701795A0 00000000 0x701795A4 TEST_MSG_1 0x701795A4 00000000 00000000 00000000 0x701795B0 void LogTestWriter::logfunc 0x701795B0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
and after
0x701790A4 .L.str 0x701790A4 6362696C 62612B2B 00203A69 0x701790B0 .L__const._ZN7x6x20x21xEv.regs 0x701790B0 28001000 00000080 0x701790B8 .L.str 0x701790B8 5464654C 006B7361 0x701790C0 .L.str 0x701790C0 7017AA50 7017A960 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x701790F0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x70179120 E5810000 E30E1603 E3451003 E30E264C E3452003 E3A00000 E3A030F2 EB003CC7 EAFFFFFF E3040E42 E3400049 E58D0078 0x70179150 EB00895E E3A01003 E28D2078 E3A03004 EB005366 E3500000 1A00000F EAFFFFFF E30E066F E3450003 E1A0100D E5810004 0x70179180 E30E0669 E3450003 E5810000 E30E1603 E3451003 E30E264C 0x70179198 .L.str.13 0x70179198 E3452003 E3A00000 E3A030F9 EB003CAD EAFFFFFF E30E16A5 E3451003 E28D0060 E58D0010 E3A02018 E58D2014 EB0004BC 0x701791C8 EB008940 E59D2010 E59D3014 E3A01004 EB005348 E3500000 1A00000F EAFFFFFF E30E066F E3450003 E1A0100D E5810004 0x701791F8 E30E0669 E3450003 E5810000 E30E1603 E3451003 E30E264C E3452003 E3A00000 E3A03C01 EB003C8F EAFFFFFF E3040655 0x70179228 E3400046 E58D005C E3040142 E3440C4C E58D0058 EB008923 E3A01005 E28D2058 E3A03008 EB00532B E3500000 1A00000F 0x70179258 EAFFFFFF E30E066F E3450003 E1A0100D E5810004 E30E0669 E3450003 E5810000 E30E1603 0x7017927C .L__FUNCTION__._ZN7x8x3x26xIJEE12xEv 0x7017927C E3451003 E30E264C E3452003 E3A00000 E3003107 EB003C72 EAFFFFFF E30E16C5 E3451003 E28D0041 E58D0008 E3A02017 0x701792AC E58D200C EB000481 EB008905 E59D2008 E59D300C E3A01006 EB00530D E3500000 0x701792CC .L.str.17 0x701792CC 1A00000F EAFFFFFF E30E066F E3450003 E1A0100D E5810004 E30E0669 E3450003 E5810000 E30E1603 E3451003 E30E264C 0x701792FC E3452003 E3A00000 E300310E EB003C54 EAFFFFFF E3010001 E34B0717 E58D003C EB0088EB E3A01008 E28D203C E3A03004 0x7017932C EB0052F3 E3500000 1A00000F EAFFFFFF E30E066F E3450003 E1A0100D E5810004 E30E0669 E3450003 E5810000 E30E1603 0x7017935C E3451003 E30E264C E3452003 E3A00000 E3003115 EB003C3A EAFFFFFF E30420E4 E3452004 E5920000 E5921004 E5922008 0x7017938C E58D2038 E58D1034 E58D0030 EB0088CC E3A01007 E28D2030 E3A0300C EB0052D4 E3500000 1A00000F EAFFFFFF E30E066F 0x701793BC E3450003 0x701793C0 LogTest::func() 0x701793C0 E1A0100D E5810004 E30E0669 E3450003 E5810000 E30E1603 E3451003 E30E264C E3452003 E3A00000 E3A03F47 EB003C1B 0x701793F0 EAFFFFFF E3A00000 E58D0024 E58D0028 E3A00001 E58D002C E59D0024 E59D1028 E59D202C E58D2038 E58D1034 E58D0030 0x70179420 EB0088AA E3A01009 E28D2030 E3A0300C EB0052B2 E3500000 1A00000F EAFFFFFF E30E066F E3450003 E1A0100D E5810004 0x70179450 E30E0669 E3450003 E5810000 E30E1603 E3451003 E30E264C E3452003 E3A00000 E3003123 EB003BF9 EAFFFFFF E3A00000 0x70179480 E5CD0020 E58D001C EB008890 E3E01000 E28D201C E3A03005 EB005298 E3500000 1A00000F EAFFFFFF E30E066F E3450003 0x701794B0 E1A0100D E5810004 E30E0669 E3450003 E5810000 E30E1603 E3451003 E30E264C E3452003 E3A00000 E300312B EB003BDF 0x701794E0 EAFFFFFF EB008879 EB00C14C EAFFFFFF E28DD0A0 E8BD8800 EA003C13 EA003C12 E92D4800 E24DDF42 E58D0104 E58D1100 0x70179510 E59D0104 E58D0008 E59D0100 E5D00000 E2400002 E58D000C E350004E 8A00010B E59D100C E28F0004 E7900101 E1A0F000 0x70179540 500027DC 50002AC0 500027F4 50002AC0 5000280C 50002AC0 50002824 50002AC0 5000283C 50002AC0 50002854 50002AC0 0x70179570 50002AC0 50002AC0 50002974 50002A68 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 0x701795A0 50002AC0 0x701795A4 TEST_MSG_1 0x701795A4 50002AC0 50002AC0 50002AC0 0x701795B0 void LogTestWriter::logfunc 0x701795B0 50002AC0 50002AC0 5000286C 50002934 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0 50002AC0
The copy-tables looks the following:
0x7017B2E0 TESTCODELOG, __TI_table_TESTCODELOG 0x7017B2E0 0001000C 50000000 701790C0 00002220 0x7017B2F0 TESTCODESIG, __TI_table_TESTCODESIG 0x7017B2F0 0001000C 50002220 701790C0 000006F0
The copied data is exactly the data which is located in EXTRAM.
what now happens is that the call of the line "new SignalTest()" brings the device to an data abort. The problem is, I can not really debug, because as you see the symbol-demangling uses the first seen symbol and not the actually loaded ones.
It won't crash if linked normaly into the sections, so it's not a problem of the classes/objects.
It doesn't matter if I load the LogTest or SignalTest.
Also I wondered if it may happen because of the sections. So I wondered which sections does the compiler generate? Because just linking the libs I thought it may include all the sections of this library. Which would be fine, but I was not sure about the initialization process of some const-objects which are initialized before call of main(). So I tried playing with the .init_array-section and putting it somewhere else but this did not help.
The documentation has a lack of explanation which sections are generated. There are many chapters which are sometimes redundant but none of those does explain all the possible sections generated, so I can just guess.
I found informations here:
But none are really explaining how to use something. So I tried just putting in the sections text, rodata and data. But if the init_array-section is missing the loaded program won't even run to main but abort inside of __TI_auto_init but I think that may happen because we put the global init_array into TCMA.
So this wasn't a solution anyways.
The problem also happens if we just use one lib with different load- and run-addresses without the UNION statement, so it's not related to overlapping.:
.testSignal: { -l libtestSignal.a } load > MCU1_0_EXTRAM_CODE, palign(8), run > MCU1_0_R5F_MEM_TEXT, table(TESTCODESIG)
Debugging in code showed that the Constructor-Call does not work correctly. The allocation beforehand with new works, we use our own heap-implementation.
After some steps I saw in the disassembly the program just steps through the copied code, and whats interesting, it does just continue stepping and even steps to the 00000000 parts in exectuion inside this copied part:
0x7017B5C0 SignalTest() 0x7017B5C0 E92D4800 E24DD018 E58D0014 E58D1010 E58D200C E5CD300B E59D0014 E58D0004 E59D1010 EBFF7F95 E59D0004 E2800008 0x7017B5F0 E59D1010 E59D200C E5DD300B EBFF49F3 E59D0004 E30B1710 E3471017 E2812008 E5802000 E2811044 E5801008 E3A01000 0x7017B620 E5801010 E5801014 E5801018 E28DD018 E8BD8800 00000000 00000000 00000000
after some more steps the abort happens.
So I have no more idea what I am doing wrong here. Any suggestions? Is there a special handling with C++-code?
Best regards
Felix
Please understand that this code ...
.testLog: { -l libtestLog.a }
... says to create an output section named testLog. The input sections include all the .text sections from libtestLog.a, which contains the code for the functions. But it also includes all the other input sections from libtestLog.a, such as .rodata. You may not intend that. If you only want the code for the functions to be in this custom overlay, then write ...
.testLog: { -l libtestLog.a(.text) }
Another point to keep in mind ... Everything in the program always thinks everything in the output sections testLog and testSignal are always at the run address. The only exception is the copy_in function. You have to make sure that those output sections really are present at the run address before any other part of the program attempts to read or write any of it.
Please let me know if these suggestions resolve the problem.
Thanks and regards,
-George
Hey George,
so I found time again and tested just copying in the text-section. It does not work either, I still get an data-abort.
I tried it like this now:
.testSignal: { -l libtestSignal.a(.text) } load > MCU1_0_EXTRAM_CODE, palign(8), run > MCU1_0_R5F_MEM_TEXT, table(TESTCODESIG)
I see the code is copied correctly but it does not run as expected.
I see the code is copied correctly
I further presume this copy completes before any call to the functions in this code. This is as far as my expertise goes. There must be some other system related issue causing the problem.
One possibility is that the CPU is reading old instructions from some cache when it should read new instructions from memory instead.
That being the case, I am handing responsibility for this thread over to experts on AM243x systems.
Thanks and regards,
-George
Thanks George,
yes, it's arranged like in my first post, so directly after a copy the function/CTOR related to the code will be called. So I guess it could be really a problem with cache. I'm not that deep into that topic, but I'm stepping through the dissassembly and the assembly-commands there look exactly like the ones copied. Is it possible here, that this view is not correct since in cache there are still possibly other assembly-commands stored, which are not shown correctly inside CCS?
This means I need to invalidate the cache, which of course will need a call to the registers of the AM24.
Thanks so far! I will have a look at the TRM and try to invalidate the cache and see what happens and keep this thread updated.
Hi Felix,
This thread came back to me again. I am on vacation. I will get back to you later today or tomorrow. Thanks!
Ming
Hi Felix,
I agree with George's assessment. I think it is cause by the cache. Can you put the memory section for the copy-to area in non-cached area? Can you share the linker.cmd and the example.syscfg file with us, so that we can help to identify where the problem might be?
Thanks!
Ming
Hey Ming,
I tried it and yes it works. I get no more abort.
Since we want the region where it is copied in to be cached, is it possible to invalidate the caches?
Hi Felix,
It depends on how do you load the code into memory.
1. If you use the SBL to do the loading, then after the SBL loaded the application image into the memory before it branch to the entry point of the application code, you can add the cache invalidate operation for the cached memory sections.
2. If you use the CCS to load the application image, then you may have to do the cache invalidate in the CCS with memory browser.
Best regards,
Ming
Since we want the region where it is copied in to be cached, is it possible to invalidate the caches?
While for a different ARM Cortex-R5 based device, TMS570LC4357: Moving a function to RAM has some code about cleaning the cache (does a clean rather than invalidate to ensure any modified data in the cache is written to memory).
My suggestion would be to use dsb and isb instructions after your copy is complete.
Hey Ming, so I tried to invalidate the cache as follows:
copy_in(&TESTCODESIG); CacheP_inv(reinterpret_cast<void*>(TESTCODESIG.recs[0].run_addr), TESTCODESIG.recs[0].size, CacheP_TYPE_ALLP);
Am I doing something wrong here?
Hi Felix,
As mentioned by Chester, the memory copy (from Flash to Memory) also need to be flushed. You may want to use the CacheP_wbInv(), instead of CacheP_inv().
Best regards,
Ming