Program Development Tools: Code Composer Studio
Program Development Tools: Code Composer Studio
Program Development Tools: Code Composer Studio
Introduction
The objective of this module is to understand the basic functions of the Code Composer
Studio Integrated Design Environment (IDE) for the C2000 Family of Texas Instruments
Digital Signal Processors and Microcontrollers. This involves understanding the basic
structure of a project in C and Assembler coded source files, along with the basic operation
of the C - Compiler, Assembler and Linker.
Productive Editor:
Structure Expansion
Module Topics
eZdsp™
Asm Link Debug
Emulator
Editor Libraries Graphs,
(XDS100)
Profiling
MCU
Board
• Code Composer Studio includes:
– Integrated Edit/Debug Graphical User Interface
– Code Generation Tools
– Real – Time Operating System (DSP/BIOS)
3-3
You can use Code Composer Studio with a Simulator (running on the Host - PC) or you can
connect a microcontroller system and test the software on a real “target”. For this tutorial, we
will rely on the Peripheral Explorer Board and the TMS320F28335 Control Card as our
“target”. Here the word “target” means the physical processor we are using, in this case a
TMS320F28335.
The next slides will show you some basic features of Code Composer Studio and the
hardware setup for lab exercises that follow.
3-4
3-5
3-6
3-7
3-8
3-9
3 - 10
To be able to practice with all the peripheral units of the Digital Signal Controller and some
‘real’ process hardware, the Peripheral Explorer Board provides:
• 1 stereo audio codec AIC23B for line -in and headphone -out (connected via McBSP
and SPI)
Once you or your instructor has installed the tools and the correct driver (Setup CCS3.3),
you can start Code Composer Studio by simply clicking on its desktop icon. If you get an
error message, check the USB connection of the target board. If everything goes as expected,
you should see a screen, similar to this:
Project-
tree Workspace
3 - 12
The step-by-step approach for Lab3 will show how to do the following:
• Watch Variables
• Use of Breakpoints
• View registers
Create a project
Note : the project file (“Lab3.pjt”) is a simple ASCII-text file and stores
the set-up and options of the project. This is very useful for a
revision management.
3 - 13
The first task is to create a project. This is quite similar to most of today’s design
environments with one exception: we have to define the correct target, in our case
“TMS320C28xx”. The project itself generates a subdirectory with the same name as the
project. Ask your instructor for the correct location to store your project.
Write C - code
Next, write the source code for your first application. The program from the slide below is
one of the simplest tasks for a processor.
The code example consists of an endless while(1) - loop, which contains a single for - loop -
instruction.
In that for-loop we:
3 - 15
The C - source code file is now stored on the hard disk of the PC but it is not yet part of the
project. Why does Code Composer Studio not add this file to our project automatically?
Answer: If this were an automatic procedure, then all the files that we touch during the
design phase of the project would be added to the project, whether we wanted to or not.
Imagine you open another code file, just to look for a portion of code that you used in the
past; this file would become part of your project.
To add a file to your project, you will have to use an explicit procedure. This is not only
valid for source code files, but also for all other files that we will need to generate the DSP’s
machine code. The following slide explains the next steps for the lab exercise:
C:\CCStudio_v3.3\C2000\cgtools\lib\rts2800_ml.lib
3 - 16
When you have done everything correctly, the build options window should look like this:
C:\tidcs\c28\DSP2833x\v131\DSP2833x_common\cmd\28335_RAM_lnk.cmd
3 - 18
C - Compiler Sections
When we compile our tiny code from Lab3, the C - compiler will generate 4 so-called
“sections”. These sections cover different parts of the object module, which must be “linked”
to physical memory. Our four sections are:
C – Compiler Sections
unsigned int k = 0;
void main(void)
{
unsigned int i; Local vars (.stack)
while(1)
{
for(i=0;i<100;i++) Code (.text)
{
k=i*i;
}
}
}
3 - 19
The linker will connect these sections to physical memory. For this task we pass information
to the linker with the help of “Linker - command - files” (extension *.cmd). But before we
look at the details of this procedure, let us finish the C compiler sections. As you can
probably guess, when we use a slightly more complex program than Lab3, the C compiler
will generate more sections. The following slide will summarize all possible C sections:
Uninitialized Sections
Name Description Link Location
.ebss global and static variables RAM
.stack stack memory area RAM (lower 64K)
.esysmem heap memory for dynamic memory allocation. RAM
Memory
Sections
0x00 0000 M0SARAM
(0x400)
.ebss
0x00 0400 M1SARAM
(0x400)
.stack
.text
3 - 21
Linking
Memory description
How to place Software
Sections into Memory
name.cmd
.map
3 - 22
The procedure of linking connects one or more object files (*.obj) into an output file (*.out).
This output file contains not only the absolute machine code for the DSC, but also
information used to debug, to flash the controller and for more JTAG based tasks. NEVER
take the length of this output file as the length of your code! To extract the usage of
resources we always use the MAP file (*.map).
MEMORY
{
PAGE 0: /* Program Space */
FLASH: org = 0x300000, len = 0x40000
SECTIONS
{
.text: > FLASH PAGE 0
.ebss: > M0SARAM PAGE 1
.cinit: > FLASH PAGE 0
.stack: > M1SARAM PAGE 1
}
3 - 23
Note: Slide 3-23 is the solution for the example from Slide 3-21 and not for lab3!
3 - 24
After Debug Go main, a yellow arrow shows the current position of the Program
Counter (PC). The purpose of register “PC” is to always point the next machine code
instruction to be executed.
yellow arrow:
current position
of PC
3 - 25
When we start to test our first program, there is no hardware activity to be seen. Why not?
Well, our first program does not use any peripheral units of the controller.
To exercise the different start and stop options, go through the steps, shown on the next slide.
Note 2: the yellow arrow is no longer visible, because the F2833x runs at
full speed.
3 - 26
• Monitor the variables of that code snippet and compare the results with your
expectations.
3 - 27
Another useful part of a debug session is the ability to debug the code in larger portions and
to run the program for a few instructions. This can be done using other commands in the
single-step group:
3 - 28
Step Out
3 - 29
When you would like to run the code through a portion of your program that you have
already tested before, a “Breakpoint” is very useful. After the “Run” command, the JTAG
debugger stops automatically when it hits a line that is marked by a breakpoint.
6. Adding a Breakpoint
• Set a Breakpoint :
– Place the Cursor in Lab3.c at line: k = i * i;
– Click right mouse and select ‘Toggle Software Breakpoint’
– the line is marked with a red dot to indicate an active breakpoint.
– Another option to toggle a breakpoint is the “hand” – icon on the top
menu of CCS.
– Or, use a left mouse double click at the grey left hand side of window
“Lab3.c” to toggle the breakpoint.
Remove all
Breakpoints
yellow arrow:
Red dot:
current position
active
of PC
Breakpoint
3 - 31
Reset F2833x:
Debug Reset CPU
Watchdog – Timer:
• active after Reset.
• if not serviced, it will cause another Reset after 4.3
milliseconds.
• normally, watchdog is cleared by “Key”-instructions
• for the first lab, let us disable the watchdog:
GEL Watchdog Disable Watchdog
To switch into Real - Time - Debug, it is good practice to first reset the device. This step
ensures that all previous core and peripheral initialization is cancelled.
We have not discussed so far the internal watchdog unit. This unit is nothing more than a
free running counter. If it is not serviced, it will cause a hardware reset. The purpose of this
unit is to monitor the correct flow of control code. There are two dedicated clear instructions,
which are normally executed from time to time, if the code is still running as expected. If
not, because the code hangs somewhere, the watchdog will bring the device back into a safe
passive state. It operates similar to a “dead man’s handle” in a railway locomotive.
We will discuss and use the watchdog in detail in chapter 5. However, the watchdog is active
after power on, so we cannot neglect it! For now, we can use a CCS GEL - command to
disable the watchdog. We would never do that in a real project!
To use “Real - Time - Debug” perform:
Debug Reset CPU
GEL Watchdog Disable Watchdog
GEL Realtime Emulation Control Run_Realtime_with_Restart
Now the code is running in real-time. The new feature is that we can interact with the device,
while the code is running. To practice this:
• Right click into the Watch Window and enable the option “Continuous Refresh”
The content of the watch window is updated frequently. The JTAG - controller uses cycles,
in which the core of the device does not access the variables to “steal” the information
needed to update the window. This real - time mode is called “Polite”, as you can see in the
lower left corner of CCS.
Watch – Window:
• right mouse click into watch window and select
“Continuous Refresh”.
• The variables k and i are updated in the
background, while the code is running
• The execution speed of the control code is not
delayed by monitoring variables.
• Note: The USB – emulator is too slow to update
the watch window as fast as the F2833x executes
the for-loop. That is why you will not see each
iteration of i and k.
When you are done, you should stop the real - time test by:
Note: the test mode “Run_Realtime_with_Reset” will first perform a reset followed by a
direct start of the device from its reset address. The device will follow its hardware boot se-
quence (see Chapter 15) to begin the code execution. Since the Peripheral Explorer Board
sets the coding pins to “Branch to FLASH” by default, it would start code stored in FLASH.
The problem is, that so far we have not stored anything in FLASH (we will do this in Chap-
ter 14). By using “Run_Realtime_with_Restart”, we force CCS to place the program coun-
ter at the start address of our project in RAM (a function called “c_int00”) and to start from
this position.
The option “Tree View” allows you to inspect details of registers more in detail. At this early
stage of the tutorial it is not important to understand the meaning of all the bit fields and
registers, shown in this window. But you should get the feeling, that with the help of such
windows, you can obtain control information about internal activities of the device.
There are two core registers, ST0 and ST1, which combine all core control switches and
flags of the CPU, such as carry, zero, negative, overflow, sign extension mode, interrupt
enable and so on. An inspection of these flags and bits allows you to immediately monitor
the status of the CPU in a certain spot of code.
The 32-bit registers ACC (“accumulator”), P (“Product”) and XT (“eXtended Temp”) are the
core math registers of the fixed - point arithmetic unit.
The 32-bit registers XAR0 to XAR7 are general purpose registers, often used as pointer
registers or auxiliary registers for temporary results.
The register PC (“Program Counter”) points always the address of the next machine code
instruction in code memory. The register RPC (“return program counter”) stores the return
address of a function, which has called a sub-routine.
9. Memory Window
View Memory
– make sure to inspect data space (bottom centre box)
– enter address &k in the top left corner box:
3 - 35
The bottom left box allows us to specify the display mode of the 16-bit memory locations in
different form, such as:
• Hexadecimal
• Binary
• Float
• Character
The number of memory windows is not limited, you can open as many as you like!
Graphical View
A unique feature of Code Composer Studio (CCS) is the ability to display any region of
memory in a graphical form. This is very helpful for inspection of data, such as sampled
analogue signals. We can display such memory values as raw data on a time - axis or even
better, we can display the samples a frequency axis. In the 2nd option CCS is performing a
FOURIER - transform, before it displays the data.
Let us inspect this graph feature. The BOOT-ROM contains a sine - value lookup table of
512 samples for a unit circle of 360 degree. The data format is 32-bit signed integers in frac-
tional I2Q30 - format. The start address of this table is 0x3FE000.
Open a graph window and enter the properties from the left hand side of Slide 3 - 36:
3 - 36
Optionally, right click into the graph window, select “Properties” and change the display
type from “Single Time” into “FFT Magnitude”:
– You will see two arrows, a yellow one at a C-line and a green one at the
current assembler instruction-line
– “Assembly Single Step” allows to monitor the internal machine code
flow.
3 - 37
Although this test method is not always required, especially not at the beginning of a tutorial,
it allows us to benchmark the efficiency of the C compiler.
Also later, when we have to use assembly optimized libraries and to design time critical
control loops, it will be important to optimize programs. For high speed control loops, for
example in Digital Power Supply, where sometimes the control loop (e.g. sample
measurement values, compute new output values and adjust PWM - outputs) runs at 500 kHz
or even at 1 MHz, we deal with time intervals of 1/1MHz = 1µs. Assuming that the device
runs at 150MHz (= 6.667 Nanoseconds clock period), we can execute just 150 machine code
instructions in such a loop. In such circumstances an option to monitor a code flow on
assembly language level is very helpful.
ASM –
single step Current
C - line
Current
ASM -
Instruction
Note: When you are done with mixed mode, switch the visualization
back to „Source Mode“ (right mouse click).
3 - 38
If you use “Assembly Single Step”, the code is executed machine code line by machine code
line. The green arrow marks the next following assembly line. The yellow arrow remains at
the corresponding C - line, as long as we deal with the assembly results of that line.
When you have finished the mixed mode tests, please switch back to “Source Mode” (right
mouse click).
3 - 39
By default, a start GEL - file is automatically added to a new project by Code Composer
Studio. Expand the “GEL” - directory and open file “F28335.gel”. Since we are still in an
early stage of the classes, please do not change anything inside this file.
We can also add more GEL - Files to a project. To manually add a 2nd GEL - file use:
File Load GEL…
C:\tidcs\C28\DSP2833x\v131\DSP2833x_headers\gel\DSP2833x_Peripheral.gel
This file will extend the options in the “GEL” - menu of CCS by adding a new entry “Watch
DSP2833x Peripheral Structures”. This new entry allows us to extend the Watch - Window
options, which we will use in the following chapters.
Procedure
unsigned int k = 0;
void main (void)
{
unsigned int i;
while(1)
{
for (i = 0; i < 100; i++)
{
k = i * i;
}
}
}
Save this file by clicking File Save as and type in: Lab3.c
• Lab3.c
• C:\CCStudio_v3.3\C2000\cgtools\lib\rts2800_ml.lib
• C:\tidcs\c28\DSP2833x\v131\DSP2833x_common\cmd\28335_RAM_lnk.cmd
Note1: The file “rts2800_ml.lib” is part of the Code Composer Studio environment
and has been stored at the hard disk of your PC during installation time. The file loca-
tion might be different at your computer. If you cannot locate the correct path, ask
your teacher.
Note2: The file “28335_RAM_lnk.cmd” is part of the header file package for the
F28335 (sprc530.zip). If you cannot find that file on your PC, ask your teacher to in-
stall the package for you. The zip-file can be found in the “Software” folder of this
Teaching CD-ROM.
4. Verify that in Project Build Options Linker the Autoinit- Model field is set to:
“Run-time-Autoinitialisation [-c]”
5. Set the stack size to 0x400: Project Build Options Linker Stack Size
Note: The stack memory is used by the compiler to store local variables, parameters
and the processors context in case of hardware interrupts. It is our task to specify a
certain amount of memory for this purpose and 0x400 is sufficient for this lab.
8. Load the output file to the device. Click: File Load Program and choose the output
file “Lab3.out”, which you just generated. Note: the file is stored in the “Debug” sub-
directory in the project folder.
Note: Code Composer can automatically load the output file after a successful build.
To do this by default, click on the menu bar: Option Customize Program Load
Options and select: “Load Program After Build”, then click OK.
Test
9. Reset the DSP by clicking on Debug Reset CPU, followed by Debug Res-
tart
10. Run the program until the first line of your C-code by clicking: Debug Go main.
Verify that in the working area the source code “Lab3.c” is highlighted and that the
yellow arrow for the current Program Counter is placed on the first line of function
“main()”.
13. Verify the note at the bottom left corner of the screen: “DSP Running” to mark a real
time run. Because we are doing nothing with peripherals so far, there is no other visi-
ble activity.
14. Halt the program by clicking: Debug Halt, reset the DSP (Debug Reset CPU,
followed by Debug Restart) and go again until main (Debug Go main)
15. Open the Watch Window to watch your variables. Click: View Watch Window.
Look into the window “Watch locals”. Once you are in “main()”, you should see vari-
able i. Variable k is a global variable. To display this variable we have to add it to the
window ‘Watch 1’. Just enter the name of variable ‘k’ into the first column ‘Name’.
Use line 2 to enter variable i as well. Try changing the value in the “Radix” column.
16. Perform a single-step through your program by clicking: Debug Step Into (or use
function Key F11). Repeat F11 and watch your variables.
17. Place a Breakpoint in the Lab3.c - window at line “k = i * i;”. Do this by placing the
cursor on this line, click right mouse and select: “Toggle Breakpoint”. The line is
marked with a red dot to show an active breakpoint. Perform a real- time run by De-
bug Run (or F5). The program will stop execution when it reaches the active
breakpoint. Remove the breakpoint after this step (click right mouse and “Toggle
Breakpoint”).
18. Now we will exercise with the real-time debug mode. Make sure that all breakpoints
have been deleted or disabled. Next, reset the device:
Debug Reset
This reset will set the device in its default state, including the watchdog unit, which is
enabled after reset. To exercise without this unit, do:
When you are done, stop the real - time mode by:
Note: the test mode “Run_Realtime_with_Reset” will first perform a reset followed
by a direct start of the device from its reset address. The device will follow its hard-
ware boot sequence (see Chapter 15) to begin the code execution. Since the Peripheral
Explorer Board sets the coding pins to “Branch to FLASH” by default, it would start
code stored in FLASH. The problem is, that so far we have not stored anything in
FLASH (we will do this in Chapter 14). By using “Run_Realtime_with_Restart” we
force CCS to place the program counter at the start address of our project in RAM (a
function called “c_int00”) and to start from this position.
View Memory
Enter the address for variable k (&k) in the address box (top left hand side).
This window allows us to inspect any physical memory location of the device, includ-
ing RAM, FLASH, OTP and Boot - ROM. Since the core of this device is a Digital
Signal Processor, we have always to remember that there are two memory spaces,
code and data. To inspect variables, we have to select “data space”. For machine code
instructions inspection we have to look into “code space”. The selection is made in the
center box at the bottom of this window.
The bottom left box allows us to specify the display mode of the 16-bit memory
locations in different form. Try using the different formats available: 16-bit
hexadecimal, signed integer, unsigned integer and binary.
21. A unique feature of Code Composer Studio (CCS) is the ability to display any region
of memory in graphical form. This is very helpful for inspection of data, such as
sampled analogue signals. We can display such memory values as raw data on a time -
axis or even better, we can display the samples a frequency axis. In the 2nd option CCS
is performing a FOURIER - transform, before it displays the data.
The BOOT-ROM contains a sine value lookup table of 512 samples for a unit circle of
360 degree. The data format is 32-bit signed integers in fractional I2Q30 - format. The
start address of this table is 0x3FE000. Enter the following parameters:
Change the properties from “Single Time” to “FFT Magnitude”. Since the signal is a
pure harmonic signal, the FFT will show just one single frequency line:
22. Now let us exercise the mixed mode test. An important test method for inspecting both
C and the resulting assembly code from the C - compilation is called “Mixed Mode” -
monitoring. This option allows us to inspect and verify the device steps both on C
high-level language, and also in the device native environment assembly language.
Right click into “Lab3.c” and select “Mixed Mode”.
Perform:
Debug Reset CPU
Debug Restart
Debug Go Main
Debug Assembly/Source Stepping Assembly Step Into (ALT+SHIFT + F11)
Optionally, use the green icon “Assembly Single Step” on left hand side of CCS.
If you use “Assembly Single Step”, the code is executed machine code line by
machine code line. The green arrow marks the next following assembly line. The
yellow arrow remains at the corresponding line of C code, as long as we deal with the
assembly results of that line.
When you have finished the mixed mode tests, please switch back to “Source Mode”
(right mouse click).
23. Inspect the GEL - script files. The General Extension Language (GEL) is a high-level
script language. Using a *.gel file, the user can expand the features of Code Composer
Studio or perform recurrent steps automatically. By default, a start GEL - file is
automatically added to a new project by Code Composer Studio.
Expand the “GEL” - directory and open the file “F28335.gel”.
Since we are still in an early stage of the classes, please do not change anything inside
this file.
We can also add more GEL - Files to a project. To manually add a 2nd GEL - file use:
24. You might want to use the workspace environment in further sessions. For this pur-
pose, it is useful to store the current workspace. To do so, click: File Workspace
Save Workspace and save it as “Lab3.wks”
25. Close the project by Clicking Project Close Project and close all open windows that
you do not need any further.
End of Lab 3
Blank page