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.

Compiler/TM4C123FH6PM: Placing a library in special FLASH section

Part Number: TM4C123FH6PM


Tool/software: TI C/C++ Compiler

Hello!

Developing custom boot loader for our project I need to place it's code to special place in FLASH, so it will not erase itself and configuration data during firmware update. This bootloader uses usblib and custom update protocol, so I need to place usblib and usb driver from driverlib also in this section.

The problem is when I write a linker command file as this:

	.bootu: {
		--library=usblib.lib(.text)
		--library=driverlib.lib<usb.obj>(.text)
	}			> BOOT
	.bootc: {
		--library=usblib.lib(.const)
	}			> BOOT

in SECTIONS block, meaning BOOT is a special memory region, I got a hardware fault during USB device initialization, and debugging this point I see the relocations for const data is not correct, i.e. I see

g_ppCDCSerConfigDescriptors has address 0x0032b70, but on the line 

psInst->sDevInfo.ppsConfigDescriptors = g_ppCDCSerConfigDescriptors;

I see the variable loaded with incorrect address of 0x002CA50, as if the const variable still resided in .const section, not in .bootc.

.map file shows correct locations for these consts:

.bootc     0    00032a68    00000110     
                  00032a68    00000034     usblib.lib : usbdenum.obj (.const:g_psUSBDStdRequests)
                  00032a9c    00000030                : usbdcdc.obj (.const:g_sCDCHandlers)
                  00032acc    00000023                : usbdcdc.obj (.const:.string:g_pui8CDCSerCommInterface)
                  00032aef    00000017                : usbdcdc.obj (.const:.string:g_pui8CDCSerDataInterface)
                  00032b06    00000017                : usbdcdc.obj (.const:.string:g_pui8CDCSerDataInterfaceHS)
                  00032b1d    00000003     --HOLE-- [fill = 0]
                  00032b20    00000008                : usbdcdc.obj (.const:g_sCDCCompSerConfigHeader)
                  00032b28    00000008                : usbdcdc.obj (.const:g_sCDCCompSerConfigHeaderHS)
                  00032b30    00000008                : usbdcdc.obj (.const:g_sCDCSerCommInterfaceSection)
                  00032b38    00000008                : usbdcdc.obj (.const:g_sCDCSerConfigHeader)
                  00032b40    00000008                : usbdcdc.obj (.const:g_sCDCSerConfigHeaderHS)
                  00032b48    00000008                : usbdcdc.obj (.const:g_sCDCSerConfigSection)
                  00032b50    00000008                : usbdcdc.obj (.const:g_sCDCSerDataInterfaceSection)
                  00032b58    00000008                : usbdcdc.obj (.const:g_sCDCSerDataInterfaceSectionHS)
                  00032b60    00000008                : usbdcdc.obj (.const:g_sIADSerConfigSection)
                  00032b68    00000004                : usbdcdc.obj (.const:g_pCDCCompSerConfigDescriptors)
                  00032b6c    00000004                : usbdcdc.obj (.const:g_pCDCCompSerConfigDescriptorsHS)
                  00032b70    00000004                : usbdcdc.obj (.const:g_ppCDCSerConfigDescriptors)
                  00032b74    00000004                : usbdcdc.obj (.const:g_ppCDCSerConfigDescriptorsHS)

What am I doing wrong?

  • Because I can't see everything, I'm not sure my proposed solution is correct.  But I'm confident enough to ask you to try it.

    This source line ...

    Oleg Kobrin said:
    psInst->sDevInfo.ppsConfigDescriptors = g_ppCDCSerConfigDescriptors;

    copies the contents of the variable on the right side of the assignment.  It is likely the memory location 0x32b70 contains the value 0x2CA50.  You probably want the address instead.  If that is the case, then you need to write ...

    psInst->sDevInfo.ppsConfigDescriptors = &g_ppCDCSerConfigDescriptors;

    Note the addition of the ampersand character &.

    Thanks and regards,

    -George

  • It is not my code, it is code inside TivaWare usblib, and it is working.

    When I comment these lines in linker command file, everething is working ok.

  • Experimenting with this issue I see that ANY relocation of either .text or .const of usblib to another section causes the unpredictable behavior and hard fault in different places.

    Tool chain is 16.6.0.STS

  • Please ignore everything in my previous post.

    I want to go back to this part of your first post ...

    Oleg Kobrin said:

    g_ppCDCSerConfigDescriptors has address 0x0032b70, but on the line 

    1
    psInst->sDevInfo.ppsConfigDescriptors = g_ppCDCSerConfigDescriptors;

    I see the variable loaded with incorrect address of 0x002CA50, as if the const variable still resided in .const section, not in .bootc.

    The changes in the linker command file only control the location of g_ppCDCSerConfigDescriptorsThey do not affect the contents at that memory location.  Since this is a const variable, the contents are controlled by the initialization.  You don't show how it is initialized.  It seems likely that, once the initialization is taken into account, it is correct for g_ppCDCSerConfigDescriptors to have contents of 0x2CA50.

    Please check on that initialization and report back.  If it is confusing, please show the code which initializes g_ppCDCSerConfigDescriptors.

    Thanks and regards,

    -George

  • People! Are you serious?

    This is the lines from RELEASED and WORKING TivaWare usblib!

    So this library is perfectly working when it is linked in the conventional way, but when I'm trying to move it to the different memory area it is not working at all, causing hard faults.

    So the question is: WHY the prebuild library usblib from TivaWare cause faults when it is moved to different location in memory? WHY the addresses of constants is not loaded correctly?

    And latest field tests shows that even if const section is in it usual place, the code relocations causes some B's to direct code to go to inproper place as it's relocation was loaded improperly, so I got hard faults about code execution from nonexistant memory areas.

  • Oleg Kobrin said:
    This is the lines from RELEASED and WORKING TivaWare usblib!

    It is likely this library presumes certain constraints regarding where the code and data reside in memory.  Those constraints are met, or broken, in the linker command file.  My expertise is in the compiler tools, including the linker.  So, I am trying to help you understand how your changes in the linker command file have affected the placement of the code and data.  I do not have any expertise in any TI software package, such as the TivaWare usblib.  Thus, I cannot tell you whether you have broken its constraints on memory placement.  

    At this point, it seems that expertise is what is needed most.  Therefore, I will notify those experts of this thread.

    Thanks and regards,

    -George

  • Hi Oleg,

    We are not aware of any special allocation requirements on the usblib.lib routines. Did you get the fault after the "application" section of your code was erased? I am wondering if there were some additional sections that need to be moved to your protected area. Can you attach your original (working) .map file and the .map file of the code with the modified link command file you your next reply?

  • No, I get hard fault during USBCDCInit() execution. It is happening just even when my boot loader is not yet initialized - as it is initialized by special command form protocol. So I just moved usblib to different memory location and it causes hard fault during initialization.

    I have one suspection. Some libraries in my project (i.e. kernel) are build with Release settings, but other are build with Debug one. I tryed to build usblib with Release, the behaviour is changed (i.e. I see correct addresses for const's), but later I get jump to nonexistent memory area and hard fault. 

    Sudenly, I get hard flu now and cannot go to office to continue research, but I am collecting data. 

    How do youy think, if I change all components of my project to the same optimization settings, whould it help?

  • Hi Oleg,

    Sorry to hear you are not well. Get well soon.

    I don't think different optimization settings are the root cause, as the USBLIB has been used in other projects with and without optimization. When you feel better and are back at work, please send the map files and we can continue to help debug this issue.

  • Here is the map file for usblib placed in default location and working well:

    JC2_HPLC.map.txt

    And this map file for usblib moved to other flash area and causing hard faults:

    JC2_HPLC.map.2.txt

  • I took the example "usb_dev_serial" and modified the link command file to put the usblib.lib(.text and .const) and the usb.obj (.text) sections in the 0x30000 to 0x3F000 space. That program ran with no issues. There is no inherent problem in moving these sections of code. Your issue must be tied more closely to your code. I have attached my project in a .zip file. You can use the Code Composer "File" -> "Import" feature to add this project to your workspace.

    /cfs-file/__key/communityserver-discussions-components-files/81/usb_5F00_dev_5F00_serial2.zip

  • So, I do completely the same, and it does not work. 

    The differencies are:

    1. I use mixed C/C++ code.

    2. I use mixed Debug and Release libraries.

  • From your map files, you have a large and complex application with what looks like many assembly functions from custom libraries. What I can say for sure is that it is not inherently a problem to relocate the usb library to the upper part of flash. I see two approaches to debugging this. One would be to simplify your code and check if you still have the problem after eliminating some functionality. I suspect that might be difficult for this complex application. The other is to dig deeper into the assembly language as to why the wrong value was loaded for the address of g_ppCDCSerConfigDescriptors.