By
This material refers to Code Composer Version 3.04 and might be somewhat outdated, but the compiler caveats could still be worth a look.
The development environment Code Composer (CC, Version 3.04) is a great tool, but it has a few annoying quirks.
Texas Instruments' Compiler 5.0 for TMS320C3x/4x produces code that
comes close to hand-coded assembler. I discovered some strange
features I considered bugs at first, but these all turned up to be the
result of aggressive, yet correct, optimization, and my lack of respect
for volatiles.
This page summarizes some things I found out when developing an ultrasound environment simulator with a tandem TMS320C4X.
Every time I invoke an incremental build, a full build is done, even if I changed only one module.
Check Project/Show Dependencies for a file name displayed red, i.e. reported missing. Whenever there is such a file, a full build will always be done. But why is a file reported missing, yet the project compiles without errors? Assume you have a header file that is shared between a Windows project and DSP project, and it includes a file that only makes sense for Windows.
#ifdef WINDOWS #include <checks.h> #endif
Checks.h is not on your DSP-path, because it should not be used anyway. Code Composer's dependency parser is a bit simple-minded and does not see the #ifdef, so it reports the file missing.
Workaround: Put a
dummy file checks.h into your DSP path. Don't forget to
add at least a comment blaming CC, people in future programming
generations may not understands CC's subtleties.
A project build
needs 3 minutes in Win95. On the same computer under Windows 2000, it
crosses the line after 50 seconds.
This is a problem
GO-DSP refuses to acknowledge, so it may be caused by my installation.
Using Wintop, I found out that under Win95 CC_app always takes about
85% CPU time when the compiler is running; under Windows 2000, the same value is
below 5%. It looks like the GUI never releases the time slice to let
the compiler do the C-crunching. I also noticed that the 16-bit
auxiliary program Ccvhrl3.exe is loaded under Win95, and not the
32-bit version cvrlh32.exe as under Win2k.
Workaround: use
Windows 2000 or XP, it's anyway more fun. Or tell me how you did it under Win95.
I am confused by
the many compiler options (SET=) and special paths I have to set in my
autoexec.bat file or NT-like-environment when installing the Texas
C-compiler.
Not a workaround,
a solution: remove all SET/PATH statements needed for Code Composer,
the compiler, assembler and for special library files of your board.
Instead, define all options in Code Composer. Options not supported by
checkboxes may be added manually into the edit field, CC is kind or
clever enough to keep entries it has not created itself. (see next
paragraph for an exception). Feel relieved when you project first
compiles error-free in an unpolluted environment.
The function fabs gives an incorrect results when used with an integer argument.
Do you still rely on implicit conversion rules? I know, these things work in Borland and MS-compilers. Or at least, they give decent warning. Ooops ... maybe the function is right after all and you did not see the warning? Exactly: CC does not allow checkbox selection of the most important warning category, i.e. undeclared functions. And it hides quite a few intrinsic functions headers in <intrin.h>, where you won't expect it after so many ANSI-years.
Not a workaround, THIS IS AN ORDER
: Use the warning
level -pw2 that reports undeclared functions. I believe this option
has been added in compiler version 5.0. It is not supported in CC
3.04, but as other levels of -pw are supported, adding it
manually in the compiler options confuses CC. So, despite what I said
above about unpolluted environments, I have added this life-saver as
the only option to my environment on startup.
SET C_OPTION=-pw2
Under Win2k, use Control Panel/System/Environment instead to add the option.
After recompiling, you will probably have to add a few
#include <intrin.h>to your code, and possibly a
few more missing headers will turn up. And, all of a sudden, some
other unwanted features of your program disappear miraculously.
For TMS-C is an aggressively optimizing compiler...don't be caught
volatile.
My code runs
nicely in debug optimization, but plays by its own rules when
optimized.
Well, if you have
done embedded C-programming all your life, skip this. Windows programmers, like me,
got used to never touch anything dangerous such as port addresses, by
penalty of Dr. Watson or blue-screen. For all those: make sure to
check your volatiles with embedded systems. When optimizing,
Texas-C is really aggressive and removes all code accessing memory
locations it believes full under its own control. If you get strange
effects with optimization, try to add volatile to suspect
variables.
Maybe you have written clever code that accesses contiguous external registers through structs; this approach gives highly efficient code, as addresses can be read and written with small offsets from a common base address in a register. In this case, make sure that you added the volatile to the struct-member that can be modified by the processor, e.g. read-only flags in DMA control.
If you occasionally are in masochistic moods: Try good old lint, e.g. Gimpel's PC-lint, or more recent splint, with the supplied settings for the TMS-compiler. It caught all my volatile-violations, hidden among 723 other violations, mostly in third-party code. After I had corrected 722 of them (I always leave one behind, so that the Gods won't be jealous, according Feynman Volume III, Quantum Mechanics, last page), my program worked. And I felt like Easter and Christmas falling on the same day, as we say in Germany.
After I introduced some conversions to IEEE-floats, some results were strange.
TMS can't
handle IEEE-floats, so make sure once you converted to IEEE, you
don't do any numerics with these. While you probably won't do
it explicitly also check if some implicit conversion jump in. You may
have to look at the generated assembler to make sure that the
IEEE's aren't doubly converted to float or from float by
compiler confusion.
Sure, you can
debug Assembler with C4X, only Code Composer won't let you do it
easily.
This is what the help file says:
Enable Source Level Debugging (-g):
(Available with TI assembler version 6.63 & higher for C2XX/C5X
DSPs only) This option must be enabled to generate symbolic
information for assembly source files. If this options is not
selected, Code Composer will not be able to display Assembly-source
when debugging
Because GO-DSP
believes in this limitation, there is no checkbox for option -g with a
C4X installed. However, you can add the switch -g manually in the edit
field under Options/Assembler, to allow single-stepping through
assembler source code. It works reasonably for macros, but fails with
included assembler files (.include echo98.asm). Here is what Steve
White of GO-DSP replied when I reported this:
Dieter,
I apologize for any inconvenience this may have caused. We will try to
reproduce your results here and see if we are successful. We
appreciate the below information as it may be that you have discovered
something previously unknown by both TI and GO DSP.
Best Regards,
Steve White (GO-DSP)
No problem, Steve, if only things like this would turn up in your FAQ at some time.
printf (via
JTAG) does not work.
Make sure that
"Make global symbols static" on the linker page is NOT
checked. Code Composer peeks at the symbols on loading and only opens
the output page for printf and friends if it sees one of these
functions.
Don't use
explicit output path's for executables or intermediate assembler
files.
Don't use
non-default names for object output (e.g. o30 or o40).
This an annoying
bug in Code Composer 3.04 and earlier that should have been corrected
in a maintenance release. Whatever you try to do to keep your files
nicely separated, there comes the point where CC does not find these
in a following step, e.g. when auto-loading the program. I don't
recall the details, since I gave up in an early phase. GO-DSP, this
feature has not been tested carefully.
In a
multiprocessor configuration, symbols with same name #define'd in
different GEL files conflict.
In a system with
two processors and two project, I had two GEL Files
/* FILT98.GEL Project Filt98, secondary Processor on TIM 44 */
#define Program "C:\\ECHO\\bin\\Filt98.out"
StartUp()
{
GEL_Load(Program);
}
/* ECHO98.GEL Project Echo98, Main Processor */
#define Program "C:\\ECHO\\bin\\Echo98.out"
StartUp()
{
GEL_Load(Program);
}
This does not work, and the error message is so confusing I needed some time to track down the source. CC seems to combine the two GEL-files, and believes that Program is defined twice. You must make #define's unique even in separate GELs used together, e.g.
#define FProgram "C:\\ECHO\\bin\\Filt98.out" #define EProgram "C:\\ECHO\\bin\\Echo98.out"

Dr. Dieter Menne
07071 52176