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.

ROM_SysCtlPeripheralEnable works from main(), but not from a library call

I am developing an application and a library of an LM4F232H5QD using CCS 5.1.  The libary initialized the hardware.  When I call the FLASH versions of the SysCtlPerifheralEnable it works just fine.  I switched to ROM code to save FLASH.  Now that library routine does not work.  I copied the offending ROM_SysCtlPerpheralEnable to my main function and it works fine.  I then stepped through the assembly to see what is happening and I find:

768 ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
00000d7e: 484D LDR R0, $C$CON34 R0 <- 01000044
00000d80: 6800 LDR R0, [R0] R0 <- 01000890
00000d82: 6981 LDR R1, [R0, #0x18] R1 <- 01004754 R1 holds jump to address
00000d84: 484C LDR R0, $C$CON35 R0 <- 20000001 (SYSCTL_PERIPH_GPIOA), So R0 holds argument
00000d86: 4788 BLX R1 Jumps to 1004754

75 ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
00002528: 487E LDR R0, $C$CON2 R0 <- 21C06800
0000252a: 6800 LDR R0, [R0] R0 <- 6800487E
0000252c: 6981 LDR R1, [R0, #0x18] < debug hangs, suspect we ar trying to read memory location 6800487E, which is out of range
0000252e: 487F LDR R0, $C$CON4
00002530: 4788 BLX R1

The compile command for both is (some newlines for readability):
'Building file: C:/Data/Code/TEC2402/Monitor2402/trunk/Monitor2402.c'
'Invoking: TMS470 Compiler'
"C:/ti/ccsv5/tools/compiler/tms470/bin/cl470" -mv7M4 --code_state=16
--float_support=FPv4SPD16 --abi=eabi -me -g
--include_path="C:/ti/ccsv5/tools/compiler/tms470/include"
--include_path="C:/StellarisWare"
--include_path="C:/Data/Code/LM4FCommon/CommonLib/trunk"
--define=DEBUG --define=css --define=PART_LM4F232H5QD --define=TARGET_IS_BLIZZARD_RA1 --diag_warning=225
--display_error_number
--use_dead_funcs_list=C:\Data\Code\TEC2402\CCS5_WorkSpace\Monitor2402\Debug-Monitor\dead_funcs.xml
--preproc_with_compile --preproc_dependency="Monitor2402.pp"
"C:/Data/Code/TEC2402/Monitor2402/trunk/Monitor2402.c"
'Finished building: C:/Data/Code/TEC2402/Monitor2402/trunk/Monitor2402.c'
 
Any idea on why it appears the linker is not getting the references correct?  Linker command is:

"C:/ti/ccsv5/tools/compiler/tms470/bin/cl470" -mv7M4 --code_state=16 --float_support=FPv4SPD16 --abi=eabi -me -g --define=DEBUG --define=css --define=PART_LM4F232H5QD --define=TARGET_IS_BLIZZARD_RA1 --diag_warning=225 --display_error_number --use_dead_funcs_list=C:\Data\Code\TEC2402\CCS5_WorkSpace\Monitor2402\Debug-Monitor\dead_funcs.xml -z --stack_size=2048 -m"Monitor2402.map" --heap_size=0 -i"C:/ti/ccsv5/tools/compiler/tms470/lib" -i"C:/ti/ccsv5/tools/compiler/tms470/include" --reread_libs --warn_sections --generate_dead_funcs_list=dead_funcs.xml --rom_model --unused_section_elimination=on -o "Monitor2402.out" "./startup_ccs.obj" "./Monitor2402.obj" -l"libc.a" -l"C:\StellarisWare\driverlib\ccs-cm4f\Debug\driverlib-cm4f.lib" -l"C:\Data\Code\TEC2402\CommonLib2402\trunk\ccs\Debug-Monitor\CommonLib2402.lib" -l"C:\Data\Code\LM4FCommon\CommonLib\trunk\ccs\Debug-Monitor\CommonLib.lib" "../lm4f232h5qd.cmd"

 I produced listing files for these to modules.  If you go an find the definitions of $C$CON2, etc and then interpret the code it should work.  But it looks like during link
the definition of $C$CON2 gets linked to the definition in the main.c module, which is different.  So you get a bad address loaded for the LDR instruction.
 
This seems to be a linker/compiler issue, so I will post this on the compiler forum as well.
  • I tried creating a very simple test case based on the LM4F242 kit, using the "hello" example.  I simply created/added a new library project with a single file/api that just calls the ROM function that you were calling.  It worked exactly as I would expect it to.  I am running version 5.2 of CCS (recenly released) along with version 4.9.5 of the TMS470 compiler tools, which is different than what you reported, but I would not expect that to make any differences.

    If you can create a simple workspace/project that illustrates the issue that you have been seeing, zip it up, and post it here, I can take a look at the details to see what might be happening.

    --Bobby

  • Thanks for the very fast reply.  I also created a UART only version of the stock hello project, then created a library that called one the ROM_function in question.  It worked.  I will study the differences between the compile and link commands and see if there is a difference.

  • I got it working.  I am not sure what changes were necessary, but the ones I made were:

    On the main project:

    Turn on -gcc, --O2 and --ual, turn off a precompile symbol 'DEBUG' which I have no idea what it was there

    On library project turn off (many of these were hacks I was trying when your suggestion came in to try a blank project)

    --gen_func_subsections=on --call_assumptions=1 --asm_listing --output_all_syms

    Any idea which option started things working?  I am betting -O2?  But I am calling it a day.

  • If I had to guess, I would say that removing the --call_assumptions=1 have also had some impact.  From a brief look at the documentation for this option, the "=1" option indicats that the module has no functions that are called from outside.  Also, gen_func_subsections may have altered how the functions that were referencing the ROM calls accessed literal pool data.

    If you post this over in the Development Tools forum, in the Compiler section, they may be able to provide you with a more detailed explanation.

    --Bobby

  • John Osen said:

    I got it working.  I am not sure what changes were necessary, but the ones I made were:

    On the main project:

    Turn on -gcc, --O2 and --ual, turn off a precompile symbol 'DEBUG' which I have no idea what it was there

    On library project turn off (many of these were hacks I was trying when your suggestion came in to try a blank project)

    --gen_func_subsections=on --call_assumptions=1 --asm_listing --output_all_syms

    Any idea which option started things working?  I am betting -O2?  But I am calling it a day.

     

    Let me retract that "I got it working".  It was late in the day and I had also just moved back to the library rather than ROM functions to prove to myself the code still worked.  After I put the ROM_* functions back in, the behavior is still broken - getting bad address into the library calls.

  • I did post yesterday, but have not had a reply.  I am trying now to whittle my project down to the failing lines but not much else.  This way I may be able to send the projects to TI for an inspection.

  • I am still wresting the problem.  I have reduced my project to about 8 lines of code.  3 lines in the library - all calls to StellarisWare functions.  And 5 lines in the main function:  A call to the offending function (to prove that it works in main()), a call to the library function and then a forever loop.

    Perhaps this a "read one of the many other manuals" issue.  I am running at 80MHz.  I was calling the function:

    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    I read the ROM user guide and I see the quote:

    The system clock divider is chosen with one of the following values: SYSCTL_SYSDIV_1,SYSCTL_SYSDIV_2, SYSCTL_SYSDIV_3, ... SYSCTL_SYSDIV_64

    As it does not mention SYSCTL_SYSDIV_2_5, should I assume that it is unsupported and that I just requested something the ROM routine can not handle?

    When I set the clock this way in the hello program, the FW goes out to lunch.

  • I have changed something that makes my original code work - but for unknown reasons. 

    The offending line was not the one I was studying, but the one directly before it that set the clock speed.  The ROM version messes something up.  I have restored my original code and just call the library version of SysCtlClockSet with the 2_5 argument.  That seems to work. 

  • My apologies for not picking up on this detail before.  In the errata document for the device, section 4.2, there is an issue with fractional dividers in the ROM API call.  The workaround is exactly what you have done ... use the latest version of the StellarisWare driver API.

    --Bobby