9.1. CCS Integration Guide
This guide explains how to deploy Tiny ML models to TI microcontrollers using Code Composer Studio (CCS).
9.1.1. Prerequisites
Before deploying, ensure you have:
Code Composer Studio (CCS) installed
Download from: https://www.ti.com/tool/CCSTUDIO
Version 12.x or later recommended
Install support for your target device family
Device-specific SDK
C2000WARE for C2000 devices
MSPM0 SDK for MSPM0 devices
AM26x SDK for AM26x devices
TI Compilers
Included with CCS
Or download separately from TI website
Trained and compiled model
mod.alibrary filemod.hheader fileFeature extraction code
9.1.2. Compilation Output
After running Tiny ML Tensorlab with compilation: enable: True:
.../compilation/artifacts/
├── mod.a # Compiled model library
├── mod.h # Model interface header
├── model_config.h # Model configuration
├── feature_extraction.c # Feature extraction code
├── feature_extraction.h # Feature extraction header
└── inference_example.c # Example usage code
9.1.3. Creating a CCS Project
Step 1: Import Project from Resource Explorer
Open CCS
Navigate to Resource Explorer
Find your target device SDK
Resource Explorer in Code Composer Studio
Select and import the example project
Importing a project into CCS
Step 2: Create New Project (Alternative)
Open CCS
File → New → CCS Project
Select your target device (e.g., F28P55x)
Choose “Empty Project” template
Name your project
Step 2: Add Model Files
Copy compiled artifacts to your project:
MyProject/
├── main.c # Your application
├── model/
│ ├── mod.a # Model library
│ ├── mod.h # Model header
│ ├── model_config.h # Configuration
│ ├── feature_extraction.c
│ └── feature_extraction.h
└── ...
Step 3: Configure Project
Add model directory to include paths:
Right-click project → Properties
Build → Compiler → Include Options
Add:
${PROJECT_ROOT}/model
Add library to linker:
Build → Linker → File Search Path
Add library:
${PROJECT_ROOT}/model/mod.a
9.1.4. Integration Code
Basic Inference Example:
#include "mod.h"
#include "feature_extraction.h"
// Allocate buffers
float input_buffer[INPUT_SIZE];
float feature_buffer[FEATURE_SIZE];
float output_buffer[NUM_CLASSES];
void run_inference(void) {
// 1. Collect sensor data into input_buffer
collect_sensor_data(input_buffer);
// 2. Extract features
extract_features(input_buffer, feature_buffer);
// 3. Run model inference
mod_inference(feature_buffer, output_buffer);
// 4. Get prediction
int predicted_class = argmax(output_buffer, NUM_CLASSES);
// 5. Take action based on prediction
handle_prediction(predicted_class);
}
int argmax(float* array, int size) {
int max_idx = 0;
float max_val = array[0];
for (int i = 1; i < size; i++) {
if (array[i] > max_val) {
max_val = array[i];
max_idx = i;
}
}
return max_idx;
}
Continuous Inference Loop:
void main(void) {
// Initialize hardware
System_Init();
ADC_Init();
Timer_Init();
// Initialize model
mod_init();
while (1) {
// Wait for data ready
if (data_ready_flag) {
run_inference();
data_ready_flag = 0;
}
}
}
9.1.5. Memory Placement
For optimal performance, place buffers in fast memory:
// Place in fast RAM (device-specific syntax)
#pragma DATA_SECTION(feature_buffer, ".ramgs0")
float feature_buffer[FEATURE_SIZE];
#pragma DATA_SECTION(output_buffer, ".ramgs0")
float output_buffer[NUM_CLASSES];
Consult your device’s memory map for available sections.
9.1.6. Linker Command File
Modify your linker command file to allocate space:
MEMORY
{
/* Existing memory regions */
/* Add space for model */
MODEL_RAM : origin = 0x00010000, length = 0x00002000
}
SECTIONS
{
/* Place model data */
.model_weights : > MODEL_RAM
.model_buffers : > MODEL_RAM
}
9.1.7. Interrupt-Based Inference
For real-time applications, trigger inference from interrupts:
volatile uint16_t sample_count = 0;
volatile uint8_t inference_ready = 0;
// ADC interrupt - collect samples
__interrupt void ADC_ISR(void) {
input_buffer[sample_count++] = ADC_Result;
if (sample_count >= INPUT_SIZE) {
sample_count = 0;
inference_ready = 1;
}
// Clear interrupt flag
ADC_clearInterruptStatus();
}
void main(void) {
// ... initialization ...
while (1) {
if (inference_ready) {
run_inference();
inference_ready = 0;
}
}
}
9.1.8. Timing and Profiling
Measure inference time:
#include "device.h"
uint32_t start_time, end_time, inference_time;
void profile_inference(void) {
// Start timer
start_time = CPUTimer_getTimerCount(CPUTIMER0_BASE);
// Run inference
mod_inference(feature_buffer, output_buffer);
// Stop timer
end_time = CPUTimer_getTimerCount(CPUTIMER0_BASE);
// Calculate time (adjust for timer configuration)
inference_time = start_time - end_time; // Downcounting timer
}
9.1.9. Debugging
Verify Model Output:
Set breakpoint after inference
Examine output_buffer values
Compare with expected results from training
Setting a breakpoint in CCS debugger
CCS Debug perspective showing variables
Viewing Test Results:
Examining model output variables
Verifying inference results
Memory Debugging:
Use Memory Browser in CCS
Verify buffers are properly allocated
Check for memory corruption
Performance Debugging:
Use Profiler in CCS
Identify bottlenecks
Optimize critical sections
9.1.10. Build Configurations
Debug Configuration:
Optimization: Off
Debug symbols: Enabled
Use for development
Release Configuration:
Optimization: High (O3)
Debug symbols: Optional
Use for deployment
Build → Manage Build Configurations
→ Set Active Configuration → Release
9.1.11. Example Project Structure
Complete project layout:
ArcFaultDetection/
├── main.c # Application entry
├── hardware/
│ ├── adc_config.c # ADC setup
│ ├── gpio_config.c # GPIO setup
│ └── timer_config.c # Timer setup
├── model/
│ ├── mod.a # Model library
│ ├── mod.h # Model interface
│ ├── model_config.h # Model params
│ ├── feature_extraction.c # Feature code
│ └── feature_extraction.h # Feature header
├── app/
│ ├── inference.c # Inference logic
│ └── fault_handler.c # Response logic
├── F28P55x.cmd # Linker command file
└── .project # CCS project file
9.1.12. Common Issues
Linker Error: Undefined symbol
Model library not linked properly:
Verify mod.a is in linker search path
Check library order in linker options
Runtime Error: Hard Fault
Memory access issue:
Check buffer sizes match model requirements
Verify memory sections are properly defined
Incorrect Results
Data format mismatch:
Verify input data scaling matches training
Check feature extraction parameters
Ensure correct byte order
Slow Inference
Optimization needed:
Enable compiler optimizations
Use NPU if available
Place buffers in fast memory
9.1.13. Testing on Hardware
1. Build the Project:
Building the project in CCS
2. Flash the Device:
Click Debug button in CCS
Wait for code to load
Click Resume to run
Flashing the application to the device
3. Set Active Target Configuration:
Selecting the active target configuration
4. Verify Operation:
Monitor output variables
Check GPIO/LED indicators
Use serial output for status
5. Validate Results:
Compare with training test set
Test with known inputs
Verify edge cases
9.1.14. Next Steps
See NPU Device Deployment for NPU-specific details
See Non-NPU Deployment for CPU-only devices
Review Common Errors for issues