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.
I am having trouble building a DSP image to run DSP code from flash. The boot order we are using is a small AIS script that only sets the PINMUX Registers and jumps to ARM code, a small ARM boot code that remains in supervisor mode to wake the DSP, and an initial DSP hardware setup program that turns everything on. Memory space and power consumption are not an issue for us.
The ARM boot, DSP hardware initialization, and a secondary DSP application are all built as separate images using the settings following. The initial jump from AIS to ARM to DSP hardware initialization works fine. I can also see the jump from the DSP initialization to the DSP application. If the application is simple enough, it loads from flash and works. If there are global or static variables, it seems that the code does not work. I am having trouble tracing exactly where the problem occurs.
We are using a simple assembly jump instruction to get to the rest of the DSP application code. The problem comes with the initialization that is created by the compile and link process.
Build environment:
Code Composer Studio v 5.1.0.09000
ARM Compiler/Linker: TMS470 - TI v4.9.1
DSP Compiler/Linker: C6000 - TI v7.3.1
Output format for all projects: eabi (ELF)
I have built the image independently on the command line using the included "build.bat" file, as well as the project build feature in the CCS IDE with the following post build steps.
"${CG_TOOL_ROOT}/bin/hex470.exe" -b -o "${BuildArtifactFileBaseName}.bin" "${BuildArtifactFileName}"
"${CG_TOOL_ROOT}/bin/hex6x.exe" -b -o "${BuildArtifactFileBaseName}.bin" "${BuildArtifactFileName}"
COMPILE COMMAND FORMAT: "C:/ti/ccsv5/tools/compiler/c6000/bin/cl6x" -mv6740 -g --include_path="C:/ti/ccsv5/tools/compiler/c6000/include" --display_error_number --diag_warning=225 --abi=eabi --preproc_with_compile --preproc_dependency="wdt.pp" "../wdt.c"
LINK COMMAND: "C:/ti/ccsv5/tools/compiler/c6000/bin/cl6x" -mv6740 -g --display_error_number --diag_warning=225 --abi=eabi -z -m"DSP.map" --warn_sections -i"C:/ti/ccsv5/tools/compiler/c6000/lib" -i"C:/ti/ccsv5/tools/compiler/c6000/include" --reread_libs --rom_model -o "DSP.out" "./wdt.obj" "./timer.obj" "./led.obj" "./gpio.obj" "./DSP_LED_wdt_manual_blink.obj" "./DSP_LED_wdt_blink.obj" "./DSP_LED_blink.obj" -l"libc.a" "../DSP_linker.cmd"
3513.DspConstInitializationProblem.zip
The sample code is designed to service a hardware watch dog timer (WDT) through a GPIO pin. We have a breakout board that brings all of the signals for our OMAP out of the board and provides power. It has a toggle switch that disables the WDT for debugging. If I load the code in RAM using the CCS interface, it runs correctly. If I build the code to run in flash memory, it does not.
What is Code Composer doing that I am missing? I thought that the global variables were initialized by the auto_initialization sequence, since I can see the .neardata and .fardata copy tables in the map file. The ".const" section is the only addition to the output text from hex6x.exe. ".const" is listed as an automatically generated section in the Hex Conversion Utility Description section (11.5) of the TMS320C6000 Assembly Language Tools v7.3 (spru186V).
The gpio code uses three "static const" variables, two with function scope, and one with file scope. If I compile the files as they are, the GPIO functions do not work. The system will run the lights until I enable the WDT, at which point it fails to service it and is reset. If I simply take away the "const" modifier from the "bit_mask" function scope "static const" variable, the system seems to work fine, toggling the lights even while the WDT is enabled. That is with the file scope "static const" and the function scope "static const *" variables left with their "const" keywords.
How do I initialize these function scope constant variables?
Do I need to write a loader function for the generated .const section if we have function level "const"?
Is there any way to avoid moving all function level "const" to the file scope? We are trying to follow MISRA2004, and it prefers we place variables used in only one function into the function they are used in.
Also, this is minor compared to the other questions, and may even be a code composer question, but why are the map files different when I build in CCS and run the batch file? The files are the same byte size and their functionality from flash is the same, but the symbol placement is different for the two binary files.
I realize the code is not optimized or cleaned, but we are collaborating and this is the basic format of what we will use. I would greatly appreciate it if someone could please help explain what else I have to put into the linker file (or which boot/init functions to call) to properly use this code from within flash memory.
Kaitlyn Opperman said:If I load the code in RAM using the CCS interface, it runs correctly. If I build the code to run in flash memory, it does not.
What is Code Composer doing that I am missing? I thought that the global variables were initialized by the auto_initialization sequence, since I can see the .neardata and .fardata copy tables in the map file.
There are a lot of questions in your post, and unfortunately I don't have a direct answer for any of them. I can tell you that .const is not subject to boot-time auto-initialization; the .const section is not represented at all in the .cinit records. It is the responsibility of the program loader (e.g. CCS) to copy .const sections to target memory before the bootstrap routine begins. When you say you build the code to run in flash memory, what entity is responsible for making sure that .const ends up where it's supposed to be? Did you give .const a different load and run address (this would be unusual for a .const section)?
I recommend you read the sections titled System Initialization and Sections in the C6000 compiler book. You may also find some of the suggestions in this thread useful.
Thanks and regards,
-George
Archaeologist said:
I can tell you that .const is not subject to boot-time auto-initialization; the .const section is not represented at all in the .cinit records. It is the responsibility of the program loader (e.g. CCS) to copy .const sections to target memory before the bootstrap routine begins.
Archaeologist said:
When you say you build the code to run in flash memory, what entity is responsible for making sure that .const ends up where it's supposed to be? Did you give .const a different load and run address (this would be unusual for a .const section)?
At the moment, no entity performs this copying/initializing feature. This must be where my problem is. I am trying to figure out what steps we will need to run ourselves, and what the TI library and compiler tools provide for us. For example, the linker provides RLE compression by default, but TI functions to decompress are included automatically. We are currently trying to run part of our code from flash, so we plan to load only some sections at a time. It is this actual load process that I am struggling with. I tried a boot table before, but had little success understanding the steps.
As an update to the boot tables, attached are the new project files that do not work.
If I make a boot table of just the .const section, and I use the -b option for a binary dump, is this supposed to produce anything useful?
I am assuming the boot table instructions are something that can be interpreted by the DSP at any time, so if I jump to the start of the table after hardware initialization, it should initialize my constant variables in RAM and then jump to the application code. How do I actually accomplish this? If I use the attached files, I end up with a program that gets to the point of cycling the LEDs, but still times out, suggesting the initialization still fails.
I tried with both memwidth and romwidth set to 16, but that did not work. I am unclear how to load the images if I use a memwidth of 32. The two images created have a nice diagram of how they have split the data (Figure 11-4, spru186v) but do not mention how to store these images. I need both to run to create the .const section in RAM. Do I have to write a loader for the tables? If not, and if TI tools do this, how should they be stored in memory?
I notice the "Binary format" I had from the -b option is now "Generic format" so that doesn't seem like instructions were created. The map file produced also uses a width of 8, not the 16 I thought I specified.
I'm sorry, I don't have any experience with creating boot tables.
Kaitlyn Opperman said:I was confused by the statements in section 7.8 of spru187 that the _c_int00 function "Performs C autoinitialization of global/static variables" and "initializes global variables..." in that I though this covered regular initialization as well.
The RTS (run-time support library) autoinitialization function only initializes those global variables which are non-const.
Kaitlyn Opperman said:Am I now correct in thinking that CCS will copy the .const section to the appropriate location as part of its debug load setup
If you mean you are using CCS only to load the debugging symbols, and not the program image, then no, loading the debugging symbols won't cause .const to be loaded.
You've said .const has different load and run addresses. Are you sure that's what you want? It's unusual to want to move .const data at run-time; the program should be able to read it from any place in memory. Assuming you do mean to do that, the compiler will not automatically insert any code to move code or data which has different run or load addresses; you must arrange to create the copy table and call the appropriate function at run time, or use some other method to move it. You may want to look at http://focus.ti.com/lit/an/spra999a/spra999a.pdf, which talks about bootloading on C6000 devices.
Kaitlyn Opperman said:At the moment, no entity performs this copying/initializing feature.
Let's be sure we're talking about the same problem: Is there an image of your .const section somewhere in target memory?
Thank you for the help so far. The image of the .const section will reside in the same memory as the code in the end. I was working with simple debug code to see which sections could be placed where, and how much initialization was done by library functions. I had put the .const into RAM to see if it could be moved there by the basic compile options. Apparently it cannot, so I will try to modify or mimic the auto-initialization and copy table library functions.
While this is just a demo, the goal is a chain of boot programs. When the DSP loader code runs, it is supposed to allow other images to be programmed to flash when load is selected, and continue after loading to run from a fixed location. I will need to move the DSP loader program from flash to RAM before running, since loading our flash memory involves flash returning status information at any address during a write (which makes it hard to read instructions). I realize the AIS script is designed for such moves of images, but we are trying to avoid the AIS code having to know about the size of anything else so we can have an independent fixed image. We want each of the DSP code modules to be as independent as possible.
For example, the hardware set up code should be able to be called, run through, and jump to the next starting location. If setup does not see the load indication, it should jump past the loader to the application code. Otherwise setup should jump to the start of the loader without worrying about how much to copy first. This allows up to rebuild only the loader image if the design changes, while the hardware setup can remain the same.
Having a separate load and run address of the .const section is not really what I want, but only because a copy table is not created. I may be able to force the .const into a copy table, or at least use that functionality to set it up. I would ultimately like to perform a move action similar to how AIS moves an image. This description seems to be closest to the hex conversion boot tables functionality wise, since they are also designed to move a full image. It would be easiest if the output were a binary dump, and not ascii, to be able to load the image directly, but the famously undocumented "-b" hex6x option (for creating the common version of a binary dump of machine instructions) does not appear to be working in this case, as the output text does not state the created image is "Binary" but "Generic".
I think we compiler experts have helped you as much as we are able. Your best option is to take this discussion to the forum for your device. Please tell me exactly which device you are using, and I can move this thread to the forum for that device. Or, you are welcome to find the device forum on your own.
Thanks and regards,
-George
I think my original question was answered, so thank you both. I can search other threads for my new questions on boot images and copy tables. Is there specifically a hex6x forum? My device is the OMAP-L138 (not an EVM), but I am working with the DSP side C6-Integra C6748.