Overview
------------
This workshop provides an introduction to the Code Composer Studio integrated development environment. It will cover how to get started using a SimpleLink LaunchPad.
Requirements
------------
Software:
* [Code Composer Studio v8](https://processors.wiki.ti.com/index.php/Download_CCS) or greater.
* The latest version of the SimpleLink SDK for your LaunchPad. This will be installed as part of Lab 1.
Hardware
* Any SimpleLink LaunchPad that has SimpleLink SDK support, including:
* CC1310 LaunchPad (LAUNCHXL-CC1310)
* CC1350 LaunchPad (LAUNCHXL-CC1350)
* CC1312R LaunchPad (LAUNCHXL-CC1312R1)
* CC1352R LaunchPad (LAUNCHXL-CC1352R1)
* MSP432P401R LaunchPad (MSP-EXP432P401R)
* MSP432P4111 LaunchPad (MSP-EXP432P4111)
* MSP432E401Y LaunchPad (MSP-EXP432E401Y)
* CC26X2R LaunchPad (LAUNCHXL-CC26X2R1)
* CC2640R2 LaunchPad (LAUNCHXL-CC2640R2)
* CC3220S LaunchPad (CC3220S-LAUNCHXL)
* CC3220SF LaunchPad (CC3220SF-LAUNCHXL)
### Recommended Reading
* You may wish to read more about the [SimpleLink MCU Platform](https://www.ti.com/wireless-connectivity/simplelink-solutions/overview/overview.html) and the [SimpleLink SDK](https://www.ti.com/wireless-connectivity/simplelink-solutions/overview/software.html).
* You may wish to read about concepts involving [RTOS](https://dev.ti.com/tirex/content/simplelink_academy_cc2640r2sdk_1_14_02_04/modules/rtos_concepts/rtos_concepts.html) and [TI-RTOS](https://dev.ti.com/tirex/content/simplelink_academy_cc2640r2sdk_1_14_02_04/modules/tirtos_basics/tirtos_basics.html).
Lab 1: Importing, Editing, and Running a Project
---------------
This lab will go over importing an example project from the SimpleLink SDK, making some edits to modify the program's functionality, and flashing the program to the target (the SimpleLink LaunchPad) to run the program.
### Importing and Running an Example Project
1. Connect your SimpleLink LaunchPad board to the computer via USB cable.
2. Open Code Composer Studio.
3. From the top menubar, open: **View → Resource Explorer**.
{{b You can use **Resource Explorer** to browse through documentation, libraries, and software examples.}}
4. From the home page of **Resource Explorer**, scroll down to the *Working Offline* section, and download and install the latest SimpleLink SDK that corresponds to your LaunchPad. For example, if you are using the CC1310 LaunchPad, you would need to download and install the **SimpleLink CC13X0 SDK**. You may also be prompted to download and install **SimpleLink Academy**; this is optional.
![Download and install SimpleLink SDK](.\images\CCSv8_simplelink_workshop_01_00.PNG)
Expand the **Software** folder in the tree view on the left, and verify that **SimpleLink (YourDeviceFamily) SDK -v:(X.X.X.X)** is present, with a green down-arrow on the icon. *The green down-arrow indicates that the most recent version of this software package is downloaded and installed locally.*
{{b **Note:** to return to the home page from another view in **Resource Explorer**, click on the Home button near the top-right.}}
{{y **Note:** If the optional step of downloading and installing **SimpleLink Academy** was skipped, then the down-arrow for it will be grey.}}
5. From the “Select a Device or Board” box near the top-left of the **Resource Explorer** view, search for and select your SimpleLink LaunchPad.
This will filter the tree view to only display results matching your LaunchPad.
6. Under the tree view, expand and select **Software → SimpleLink (YourDeviceFamily) SDK – v:(X.X.X.X) → Examples → Development Tools → (YourLaunchPad) → TI Drivers → empty → TI-RTOS → CCS Compiler → empty**, and then click the Import to IDE button at the top-right.
{{b In **Resource Explorer**, you are also able to browse through examples and other resources that you have not yet installed locally. You will simply be prompted to download and install when attempting to import an example to IDE.}}
{{y **Note:** When importing the project using CCSv8.3.0, CCS may give an error stating that the project requires XDCtools v3.50.999 or later - even if the user has version v3.51 installed. A workaround is to install the version of XDCtools originally used with the SDK version being used (ex: XDCtools v3.50.08.24 with SimpleLink CC2640R2 SDK v2.30.00.28) using **Resource Explorer** in CCS. This issue has been fixed in CCSv9.0.}}
The *empty* project is a simple TI-RTOS program that blinks LED0 on your board (ON for one second and then OFF for one second). This project is useful as a bare starting point to develop your application.
![Importing example project to IDE](.\images\CCSv8_simplelink_workshop_01_01.PNG)
7. Two projects should have appeared in your Project Explorer: the *empty* project as well as the *tirtos* kernel configuration project. The *empty* project is dependent on this *tirtos* project, which contains the configuration for the TI-RTOS. More information about the TI-RTOS Kernel and configuration can be found in the [SimpleLink MCU SDK User's Guide](https://dev.ti.com/tirex/content/simplelink_cc13x0_sdk_1_40_00_10/docs/simplelink_mcu_sdk/Users_Guide.html#ti-rtos-kernel).
If you have multiple projects open in the Project Explorer, ensure that the *empty* project for your LaunchPad is active (it is shown as bold). If not, you can set it to the active project by double-clicking it.
8. You can use the Project Explorer to browse through the *empty* project. Useful files to open and read through include *Board.html*, *Board.h*, *empty.c*, and *main_tirtos.c*.
* **Board.html**: Provides an overview of your LaunchPad hardware. Location of GPIO Buttons and LEDs on the board. Jumper settings. Board resources and peripherals.
* **Board.h**: Header file containing define macros that enable the use of generic references such as *Board_GPIO_LED1* for 100% code portability across SimpleLink devices.
* **main_tirtos.c**: The *main()* function is defined here, and in this case, simply creates a single thread that runs the *mainThread()* function indefinitely.
* **empty.c**: The application code will be in this file. The *mainThread()* function (which is called by the *main()* function in *main_tirtos.c*) will initialize and configure the needed drivers, before entering an infinite main loop. Other application functions such as interrupt callbacks can be defined in this file as well.
9. From the top menubar, select **Run → Debug**. This will prompt to save source files, build the project, start the debugger, switch to CCS Debug perspective, connect CCS to the target, and then flash (load) the program to the target. The first time you run this, it may take a minute to build the TI-RTOS kernel configuration project.
* There are icons near the top-right of the toolbar which allow you to go between the **CCS Debug** and the **CCS Edit** perspectives.
* **When running in debug mode, your LaunchPad is at first suspended**. Click on **Resume** near the top left on the toolbar, or under the menubar at **Run → Resume**, for your LaunchPad to run the program.
* Note that LED0 on your LaunchPad board is now blinking at 0.5 Hz, as expected. The program is being run.
* You can **Suspend** and **Resume** program execution on the target as desired.
![CCS shortcuts](.\images\CCSv8_simplelink_workshop_01_02.PNG)
10. When you are done with this part of the lab, **Terminate** the debug session (which will also return you to the **CCS Edit** perspective).
### Modifying the Project
Currently the program simply blinks LED0 on the LaunchPad at 0.5 Hz. Say that some functionality needs to be added to the program such that the blinking frequency of LED0 is controllable. The program will be modified as follows.
* When the program is run on the LaunchPad, LED0 will *initially* be blinking at 1 Hz.
* Whenever GPIO_Button0 is pressed, the frequency of LED0 will be doubled, up to a maximum of 32 Hz.
* Whenever GPIO_Button1 is pressed, the frequency of LED0 will be halved, down to a minimum of 1 Hz.
* Whenever either GPIO_Button0 or GPIO_Button1 is pressed, the state of LED1 will be toggled.
[[r Note:
Some LaunchPad boards will not have a separate LED1 available for use for GPIO. This can be confirmed by inspecting your **Board.html** or **Board.h** files. For example, in the **Board.h** file for the CC3220S/CC3220SF LaunchPad it can be seen that **Board_GPIO_LED0**, **Board_GPIO_LED1**, and **Board_GPIO_LED2** all refer to the same LED.
Even if your LaunchPad is affected, the following code modifications will build and run on the target. You simply won't see a second LED toggling on button presses.
]]
Let's get started!
1. In **empty.c**, in **mainThread()**, the integer variable `time` is defined and initialized to 1. This variable is used in the infinite main loop at the bottom of **mainThread()** to set the delay in seconds between toggling LED0.
* **Move this code block from inside _mainThread()_ to just below the include statements** at the top of **empty.c**, making this a **global variable**, such that its value can be more easily modified from any function.
* Currently in the main loop, the **sleep(seconds)** function is being used. For more resolution, this will be changed to **usleep(useconds)**, which uses microseconds. As such, for LED0 to be blinking at 1 Hz to start, the value of this variable needs to be initialized to 500000 (useconds).
* Rename the variable from `time` to something more descriptive, like `led0_on_off_useconds`.
``` cpp
/* Board_GPIO_LED0 on and off time in microseconds */
uint32_t led0_on_off_useconds = 500000;
```
2. Modify the contents of the mainThread() main loop, to account for the changes that were just made.
``` cpp
while (1) {
usleep(led0_on_off_useconds);
GPIO_toggle(Board_GPIO_LED0);
}
```
{{y **Regarding usleep():** the *usleep(useconds)* function can only take unsigned integer arguments *strictly less than 1000000*. Otherwise, an overflow may occur.}}
3. In **mainThread()**, configure and initialize the state of LED1, next to where this is already done for LED0.
``` cpp
/* Configure the LED pins */
GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/* Initialize LED states to ON */
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
```
4. Define callback functions which will be called whenever Button0 or Button1 are pressed. These functions will double or halve the switching frequency of LED0, respectively, by halving or doubling the value of led0_on_off_useconds. Recall that the max switching frequency will be 32 Hz, and the min frequency will be 1 Hz, so those limits need to be guarded against. Both functions will also toggle the state of LED1. **Note: these function definitions need to be placed directly above the definition of mainThread().**
``` cpp
/*
* ======== gpioButtonFxn0 ========
* Callback function for the GPIO interrupt on Board_GPIO_BUTTON0.
*/
void gpioButtonFxn0(uint_least8_t index)
{
/* Double LED0 frequency, and toggle LED1 */
if(led0_on_off_useconds >= 31250) { /* LED0 frequency currently <= 16 Hz; can double */
led0_on_off_useconds /= 2;
}
else { /* limit LED0 frequency to 32 Hz max */
led0_on_off_useconds = 15625;
}
GPIO_toggle(Board_GPIO_LED1);
}
/*
* ======== gpioButtonFxn1 ========
* Callback function for the GPIO interrupt on Board_GPIO_BUTTON1.
*/
void gpioButtonFxn1(uint_least8_t index)
{
/* Halve LED0 frequency, and toggle LED1 */
if(led0_on_off_useconds <= 250000) { /* LED0 frequency currently >= 2 Hz; can halve */
led0_on_off_useconds *= 2;
}
else { /* limit LED0 frequency to 1 Hz min */
led0_on_off_useconds = 500000;
}
GPIO_toggle(Board_GPIO_LED1);
}
```
5. Finally, some code needs to be added to **mainThread()** between the LED configuring/initialization and the main loop, to configure the buttons as interrupts, install the callbacks, and enable interrupts.
``` cpp
/* Configure the board Pushbuttons as interrupts */
GPIO_setConfig(Board_GPIO_BUTTON0, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
GPIO_setConfig(Board_GPIO_BUTTON1, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
/* Install Button callbacks */
GPIO_setCallback(Board_GPIO_BUTTON0, gpioButtonFxn0);
GPIO_setCallback(Board_GPIO_BUTTON1, gpioButtonFxn1);
/* Enable interrupts */
GPIO_enableInt(Board_GPIO_BUTTON0);
GPIO_enableInt(Board_GPIO_BUTTON1);
```
[[b Note:
You can find very useful code snippets by browsing through various example projects in **SimpleLink SDK → Examples → Development Tools → (YourLaunchPad) → TI Drivers**. There will be simple projects that utilize hardware resources such as the ADC, GPIO interrupts, timers, PWM, etc.
]]
That's it!
[[+d Your **empty.c** file should now look something like this. (expand)
``` cpp
/*
* Copyright (c) 2015-2017, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* ======== empty.c ========
*/
/* For usleep() */
#include
#include
#include
/* Driver Header files */
#include
// #include
// #include
// #include
// #include
// #include
/* Board Header file */
#include "Board.h"
/* Board_GPIO_LED0 on and off time in microseconds */
uint32_t led0_on_off_useconds = 500000;
/*
* ======== gpioButtonFxn0 ========
* Callback function for the GPIO interrupt on Board_GPIO_BUTTON0.
*/
void gpioButtonFxn0(uint_least8_t index)
{
/* Double LED0 frequency, and toggle LED1 */
if(led0_on_off_useconds >= 31250) { /* LED0 frequency currently <= 16 Hz; can double */
led0_on_off_useconds /= 2;
}
else { /* limit LED0 frequency to 32 Hz max */
led0_on_off_useconds = 15625;
}
GPIO_toggle(Board_GPIO_LED1);
}
/*
* ======== gpioButtonFxn1 ========
* Callback function for the GPIO interrupt on Board_GPIO_BUTTON1.
*/
void gpioButtonFxn1(uint_least8_t index)
{
/* Halve LED0 frequency, and toggle LED1 */
if(led0_on_off_useconds <= 250000) { /* LED0 frequency currently >= 2 Hz; can halve */
led0_on_off_useconds *= 2;
}
else { /* limit LED0 frequency to 1 Hz min */
led0_on_off_useconds = 500000;
}
GPIO_toggle(Board_GPIO_LED1);
}
/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{
/* Call driver init functions */
GPIO_init();
// I2C_init();
// SDSPI_init();
// SPI_init();
// UART_init();
// Watchdog_init();
/* Configure the LED pins */
GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/* Initialize LED states to ON */
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
/* Configure the board Pushbuttons as interrupts */
GPIO_setConfig(Board_GPIO_BUTTON0, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
GPIO_setConfig(Board_GPIO_BUTTON1, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
/* Install Button callbacks */
GPIO_setCallback(Board_GPIO_BUTTON0, gpioButtonFxn0);
GPIO_setCallback(Board_GPIO_BUTTON1, gpioButtonFxn1);
/* Enable interrupts */
GPIO_enableInt(Board_GPIO_BUTTON0);
GPIO_enableInt(Board_GPIO_BUTTON1);
while (1) {
usleep(led0_on_off_useconds);
GPIO_toggle(Board_GPIO_LED0);
}
}
```
+]]
Click **Run → Debug** and then **Resume** to run the program on the target. Test the program by verifying that the pressing buttons on the LaunchPad controls the LED0 blink frequency and toggles the state of LED1.
Lab 2: Basic Debug Concepts
---------------
This lab will cover the basics of debugging, using [the modified **empty.c** code from Lab 1](#modifying-the-project). Specific tools and concepts that are covered are:
* Breakpoints
* Watchpoints
* Profile Clock
* Disassembly View
* Other Views
* Loading Symbols Only to Debug Flashed Program
### Breakpoints
Breakpoints are specific points that can be set in the code, where the program is to halt execution. Once halted, the values in registers/memory/etc. can be inspected to gain a deeper understanding of the program execution. This is very useful when debugging.
[[b Both software breakpoints and hardware breakpoints are available for use
A hardware breakpoint uses debug resources on the target as compared to a software breakpoint which is typically an opcode replacement. A hardware breakpoint is required when setting a breakpoint in Flash, while a software breakpoint can be used in RAM. While the number of software breakpoints available is practically limitless, the number of hardware breakpoints is typically small in number and varies per target. More information can be found [here](https://processors.wiki.ti.com/index.php/How_Do_Breakpoints_Work).
]]
1. If your SimpleLink LaunchPad is currently running, ensure you are in the **CCS Debug** perspective and **Suspend** it. Otherwise, click on **Run → Debug** to flash the program to the target and suspend it.
2. Click on **View → Breakpoints** to open a Breakpoints view. There should be no breakpoints to start.
3. While staying in the **CCS Debug** perspective, in **empty.c**, scroll to the definition of the **gpioButtonFxn1()** function, and double-click on the margin to the left of the line number. This will insert a breakpoint that will halt program execution whenever it reaches this point in the code. CCS will automatically use either a hardware breakpoint or a software breakpoint, as necessary.
![Inserting a breakpoint](.\images\CCSv8_simplelink_workshop_02_00.PNG)
4. Click **Run → Resume** to resume program execution on the LaunchPad. Click Button0 on the board a few times, until LED0 is blinking at its max frequency of 32 Hz. Note that the program continues to run as expected without interruption. Click Button1 on the board, and note that the program has suspended due to the breakpoint.
* Place your mouse over an instance of the **led0_on_off_useconds** variable in **empty.c**. A tooltip will appear, showing the current value of the variable. The value is still 15625 (corresponding to a frequency of 32 Hz), because the breakpoint has suspended to program at the start of the function, before it has doubled the value of **led0_on_off_useconds**.
* Apart from hovering your mouse over variables in the code, you can add **Watch Expressions** to inspect the value of any expression. Click **View → Expressions**. In the **Expressions** view, click **Add a new expression**, and add `led0_on_off_useconds`. You can watch any arbitrary expression; click **Add a new expression** and also add `500000/led0_on_off_useconds`, which is the blinking frequency of LED0. Finally, click **Continuous Refresh** to automatically update these values even during program execution.
![Continuous refresh](.\images\CCSv8_simplelink_workshop_02_01.PNG)
5. Note that there is a blue arrow next to the line of code where the breakpoint has suspended program execution. By clicking **Run → Step Into** or **Run → Step Over** (also available in the top toolbar), the target will *step*, or execute one line of code at a time, indicated by the blue arrow. Step until the value of **led0_on_off_useconds** has been modified, and note that this change is reflected in the **Expressions** view. Click **Run → Resume** to resume program execution.
* **Step into** steps to the next line of code, including stepping into a new function call.
* **Step over** steps to the next line of code in the current function, but will not step into a new function call. It will remain in the current function until it ends or returns.
* **Step return** steps out of the current function before it reaches its end, and suspends execution on the next statement of the calling function.
6. After you are finished with this part of the lab, in the **Breakpoints** view, remove the hardware breakpoint. You can also remove it by double-clicking the margin next to the line number in *empty.c*, where the breakpoint currently exists.
### Watchpoints
A watchpoint is a type of breakpoint that monitors activity on a memory address, for example where a variable's value is stored.
1. If your SimpleLink LaunchPad is currently running, ensure you are in the **CCS Debug** perspective and **Suspend** it. Otherwise, click on **Run → Debug** to flash the program to the target and suspend it.
2. In the **Breakpoints** view, click **New (down arrow) → Hardware Watchpoint**, set **Location** to `led0_on_off_useconds` and **Memory** to **Write**, and click **OK**. This installs a watchpoint which will suspend program execution on the target whenever the value of `led0_on_off_useconds` is modified (whenever it is written to).
![New hardware watchpoint](.\images\CCSv8_simplelink_workshop_02_02.PNG)
3. **Run → Resume** the program, and press the buttons on the board to test the watchpoint. As expected, whenever either button is pressed, a callback function is called that writes to `led0_on_off_useconds`, and the watchpoint suspends program execution.
4. In the **Breakpoints** view, right-click on the existing hardware watchpoint and click **Breakpoint Properties...**. In the **Breakpoint Properties** window that opens, specific configurations can be made to the watchpoint. Expand the **Type** property, and then set **With Data** to **Yes**, set **Data Value** to **15625**, and click **Apply and Close**. This configures the watchpoint to only trigger (suspend program execution) when the value **15625** is written to **led0_on_off_useconds**. Resume program execution and verify that the program only suspends on button presses that set the LED blinking frequency to 32 Hz.
5. After you are finished with this part of the lab, in the **Breakpoints** view, remove the hardware watchpoint.
### Profile Clock
The profile clock can be used to count clock cycles, for example between two points in the program code.
1. If your SimpleLink LaunchPad is currently running, ensure you are in the **CCS Debug** perspective and **Suspend** it. Otherwise, click on **Run → Debug** to flash the program to the target and suspend it.
2. Click on **Run → Clock → Enable**. A **Profile Clock** icon should appear near the bottom-right of the **Code Composer Studio** window.
![Profile clock icon](.\images\CCSv8_simplelink_workshop_02_03.PNG)
3. Double-click on the margin next to the line number, at the opening and closing braces of the definition of the **gpioButtonFxn1()** function. This creates two breakpoints, as can be seen in the **Breakpoints** view.
![Adding two breakpoints](.\images\CCSv8_simplelink_workshop_02_04.PNG)
4. Click on **Run → Resume** to resume program execution on the LaunchPad.
* Press **Button0** on the LaunchPad a few times. Note that this does not suspend program execution, because the breakpoints are in the **gpioButtonFxn1()** function, which is installed as a callback for Button1.
* Press **Button1** on the LaunchPad. This triggers the first breakpoint and suspends program execution. Note that the **Profile Clock** at the bottom-right of **Code Composer Studio** is displaying a very large number. This is the number of clock cycles that have passed on the target since the program began execution. Double-click on the **Profile Clock** to reset this count to zero.
* Click on **Run → Resume**. The program will resume execution until the second breakpoint, at which point the program will suspend again. The **Profile Clock** should show a clock cycle count of about 100 or 200, depending on your specific LaunchPad. **This is the number of clock cycles that the target takes to run the program between the two breakpoints.**
5. After you are finished with this part of the lab, in the **Breakpoints** view, remove the breakpoints.
### Disassembly View
1. If your SimpleLink LaunchPad is currently running, ensure you are in the **CCS Debug** perspective and **Suspend** it. Otherwise, click on **Run → Debug** to flash the program to the target and suspend it.
2. Click on **View → Disassembly** to open the **Disassembly** view. By default it will show the disassembly of the current location in the code. The location of the Program Counter is indicated with a small blue arrow.
{{b You can enter in an address or symbol in the location box at the top-left of the Disassembly View to change the address that the view starts at. For example, you can enter **0x2600** or **main**.}}
3. Click **Show Source** in the **Disassembly** view to toggle interleaving of source code with the assembly code.
![Disassembly view with show source](.\images\CCSv8_simplelink_workshop_02_05.PNG)
### Other Views
Several other views are available under the View menu. Experiment with the various views.
#### Registers View
The **Registers** view is used to display and edit the values of core and memory mapped (peripheral) registers.
#### Modules View
The **Modules** view enables browsing of loaded debug symbols. This can be especially useful in project-less debug sessions as it provides file and function listings.
### Loading Symbols for Flashed Program
If a program is already flashed to the target and you wish to just debug the existing code in flash without reloading the code every time, you can configure CCS to debug the program by only loading the symbols.
1. If you currently have a debug session active, click on *Run → Terminate* to terminate it. This will also enter the **CCS Edit** perspective.
2. Click on **Run → Debug Configurations...**. Debug configuration contains information about various debug settings. This information is created when a debug session is first launched for a project or target configuration and is cached for future use.
3. Select the **empty** project in the left pane, and then the **Program** tab in the right pane. Under **Loading Options** select **Load symbols only**. Click **Apply** and then **Debug**.
The debugger will start up, connect to the target, and load only the symbols for the program (no code is loaded/flashed on the target).
![Debug configurations](.\images\CCSv8_simplelink_workshop_02_06.PNG)
4. **Note that the Program Counter is set to the entry point of the code, and not at the start of the main() function.** To run the target until the start of **main()** and then suspend it, click on **Run → Go Main**. An alternate way to suspend program execution at **main()** is **Run → Restart**.
5. Click on **Run → Resume** for the target to run the program as normal. You can now debug as desired.
6. After you are finished with this part of the lab, click on **Run → Terminate** to terminate the debug session. You may also wish to re-open **Debug Configurations** in order to change the **Loading options** back to **Load program**.
###Summary
Lab 1 covered using *Code Composer Studio* to import an example TI-RTOS project, modify it, and flash it to a target to run the program. Lab 2 provided information on the basics of using debug tools in *Code Composer Studio*.