BIOS MCSDK 2.0 User Guide

From Texas Instruments Wiki
Jump to: navigation, search

TIBanner.png


BIOS Multicore Software Development Kit

Version 2.x

User's Guide

Last updated: 11/12/2013


Contents

Introduction

c66x-multicore.jpg

The BIOS Multicore Software Development Kit (MCSDK) provides the core foundational building blocks that facilitate application software development on TI's high performance and multicore DSPs. The foundational components include:

  • SYS/BIOS which is a light-weight real-time embedded operating system for TI devices
  • Chip support libraries, drivers, and basic platform utilities
  • Run-time libraries (OpenMP, OpenEM)
  • Interprocessor communication for communication across cores and devices
  • Basic networking stack and protocols
  • Optimized application-specific and application non-specific algorithm libraries
  • Debug and instrumentation
  • Bootloaders and boot utilities
  • Demonstrations and examples

The purpose of this User's Guide is to provide more detailed information regarding the software elements and infrastructure provided with MCSDK. MCSDK pulls together all the elements into demonstrable multicore applications and examples for supported EVMs. The objective being to demonstrate device, platform, and software capabilities and functionality as well as provide the user with instructive examples. The software provided is intended to be used as a reference when starting their development.

Helpful tips image.jpg

Useful Tip

It is expected the user has gone through the EVM Quick Start Guide provided with their EVM and have booted the out-of-box demonstration application flashed on the device. It is also assumed the user has gone through the MCSDK Getting Started Guide and have installed both CCS and the MCSDK.

Acronyms and Definitions

The following acronyms are used throughout this document.

Acronym Meaning
AMC Advanced Mezzanine Card
CCS Texas Instruments Code Composer Studio
CSL Texas Instruments Chip Support Library
DDR Double Data Rate
DHCP Dynamic Host Configuration Protocol
DSP Digital Signal Processor
DVT Texas Instruments Data Analysis and Visualization Technology
EDMA Enhanced Direct Memory Access
EEPROM Electrically Erasable Programmable Read-Only Memory
EVM Evaluation Module, hardware platform containing the Texas Instruments DSP
HUA High Performance Digital Signal Processor Utility Application
HTTP HyperText Transfer Protocol
IP Internet Protocol
IPC Texas Instruments Inter-Processor Communication Development Kit
JTAG Joint Test Action Group
MCSA Texas Instruments Multi-Core System Analyzer
MCSDK Texas Instruments Multi-Core Software Development Kit
NDK Texas Instruments Network Development Kit (IP Stack)
NIMU Network Interface Management Unit
PDK Texas Instruments Programmers Development Kit
RAM Random Access Memory
RTSC Eclipse Real-Time Software Components
SRIO Serial Rapid IO
TCP Transmission Control Protocol
TI Texas Instruments
UART Universal Asynchronous Receiver/Transmitter
UDP User Datagram Protocol
UIA Texas Instruments Unified Instrumentation Architecture
USB Universal Serial Bus

NoteNote: We use the abbreviation TMS when referring to a specific TI device (processor) and the abbreviation TMD when referring to a specific platform that the processor is on. For example, TMS320C6678 refers to the C6678 DSP processor and TMDSEVM6678L refers to the actual hardware EVM that the processor is on.

Supported Devices/Platforms

The latest BIOS MCSDK Release supports the following Texas Instrument devices/platforms:

Platform Development Kit Supported Devices Supported EVM
C6657 TMS320C6657 TMDXEVM6657L, TMDXEVM6657LE
C6670 TMS320C6670, TMS320TCI6618 TMDSEVM6670L, TMDSEVM6670LE,TMDSEVM6670LXE, TMDSEVM6618LXE
C6678 TMS320C6678, TMS320TCI6608 TMDSEVM6678L, TMDSEVM6678LE, TMDSEVM6678LXE


Other Resources

Training

This section provides a collection links to training resources relevant to this release.

Link Description
BIOS-MCSDK Short Video This short video describes what the BIOS Multicore Software Development Kit is and how it helps customers get to market faster.
MCSDK Overview Online This video training module provides an overview of the multicore SoC software for C66x devices. This module introduces the optimized software components that enable the rapid development of multicore applications and accelerate time to market using foundational software in the MCSDK. The MCSDK also enables developers to evaluate the hardware and software capabilities using the C66x evaluation module.

The Mandarin version of this training can be found here.

KeyStone Architecture Wiki KeyStone Architecture Overview Mediawiki
KeyStone Architecture Online C66x Multicore SOC Online Training for KeyStone Devices
SYS/BIOS Online SYS/BIOS Online Training
SYS/BIOS 1.5 Day SYS/BIOS 1.5-DAY Workshop
MCSA Online Multicore System Analyzer Online Tutorial


White Papers

The following lists some relevant white papers. Additional white papers can be found on the device product page (e.g., C6678).

Document Description
MCSDK White Paper This paper introduces TI’s Multicore Software Development Kit (MCSDK) by outlining the various software packages available, along with utilities and tool chains that can aid programmers in development for high-level operating systems such as Linux, and the real time operating system SYS/BIOS.


Getting Started Guides

The getting started guides walk you through setting up your EVM and running the "Out of Box" Demonstration application. This is where you should start after receiving your EVM.

Document Description
MCSDK Release Notes Contains latest information on the release including what’s changed, known issues and compatibility information. Each foundational component will have individual release notes as well.
MCSDK Getting Started Guide Discusses how to install the BIOS-MCSDK and access the demonstration application.
TMDSEVM66xxL Quick Setup Guide Quick Setup Guides showing how to set up the EVM and run the Out of Box demonstration application from flash. These documents can be found in the links provided below for Hardware - EVM Overview.


API and LLD User Guides

API Reference Manuals and LLD User Guides are provided with the software. You can reference them from the Eclipse Help system in CCS or you can navigate to the components doc directory and view them there.


Tools Overview

The following documents provide information on the various development tools available to you.

Document Description
CCS v5 Getting Started Guide How to get up and running with CCS v5
XDS560 Emulator Information Information on XDS560 emulator
XDS100 Emulator Information Information on XDS100 emulator
TMS320C6000 Optimizing Compiler v 7.3 Everything you wanted to know about the compiler, assembler, library-build process and C++ name demangler.
TMS320C6000 Assembly Language Tools v 7.3 More in-depth information on the assembler, linker command files and other utilities.
Multi-core System Analyzer How to use and integrate the system analyzer into your code base.
Eclipse Platform Wizard How to create a platform for RTSC. The demo uses CCSv4 but the platform screens are the same in CCSv5.
Runtime Object Viewer How to use the Object Viewer for Eclipse Based Debugging.


Hardware - EVM Overview

The following resources provide information about the EVM.

Document Description
Introducing the C66x Lite EVM Video Short video on the C66x Lite Evaluation Module, the cost-efficient development tool from Texas Instruments that enables developers to quickly get started working on designs for C66x multicore DSPs based on the KeyStone architecture.
TMDSEVM6657L documentation and support Discusses the technical aspects of your EVM including board block diagram, DIP Switch Settings, memory addresses and range, power supply and basic operation.
TMDSEVM6670L documentation and support
TMDSEVM6678L documentation and support
TMDSEVM6618LXE documentation and support (TBD)


Hardware - Processor Overview

The following documents provide information about the processor used on the EVM.

Document Description
TMS320C6657 Data Manual Data manual for specific TI DSP
TMS320C6670 Data Manual
TMS320C6678 Data Manual
TMS320TCI6618 Data Manual


Related Software

This section provides a collection links to additional software elements that may be of interest.

Link Description
Security Accelerator LLD Download page for Security Accelerator (SA) low level driver
C6x DSP Linux Project Community site for C6x DSP Linux project
Telecom Libraries TI software folder for information and download of Telecom Libraries (Voice, Fax, etc) for TI processors.
c66x Speech and Video Codecs TI software folder for information and download of Speech and Video codecs for c66x.
Medical Imaging Software Tool Kits TI software folder for information and download of medical imaging software tool kits for TI processors.
c6x Software Libraries Mediawiki providing an overview of available software libraries for TI's c6x family of DSP processors.
Multicore Video Infrastructure Demonstration Application TI software folder for information and download of multicore video infrastructure demonstration application using the BIOS-MCSDK.


Software Overview

The MCSDK is comprised of the foundational software infrastructure elements intended to enable development of application software on TI high-performance and multicore DSPs.


MCSDK200SoftwareStack.jpg


After installing CCS and MCSDK, the components in the picture above will be located as follows:

Software Element Location
CSL and Low Level Drivers
Chip Support Library pdk_<platform>_w_xx_yy_zz/packages/ti/csl/
All LLD (except EDMA3) pdk_<platform>_w_xx_yy_zz/packages/ti/drv/ - If the driver is supported for a given platform it will be located in the drv/ directory
EDMA3 LLD edma3_lld_ww_xx_yy_zz/
Runtime Libraries
OpenEM openem_w_x_y_z/
OpenMP omp_w_x_y_z/
Algorithm Libraries
DSPLIB dsplib_<proc_type>_w_x_y_z/
IMGLIB imglib_<proc_type>_w_x_y_z/
MATHLIB mathlib_<proc_type>_w_x_y_z/
Platform/EVM Software
Platform Libary pdk_<platform>_w_xx_yy_zz/packages/ti/platform/<device>/platform_lib
Resource Manager pdk_<platform>_w_xx_yy_zz/packages/ti/platform/resource_mgr.h (Note: There is also a RM LLD provided for resource management)
Platform OSAL pdk_<platform>_w_xx_yy_zz/packages/ti/platform/platform.h
Transports pdk_<platform>_w_xx_yy_zz/packages/ti/transport/ipc/qmss/ - QMSS IPC Transport
pdk_<platform>_w_xx_yy_zz/packages/ti/transport/ipc/srio/ - SRIO IPC Transport
pdk_<platform>_w_xx_yy_zz/packages/ti/transport/ndk - NDK Transport
POST mcsdk_w_xx_yy_zz/tools/post/
Bootloader mcsdk_w_xx_yy_zz/tools/boot_loader/
Target Software Components
SYS/BIOS RTOS bios_w_xx_yy_zz/
Interprocessor Communication ipc_w_xx_yy_zz/
Network Developer's Kit (NDK) Package ndk_w_xx_yy_zz/
Demonstration Applications
HUA "Out of Box" Demo mcsdk_w_xx_yy_zz/demos/hua/
Image Processing mcsdk_w_xx_yy_zz/demos/image_processing/


Platform Development Kit (PDK)

The Platform Development Kit (PDK) is a package that provides the foundational drivers and software to enable the device. It contains device-specific software consisting of a Chip Support Library (CSL) and Low Level Drivers (LLD) for various peripherals; both the CSLs and LLDs include example projects and examples within the relevant directories which can be used with CCS. It also contains the transport (NIMU), platform library, platform/EVM specific software, applications, CCS configuration files and other board-specific collaterals.


Operating System Adaptation Layer (OSAL)

Various components in the PDK support OSAL callbacks that allow applications to tailor common operations to their specific needs. The implementation of these callbacks is the applications responsibility. Typical callbacks include:

  • Memory Management
  • Critical Sections
  • Cache Coherency

See the file platform_osal.c in the demos and examples. This file can be used as a basic starting point.


Resource Management

This section covers the resource management implementations delivered as part of the MCSDK PDK package.

Platform Resource Manager

The Resource Manager defines a set of APIs and definitions for managing platform resources (e.g. Interrupts, Hardware semaphores, etc) and provides example code for initializing and using the PA, QMSS and CPPI subsystems.

The Resource Manager definitions are present in pdk_C####_#_#_#_#/packages/ti/platform/resource_mgr.h header file. This header file is included by the demos/example, NIMU and platform library.

The example implementation is included in the MCSDK demo and example applications in the resourcemgr.c/osal.c source files.

The following Linker Sections are used by the reourcemgr.c file and would need to be included in the application linker map or .cfg file.

  • .resmgr_memregion = Contains QMSS descriptors region
  • .resmgr_handles = Contains CPPI/QMSS/PA Handles
  • .resmgr_pa = Contains PA Memory


Resource Manager (RM) LLD

The Resource Manager (RM) LLD allows a system integrator to specify DSP initialization and usage permissions for device resources. The RM lets the system integrator mark a clear separation between resources available for use by the DSPs and those available for use by Linux running on the ARM. When included in a system the RM LLD allows supported LLDs to callout to the RM LLD for resource permission verification.

Currently, RM LLD support is in the following LLDs:

  • QMSS
  • CPPI
  • PA


NoteNote: The API additions to the QMSS, CPPI, and PA LLDs to support the RM LLD are fully backwards compatible. No modifications are required to existing applications integrating the new QMSS, CPPI, and PA LLD versions in order to maintain existing behavior. The QMSS, CPPI, and PA LLDs consider RM callouts disabled by default.

Managed Resources

The RM allows initialization and usage permissions to be specified for the following resources:

QMSS

  • PDSP Firmware Download
  • Queues
  • Memory Regions
  • Linking RAM Control (RAM0/1 Base address programming)
  • Linking RAM Indices
  • Accumulator Channels
  • QOS Clusters
  • QOS Queues

CPPI

  • Transmit Channels
  • Receive Channels
  • Receive Flows

PA

  • Firmware Download
  • Look-up Tables (The entire table, not individual entries)
RM Architecture Overview

The following figure provides a graphical representation of how the RM LLD fits into an application.


rmm_structure_overview.JPG


The Resource Manager LLD sits under the hood of the QMSS, CPPI, and PA LLDs to perform permission checks on the initialization and usage of resources. The RM LLD contains a permission field for each tracked QMSS, CPPI, and PA LLD resource. The permission fields contains an initialization and a usage bit for each DSP in the system. The permission fields are global and are required to be placed in the global address space for the device. Whenever a tracked LLD resource is specified for use by the application through the QMSS, CPPI, or PA LLD APIs the LLD internally sends a resource permission check request to the RM LLD. The RM LLD uses the resource data, a resource identifier and the resource value, to index the internal permission tables. When the resource entry is found the DSP number is used to extract the initialization and usage information for the resource. This information is returned to the requesting LLD. Based on the RM LLD response, resource approved or denied, the LLD either continues normal operation or returns a resource denied failure for the application to act upon.

The APIs used by the RM LLD and the QMSS, CPPI, and PA LLDs are internal APIs that are not meant to be used by an application. The application gets a RM handle for each DSP from the RM LLD after it has initialized and started the RM. The RM handle contains RM LLD resource permission internal API information that is shared between the RM and the other LLDs. The application must provide the RM handle to each LLD for each DSP operating in the system. Providing the RM handle to the LLDs effectively registers the RM with the LLD and informs the LLD that it should check initialization and usage permissions for all covered resources.

It is the job of the system integrator, or application developer, to set the LLD resource permissions prior to compile time. A resource table must be defined and passed as an argument to the "master" DSP core via the RM initialization function. The RM initialization function will parse the resource table and transfer all defined resource permissions to the internal resource permission tables in global memory. Upon completion of the transfer the "master" core will write to a global synchronization object, signalling to the "slave" DSP cores that the internal permission tables have been populated. Each "slave" core will then invalidate the entire permission table so that no further cache invalidate operations need to be performed when checking resource permissions in the data path. The upfront cache invalidate operation is possible because the RM LLD does not allow dynamic resource permission modifications. The permissions defined by the system integrator and loaded during RM initialization are static throughout the system up-time.

Using the RM LLD

Defining the Resource Table

The first step in integrating the RM LLD is defining the resource table that specifies the resource permissions for the DSPs. The resource table is an array of resource structures. Each structure specifies a resource type, the start and end range for the resource and the initialization and usage permissions for the resource for each DSP. A default resource table is delivered with the RM LLD under the resource_table/ directory. The default resource table is based on the target PDK device and gives all DSPs full permissions to all supported LLD resources.

If some resources are going to be used by another processor on the device, say Linux running on an ARM, there are two ways the system integrator can use to define the resource table. The first method, the system integrator should specify all resources that will be used by the DSPs in the resource table. Any resources that are not specified in the resource table are initialized to deny access to all DSPs by the RM LLD. The second method, the system integrator can specify all resources in the system but must make sure the resources that are used by a non-DSP processor give the DSP no permissions. The first method is preferred, and highlighted in this guide, because it provides a clear picture of the resources given to DSPs. The first method is also easier to modify if the used resources change.

A simple example for a resource table is provided below. The resources assigned in the example are not from a larger, validated example. If used to a create an example the resources assigned permissions are not enough for a system to function properly. The below code is meant as a teaching example only.

/* The Rm_Resource structure and the resource identifiers used are defined in resource_table_defs.h */
 
/** @brief RM LLD resource table permissions */
const Rm_Resource simpleResourceTable[] =
{
 /* Magic Number structure to verify RM can read the resource table */
 
 {
 /** DSP QMSS Firmware access */
 RM_RESOURCE_MAGIC_NUMBER,
 /** No start range */
 0u,
 /** No end range */
 0u,
 /** No init permissions */
 0u,
 /** No use permissions */
 0u,
 }, 
 
 /* QMSS Resource Definitions */
 
 {
 /** DSP QMSS PDSP Firmware access */
 RM_RESOURCE_QMSS_FIRMWARE_PDSP,
 /** PDSP start range */
 0,
 /** PDSP end range */
 1,
 /** Full permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS,
 /** Full use permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS, 
 },
 {
 /** DSP QMSS queue access */
 RM_RESOURCE_QMSS_QUEUE,
 /** Queue start range*/
 2000,
 /** Queue end range */
 3000,
 /** Full permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS,
 /** Full use permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS, 
 },
 {
 /** DSP QMSS accumulator channels */
 RM_RESOURCE_QMSS_ACCUMULATOR_CH,
 /** Accumulator channel start range*/
 0,
 /** Accumulator channel end range */
 7,
 /** Full permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS,
 /** Full use permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS, 
 }, 
 {
 /** DSP CPPI QMSS tx channels */
 RM_RESOURCE_CPPI_QMSS_TX_CH,
 /** CPPI QMSS tx channel start range*/
 0,
 /** CPPI QMSS tx channel end range */
 2,
 /** Full permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS,
 /** Full use permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS, 
 }, 
 {
 /** DSP CPPI QMSS rx channels */
 RM_RESOURCE_CPPI_QMSS_RX_CH,
 /** CPPI QMSS rx channel start range*/
 0,
 /** CPPI QMSS rx channel end range */
 2,
 /** Full permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS,
 /** Full use permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS, 
 }, 
 {
 /** DSP CPPI QMSS rx flows */
 RM_RESOURCE_CPPI_QMSS_FLOW,
 /** CPPI QMSS rx flow start range*/
 0,
 /** CPPI QMSS rx flow end range */
 2,
 /** Full permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS,
 /** Full use permissions for all DSPs */
 RM_RESOURCE_ALL_DSPS_FULL_PERMS, 
 }, 
 
 /* Final entry structure for RM to find the last entry of resource table */
 
 {
 /** Final entry */
 RM_RESOURCE_FINAL_ENTRY,
 /** No start range*/
 0u,
 /** No end range */
 0u,
 /** No init permissions */
 0u,
 /** No use permissions */
 0u,
 }
};
  • RM_RESOURCE_MAGIC_NUMBER - The magic number entry should ALWAYS be the first entry in the resource table. This value is used by the RM to validate the resource table prior to using it to populate the internal permission tables.
  • RM_RESOURCE_QMSS_FIRMWARE_PDSP - This entry gives all DSPs permission download the firmware for QMSS PDSP0 and PDSP1.
  • RM_RESOURCE_QMSS_QUEUE - This entry gives all DSPs permission to initalize and use QMSS queues 2000 through 3000.
  • RM_RESOURCE_QMSS_ACCUMULATOR_CH - This entry gives all DSPs permission to initialize and use QM Accumulator channels 0 through 7.
  • RM_RESOURCE_CPPI_QMSS_TX_CH - This entry gives all DSPs permission to initialize and use CPPI QM transmit channels 0 through 2.
  • RM_RESOURCE_CPPI_QMSS_RX_CH - This entry gives all DSPs permission to initialize and use CPPI QM receive channels 0 through 2.
  • RM_RESOURCE_CPPI_QMSS_FLOW - This entry gives all DSPs permission to initialize and use CPPI QM flows 0 through 2.
  • RM_RESOURCE_FINAL_ENTRY - The final entry should ALWAYS be the last entry in the resource table. This value is used by the RM to stop parsing the resource table.

The RM LLD will read this resource table and transfer the permissions specified to the internal permission tables. All resources that have been left unspecified will be assigned deny permissions for all DSPs.

Placing the RM LLD Permission Tables

The RM LLD internal permission tables contain the permissions for all DSP cores. Therefore, the tables are global and placed into the ".rm" memory section. Similar to the QMSS ".qmss", and CPPI ".cppi" sections, this memory section MUST be manually placed in shared memory (MSMC or DDR) via the linker command file.

Initializing the RM LLD

The RM LLD has two initialization APIs that are used based on the context in which the application runs. The Rm_init API is the primary initialization routine and should be called on the "master" DSP core. The Rm_start routine should be called on all other "slave" DSP cores. Both APIs should be called prior to any other LLD init/start routines. The Rm_init function should be passed a pointer to the resource table. The Rm_init function will validate and parse the resource table, using it to populate the internal permission tables. When the RM completes populating the internal permissions table the Rm_init will write to a global synchronization object to sync with all slave DSP cores who have invoked the Rm_start API. The slave cores that have invoked Rm_start will stop spinning once the global synchronization has been written. At this time Rm_start will invalidate all internal permission tables so that no further cache invalidate operations need to be performed when checking resource permissions in the data path. The upfront cache invalidate operation is possible because the RM LLD does not allow dynamic resource permission modifications. The permissions defined by the system integrator and loaded during RM initialization are static throughout the system up-time.

Registering RM with LLDs

The RM must be registered with a LLD in order for the LLD to perform resource permission checks. If the RM is not registered with a LLD the LLD will operate as if the RM LLD is not there. This maintains full backwards compatability with existing applications not using the RM LLD. In order to register the RM LLD with LLDs the following steps should be taken

  • Get a Rm_Handle via the Rm_getHandle API on each DSP that uses the RM LLD.
  • Register the RM LLD with other LLDs by passing the Rm_Handle to the LLD's _startCfg API. Again, this should be performed on all DSP cores using the RM LLD. NoteNote: The master core for the QMSS LLD should have the Rm_Handle registered via the Qmss_init API. This is done by passing the Rm_Handle inside the Qmss_GlobalConfigParams structure.

When a LLD has registered with the RM the LLD will invoke permission check callouts to the RM whenever supported resources are initialized or requested. A permission denied or approved response will be given back to the invoking LLD based on the permissions stored in the RM LLD for the resource.

RM LLD Initialization Example

The following code snippet shows how to initialize the RM LLD and register it with other LLDs on "master" and "slave" DSP cores.

/* DSP Master is Core 0 */
#define DSP_MASTER_CORE 0
 
/* Global PA instance */
Pa_Handle paInst;
 
/* Externally defined resource table */
extern Rm_Resource simpleResourceTable[];
 
Void main (Void)
{
 Rm_Handle rmHandle;
 Qmss_StartCfg qmssStartCfg;
 Cppi_StartCfg cppiStartCfg;
 Pa_StartCfg paStartCfg;
 
 paSizeInfo_t paSize;
 paConfig_t paCfg;
 int sizes[pa_N_BUFS];
 int aligns[pa_N_BUFS];
 void* bases[pa_N_BUFS];
 
 if (DNUM == DSP_MASTER_CORE) 
 {
 /* Master DSP Core */
 
 /* Initialize RM and provide the resource table */
 Rm_init(rmTestResourceTable);
 
 /* Get the Rm_Handle to register with LLDs */
 rmHandle = Rm_getHandle();
 
 /* Configure Qmss_InitCfg and Qmss_GlobalConfigParams values */
 
 /* Add the Rm_Handle to the Qmss_GlobalConfigParams structure */
 qmssGblCfgParams.qmRmHandle = rmHandle;
 
 /* Initialize QMSS and register RM */
 Qmss_init(&qmssInitConfig, &qmssGblCfgParams);
 
 /* Initialize CPPI */
 Cppi_init (&cppiGblCfgParams);
 
 /* Register RM with CPPI */
 cppiStartCfg.rmHandle = rmHandle;
 Cppi_startCfg (&cppiStartCfg);
 }
 else
 {
 /* Slave DSP Core */
 
 /* Wait for master core to complete RM initialization */
 Rm_start();
 
 /* Get the Rm_Handle to register with LLDs */
 rmHandle = Rm_getHandle();
 
 /* Start QMSS and register RM */
 qmssStartCfg.rmHandle = rmHandle;
 Qmss_startCfg (&qmssStartCfg);
 
 /* Register RM with CPPI */
 cppiStartCfg.rmHandle = rmHandle;
 Cppi_startCfg (&cppiStartCfg);
 
 }
 
 /* Initialize PA, done from each core */
 
 /* Get a PA buffer */
 Pa_getBufferReq(&paSize, sizes, aligns);
 
 /* Create a PA instance */
 Pa_create (&paCfg, bases, &paInst);
 
 /* Register RM with PA */
 paStartCfg.rmHandle = rmHandle;
 Pa_startCfg (paInst, &paStartCfg);
 
}

For a working example please see the rm_testproject under the test/ directory of the RM LLD.

Chip Support Library (CSL)

The Chip Support Library constitutes a set of well-defined APIs that abstract low-level details of the underlying SoC device so that a user can configure, control (start/stop, etc.) and have read/write access to peripherals without having to worry about register bit-field details. The CSL services are implemented as distinct modules that correspond with the underlying SoC device modules themselves. By design, CSL APIs follow a consistent style uniformly across Processor Instruction Set Architecture and are independent of the OS. This helps in improving portability of code written using the CSL.

CSL is realized as twin-layer – a basic register-layer and a more abstracted functional-layer. The lower register layer comprises of a very basic set of macros and type definitions. The upper functional layer comprises of “C” functions that provide an increased degree of abstraction, but intended to provide “directed” control of underlying hardware.

It is important to note that CSL does not manage data movement over underlying h/w devices. Such functionality is considered a prerogative of a device driver and serious effort is made to not blur the boundary between device driver and CSL services in this regard.

CSL does not model the device state machine. However, should there exist a mandatory (hardware-dictated) sequence (possibly atomically executed) of register reads/writes to setup the device in chosen “operating modes” as per the device data sheet, then CSL does indeed support services for such operations.

The CSL services are decomposed into modules, each following the twin layer of abstraction described above. The APIs of each such module are completely orthogonal (the API of one module does not internally call API of another module) and do not allocate memory dynamically from within. This is key to keeping CSL scalable to fit the specific usage scenarios and ease the effort to ROM a CSL-based application.

The source code of the CSL is located under $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\csl directory.

Note: The CSL is built with LLD using same script. Please refer the LLD build section for details.

Chip Support Library Summary
Component Type Library
Install Package PDK
Install Directory pdk_c6678x_<version>\packages\ti\csl
pdk_c6670x_<version>\packages\ti\csl
pdk_c6657x_<version>\packages\ti\csl
Project Type Eclipse RTSC
Endian Support Little & Big
Linker Path $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\csl
$(TI_PDK_C6670_INSTALL_DIR)\packages\ti\csl
$(TI_PDK_C6657_INSTALL_DIR)\packages\ti\csl
Linker Sections .vecs , .switch, .args, .cio
Section Preference L2 Cache
Include Paths $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\csl
$(TI_PDK_C6670_INSTALL_DIR)\packages\ti\csl
$(TI_PDK_C6657_INSTALL_DIR)\packages\ti\csl
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources Chip support library
Downloads Product Updates
License BSD


Low Level Drivers

The Low Level Drivers (LLDs) provide interfaces to the various peripherals on your SoC Device.

The source code for the LLDs is located under $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv directory.

The following table shows PDK LLD vs. SoC availability.

Driver C6678

C6670/
TCI6618

C6657
CSL X X X
RM X X X
QMSS X X X
PKTDMA (CPPI) X X X
PA X X  
SA X X  
SRIO X X X
PCIe X X X
Hyperlink X X X
TSIP X     
EDMA3 X X X
FFTC   X  
TCP3d   X X
TCP3e   X  
BCP    X  
AIF2   X  
EMAC     X


Driver Library Summary
Component Type Library
Install Package PDK
Install Directory pdk_c6678x_<version>\packages\ti\drv
pdk_c6670x_<version>\packages\ti\drv
pdk_c6657x_<version>\packages\ti\drv
Project Type Eclipse RTSC
Endian Support Little & Big
Linker Path $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\drv
$(TI_PDK_C6670_INSTALL_DIR)\packages\ti\drv
$(TI_PDK_C6657_INSTALL_DIR)\packages\ti\drv
Linker Sections N/A
Section Preference N/A
Include Paths $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\drv
$(TI_PDK_C6670_INSTALL_DIR)\packages\ti\drv
$(TI_PDK_C6657_INSTALL_DIR)\packages\ti\drv
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources Chip support library
Downloads Product Updates
License BSD



Resource Manager (RM)

The RM low level driver provides the integrator a mechanism for assigning DSP initialization and usage permissions to various device resources. For more information on how to utilize the RM and which resources are covered by the RM please see the Resource Manager (RM) LLD section.

Additional documentation can be found in:

Document Location
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\rm\docs\rmlldDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_RM_LLD.pdf



EDMA3 Low Level Driver

EDMA3 Low Level Driver is targeted to users (device drivers and applications) for submitting and synchronizing EDMA3-based DMA transfers.

EDMA3 is a peripheral that supports data transfers between two memory-mapped devices. It supports EDMA as well as QDMA channels for data transfer. This peripheral IP is re-used in different SoCs with only a few configuration changes like number of DMA and QDMA channels supported, number of PARAM sets available, number of event queues and transfer controllers, etc. The EDMA3 peripheral is used by other peripherals for their DMA needs. Thus, the EDMA3 Driver needs to cater to the device driver requirements of these peripherals as well as other application software that may need to use DMA services.

The EDMA3 LLD consists of an EDMA3 Driver and EDMA3 Resource Manager. The EDMA3 Driver provides functionality that allows device drivers and applications for submitting and synchronizing with EDMA3-based DMA transfers. In order to simplify the usage, this component internally uses the services of the EDMA3 Resource Manager and provides one consistent interface for applications or device drivers.

EDMA3 Driver Summary
Component Type Library
Install Package EDMA3 Low level drivers
Install Directory <root_install_dir>/edma3_lld_02_11_01_02
Project Type N/A
Endian Support Little and Big
Library Name edma3_lld_drv.ae66 (little endian) and edma3_lld_drv.ae66e (big endian)
Linker Path N/A
Linker Sections N/A
Section Preference N/A
Include Paths N/A
Reference Guides See docs under install directory
Support Technical Support
Additional Resources Programming the EDMA3 using the Low-Level Driver (LLD)
Downloads Product Updates
License BSD


Multicore Navigator

Multicore Navigator provides multicore-safe communication while reducing load on DSPs in order to improve overall system performance.

Packet DMA (CPPI)

The CPPI low level driver can be used to configure the CPPI block in CPDMA for the Packet Accelerator (PA). The LLD provides resource management for descriptors, receive/transmit channels and receive flows.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\cppi\docs\ CPPI_QMSS_LLD_SDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\cppi\docs\cppilldDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_CPPI_LLD.pdf


NoteNote: As of BIOS-MCSDK 2.0.8 applications that configure the CPPI OSAL to allocate memory from an IPC SharedRegion heap may need to change. Changes are required only if the Cppi_init() function executes prior to the Ipc_attach() function. If the latter case occurs the Cppi_init() will attempt to allocate a block of memory from the SharedRegion heap located in shared memory. However, because Ipc_attach() has not executed yet the SharedRegion will not be configured. This will cause a default to allocate from a local heap in L2. The block pointer returned by this local heap will at some point be used by a remote core, expecting the CPPI heap to be shared. This will corrupt anything located in the remote core's memory located at the value of the block pointer.

Applications which suffer from the latter issue must create a static heap at compile time for use by CPPI. The heap can be provided to the CPPI LLD via new APIs. In the application source code at the following:

#define SIZE_CPPI_HEAP 1024 /* Should be sized large enough to fit all shared
 * CPPI channel and flow objects */
 
/* Statically created shared heap for CPPI since IPC does create a
 * shared heap for SharedRegion prior to Ipc_attach */
#pragma DATA_SECTION (cppiHeap, ".cppi_heap");
#pragma DATA_ALIGN (cppiHeap, 128)
UInt8 cppiHeap[SIZE_CPPI_HEAP];
 
Int32 systemInit (Void)
{
 Cppi_InitCfg cppiHeapInit; /* Static CPPI heap */
 
 ...
 
 /* Configure Cppi_init() parameters to configure static heap */
 cppiHeapInit.heapParams.staticHeapBase = &cppiHeap[0];
 cppiHeapInit.heapParams.staticHeapSize = SIZE_CPPI_HEAP;
 cppiHeapInit.heapParams.heapAlignPow2 = 7; /* Power of 7 (128 byte) */
 cppiHeapInit.heapParams.dynamicHeapBlockSize = -1; /* Shut off malloc if block runs out */
 result = Cppi_initCfg (&cppiGblCfgParams, &cppiHeapInit);
 if (result != CPPI_SOK)
 {
 Error...
 }
 
 ...
 
}
 
Int main(Int argc, Char* argv[])
{
 Int32 result = 0;
 
 selfId = CSL_chipReadReg (CSL_CHIP_DNUM);
 
 /* System initializations for each core. */
 if (selfId == 0) 
 {
 /* SRIO, QMSS, and CPPI system wide initializations are run on
 * this core */
 result = systemInit();
 }
 
 ...
 
}

In the application linker command file or XDC configuration place the static CPPI heap into shared memory.

If using XDC .cfg file to add sections to the linker command file:
Program.sectMap[".cppi_heap"] = new Program.SectionSpec();
Program.sectMap[".cppi_heap"] = "MSMCSRAM";
If explicitly placing the heap in the application linker command file:
.cppi_heap: load >> MSMCSRAM


Queue Manager (QMSS)

The QMSS low level driver provides the interface to Queue Manager Subsystem hardware which is part of the Multicore Navigator functional unit for a KeyStone device. QMSS provides a hardware-assisted queue system and implements fundamental operations such as en-queue and de-queue, descriptor management, accumulator functionality and configuration of infrastructure DMA mode. The LLD provides APIs to get full entitlement of supported hardware functionality.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\qmss\docs\ CPPI_QMSS_LLD_SDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\qmss\docs\qmsslldDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_QMSS_LLD.pdf


Network Co-processor (NETCP)

NETCP provides hardware accelerator functionality for processing Ethernet packets.

Security Accelerator (SA)

The SA, also known as cp_ace (Adaptive Cryptographic Engine), is designed to provide packet security for IPsec, SRTP and 3GPP industry standards. The SA LLD provides APIs to abstract configuration and control between application and the SA. Similar to the PA LLD, it does not provide a transport layer. The Multicore Navigator is used to exchange control packets between the application and the SA firmware.

NoteNote: Due to export control restrictions the SA driver is a separate download from the rest of the MCSDK. See download link in the Related Software link above.


Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_SA_LLD_<ver>_INSTALL_DIR)\sasetup\docs\UserGuide_SA_LLD.pdf
API Reference Manual $(TI_SA_LLD_<ver>_INSTALL_DIR)\sasetup\packages\ti\drv\sa\docs\doxygen\sa_lld_docs.chm
Release Notes $(TI_SA_LLD_<ver>_INSTALL_DIR)\sasetup\packages\ti\drv\sa\docs\ReleaseNotes_SA_LLD.pdf


Packet Accelerator (PA)

The PA LLD is used to configure the hardware PA and provides an abstraction layer between an application and the PA firmware. This does not include a transport layer. Commands and data are exchanged between the PA and an application via the Mutlicore Navigator.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\pa\docs\pa_sds.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\pa\docs\paDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_PA_LLD.pdf


I/O and Buses

Serial RapidIO (SRIO)

The SRIO Low Level Driver provides a well defined standard interface which allows application to send and receive messages via the SRIO peripheral.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\docs\SRIO_SDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\srio\docs\api_ref.html
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_SRIODriver.pdf


Peripheral Component Interconnect Express (PCIe)

The PCIe module supports dual operation mode: End Point (EP or Type0) or Root Complex (RC or Type1). This driver focuses on EP mode but it also provides access to some basic RC configuration/functionality. The PCIe subsystem has two address spaces. The first (Address Space 0) is dedicated for local application registers, local configuration accesses and remote configuration accesses. The second (Address Space 1) is dedicated for data transfer. This PCIe driver focuses on the registers for Address Space 0.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\pcie\docs\pcieDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_PCIE_LLD.pdf


Antenna Interface (AIF2)

This AIF2 low level driver aims at generalizing the configuration of AIF2 for different modes (CPRI/OBSAI/ABTLib/Generic packet, WCDMA/LTE/Dual mode). The AIF2 LLD makes use of Chip Support Library and CPPI/QMSS Low Level Drivers (LLDs). This driver is only supported in C6670.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C6670_INSTALL_DIR)\packages\ti\drv\aif2\docs\AIF2-c6670_usersguide.pdf
API Reference Manual $(TI_PDK_C6670_INSTALL_DIR)\packages\ti\drv\aif2\docs\AIF2-c6670_apireferenceguide.html
Release Notes $(TI_PDK_C6670_INSTALL_DIR)\docs\ReleaseNotes_AIF2_LLD.pdf


TSIP

The TSIP is multi-link serial interface consisting of a maximum of eight transmit data signals (or links), eight receive data signals (or links), two frame-sync input signals, and two serial clock inputs. Internally, the TSIP offers multiple channels of time-slot data management and multi-channel DMA capability that allow individual time-slots to be selectively processed. The LLD provides a well-defined standard interface which allows application to configure the peripheral.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tsip\docs\tsipDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_TSIP_LLD.pdf


Hyperlink

The Hyperlink peripheral provides a high-speed, low-latency, and low-power point-to-point link between two Keystone (SoC) devices. The peripheral is also known as vUSR and MCM. Some chip-specific definitions in CSL and documentation may have references to the old names. The LLD provides a well defined standard interface which allows application to configure this peripheral.

NoteNote: Hyperlink is a point-to-point peripheral, so can only support communication between two devices.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\hyplnk\docs\hyplnkDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_HYPLNK_LLD.pdf


Ethernet Media Access Controller (EMAC)

The device driver exposes a set of well defined API which is used by the application layer to send and receive data packets via the EMAC peripheral, and configure and monitor PHY via the MDIO peripheral. The driver also exposes a set of well defined OS abstraction API which is used to ensure that the driver is OS independent and portable. The EMAC driver uses the CSL EMAC functional layer for all EMAC MMR accesses.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\emac\docs\doxygen\emac.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\docs\ReleaseNotes_EMAC_LLD.pdf


Co-processors

Bit-rate Coprocessor (BCP)

The BCP driver is divided into 2 layers: Low Level Driver APIs and High Level APIs. The Low Level Driver APIs provide BCP MMR access by exporting register read/write APIs and also provides some useful helper APIs in putting together BCP global and sub-module headers required by the hardware. The BCP Higher Layer provides APIs useful in submitting BCP requests and retrieving their results from the BCP engine.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\bcp\docs\BCP_SDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\bcp\docs\bcpDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\bcp\docs\ReleaseNotes_BCPDriver.pdf


Turbo Coprocessor Decoder (TCP3d)

The TCP3 decoder driver provides a well-defined standard interface which allows the application to send code blocks for decoding and receive hard decision and status via EDMA3 transfers.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tcp3d\docs\TCP3D_DriverSDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tcp3d\docs\TCP3D_DRV_APIIF.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tcp3d\docs\ReleaseNotes_TCP3DDriver.pdf


Turbo Coprocessor Encoder (TCP3e)

The TCP3 Encoder driver provides a well-defined standard interface which allows the application to send code blocks for encoding and receive encoded bits via EDMA3 transfers.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tcp3e\docs\TCP3E_DriverSDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tcp3e\docs\TCP3E_DRV_APIIF.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\tcp3e\docs\ReleaseNotes_TCP3EDriver.pdf


FFT Accelerator Coprocessor(FFTC)

The FFTC driver is divided into 2 layers: Low Level Driver APIs and High Level APIs. The Low Level Driver APIs provide FFTC MMR access by exporting register read/write APIs and also provides some useful helper APIs in putting together FFTC control header, DFT size list, etc. as required by the hardware. The FFTC Higher Layer provides APIs useful in submitting FFT requests and retrieving their results from the FFTC engine without having to know all the details of the Multicore Navigator.

Additional documentation can be found in:

Document Location
Hardware Peripheral Users Guide User Guide
LLD Users Guide $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\fftc\docs\FFTC_SDS.pdf
API Reference Manual $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\fftc\docs\fftcDocs.chm
Release Notes $(TI_PDK_C66##_INSTALL_DIR)\packages\ti\drv\fftc\docs\ReleaseNotes_FFTCDriver.pdf



Platform Library

The platform library defines a standard interface for platform utilities and functionality and provides sample implementations for the EVM platform. These include things such as reading and writing to EEPROM, FLASH, UART, etc. Platform library supports three libraries:

  1. debug library (e.g., ti.platform.evm6678l.ae66) - located under \platform_lib\lib\debug, needed only when a debug is needed on the platform library since the source is compiled with full source debugging.
  2. release library (e.g., ti.platform.evm6678l.ae66) - located under \platform_lib\lib\release, should be used normally for the best performance of the cycles since the code is compiled with the full optimization.
  3. lite library (e.g., ti.platform.evm6678l.lite.lib) - \platform_lib\lib\debug, not needed for regular platform development - this is used to link for the Power On Self Test (POST) application.
Platform Library Summary
Component Type Library
Install Package PDK for C66X
Install Directory pdk_c6657_<version>\packages\ti\platform\evm6657l\platform_lib

pdk_c6670_<version>\packages\ti\platform\evm6670l\platform_lib pdk_c6678_<version>\packages\ti\platform\evm6678l\platform_lib

Project Type CCS
Endian Support Little
Library Name Select for the C6678L EVM

ti.platform.evm6678l.ae66 (little)

Linker Path $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\platform\evmc6678l\platform_lib\lib\debug - for debug version
$(TI_PDK_C6678_INSTALL_DIR)\packages\ti\platform\evmc6678l\platform_lib\lib\release - for release version


(similar paths for C6670, C6657)

Linker Sections platform_lib
Section Preference none
Include Paths $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\platform


(similar paths for C6670, C6657) platform.h defines the interface

Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources Texas Instruments Embedded Processors Wiki
Downloads Product Updates
License BSD

Platform Library Migration Information

The below table provides the migration information for the platform library for maintenance updates to the BIOS-MCSDK 2.0.0 production release:


Release API Change Migration Notes
BIOS-MCSDK 2.0.2
 
 
Added Platform_STATUS platform_get_emac_info(uint32_t port_num, PLATFORM_EMAC_EXT_info * emac_info)  
Deprecated the efuse_mac_address[6], eeprom_mac_address[6] fields in EMAC_info structure as MAC address is now defined in the new data structure PLATFORM_EMAC_EXT_info Use PLATFORM_EMAC_EXT_info structure for MAC address
Added Platform_STATUS platform_get_macaddr(PLATFORM_MAC_TYPE type, uint8_t * mac_address);  
BIOS-MCSDK 2.0.5
 
 
No Platform library API change Updated the main PLL, DDR3 PLL and PA PLL sequences. Please refer to \platform_lib\src\evm667#.c file for the updates.


Transport

Transports are intermediate drivers that sit between either the NDK or IPC sub-systems and interface them to the appropriate EVM peripherals. The transports supported by MCSDK are:

  • NDK transport - Network Interface Management Unit (NIMU) Driver
  • QMSS IPC transport - IPC MessageQ transport utilizing QMSS
  • SRIO IPC transport - IPC MessageQ transport utilizing SRIO

More information on these can be found in the NDK or IPC sections of this guide.


SYS/BIOS RTOS

SYS/BIOS is a scalable real-time kernel. It is designed to be used by applications that require real-time scheduling and synchronization or real-time instrumentation. SYS/BIOS provides preemptive multi-threading, hardware abstraction, real-time analysis, and configuration tools. SYS/BIOS is designed to minimize memory and CPU requirements on the target.

SYS/BIOS Summary
Component Type Libraries
Install Package SYS/BIOS
Install Directory bios_6_<version>\
Project Type Eclipse RTSC
Endian Support Little and Big
Library Name The appropriate libraries are selected for your device and platform as set in the RTSC build properties for your project and based on the use module statements in your configuration.
Linker Path The appropriate path is selected to the libraries for your device and platform as set in the RTSC build properties for your project.
Linker Sections N/A
Section Preference N/A
Include Paths

BIOS_CG_ROOT is set automatically by CCS based on the version of BIOS you have checked to build with.
${BIOS_CG_ROOT}\packages\ti\bios\include

Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources SYS/BIOS Online Training
SYS/BIOS 1.5-DAY Workshop
Eclipse RTSC Home
Downloads

SYS/BIOS Downloads

License BSD


Inter-Processor Communication (IPC)

Inter-Processor Communication (IPC) provides communication between processors in a multi-processor environment, communication to other threads on same processor, and communication to peripherals. It includes message passing, streams, and linked lists.

IPC can be used to communicate with the following:

  • Other threads on the same processor
  • Threads on other processors running SYS/BIOS
  • Threads on GPP processors running SysLink (e.g., Linux)
IPC Summary
Component Type Libraries
Install Package IPC
Install Directory ipc_<version>\
Project Type Eclipse RTSC
Endian Support Little and Big
Library Name The appropriate libraries are selected for your device and platform as set in the RTSC build properties for your project and based on the use module statements in your configuration.
Linker Path The appropriate path is selected to the libraries for your device and platform as set in the RTSC build properties for your project.
Linker Sections N/A
Section Preference N/A
Include Paths N/A
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources Eclipse RTSC Home
Downloads IPC Downloads
License BSD


IPC Transports

QMSS IPC Transport

The QMSS transport is an additional transport for IPC. The QMSS transport can be used by MessageQ to send data between tasks and cores via the QMSS IP block. This package has a QMSS transport unit test/benchmark example for all supported platforms.


NoteNote: This module is only intended to be used with IPC MessageQ. As such, users should not tie up to its API directly.

QMSS IPC Transport Summary
Component Type Library
Install Package PDK_C6678_INSTALL_DIR
Install Directory mcsdk_<version>\packages\ti\transport\ipc\qmss
Project Type Eclipse RTSC
Endian Support Little, Big
Library Name ti.transport.ipc.qmss.transports.ae66 (little)
ti.transport.ipc.qmss.transports.ae66e (big)
Linker Path $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ipc\qmss\transports\lib\whole_program_debug
Reference Guides None
Support Technical Support
Additional Resources The QMSS IPC Transport benchmark example is available in
$(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ipc\examples\qmssIpcBenchmark
Downloads http://focus.ti.com/docs/toolsw/folders/print/bioslinuxmcsdk.html
License BSD


The MessageQ communication architecture utilizing the QMSS IPC transport is shown below.
QMSS_Transport.JPG


SRIO IPC Transport

The SRIO transport is an additional transport for IPC. The SRIO transport can be used by MessageQ to send data between tasks, cores, and chips via the SRIO IP block. This package has SRIO transport unit test and benchmark examples for all supported platforms.


NoteNote: This module is only intended to be used with IPC MessageQ. As such, users should not tie up to its API directly.

SRIO IPC Transport Summary
Component Type Library
Install Package PDK_C6678_INSTALL_DIR
Install Directory mcsdk_<version>\packages\ti\transport\ipc\srio
Project Type Eclipse RTSC
Endian Support Little, Big
Library Name ti.transport.ipc.srio.transports.ae66 (little)
ti.transport.ipc.srio.transports.ae66e (big)
Linker Path $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ipc\srio\transports\lib\whole_program_debug
Reference Guides None
Support Technical Support
Additional Resources The SRIO IPC Transport benchmark example is available in
$(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ipc\examples\srioIpcBenchmark
The SRIO IPC Transport Chip to Chip example is available in
$(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ipc\examples\srioIpcChipToChipExample
Downloads http://focus.ti.com/docs/toolsw/folders/print/bioslinuxmcsdk.html
License BSD


The MessageQ communication architecture utilizing the SRIO IPC transport is shown below. SRIOtransport.PNG


Rebuilding the IPC Transports

For experimentation and debug the QMSS and SRIO transports can be rebuilt following the below instructions.

  1. [Optional - Required for debug single stepping] Modify the transports config.bld file C66LE/BE.ccOpts.prefix to remove optimization and add symbolic debug
    From: "-mo -o3 -q -k -eo.o"
    To: "-mo -g -q -k -eo.o"
  2. From a command prompt navigate to the pdk\packages\ti\transport\ipc\(qmss or srio) directory
  3. Configure the XDCPATH environment variable with the BIOS and IPC install locations:
    set XDCPATH=c:\ti\bios_w_xx_yy_zz\packages\
    set XDCPATH=%XDCPATH%;c:\ti\ipc_w_xx_yy_zz\packages\
  4. Configure the XDCCGROOT environment variable with the compiler install path (Using CGT 7.2.4 installed as part of CCS as an example)
    set XDCCGROOT=c:\ti\ccsv5\tools\compiler\c6000_7.2.4
  5. Add the XDC Tools to your system PATH
    set PATH=%PATH%;c:\ti\xdctools_w_xx_yy_zz\
  6. Clean the transport
    >xdc clean -PR .
  7. Build the transport
    >xdc -PR .

The transport example projects can now be rebuilt via CCS with the debug profile. The example code as well as the transport code can be single stepped after rebuilding the transport with symbolic debug.

Note: To allow single-step debug of the IPC and BIOS source rebuild the example projects with the following command added to the example's .cfg file
BIOS.libType = BIOS.LibType_Debug;

IPC Flow

This section provides ladders diagrams showing the execution flow that takes place when multiple cores access shared resources or exchange data using IPC. Not all function calls and input parameters are described in the ladder diagram. However, enough detail is provided to show how different cores share resources without stepping on one another.

IPC Overview

A high-level ladder diagram showing how two cores would share a heap, MessageQ queues, and exchange a message using IPC ipc_overview_ladder.JPG


IPC Startup

This ladder diagram shows how two cores initialize and attach to one another via IPC: ipc_startup_ladder.JPG


IPC Heap Sharing

This ladder diagram shows how two cores initialize and share a global heap for allocating and freeing messages: ipc_heap_ladder.JPG


IPC MessageQ Queue Sharing

This ladder diagram shows how two cores search for, and find MessageQ queues located on remote cores: ipc_messageq_ladder.JPG


IPC Shared Memory Transport Message Passing

This ladder diagram shows how two cores allocate, send, receive, and free MessageQ messages over the Shared Memory transport: ipc_shared_mem_ladder.JPG


IPC QMSS Transport Message Passing

This ladder diagram shows how two cores allocate, send, receive, and free MessageQ messages over the QMSS transport: ipc_qmss_ladder.JPG


IPC Module Usage for Different Transports

When different IPC transports are used by an application some IPC modules may cease to function due to the system architecture. The system architecture dictates the IPC transport used. For example, chip to chip data transfer over MessageQ would be handled by the SRIO transport since SRIO established a transport path between two chips. This is something the Shared Memory and QMSS/Navigator transports are incapable of. The following describes which modules delivered in the IPC component are functional for each IPC transport.

Shared Memory IPC Transport

The Shared Memory transport is delivered with the IPC component package. The Shared Memory transport is the default IPC transport. As such, all modules delivered in IPC are functional and useable with the Shared Memory transport within the context of a single chip. The Shared Memory transport is delivered with IPC and used by default since it fits the generality module of IPC. It is the only transport that can be used when the architecture of the chip is not known.


Useable IPC Modules
IPC Component Supported? Comments
IPC YES Required to start IPC regardless of transport
MessageQ YES Can use Shared Memory transport to send messages between threads on the same core and cores on the same chip
Heap*MP YES Messages allocated from shared memory on a source thread/core using a Heap*MP then sent over the Shared Memory transport can be freed on the destination thread/core
GateMP YES Can be used to synchronize threads/cores communicating over the Shared Memory transport
Notify YES Used to generate interrupt on destination core signalling there is a message available for it to receive on over the Shared Memory transport
SharedRegion YES Specifies the IPC Shared Region from which Heaps, MessageQ queues, and Shared Memory transport FIFOs should be allocated
MultiProc YES Specifies the cores within the system that the Shared Memory transport can transport messages between
NameServer YES Used to service MessageQ, Heap, and Gate _open requests between cores which intend to communicate over the Shared Memory transport


QMSS/Navigator IPC Transport

The QMSS/Navigator transport is delivered with the PDK component packages. The QMSS/Navigator transport is a platform specific IPC transport that uses QMSS resources on the PDK platform. The QMSS/Navigator transport allows communication between threads on the same core and cores on the same chip. This is similar to the Shared Memory transport except the Navigator QMSS queues are used to move the message instead of shared memory. As such, all modules delivered in IPC are functional and useable with the QMSS/Navigator transport within the context of a single chip.


Useable IPC Modules
IPC Component Supported? Comments
IPC YES Required to start IPC regardless of transport
MessageQ YES Can use QMSS/Navigator transport to send messages between threads on the same core and cores on the same chip
Heap*MP YES Messages allocated from shared memory on a source thread/core using a Heap*MP then sent over the QMSS/Navigator transport can be freed on the destination thread/core
GateMP YES Can be used to synchronize threads/cores communicating over the QMSS/Navigator transport
Notify YES but... Is not directly used by the QMSS/Navigator transport which generates an interrupt on the destination core via QMSS queue interrupt mechanisms. However, since the QMSS/Navigator transport works within the context of a single chip the Notify module can still be used to generate interrupts, out-of-band from the QMSS/Navigator transport, to different cores on the chip
SharedRegion YES Specifies the IPC Shared Region from which Heaps, and MessageQ queues should be allocated
MultiProc YES Specifies the cores within the system that the QMSS/Navigator transport can transport messages between
NameServer YES Used to service MessageQ, Heap, and Gate _open requests between cores which intend to communicate over the QMSS/Navigator transport


SRIO IPC Transport

The SRIO transport is delivered with the PDK component packages. The SRIO transport is a platform specific IPC transport that uses SRIO and QMSS resources on the PDK platform. The SRIO transport allows communication between threads on the same core, cores on the same chip, and cores on different chips. When the SRIO transport is used to transport messages between entities within the same chip all IPC modules are useable, similar to the Shared Memory and QMSS/Navigator transports. However, when the SRIO transport is used to transport messages between entities on two separate chips only a subset of the IPC modules are useable. This is due to the assumption that there are no shared resources, such as hardware semaphores or shared memory, between two chips. The only thing connecting the chips are the SRIO lanes.


Useable IPC Modules When Communicating Between Cores on Different Chips
IPC Component Supported? Comments
IPC YES Required to start IPC regardless of transport
MessageQ YES Can use SRIO transport to send messages between cores on different chips
Heap*MP NO Any heaps opened would only be useable for cores on the chip which the Heap*MP was opened. There is no sense of a Heap*MP instance that would be shared between cores on different chips. IPC assumes there is no shared memory between chips
GateMP NO Any gates used would only be synchronize cores on the chip which the Gate was opened. There is no sense of a Gate instance that would be shared between cores on different chips. IPC assumes there are no shared hardware semaphores between chips
Notify NO IPC assumes there is no hardware or software interrupt mechanism between cores on different chips
SharedRegion NO Any SharedRegion created would only be useable by cores on the chip which the SharedRegion was defined. There is no sense of a SharedRegion between cores on different chips. IPC assumes there is no shared memory between chips for the SharedRegion to exist
MultiProc YES Specifies the cores within the system, all chips, that the SRIO transport can transport messages between
NameServer YES Used to service MessageQ_open requests between cores on different chips which intend to communicate over the SRIO transport. The SRIO transport itself is used to pass the NameServer request/response messages between the cores


IPC Benchmarks

IPC performance is measured in terms of the time (in cycles) to send a message from one core to another core and includes all cache coherency operations to ensure the message is ready for use by the receiving core. The one way latency is measured for shared memory, QMSS/Navigator, and SRIO transports.

Latency Benchmark Setup

To measure the 1-way latency a message is ping-ponged between two cores. Core 0 starts the test by sending a message to Core 1. Core 1 relays the message back to Core 0 who then sends it back to Core 1. The message ping-pongs between the two cores for a configured amount of iterations. Each time Core 0 receives the message it stores the round-trip time, in cycles, representing the total time for the message to go from Core 0 to Core 1 then back to Core 0. This measured time is divided by two to get the one-way latency. The one-way latency measurements are then averaged over all iterations to yield the average 1-way latency.

The QMSS/Navigator transport results are presented for both QPEND and Accumulator options. See IPC Transports for more information on the QPEND and Accumulator implementations.

For the SRIO transport a four 1x port and 3.125 Gbps link rate was used. Loopback mode was disabled so all packets were transferred over the SRIO lanes and not looped back in the SRIO hardware.

Benchmark Results

Shared Memory Transport QMSS Transport (QPEND) QMSS Transport (Accumulator - 1 Descriptor per Interrupt) QMSS Transport (Accumulator - 10 Descriptors per Interrupt) SRIO Transport (Type 11 - 1 packet per Interrupt) SRIO Transport (Type 11 - 10 packets per Interrupt)
Avg 1-way Latency (Cycles) 2,402 1,673 4,522 4,606 9,056 9,104

Notes:

  • -o3 compiler option
  • All debug and assert options disabled

Benchmark Comments:

  • The Shared Memory transport is the default IPC transport offering good out-of-the box performance.
  • Applications which require the very best in latency performance should use the QPEND implementation of the QMSS/Navigator transport. These queues, when pushed descriptors, interrupt the DSP directly through the INTC module. The QMSS/Navigator transport is delivered as part of PDK. For information on how to configure the QMSS/Navigator transport to use QPEND queues please see Using and Configuring the Navigator/QMSS Transport.
  • The QMSS/Navigator transport should be configured to use the Accumulator implementation if interrupt pacing is desired. The Accumulator configuration has a higher latency than its transport counterpart but offers the ability to interrupt the DSP after a number of descriptors have been pushed to an accumulator queue or after a certain amount of time has passed. For information on how to configure the QMSS/Navigator transport to use Accumulator queues, as well as configure the pacing and timeout values, please see Using and Configuring the Navigator/QMSS Transport.
  • The SRIO transport, despite a high latency, offers the ability to transfer messages between cores on different chips. This is something that is not possible with the Shared Memory or QMSS/Navigator transports. The SRIO transport is delivered as part of PDK. For information on how to configure the SRIO transport please see Using and Configuring the SRIO Transport.


The benchmark applications used to find the latency measurements are included in PDK under $(TI_PDK_C667x_INSTALL_DIR)\packages\ti\transport\ipc\examples. READMEs describing how to build and run the benchmarks are contained within the individual benchmark directories. See Explicit Programming Module Using IPC for guidance on modifying transport configuration options when rerunning the benchmark applications.


Network Development Kit (NDK)

The NDK is a platform for development and demonstration of network-enabled applications on DSP devices and includes demonstration software showcasing DSP capabilities across a range of network-enabled applications. The NDK serves as a rapid prototype platform for the development of network and packet-processing applications, or to add network connectivity to existing DSP applications for communications, configuration, and control. Using the components provided in the NDK, developers can quickly move from development concepts to working implementations attached to the network.

The NDK provides an IPv6 and IPv4 compliant TCP/IP stack working with the SYS/BIOS real-time operating system. Its primary focus is on providing the core Layer 3 and Layer 4 stack services along with additional higher-level network applications such as HTTP server and DHCP.

The NDK itself does not include any platform or device-specific software. The NDK interfaces through well-defined interfaces to the PDK and platform software elements needed for operation.

The functional architecure for NDK is shown below.
Ndkarch.png
Network Development Kit Summary
Component Type Libraries
Install Package NDK
Install Directory ndk_<version>\
Project Type Eclipse RTSC
Endian Support Little and Big
Library Name

binsrc.lib or binsrce.lib
and
cgi.lib or cgie.lib
and
console.lib or consolee.lib
and
hdlc.lib or hdlce.lib
and
miniPrintf.lib or miniPrintfe.lib
and
netctrl.lib or netctrle.lib
and
nettool.lib or nettoole.lib
and
os.lib or ose.lib
and
servers.lib or serverse.lib
and
stack.lib or stacke.lib

Linker Path $(NDK_INSTALL_DIR)\packages\ti\ndk\lib\<arch>
Linker Sections .far:NDK_OBJMEM, .far:NDK_PACKETMEM
Section Preference L2 Cache
Include Paths NDK_INSTALL_DIR is set automatically by CCS based on the version of NDK you have checked to build with.

${NDK_INSTALL_DIR}\packages\ti\ndk\inc
${NDK_INSTALL_DIR}\packages\ti\ndk\inc\tools

Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources The NDK unit test examples are available in
$(TI_MCSDK_INSTALL_DIR)\packages\ti\platform\nimu\test\evm####
Extended Support

Eclipse RTSC Home
NDK User's Guide
NDK Programmer's Reference Guide
NDK Support Package Ethernet Driver Design Guide
NDK_FAQ
Rebuilding NDK Core

Downloads NDK Downloads
License BSD


Network Interface Management Unit (NIMU) Driver

NIMU sits between NDK common software and the C6678 SoC and provides a common interface for NDK communication. This package contains NDK unit test examples for all supported platforms.


NoteNote: This module is only intended to be used with NDK. As such, users should not tie up to its API directly.


The functional architecture for NIMU (taking the C6678 platform as an example) is shown below. A similar architecture is also applicable for the C6670 platform.
Ndkarch.png


Note: The below model is applicable for C6657 platform.
Ndkarch-6657.png
NIMU Summary
Component Type Library
Install Package PDK_C6678_INSTALL_DIR
Install Directory mcsdk_<version>\packages\ti\transport\ndk\nimu
Project Type Eclipse RTSC
Endian Support Little
Library Name ti.transport.ndk.nimu.ae66 (little)
Linker Path $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ndk\nimu\lib\debug for debug version
$(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ndk\nimu\lib\release for release version
Linker Sections nimu_eth_ll2
Section Preference L2SRAM
Include Paths $(TI_PDK_C6678_INSTALL_DIR)\packages\ti\transport\ndk\nimu\include
Reference Guides None
Support Technical Support
Additional Resources The NDK unit test examples are available in
$(TI_MCSDK_INSTALL_DIR)\examples\ndk\evm####
Downloads http://focus.ti.com/docs/toolsw/folders/print/bioslinuxmcsdk.html
License BSD














Runtime Libraries

OpenEM

The Open Event Machine (OpenEM) is a multi-core runtime for KeyStone devices. TI’s implementation extensively leverages KeyStone’s multicore infrastructure and especially the Multicore Navigator. The main missions of OpenEM are to enable efficient scheduling, dispatching and load balancing of work across the cores of a KeyStone device.

In addition, OpenEM facilitate easy porting of multi-core applications from one KeyStone device to another. It is able to transfer data between global shared and local private memories and optionally manages cache coherency. Finally, it integrates well with many interfaces and accelerators as well as with different Operating Systems.

OMP Library Summary
Component Type Library
Install Package OPENEM
Install Directory openem_<version>\
Project Type Eclipse RTSC
Endian Support Little
Linker Path The appropriate path is selected to the libraries for your device and platform as set in the RTSC build properties for your project.
Linker Sections N/A
Section Preference N/A
Include Paths $(OEM_INSTALL_DIR)\packages
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources
Downloads BIOS-MCSDK
License BSD



OpenMP

OMP is an implementation of an openMP run-time library for SYS/BIOS supporting KeyStone multicore DSP devices. The library implements support for thread management, shared memory, and synchronization as required for openMP.

Combined with the TI compiler (version 7.4 or greater) a user can create OpenMP programs for TI's multicore DSPs.

OMP Library Summary
Component Type Library
Install Package OMP
Install Directory omp_<version>\
Project Type Eclipse RTSC
Endian Support Little
Linker Path The appropriate path is selected to the libraries for your device and platform as set in the RTSC build properties for your project.
Linker Sections N/A
Section Preference N/A
Include Paths $(OMP_INSTALL_DIR)\packages
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources PDK
Downloads BIOS-MCSDK
License BSD and GPL-3.0-with-GCC-exception



Algorithm Libraries

TI provides several algorithm libraries, each specific to a particular arena. Each library provides a collection of C-callable low-level functions (kernels), each tailored for optimal performance on a specific TI processing device (or devices). The libraries are typically used in computationally intensive real-time applications where execution speed is a critical factor. Their use generally accelerates execution speeds well beyond that achieved by equivalent code written in standard ANSI C. Additionally, use of these libraries can significantly reduce application development time. Source code is provided in all cases to facilitate kernel modification when needed.

See c6x Software Library mediawiki for a comprehensive overview of the various software libraries available for TI's c6x family of processors.


DSP Library (DSPLIB)

DSPLIB is an optimized DSP Function Library and includes many C-callable, optimized, general-purpose signal-processing routines including:

  • Adaptive Filtering
  • Correlation
  • Fast Fourier Transform
  • Filtering and convolution
  • Matrix
DSPLIB Summary
Component Type Library
Install Package DSPLIB
Install Directory dsplib_c66x_<version>\
Project Type CCS
Endian Support Big and Little
Library Name dsplib.a66 (COFF, little-endian)
dsplib.a66e (COFF, big-endian)
dsplib.ae66 (ELF, little-endian)
dsplib.ae66e (ELF, big-endian)
Linker Path <root_install_dir>\lib\
Linker Sections N/A
Section Preference N/A
Include Paths <root_install_dir>\inc\
<root_install_dir>\packages\
Reference Guides See docs under Install Directory
Support BIOS E2e Forum
Additional Resources c6x Software Library mediawiki
Downloads DSPLIB Downloads
License BSD


Image Processing Library (IMGLIB)

IMGLIB is an optimized image/video processing library with kernels in the following functional categories:

  • Compression & Decompression
  • Image Analysis
  • Image Filtering and Conversion
IMGLIB Summary
Component Type Library
Install Package IMGLIB
Install Directory imglib_c66x_<version>\
Project Type CCS
Endian Support Little
Library Name imglib.ae66 (ELF, little-endian)
Linker Path <root_install_dir>\lib\
Linker Sections N/A
Section Preference N/A
Include Paths <root_install_dir>\inc\
<root_install_dir>\packages\
Reference Guides See docs under Install Directory
Support BIOS E2e Forum
Additional Resources c6x Software Library mediawiki
Downloads IMGLIB Downloads
License BSD


Floating Point Math Library (MATHLIB)

MATHLIB contains optimized versions of most commonly used floating point math routines contained in the RTS library. Kernels are offered in two variations:

  • Double-precision floating point
  • Single-precision floating point
MATHLIB Summary
Component Type Library
Install Package MATHLIB
Install Directory mathlib_c66x_<version>\
Project Type CCS
Endian Support Big and Little
Library Name mathlib.a66 (COFF, little-endian)
mathlib.a66e (COFF, big-endian)
mathlib.ae66 (ELF, little-endian)
mathlib.ae66e (ELF, big-endian)
Linker Path <root_install_dir>\lib\
Linker Sections N/A
Section Preference N/A
Include Paths <root_install_dir>\inc\
<root_install_dir>\packages\
Reference Guides See docs under Install Directory
Support BIOS E2e Forum
Additional Resources c6x Software Library mediawiki
Downloads MATHLIB Downloads
License BSD


Demonstration Software

The MCSDK consist of demonstration software to illustrate device and software capabilities, benchmarks, and usage.

High-Performance DSP Utility Application (HUA)

HUA is the MCSDK out-of-box demonstration/utility application which includes a web server and has pages to query information about the platform and software versions, network statistics, network throughput benchmark, board diagnostics, flash read and write, and EEPROM read and write functions. This is a basic utility application which demonstrates basic platform functionality and how to integrate some of the basic software infrastructure (e.g., SYS/BIOS, NDK, Platform Library). The Utility is accessed from a web browser by browsing the platforms IP address (which can be assigned either as a static IP or through DHCP.) Pages available in the utility are Information, Statistics, Benchmarks, Flash, Diagnostics, and EEPROM.

See the HUA Demonstration Guide for more information.

Image Processing Demonstration

The Image Processing Demonstration illustrates the integration of key components in the MCSDK. The purpose of the demonstration is to provide a multicore software development framework on an evaluation module (EVM).

  1. Demonstrates the transfer of image data from/to DDR and internal memory. Typically, images are large and need to be stored in external memory.
  2. Operates on different segments of the same image in different DSP cores.
  3. Operates across multiple cores executing different algorithms on the same image data.
  4. Transfers input/output image to external systems (e.g., a PC).

See the Image Processing Demo Guide for more information.

Multicore Video Infrastructure Demonstration

The multicore video infrastructure demonstration includes a set of demonstration applications targeted to demonstrate the use of MCSDK for real-time multicore video processing applications. The applications include Ethernet packet-to-packet processing of video streams (transcoding, encoding, decoding) for a various common video standards, resolutions, and use cases. There are two demonstrations included:

  1. Multichannel high-density operation with low resolution
  2. Multicore processing of high resolution video codecs

See the MCSDK Video Demonstration Guide for more information.

NoteNote: The multicore video infrastructure demo is not provided as part of the MCSDK, but is provided as a separate package available here.

Bootloader and Boot Utilities

The platform package includes POST (Power On Self Test), bootloader software and utilities to write images to the EEPROM, NOR and NAND Flash.

Boot Utilities

Boot Utilities include a set of tools to configure and boot the board. These include:

  • Intermediate Boot Loader (IBL): Resides on EEPROM that supports customizing configuration for boot modes. See IBL user guide for details.
  • Examples of booting/loading images for NAND, NOR, and Ethernet
  • Write utilities for NAND, NOR, and EEPROM

The boot utilities are discussed further in the section on Booting and Flash.

Multicore Application Deployment (MAD) Utilities

The Multicore Application Deployment (MAD) is a collection of tools allows you to create a bootable image that can support multiple images and multiple cores. The premise behind MAD is to allow you to:

  • Deploy multiple applications on multiple cores.
  • Conserve memory by sharing common code.
  • Deploy an application dynamically on a core, if needed.

See MAD Utils User Guide for more details.

An example of an MCSDK application that uses MAD is the Image Processing Demo Guide.



Tools

cToolsLibrary

The cTools library provides APIs for using the individual instrumentation libraries for advanced users and also few use case based libraries that are built on top of the individual instrumentation libraries.

As shown in the figure below, the ctoolslib_sdk module provided in the package is intended to provide the glue between the use case based libraries, individual instrumentation libraries and application:

cToolsLibrary SW architecture

The ctoolslib_sdk is a collection of libraries for Advanced Event Triggering(AET), Common Platform Tracers(CPT), Ctools use case library(Ctools_UC), DSPTrace, Embedded Trace Buffer(ETB) and System Trace Module(STM) - located under \aet\lib, \CPTLib\lib, \Ctools_UCLib\lib, \DSPTraceLib\lib, \ETBLib\lib and \STMLib\lib

Ctools Library Package Summary
Component Type Library
Install Package CtoolsLibrary for C6670, C6678 and C6657
Install Directory ctoolslib_<version>
Project Type CCS
Endian Support Little & Big
Library Name Select for the C6670, C6678 or C6657 EVM

Please see GettingStarted.htm for details

Linker Path $(TI_CTOOLSLIB_INSTALL_DIR)\packages\ti\LIBRARY_NAME\lib - for release/debug version, where LIBRARY_NAME = aet, CPTLib, Ctools_UCLib, DSPTraceLib, ETBLib and STMLib.
Linker Sections none
Section Preference none
Include Paths $(TI_CTOOLSLIB_INSTALL_DIR)\packages\ti\LIBRARY_NAME\include\*.h

and ti\ctoolslib_sdk\evmc66xx\package.xdc define the interface for c66xx use case library support

Reference Guides See doc\*html*\index.html file under respective libraries for details

and CtoolsLib

Support Technical Support
Additional Resources Texas Instruments Embedded Processors Wiki
Downloads Product Updates
License BSD

Portions of cToolsLib is implemented in the Image Processing Demonstration; please refer to the Demonstration Guide for more information. Additionally, please refer to CCSv5 CtoolsLib Examples for more information and to download other supported Ctools library examples. The downloaded Examples.zip should be extracted into [<CTOOLSLIB INSTALL>\packages\ti\] location. All the examples are CCSv5 compatible.

Multicore System Analyzer (MCSA)

Multicore System Analyzer (MCSA) is a suite of tools that provide real-time visibility into the performance and behavior of your code, and allow you to analyze information that is collected from software and hardware instrumentation in a number of different ways.

Advanced tooling features of the MCSA include the following:

  • Real-time event monitoring
  • Multicore event correlation
  • Correlation of software events, hardware events and CPU trace
  • Real-time profiling and benchmarking
  • Real-time debugging

The MCSA includes two key components:

  • DVT: Various features of Data Analysis and Visualization Technology (DVT) provide the user interface for System Analyzer within Code Composer Studio (CCS).
  • UIA: The Unified Instrumentation Architecture (UIA) target package defines APIs and transports that allow embedded software to log instrumentation data for use within CCS.
MCSA Summary
Component Type Libraries
Install Package UIA + DVT
Install Directory ccsv5/uia_<version>, ccsv5/eclipse, ccsv5/ccs_base_5.0.0.*/dvt\
Project Type Eclipse RTSC
Endian Support Little
Library Name The appropriate libraries are selected for your device and platform as set in the RTSC build properties for your project and based on the use module statements in your configuration.
Linker Path The appropriate path is selected to the libraries for your device and platform as set in the RTSC build properties for your project.
Linker Sections N/A
Section Preference N/A
Include Paths N/A
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources Multicore System Analyzer
Downloads Installed as a part of BIOS MCSDK installation
UIA License BSD
DVT License TI Technology and Software Publicly Available (TSPA). See DVT Manifest in the install directory.


Eclipse RTSC Tools (XDC)

RTSC is a C-based programming model for developing, delivering, and deploying Real-Time Software Components targeted for embedded platforms. The XDCtools product includes tooling and runtime elements for component-based programming using RTSC.

XDC Summary
Component Type Tools
Install Package XDC
Install Directory xdctools_<version>\
Project Type Eclipse RTSC
Endian Support Little and Big
Library Name The appropriate libraries are selected for your device and platform as set in the RTSC build properties for your project and based on the use module statements in your configuration.
Linker Path The appropriate path is selected to the libraries for your device and platform as set in the RTSC build properties for your project.
Linker Sections systemHeap
Section Preference none
Include Paths N/A
Reference Guides See docs under Install Directory
Support Technical Support
Additional Resources

Eclipse RTSC Home
Users Guide and Reference Manual

Downloads N/A
License See XDC Manifest in the install directory


Third Party Software and Tools

Prism from Criticalblue

Prism is a multicore analysis tool provided by Critical Blue as an Eclipse plug-in which is intended to allow developers to evaluate parallelization strategies of existing sequential code upfront without implementing any code changes. This is accomplished by the developer taking their existing serial code and running it through a standard simulator (in this case our TI C66x simulator). The results from the simulator are fed into Prism, which displays the execution profile and, more importantly, uses the simulation data to allow the developers to perform what-if analysis without changing a line of code. This includes looking at data parallelization strategies and task parallelization strategies. The obvious motivation is to allow a developer to investigate various parallelization strategies without having to go through the entire process of implementation and debug which can be time consuming and requires significant effort. This enables a kind of ROI assessment for multicore prior to investment in implementation. In the end, this represents at least a good start for someone beginning to look at migration of existing applications to a multicore device.

Please see http://www.criticalblue.com/prism/ti/ for more detailed information on Prism and to get started.

Please see Image Processing Demo Analysis with Prism for notes on running Prism with the image processing demo application.

Poly-Platform from PolyCore Software

Poly-Platform by PolyCore Software, is a development framework, consisting of tools and runtime software, providing a programming model for the application to scale from one to many cores in homogenous and heterogeneous multicore environments. The tools are Eclipse plug-ins and are integrated with CCSv5 for a seamless development environment and, provide rapid development for MCAPI programming and topology configuration. Poly-Messenger, the runtime engine which is integrated with DSP BIOS, transparently handles the communications between cores and between processors across multiple transports. Applications readily move from one core to multicore to many cores using the same source code base.

Please see http://www.polycoresoftware.com/products.php for more information.


Build and Example Guide

The Build and Example Guide talks about setting up your build environment for MCSDK, how to build the various components, and then walks you through a set of example programs that are designed to teach you how to start writing programs using the software development kit.


Setting up the Build Environment

To set up the build environment, you need to complete the following:

  • Install Code Composer Studio
  • Install the MCSDK software
  • Create a Target Configuration File that allows communication with the EVM over JTAG

The Getting Started Guide talks about how to do this.

Once CCS and MCSDK are installed, they provide both Debug and Release versions of the demonstrations, examples and components. In addition, many of the components provide pre-built big endian versions as well. To rebuild the demos and examples and components that do not provide pre-built Big Endian, see the section on re-building for Big Endian in this guide.


Building the Software


Build in Place vs. Build in Workspace

The MCSDK uses a "Build in Place" philosophy. This means projects should not be import into the workspace. You can, but if you do, the projects may not re-build automatically and you may need to edit paths and other project settings to get them to build.

Note: It can be challenging to write a project that supports both build in place and build in workspace when the project is fairly rich and uses common source files (shared with other projects), etc.


Modifying a Library

  • If you want to modify and rebuild a library, it is best not to copy it into your workspace. We suggest building it "in place". When you build in place, you do not need to change build macros and so forth. You also not have to edit the example projects as they already have the correct paths to the library.
  • If you want to experiment with a library routine, debug it or try some new functionality, add the file to your project and use it there. Once you are done with it, if it is a change you need to add, then you can rebuild it in the library.
  • You may want to make a backup copy of any library before you begin modifying it. This will allow you to get to the original more easily should you need to do so.


Platform Library

We will be building library in place which will allow other dependent application to pick up the library from usual place.

The following procedure assumes the MCSDK is installed in C:\Program Files\Texas Instruments.

  • Open CCS (preferably with a new workspace)
  • Goto Project->Import Existing CCS/CCE Eclipse project
  • In the Select search-directory: enter C:\Program Files\Texas Instruments\pdk_C667##_#_#_#_##\packages\ti\platform\evmc667#l\platform_lib and hit Browse. See Import Project Settings. This will import platform_lib_evmc667## into the workspace.
Importplatformlibproject.jpg
  • Make sure the Copy projects into workspace is not checked. Then hit Finish.
  • Import the platform library project under interest to CCS. For example, for building C6678 platform library import the project platform_lib_evmc6678l into the CCS.
  • Now Project->Rebuild All should rebuild the project and library is created in C:\Program Files\Texas Instruments\pdk_C66##_#_#_#_##\packages\ti\platform\evmc667#l\platform_lib\lib for a selected profile. Setting Profile for Project Settings. This will set the desired profile for platform_lib_evmc667## into the workspace.
Setprofileplatformlibproject.jpg


Profile Little endian Library name Big Endian Library Name Comment
Debug /lib/debug/ti.platform.evm6678l.ae66 /lib/debug/ti.platform.evm6678l.ae66e Full Symbol Debug Platform library
Release /lib/release/ti.platform.evm6678l.ae66 /lib/release/ti.platform.evm6678l.ae66e Optimized Full Platform library
Lite /lib/debug/ti.platform.evm6678l.lite.lib lib/debug/ti.platform.evm6678l.lite.libe Platform library intended only for Power On Self Test (POST) executable


See platform_library_user_guide located under C:\Program Files\Texas Instruments\pdk_C667#_#_#_#_##\packages\ti\platform\docs\platform for more information on platform APIs.

Note: The library name provided above is provided as an example for the C6678 platform. Similar naming conventions for the library can be applied for the C6657 and C6670 platforms.


Building CSL and the Low Level Device Drivers

Follow the instructions below to build CSL and LLDs.

  • Open a command window inside of the $(TI_PDK_C66##_INSTALL_DIR)\packages directory.
  • Set the environment by running the batch file and follow the instructions as per the batch file output.
.\ti\drv\pdksetupenv.bat
  • After configuring the environment successfully, the following message appears.
*******************************************************************************
...
...
...
PDK BUILD ENVIRONMENT CONFIGURED
*******************************************************************************
  • To build the drivers run the below batch file.
.\ti\drv\pdkbuilder.bat

Building the Device Drivers Example Projects

The device drivers have example projects which can be verified after they are built with CCSv5. Follow the steps below to build the CCS projects for the example projects.

  • Check Prerequisites

Ensure that all dependent/pre-requisite packages are installed before proceeding with the examples and/or unit test.

  • Configure CCS Environment

The CCS environment configuration step needs to be done only once for a workspace as these settings are saved in the workspace preferences. These settings only need to be modified if:

    • New workspace is selected
    • Newer version of the component is being used. In that case, modify the paths of the upgraded component to the newer directory.

The procedure mentioned in this section is provided using <Managed Build Macro> option in CCS. The steps are as follows:

  • Create a macro file if not available from the PDK release. For the PDK release file: <PDK_INSTALL_DIR>\packages\ti\drv\macros.ini can be used, where <PDK_INSTALL_DIR> refers to the location where PDK is installed.
The following environment would need to be available in the macros.ini file
PDK_INSTALL_PATH  = <PDK_INSTALL_DIR>\packages
CSL_INSTALL_PATH  = <PDK_INSTALL_DIR>\packages
CPPI_INSTALL_PATH = <PDK_INSTALL_DIR>\packages
QMSS_INSTALL_PATH = <PDK_INSTALL_DIR>\packages
PASS_INSTALL_PATH = <PDK_INSTALL_DIR>\packages
SA_INSTALL_PATH   = <PDK_INSTALL_DIR>\packages
MAS_INSTALL_PATH  = <PDK_INSTALL_DIR>\packages
SRIO_INSTALL_PATH = <PDK_INSTALL_DIR>\packages
  • Import macros.ini located under \pdk_C####_1_0_0_XX\packages\ti\drv
    • This can be done as Click on CCS File menu option->Import->CCS->Managed Build Macros
    • Click on Next and Browse to open the macros.ini located in the above mentioned path
    • Click Finish
  • Import the desired example project and build it under CCS to continue the test.


Compiling Big Endian MCSDK Demos and Examples

The pre-compiled platform libraries, NIMU drivers, NDK examples, and HUA demos provided in the package are Little Endian only. If Big Endian binaries are needed, they need to be rebuilt by changing the CCS build options. This section covers how to build and run the NDK Network Client example, NDK Network HelloWorld example, and HUA demo in Big Endian.


NoteNote: The following images describing the steps to build the Big Endian libraries portray c6678l projects. The same instructions can be used for c6670l projects.


Warning Warning: Make sure to execute the EVM initialization GEL on the core the examples will be run on. The GEL's Global_Default_Setup function should be executed prior to loading and running any of the clients and examples. The GEL can be found under "CCSv5 installation path"\ccsv5\ccs_base_w.x.y.zzzzz\emulation\boards\evmc66xxl\gel\evmc66xxl.gel.


Recompile Big Endian NDK NIMU Driver

  • The NIMU driver is required for all NDK examples and the HUA demo. This must be recompiled in Big Endian prior to recompiling any example or demo in Big Endian.
1. Open the CCSv5 Project Import Wizard: In CCSv5, click on File -> Import... to open the Project Import Wizard. Subsequently, select "Existing CCS/CCE Eclipse Projects" and click on the "Next" button as shown:
Import Project.JPG


2. Select and Import the NIMU Project: Click the browse button to open a directory browser. Navigate to the PDK transport directory and select the NIMU transport project. Click "Finish" to import the nimu_eth_evmc66xxl project into CCS.
Import NIMU.JPG


3. Change the NIMU project active build configuration to Big Endian (Debug or Release): In the C/C++ Projects window, right-click on the nimu_eth_evmc66xxl RTSC project folder, click on Build Configurations -> Set Active -> Debug_BE (or Release_BE for release).
NIMU debug be set active.JPG


4. Clean and Build the NIMU driver: The NIMU driver will be rebuilt in Big Endian format and can now be linked by rebuilt Big Endian NDK examples and the HUA demo.


Recompile Big Endian Platform Library

5. Import the Platform library project: Repeat steps 1. and 2. from above to import the platform_lib_evmc66xxl project. This project should be located within the PDK installation directory, under ti\platform\evmc66xxl\platform_lib.
6. Change the Platform project active build configuration to Big Endian (Debug or Release): Repeat step 3. from above to set the big endian build configuration.
7. Clean and Build the Platform library: The Platform library will be rebuilt in Big Endian format and can now be linked by rebuilt Big Endian NDK examples and the HUA demo.


Recompile Big Endian NDK Client Example

8. Import the NDK Client example project: Repeat steps 1. and 2. from above to import the client_evmc66xxl project. This project should be located within the MCSDK installation directory, under examples\ndk\client\evmc66xxl.
9. Reconfigure the Client example for Big Endian: With the client_evmc66xxl project selected, click on Project -> Properties and then select the "CCS Build" pane. In the "General" tab set "Device Endianness" to "big". Click "Apply".
Client big endian.JPG


In addition, click on the "RTSC" tab and configure the following and click "Apply" when finished:
RTSC Target: ti.targets.elf.C66_big_endian
RTSC Platform: ti.platforms.evm66xx
Client big endian RTSC.JPG


10. Clean and build the Client example: Clean and rebuild the Client example project from the project context menu.

NoteNote: When the client example is executed the IP address negotiated with DHCP will be displayed backwards. As shown below the IP address reported is 148.112.218.10. The correct IP address is 10.218.112.148.

Client running.JPG


Recompile Big Endian NDK HelloWorld Example and HUA Demo

11. Reconfigure NDK HelloWorld Example and HUA Demo as Big Endian and rebuild: Follow step 8. through 10. to rebuild the NDK HelloWorld Example and HUA Demo in Big Endian.


Building and running NDK client example with simulator

Setup RGMII/EMAC Adaptor in the CCS EMAC simulator
  • Open the target Configuration file located under CCS simulation directory (simulation_csp_ny). For example, if CCSv5 is installed to its default directory, i.e., C:\Program Files\Texas Instruments\ccsv5, then the configuration file can be found at C:\Program Files\Texas Instruments\ccsv5\ccs_base_5.x.x.xxxxxx\simulation_csp_ny\bin\configurations with name tisim_c####_pv.cfg
  • Pick a NIC on the PC running simulation that you'd like to use to run the example. This will be the interface using which the packets will be sent/received by the example.
  • Under "EMAC_ADAPTOR" section look for USER_INPUTS sub-section, locate the following line of code,


INPUT2	ADAPTOR, OFF;

Modify the above line of code to:

INPUT2	ADAPTOR, ON;

This will turn on the EMAC adapter in simulator so as to send/receive packets.


  • Under the same section, locate and modify the following line of code as follows:
INPUT4  NETWORK_ADAPTOR, Broadcom;

Modify the above line of code to include the name of the NIC card you are using, for example if the interface you are using for the test on your PC is a "Realtek" card, modify the above line to:

INPUT4  NETWORK_ADAPTOR, Realtek;
  • If the following lines are uncommented, please comment them:
CONNECT11       System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii0_tx_data_gen_opin, System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii1_rx_data_gen_ipin;
CONNECT12       System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii0_rx_data_gen_ipin, System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii1_tx_data_gen_opin;

as follows:

//CONNECT11       System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii0_tx_data_gen_opin, System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii1_rx_data_gen_ipin;
//CONNECT12       System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii0_rx_data_gen_ipin, System.C66XX_S.SHARED_SYSTEM.SWITCHSS.switchss_sgmii1_tx_data_gen_opin;

This disables loopback at EMAC adapter level (PHY simulation) in the simulator.

  • Finally, configure the switch MAC configured in the example, i.e., 0x10-0x11-0x12-0x13-0x14-0x15 on the EMAC adaptor so that the simulator can pass all packets matching the switch MAC up to the application.

example:

 INPUT5  MAC_ADDRESS_PORT0, 10-11-12-13-14-15;   // configure the Port0 MAC to be the switch MAC
INPUT6  MAC_ADDRESS_PORT1, 00-01-02-03-04-05;       

NoteNote: Note: For details see C:\Program Files\Texas Instruments\ccsv5\ccs_base_5.x.x.xxxxxx\simulation_csp_ny\docs\pdf\TCI6616-C6670-TCI6608-C6678_Device_Simulator_EMAC_Model_IO_user_guide.pdf

Re-compile NIMU library with simulator support
  • Start CCS and import project from C:\Program Files\Texas Instruments\pdk_C66##_#_#_#_##\packages\ti\transport\ndk\nimu directory
  • Open Project->Properties->C/C++ Build->Settings->Predefined symbols, add variable SIMULATOR_SUPPORT, OK to close the project
  • Re-compile the project Project->Clean, Project->Compile
Update NDK client example and run it on simulator

NoteNote: The PC running simulator needs to be set with static IP address 192.168.2.101 for this example program, see figure for Static IP Setup

  • Import project from C:\Program Files\Texas Instruments\mcsdk_#_##_##_##\examples\ndk\client\evmC####
  • Open client.cfg file in CCS text editor from the project client_evm####l and change the line
from
var PlatformLib  = xdc.loadPackage('ti.platform.evmc####l');
to
var PlatformLib  = xdc.loadPackage('ti.platform.simc####');
  • Open file client.c, then change clientMACAddress string to match your PC mac address, make sure the format needs to be as follows
Uint8 clientMACAddress [6] = {0x00,0x18,0x8B,0x10,0x17,0xBF};
  • Re-compile the project Project->Clean, Project->Build
  • Load functional simulator target on CCS
  • Load the client image created above on the simulator and hit run to run the application

Building NDK

The following instructions how how to re-build the NDK libraries and enable debug versions if you need them.


NoteNote: The NDK build re-builds everything in the library and its quite large so re-building may take some time on slower machines.


  • Before you start building its a good idea to make a backup copy of the library.
  • Open a Windows cmd window (dos box) in your NDK install directory. You can do this by selecting the NDK top directory and then right clicking and selecting run cmd here (in windows XP).

ndkdosbox.jpg

  • Change directory to packages\ti\ndk

Ndkdosboxbuild.jpg

  • You will see a file called config.bld.default. You will need to edit this file.
  • Make a *copy* of the file and call it config.bld.
  • You will need to edit some settings in config.bld as discussed below. Note: These are the paths I am using. Yours may be different depending on where you installed CCS and/or MCSDK.
Change the BIOS 6  path to where you have BIOS installed:
var bios6path = "C:/Program Files/Texas Instruments/bios_6_32_01_38/packages";
 
Change the location for the Code Generation tools:
var rootDir = "C:/Program\ Files/Texas\ Instruments/ccsv5/tools/compiler/c6000"
 
You can remove the ARM path if you are not building NDK for ARM or did not 
install ARM support. If you need ARM libraries built then make sure  this has 
the right path:
var rootDirArm = "C:/Program\ Files/Texas\ Instruments/ccsv4/tools/compiler/tms470"
 
Remove tragets you do not need built. You should see our C66 targets. The others
for ARM or C64 can removed if you do not need to build for them.
Build.targets =	[
    elfTargets.C66,
    elfTargets.C66_big_endian,
];
 
Compile for Debug if you need debug by Changing the compiler options line 
C6xSuffix and adding a -g to it as below.
var c6xSuffix = "-mi10 -mo -pdr -pden -pds=238 -pds=880 -pds1110 -g ";
  • Save the file with your changes.
  • Type xdc at the command line to build. Note that the xdc command must be run in the same directory as the config.bld.

ndkdosboxbuilding.jpg


Examples

The example programs are designed to take you from writing a simple "hello world" type program to progressively more complicated applications. At each step, various methodologies and ways of working with the MCSDK are introduced. It is highly recommended that you do them.

NoteNote: The following examples assume you installed MCSDK in C:\Program Files\Texas Instruments. If you did not, then you will need to alter the paths used in this example to the location of where you installed it.

NoteNote: The example programs make use of components contained in the PDK so you will need to specify the processor number and substitute it into the various paths and names as needed. As shown below, the #### refers to processor type (6678 for TMS320C6678 OR TMS320TCI6608; 6670 for TMS320C6670 OR TMS320TCI6618; 6657 for TMS320C6657) and the xx refers to a version number.

For example, a typical path might be:

"C:\Program Files\Texas Instruments\pdk_C####_1_0_0_xx\packages"

To specify that for the 6670 on the 2.0.0.11 release you would do:

"C:\Program Files\Texas Instruments\pdk_C6670_1_0_0_11\packages"


Example 1 - Building and running a simple single core application

This is the first example program. It's purpose is to get you used to creating projects in CCS, building an executable and then running it on your EVM. The application executes out of shared memory on the EVM and does not use the external DDR.

NoteNote: Please note that the simple platform library application code is assuming that everything is running from shared memory (MSMCRAM) - so no GEL file is needed. It is preferred to run the respective CCS GEL file for that platform before loading and running any application.

1. The first step is to create a project in CCS for this example. To do so follow the steps below.

  • Open CCS (preferably with a new workspace).
  • Open File->New->CCS Project and in the project name field enter led_play", then hit Next.
  • In the CCS project window, select Project Type: as C6000 and hit Next and hit Next again to skip the next page for Additional Project Settings.
  • In the New CCS Project, select Device Variant: as Generic C66xx Device and hit Next. See Project Settings.
Projectsettingshelloworld.jpg
  • In the Project Templets window select Empty Project and hit Next.
  • It should open an empty project with name led_play.


2. Now that we have a project, we are going to create a source file that will use the MCSDK Platform Library to a.) initialize our EVM at start-up, b.) write a simple string to the UART (console port) and c.) will blink the EVM LED's.

  • Select File->New->Source File, enter Source File name as led_play.c, then hit Finish.
  • It should open led_play.c empty file in the eclipse editor. Paste following source code in the editor
#include <cerrno>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ti\platform\platform.h"
#include "ti\platform\resource_mgr.h"
 
/* OSAL functions for Platform Library */
uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
{
    return malloc(num_bytes);
}
 
void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
{
    /* Free up the memory */
    if (dataPtr)
    {
        free(dataPtr);
    }
}
 
void Osal_platformSpiCsEnter(void)
{
    /* Get the hardware semaphore.
     *
     * Acquire Multi core CPPI synchronization lock
     */
    while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0);
 
    return;
}
 
void Osal_platformSpiCsExit (void)
{
    /* Release the hardware semaphore
     *
     * Release multi-core lock.
     */
    CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM);
 
    return;
}
 
void main(void) {
    platform_init_flags init_flags;
    platform_init_config init_config;
    platform_info p_info;
    uint32_t led_no = 0;
    char message[] = "\r\nHello World.....\r\n";
    uint32_t length = strlen((char *)message);
    uint32_t i;
 
    /* Initialize platform with default values */
    memset(&init_flags, 0x01, sizeof(platform_init_flags));
    memset(&init_config, 0, sizeof(platform_init_config));
    if (platform_init(&init_flags, &init_config) != Platform_EOK) {
        return;
    }
 
    platform_uart_init();
    platform_uart_set_baudrate(115200);
 
    platform_get_info(&p_info);
 
    /* Write to the UART */
    for (i = 0; i < length; i++) {
        if (platform_uart_write(message[i]) != Platform_EOK) {
            return;
        }
    }
 
    /* Play forever */
    while(1) {
        platform_led(led_no, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
        platform_delay(30000);
        platform_led(led_no, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
        led_no = (++led_no) % p_info.led[PLATFORM_USER_LED_CLASS].count;
    }
}

3. Our project now needs a linker command script. The linker command script defines the memory map for the platform (where internal, shared and external memory start, etc.) and where we want our code and data sections to be placed. We are going to put them in the shared memory region on the processor.

  • Select File->New->File from Template, enter File Name as led_play.cmd and hit Finish.
  • It would open led_play.cmd file in the editor, paste following linker command file in the editor
-c
-heap  0x41000
-stack 0xa000
 
/* Memory Map */
MEMORY
{
    L1PSRAM (RWX)  : org = 0x0E00000, len = 0x7FFF
    L1DSRAM (RWX)  : org = 0x0F00000, len = 0x7FFF 
    L2SRAM (RWX)   : org = 0x0800000, len = 0x080000
    MSMCSRAM (RWX) : org = 0xc000000, len = 0x200000
    DDR3 (RWX)     : org = 0x80000000,len = 0x10000000
}
 
SECTIONS
{
    .csl_vect    >       MSMCSRAM
    .text        >       MSMCSRAM
    GROUP (NEAR_DP)
    {
        .neardata
        .rodata 
        .bss
    } load       >      MSMCSRAM
    .stack       >      MSMCSRAM
    .cinit       >      MSMCSRAM
    .cio         >      MSMCSRAM
    .const       >      MSMCSRAM
    .data        >      MSMCSRAM
    .switch      >      MSMCSRAM
    .sysmem      >      MSMCSRAM
    .far         >      MSMCSRAM
    .testMem     >      MSMCSRAM
    .fardata     >      MSMCSRAM
    platform_lib > 	MSMCSRAM
}

4. Were almost done. We have some code to execute and a memory map. Now we need to build the executable we will load and run. Before we build though, we will need to define a few include paths and specify the library for the Platform Library.

  • Select Project->Properties, it should open Properties window for led_play project, select C/C++ Build from the left pane.
  • Select Settings in the left pane after opening the C/C++ Build sub menu.
  • In the Tool Settings tab, select Include Options, add following items in the Add dir to #include search path...
"C:\Program Files\Texas Instruments\pdk_C####_1_0_0_xx\packages"

See Include Path

Includepathhelloworld.jpg
  • Select File Search Path from C6000 Linker section. Add following items in Include library... section
ti.platform.evm####l.ae66
NoteNote: Please note that the above library is the little endian debug version library of the platform library. This is needed for the application built for Little Endian. Please refer to the above table for including the appropriate library for the particular platform library application.

And add following items in Add <dir> to library... section

"C:\Program Files\Texas Instruments\pdk_C####_1_0_0_xx\packages\ti\platform\evmc####l\platform_lib\lib\debug"
See Linker Input.
Linkerinputhelloworld.jpg
  • Select OK to close the properties dialog box.
  • Select Project->Build Project to build the project.

5. We should have an executable. Likely it was built as Debug since that is the default option to build unless it was changed. You can now follow the steps below to load and run your first example.

  • Select View->Target Configurations to open target configuration tab in the left pane (this step assumes you have followed Getting Started Guide to create target configuration for your setup).
  • Right click on the configurations file (######.ccxml) and select Launch Selected Configuration.
  • It should change the CCS prospective to Debug and load the configuration.
  • After loading is complete select Device for core 0 (e.g. C66XX_0).
  • Select Target->Connect Target to connect to the core.
  • After core 0 is connected, select Run->Load->Load Program, then hit Browse Project....
  • It should open Select program to load dialog, then select led_play.out [....] and hit OK and another OK to load the program to core 0.
  • After loading completes, select Target->Run to run the application.
  • The application should print Hello World if UART is connected to the board at 115200 baud rate and should flash LEDs.


Example 2 - Building and running your first tasking application using MCSDK and BIOS

This example essentially re-does the first example and takes the LED code and puts it into a task. Note that while the steps may look similar there is a significant leap being made with BIOS and Eclipse RTSC being introduced.

1. The first step is to create an Eclipse RTSC project. To do that:

  • Open CCS (preferably with a new workspace).
  • Open File->New->CCS Project and in the project name field enter led_play
    • In the CCS project window, select Device Family: as C6000
    • select Device Variant: as Generic C66xx Device
    • In the Project Templates screen, select an Empty RTSC Project and hit Next.
  • In the RTSC Configuration Settings screen, check the Products and Repositories (i.e. components) you want to use. All of them will be checked by default. Select only Sys/BIOS and the appropriate PDK for your EVM.
    • In the RTSC Target field enter ti.targets.elf.C66.
    • Select the RTSC Platform you are using. Select the ti.platforms.evm66## from the list box (note it will be empty, but just click on it and values will be filled in to select from).
    • Select Build-profile to debug
  • Hit Finish

Note: The eclipse plugin discovery tool registers the project templates from the individual components with CCSv5. After the discovery tool registers XDCtools 3.22.01 version provided with BIOS MCSDK 2.0.1 release, the option Empty RTSC Project does not appear in the Project Templates screen because XDCtools 3.22.01 does not have the Empty RTSC Project template. Please follow this link to work around this problem.


2. Now we have an Eclipse RTSC project but nothing in it. Our next step is to create a .cfg file and the source file we want to use. The .cfg is essential to this project and serves many purposes: 1.) It replaces the linker.cmd file 2.) Allows you to include the various modules from BIOS and other Components you wish to use and 3.) allows you to configure default settings within them.

If you followed along in Example one you should know how to add files to a project. Add a C source file called led_play.c. Now we need to add the configuration file called led_play.cfg to the project. Do File->New->RTSC Configuration File and then name is led_play.cfg. You should now have both files as shown in the figure to the right called BIOS LED Example Project.
LedRtscProject.JPG

Note: Do not select a regular text file or a BIOS 5 configuration file when creating the .cfg.


3. Lets add the code we need to the led_play.c file:

#include <cerrno>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/bios/include/swi.h>
#include "ti\platform\platform.h"
#include "ti\platform\resource_mgr.h"
 
/* OSAL functions for Platform Library */
uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
{
    return malloc(num_bytes);
}
 
void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
{
    /* Free up the memory */
    if (dataPtr)
    {
        free(dataPtr);
    }
}
 
void Osal_platformSpiCsEnter(void)
{
    /* Get the hardware semaphore.
     *
     * Acquire Multi core CPPI synchronization lock
     */
    while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0);
 
    return;
}
 
void Osal_platformSpiCsExit (void)
{
    /* Release the hardware semaphore
     *
     * Release multi-core lock.
     */
    CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM);
 
    return;
}
 
 
/*************************************************************************
 * main()
 * Entry point for the application.
 ************************************************************************/
int main()
{
    /* Start the BIOS 6 Scheduler - it will kick off our main thread ledPlayTask() */
    platform_write("Start BIOS 6\n");
 
    BIOS_start();
}
 
/*************************************************************************
 * EVM_init()
 * Initializes the platform hardware. This routine is configured to start in
 * the evm.cfg configuration file. It is the first routine that BIOS
 * calls and is executed before Main is called. If you are debugging within
 * CCS the default option in your target configuration file may be to execute
 * all code up until Main as the image loads. To debug this you should disable
 * that option.
 ************************************************************************/
void EVM_init()
{
    platform_init_flags sFlags;
    platform_init_config sConfig;
    int32_t pform_status;
 
 
    /* Initialize the UART */
    platform_uart_init();
    platform_uart_set_baudrate(115200);
    (void) platform_write_configure(PLATFORM_WRITE_ALL);
 
    /*
     * You can choose what to initialize on the platform by setting the following
     * flags. Things like the DDR, PLL, etc should have been set by the boot loader.
     */
    memset( (void *) &sFlags, 0, sizeof(platform_init_flags));
    memset( (void *) &sConfig, 0, sizeof(platform_init_config));
 
    sFlags.pll = 0; /* PLLs for clocking */
    sFlags.ddr = 0; /* External memory */
    sFlags.tcsl = 1; /* Time stamp counter */
    sFlags.phy = 0; /* Ethernet */
    sFlags.ecc = 0; /* Memory ECC */
    sConfig.pllm = 0; /* Use libraries default clock divisor */
 
    pform_status = platform_init(&sFlags, &sConfig);
 
    /* If we initialized the platform okay */
    if (pform_status != Platform_EOK) {
        /* Initialization of the platform failed... die */
        platform_write("Platform failed to initialize. Error code %d \n", pform_status);
        platform_write("We will die in an infinite loop... \n");
        while (1) {
            (void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
            (void) platform_delay(50000);
            (void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
            (void) platform_delay(50000);
        }
    }
 
    return;
}
 
 
/*************************************************************************
 * ledPlayTask()
 *
 * This is the main task for the example. It will write send text
 * messages to both the console and the UART using platform_write and then
 * twinkle the LEDs. This task is configured to start in led_play.cfg 
 * configuration file and it is called from BIOS.
 *
 ************************************************************************/
int ledPlayTask (void) {
 
    platform_info p_info;
    uint32_t led_no = 0;
 
    /* Get information about the platform */
    platform_get_info(&p_info);
 
    platform_write("Lets twinkle some LED's\n");
 
    /* Play forever */
    while(1) {
        platform_led(led_no, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
        platform_delay(30000);
        platform_led(led_no, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
        led_no = (++led_no) % p_info.led[PLATFORM_USER_LED_CLASS].count;
    }
}


4. Add the code to the cfg file led_play.cfg by opening it with a text editor. Note that if you double click it, it opens a tool you can use to edit the file but editing it via a text editor will be simpler.

/*
 * led_play.cfg
 * 
 * Memory Map and Program initialization for the BIOS
 * LED example program.
 */
 
/* Include the various Modules we want to use */
var Memory  = xdc.useModule('xdc.runtime.Memory');
var Startup = xdc.useModule('xdc.runtime.Startup');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Task = xdc.useModule('ti.sysbios.knl.Task');
 
/* Configure the Modules */
BIOS.taskEnabled = true; /* Enable BIOS Task Scheduler */
 
/* Create our memory map - i.e. this is equivalent to linker.cmd */
Program.sectMap[".const"] = "MSMCSRAM";
Program.sectMap[".text"] = "MSMCSRAM";
Program.sectMap[".code"] = "MSMCSRAM";
Program.sectMap[".data"] = "MSMCSRAM";
Program.sectMap[".sysmem"] = "MSMCSRAM";
Program.sectMap["platform_lib"] = "MSMCSRAM"; 
 
/* Lets register any hooks, tasks, etc that we want BIOS to handle */
 
/* 
** Register an EVM Init handler with BIOS. This will initialize the hardware. 
** BIOS calls before it starts. 
*/
Startup.firstFxns.$add('&EVM_init');
 
/* 
** Create the Main Thread Task for our application.
*/
var tskNdkMainThread = Task.create("&ledPlayTask");
tskNdkMainThread.stackSize = 0x2000;
tskNdkMainThread.priority = 0x5;
tskNdkMainThread.instance.name = "ledPlayTask";


5. Now we need to configure a few project settings for the Platform Library (just like we did in the previous example).

  • In the 'Build>C6000 Compiler>Include Options, add following items in the Add dir to #include search path...
"C:\ti\pdk_C66xx_x_x_x_x\packages"


  • Select File Search Path from C6000 Linker section. Add following items in Include library... section
ti.platform.evm####l.ae66
NoteNote: Please note that the above library is the little endian debug version library of the platform library. This is needed for the application built for Little Endian. Please refer to the above table for including the appropriate library for the particular platform library application. And add following items in Add <dir> to library... section
"C:\ti\pdk_C66xx_x_x_x_x\packages\ti\platform\evmc66xxl\platform_lib\lib\debug"


  • Select OK to close the properties dialog box.
  • Select Project->Build Project to build the project.

You maybe wondering why we do not need include/library paths or library names for BIOS? Any RTSC enabled component in the MCSDK, provides its libraries and paths automatically during the build process. The appropriate libraries (big or little) and the paths are determined by the version of the component you selected in the CCS or RTSC Settings Screen. If you need to change any RTSC settings for an existing project, you can do so by highlighting the project name in CCS, then right clicking and selecting Properties and then selecting CCS from the menu.


6. Build the project.


7. Connect to your EVM with your Target Configuration file, then load and run the program on core 0!



Example 3 - Running from external memory (DDR)

This example essentially re-does the second example and takes the LED example code and puts it into DDR3 external memory. This example is created using CCS version 5.1.1. Please note that steps used to create the LED example using CCS version 5.0 and version 5.1 are very similar.

LedPlayEx3.JPG

1. The first step is to create an Eclipse RTSC project as follows:

  • Open CCS (preferably with a new workspace).
  • Open File->New->CCS Project and in the project name field enter led_play_ddr3.
  • Select device family as C6000
  • Leave Device Variant as “select or type filter text” and select Generic C66xx Device on the next drop down list.
  • In the Project Templates screen (see image to the right), select Empty Project then hit Finish


2. The second step is to create RTSC configuration file as follows:

  • Right click on led_play_ddr3 project->New->Other->RTSC->RTSC configuration File, then hit Next
  • Enter RTSC configuration file name as led_play_ddr3.cfg and hit Finish.

3. Now we have an Eclipse RTSC project and its configuration file. Our next step is to overwrite .cfg file and the source file with test code and configuration that we want to use. The .cfg is essential to this project and serves many purposes: 1.) It replaces the linker.cmd file 2.) Allows you to include the various modules from BIOS and other components you wish to use and 3.) It allows you to configure default settings within them.

4. Lets add the code we need to the led_play_ddr3 main.c file.

/*
======== main.c =======
*/
 
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <cerrno>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/bios/include/swi.h>
#include "ti\platform\platform.h"
#include "ti\platform\resource_mgr.h"
 
 
 
 
/* OSAL functions for Platform Library */
uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
{
    return malloc(num_bytes);
}
 
void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
{
    /* Free up the memory */
    if (dataPtr)
    {
        free(dataPtr);
    }
}
 
void Osal_platformSpiCsEnter(void)
{
    /* Get the hardware semaphore.
     *
     * Acquire Multi core CPPI synchronization lock
     */
    while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0);
 
    return;
}
 
void Osal_platformSpiCsExit (void)
{
    /* Release the hardware semaphore
     *
     * Release multi-core lock.
     */
    CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM);
 
    return;
}
 
 
 
/*************************************************************************
 * EVM_init()
 * Initializes the platform hardware. This routine is configured to start in
 * the evm.cfg configuration file. It is the first routine that BIOS
 * calls and is executed before Main is called. If you are debugging within
 * CCS the default option in your target configuration file may be to execute
 * all code up until Main as the image loads. To debug this you should disable
 * that option.
 ************************************************************************/
void EVM_init()
{
    platform_init_flags sFlags;
    platform_init_config sConfig;
    int32_t pform_status;
 
    /* Initialize the UART */
    platform_uart_init();
    platform_uart_set_baudrate(115200);
    (void) platform_write_configure(PLATFORM_WRITE_ALL);
 
    /*
     * You can choose what to initialize on the platform by setting the following
     * flags. Things like the DDR, PLL, etc should have been set by the boot loader.
     */
    memset( (void *) &sFlags, 0, sizeof(platform_init_flags));
    memset( (void *) &sConfig, 0, sizeof(platform_init_config));
 
    sFlags.pll = 0; /* PLLs for clocking */
    sFlags.ddr = 0; /* External memory */
    sFlags.tcsl = 1; /* Time stamp counter */
    sFlags.phy = 0; /* Ethernet */
    sFlags.ecc = 0; /* Memory ECC */
    sConfig.pllm = 0; /* Use libraries default clock divisor */
 
    pform_status = platform_init(&sFlags, &sConfig);
 
    /* If we initialized the platform okay */
    if (pform_status != Platform_EOK) {
        /* Initialization of the platform failed... die */
        platform_write("Platform failed to initialize. Error code %d \n", pform_status);
        platform_write("We will die in an infinite loop... \n");
        while (1) {
            (void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
            (void) platform_delay(50000);
            (void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
            (void) platform_delay(50000);
        }
    }
 
    return;
}
 
 
 
/*
======== taskFxn =======
*/
Void taskFxn(UArg a0, UArg a1)
{
	platform_info p_info;
	uint32_t led_no = 0;
 
	 /* Get information about the platform */
	platform_get_info(&p_info);
 
	platform_write("Lets twinkle some LED's\n");
 
	    /* Play forever */
	    while(1) {
	        platform_led(led_no, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
	        platform_delay(30000);
	        platform_led(led_no, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
	        led_no = (++led_no) % p_info.led[PLATFORM_USER_LED_CLASS].count;
	    }
 
}
 
/*
======== main =======
*/
Void main()
{ 
    Task_Handle task;
    Error_Block eb;
 
    System_printf("enter main()\n");
 
    Error_init(&eb);
    task = Task_create(taskFxn, NULL, &eb);
    if (task == NULL) {
        System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }
 
    BIOS_start();     /* enable interrupts and start SYS/BIOS */
}

4. Add the code to the cfg file led_play_ddr3.cfg by opening .cfg file with XDCscript editor. Right click on configuration file->open with->XDCscript editor. Copy and paste the following code to .cfg file.

/*
 * led_play_ddr3.cfg
 * 
 * Memory Map and Program initialization for the BIOS
 * LED example program.
 */
 
/* Include the various Modules we want to use */
var Memory  = xdc.useModule('xdc.runtime.Memory');
var Startup = xdc.useModule('xdc.runtime.Startup');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
 
/* Configure the Modules */
BIOS.taskEnabled = true;
 
/* Create our memory map - i.e. this is equivalent to linker.cmd */
Program.sectMap[".const"] = "DDR3";
Program.sectMap[".text"] = "DDR3";
Program.sectMap[".code"] = "DDR3";
Program.sectMap[".data"] = "DDR3";
Program.sectMap[".sysmem"] = "DDR3";
Program.sectMap["platform_lib"] = "DDR3"; 
 
 
/* Lets register any hooks, tasks, etc that we want BIOS to handle 
 ** Register an EVM Init handler with BIOS. This will initialize the   ** hardware. 
** BIOS calls before it starts. 
*/
Startup.firstFxns.$add('&EVM_init');


5. Now we need to configure a few project settings for the Platform Library (just like we did in the previous example).

  • Select Project->Properties, it should open Properties window for led_play_ddr3 project, select Build->C6000 linker->File Search Path from the left pane.
  • On File Search Path window, add library file name ti.platform.evm6678l.ae66 and add dir to library file search path "c:\Program Files\Texas Instruments\ pdk_C####_1_0_0_xx \packages\ti\platform\evmc6678l\platform_lib\lib\debug"

Note: Please note that the above library is the Little Endian debug version library of the platform library. This is needed for the application built for Little Endian. Please refer to the above table for including the appropriate library for the particular platform library application. You may be wondering why we do not need include/library paths or library names for BIOS? Any RTSC enabled component in the MCSDK, provides its libraries and paths automatically during the build process. The appropriate libraries (big or little) and the paths are determined by the version of the component you selected in the CCS or RTSC Settings Screen. If you need to change any RTSC settings for an existing project, you can do so by highlighting the project name in CCS, then right clicking and selecting Properties and then selecting CCS from the menu.

6. Now select appropriate RSTC components by right click on project name->properties->Resource->General->RTSC (select PDK and BIOS versions and etc.), and then select appropriate target platform.


7. Build the project.

8. Connect to your EVM with your Target Configuration file, then load and run the program. You should now see all LEDs blinking.


Example 4 - Let's make it multi-core

This example enhances the LED example code to run on multicore and puts it into DDR3 external memory. Similar to example 3, this example uses CCS version 5.1.1 to create its project. Please note that steps used to create this LED example with CCS version 5.0 and version 5.1 are very similar.

LedPlayEx4.jpg

1. The first step is to create an Eclipse RTSC project as follows:

  • Open CCS (preferably with a new workspace).
  • Open File->New->CCS Project and in the project name field enter led_play_ddr3.
  • Select device family as C6000
  • Leave Device Variant as “select or type filter text” and select Generic C66xx Device on the next drop down list.
  • In the Project Templates screen, select Empty Project then hit Finish

2. The second step is to create RTSC configuration file as follows:

  • Right click on led_play_ddr3 project->New->Other->RTSC->RTSC configuration File, then hit Next
  • Enter RTSC configuration file name as led_play_ddr3.cfg and hit Finish.

3. Now we have an Eclipse RTSC project and its configuration file. Our next step is to overwrite .cfg file and the source file with test code and configuration that we want to use. The .cfg is essential to this project and serves many purposes: 1.) It replaces the linker.cmd file 2.) Allows you to include the various modules from BIOS and other ponents you wish to use and 3.) It allows you to configure default settings within them.

4. Lets add the code we need to the led_play_ddr3.c file:

/*
 * led_play.c
 *
 *  Created on: Feb 6, 2012
 *
 */
 
#include <cerrno>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/bios/include/swi.h>
#include "ti\platform\platform.h"
#include "ti\platform\resource_mgr.h"
 
 
#pragma DATA_SECTION(next, ".sharedVar")
#pragma DATA_ALIGN (next, 128)
 
typedef union {
	uint32_t core;
	uint8_t padding[128];
}n;
 
n next;
 
uint32_t maxFlashes = 50;
 
/* OSAL functions for Platform Library */
uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
{
    return malloc(num_bytes);
}
 
void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
{
    /* Free up the memory */
    if (dataPtr)
    {
        free(dataPtr);
    }
}
 
void Osal_platformSpiCsEnter(void)
{
    /* Get the hardware semaphore.
     *
     * Acquire Multi core CPPI synchronization lock
     */
    while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0);
 
    return;
}
 
void Osal_platformSpiCsExit (void)
{
    /* Release the hardware semaphore
     *
     * Release multi-core lock.
     */
    CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM);
 
    return;
}
 
/*****************************************************************************
 *
 * Function: Converts a core local L2 address to a global L2 address
 *   Input addr:  L2 address to be converted to global.
 *   return:  uint32_t   Global L2 address
 *
 *****************************************************************************/
uint32_t convert_CoreLocal2GlobalAddr (uint32_t  addr)
{
  uint32_t coreNum;
 
  /* Get the core number. */
  coreNum = CSL_chipReadReg(CSL_CHIP_DNUM);
 
  /* Compute the global address. */
  return ((1 << 28) | (coreNum << 24) | (addr & 0x00ffffff));
}
 
/*************************************************************************
 * main()
 * Entry point for the application.
 ************************************************************************/
int main()
{
    /* Start the BIOS 6 Scheduler - it will kick off our main thread ledPlayTask() */
    platform_write("Start BIOS 6\n");
 
    BIOS_start();
}
 
/*************************************************************************
 * EVM_init()
 * Initializes the platform hardware. This routine is configured to start in
 * the evm.cfg configuration file. It is the first routine that BIOS
 * calls and is executed before Main is called. If you are debugging within
 * CCS the default option in your target configuration file may be to execute
 * all code up until Main as the image loads. To debug this you should disable
 * that option.
 ************************************************************************/
void EVM_init()
{
    platform_init_flags sFlags;
    platform_init_config sConfig;
    int32_t pform_status;
 
    /* Initialize the UART */
    platform_uart_init();
    platform_uart_set_baudrate(115200);
    (void) platform_write_configure(PLATFORM_WRITE_ALL);
 
    /*
     * You can choose what to initialize on the platform by setting the following
     * flags. Things like the DDR, PLL, etc should have been set by the boot loader.
     */
    memset( (void *) &sFlags, 0, sizeof(platform_init_flags));
    memset( (void *) &sConfig, 0, sizeof(platform_init_config));
 
    sFlags.pll = 0; /* PLLs for clocking */
    sFlags.ddr = 0; /* External memory */
    sFlags.tcsl = 1; /* Time stamp counter */
    sFlags.phy = 0; /* Ethernet */
    sFlags.ecc = 0; /* Memory ECC */
    sConfig.pllm = 0; /* Use libraries default clock divisor */
 
    pform_status = platform_init(&sFlags, &sConfig);
 
    /* If we initialized the platform okay */
    if (pform_status != Platform_EOK) {
        /* Initialization of the platform failed... die */
        platform_write("Platform failed to initialize. Error code %d \n", pform_status);
        platform_write("We will die in an infinite loop... \n");
        while (1) {
            (void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
            (void) platform_delay(50000);
            (void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
            (void) platform_delay(50000);
        }
    }
 
    return;
}
 
 
/*************************************************************************
 * ledPlayTask()
 *
 * This is the main task for the example. It will write send text
 * messages to both the console and the UART using platform_write and then
 * each core (0-3) sequentially twinkles its LEDs. This task is configured to start in led_play.cfg
 * configuration file and it is called from BIOS.
 *
 ************************************************************************/
void ledPlayTask (void) {
 
    platform_info p_info;
    uint32_t led_no = 0;
    uint32_t coreId, i;
 
    /* determine the core number. */
    coreId = CSL_chipReadReg (CSL_CHIP_DNUM);
 
    /* Get information about the platform */
    platform_get_info(&p_info);
 
    /* determine which core to twinkle LED	*/
    if(coreId != 0){
    	while(1){
    		/* lets delay a bit before reading shared variable 	*/
    		platform_delay(30000);
    		CACHE_invL1d (&next, 4, CACHE_FENCE_WAIT);
    		if(next.core == coreId)
    			break;
    	}
    }
 
    /* lets delay a bit before twinkling the next LED	*/
    platform_delay(30000);
    i = 0;
    led_no = coreId;
    platform_write("core = %d starts twinkling its LED\n", coreId);
 
    /* twinkle the LED based on core id and LED id, respectively	*/
    while(1) {
        platform_led(led_no, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
 
        platform_delay(300000);
        platform_led(led_no, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
 
        platform_delay(300000);
 
        i++;
        if ( i == maxFlashes){
        	break;
        }
    }
 
    /* let next core twinkles its LED	*/
    next.core = coreId + 1;
    CACHE_wbL1d ((void *) &next, 4, CACHE_WAIT);
    platform_write("core %d is done.\n", coreId);
 
}


5. Add the code to the cfg file led_play_ddr3.cfg by opening it with XDCscript editor by right click on configuration file->open with->XDCscript editor

var Startup = xdc.useModule('xdc.runtime.Startup');
 
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Log = xdc.useModule('xdc.runtime.Log');
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Main = xdc.useModule('xdc.runtime.Main');
var Memory = xdc.useModule('xdc.runtime.Memory')
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text = xdc.useModule('xdc.runtime.Text');
 
var Csl = xdc.loadPackage('ti.csl');
 
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Swi = xdc.useModule('ti.sysbios.knl.Swi');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
 
/* 
 * Program.argSize sets the size of the .args section. 
 * The examples don't use command line args so argSize is set to 0.
 */
Program.argSize = 0x0;
 
/*
 * Uncomment this line to globally disable Asserts.
 * All modules inherit the default from the 'Defaults' module.  You
 * can override these defaults on a per-module basis using Module.common$. 
 * Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
 */
 
/*
 * Uncomment this line to keep module names from being loaded on the target.
 * The module name strings are placed in the .const section. Setting this
 * parameter to false will save space in the .const section.  Error and
 * Assert messages will contain an "unknown module" prefix instead
 * of the actual module name.
Defaults.common$.namedModule = false;
 */
 
/*
 * Minimize exit handler array in System.  The System module includes
 * an array of functions that are registered with System_atexit() to be
 * called by System_exit().
 */
System.maxAtexitHandlers = 4;       
 
/* 
 * Uncomment this line to disable the Error print function.  
 * We lose error information when this is disabled since the errors are
 * not printed.  Disabling the raiseHook will save some code space if
 * your app is not using System_printf() since the Error_print() function
 * calls System_printf().
Error.raiseHook = null;
 */
 
/* 
 * Uncomment this line to keep Error, Assert, and Log strings from being
 * loaded on the target.  These strings are placed in the .const section.
 * Setting this parameter to false will save space in the .const section.
 * Error, Assert and Log message will print raw ids and args instead of
 * a formatted message.
Text.isLoaded = false;
 */
 
/*
 * Uncomment this line to disable the output of characters by SysMin
 * when the program exits.  SysMin writes characters to a circular buffer.
 * This buffer can be viewed using the SysMin Output view in ROV.
SysMin.flushAtExit = false;
 */
 
/*
 * The BIOS module will create the default heap for the system.
 * Specify the size of this default heap.
 */
BIOS.heapSize = 0x1000;
 
/* System stack size (used by ISRs and Swis) */
Program.stack = 0x2000;
 
/* Circular buffer size for System_printf() */
SysMin.bufSize = 0x200;
 
/* 
 * Create and install logger for the whole system
 */
var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.numEntries = 16;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
Main.common$.diags_INFO = Diags.ALWAYS_ON;
 
System.SupportProxy = SysMin;
 
/* Example 3 Create our memory map - i.e. this is equivalent to linker.cmd */
Program.sectMap[".const"] = "DDR3";
Program.sectMap[".text"] = "DDR3";
Program.sectMap[".code"] = "DDR3";
Program.sectMap[".data"] = "DDR3";
Program.sectMap[".sysmem"] = "DDR3";
Program.sectMap[".sharedVar"] = "DDR3";
Program.sectMap["platform_lib"] = "DDR3"; 
 
 
 
/* Lets register any hooks, tasks, etc that we want BIOS to handle */ 
/* 
** Register an EVM Init handler with BIOS. This will initialize the hardware. 
** BIOS calls before it starts. 
*/
Startup.firstFxns.$add('&EVM_init');
 
/* 
** Create the Main Thread Task for our application.
*/
var tskNdkMainThread = Task.create("&ledPlayTask");
tskNdkMainThread.stackSize = 0x2000;
tskNdkMainThread.priority = 0x5;
tskNdkMainThread.instance.name = "ledPlayTask";

6. Now we need to configure a few project settings for the Platform Library (just like we did in the previous example).

  • Select Project->Properties, it should open Properties window for led_play_ddr3 project, select Build->C6000 linker->File Search Path from the left pane.
  • On File Search Path window, add library file name ti.platform.evm6678l.ae66 and add dir to library file search path "c:\Program Files\Texas Instruments\ pdk_C####_1_0_0_xx \packages\ti\platform\evmc6678l\platform_lib\lib\debug"


Note: Please note that the above library is the little endian debug version library of the platform library. This is needed for the application built for Little Endian. Please refer to the above table for including the appropriate library for the particular platform library application. 

You may be wondering why we do not need include/library paths or library names for BIOS? Any RTSC enabled component in the MCSDK, provides its libraries and paths automatically during the build process. The appropriate libraries (big or little) and the paths are determined by the version of the component you selected in the CCS or RTSC Settings Screen. If you need to change any RTSC settings for an existing project, you can do so by highlighting the project name in CCS, then right clicking and selecting Properties and then selecting CCS from the menu.

7. Now select appropriate RSTC components by right click on project name->properties->Resource->General->RTSC (select PDK and BIOS versions and etc.), and then select appropriate target platform.

8. Build the project.

9. Connect to your EVM with your Target Configuration file, then load and run the program on first 4 cores. You should now see LEDs (0-3) blinking one after another.



Multi-core Programming Models

Explicit Programming Model using IPC

The MCSDK provides the foundations to support an explicit programming model based on Inter-Processor Communication (IPC). An explicit programming model is one in which the developer analyzes their application and manually partition tasks and processing elements across the cores and devices. In this model the developer is responsible for creating and managing processing tasks, communication between tasks, and data management.

The figures below illustrate the concept in different scenarios including both Linux and BIOS Operating systems.
IPC comm features.JPG


IPC Linux comm.JPG

The IPC provides a processor agnostic API which can be used for communication between processes on the same processing core (inter-process), processes on different cores (inter-core), and processes on different devices (interdevice). For inter-core communication, the transport can be shared memory or leverage the hardware queuing in the KeyStone architecture. And across devices multiple transports can be supported (e.g., SRIO). For all cases, the API is maintained so as to ease the task of migrating tasks and processes across cores and processors as part of designing and tuning an implementation.

IPC transport types.JPG

1 Image Processing Demo Guide.

Using and Configuring the Navigator/QMSS Transport

The QMSS Transport can be used in place of the shared memory transports delivered as part of the IPC module. This section will describe how to enable the use of and configure the QMSS transport.

Following, snippets from the qmssIpcBenchmark example project's RTSC configuration file, bench_qmss.cfg, included as part of MCSDK will be used to show how an application can utilize and configure the QMSS transport for use in IPC. The qmssIpcBenchmark example is found in pdk_C667#_w_x_y_z\packages\ti\transport\ipc\examples\qmssIpcBenchmark.

Configure IPC to Use the QMSS Transport

/* Load and use the CPPI and QMSS packages */
var Cppi = xdc.loadPackage('ti.drv.cppi'); 
var Qmss = xdc.loadPackage('ti.drv.qmss'); 
 
Program.sectMap[".qmss"] = new Program.SectionSpec();
Program.sectMap[".qmss"] = "MSMCSRAM";
 
Program.sectMap[".cppi"] = new Program.SectionSpec();
Program.sectMap[".cppi"] = "MSMCSRAM";
 
var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
var TransportQmssSetup = xdc.useModule('ti.transport.ipc.qmss.transports.TransportQmssSetup');
 
MessageQ.SetupTransportProxy = xdc.useModule(Settings.getMessageQSetupDelegate());
MessageQ.SetupTransportProxy = TransportQmssSetup;

The code includes the CPPI and QMSS modules, allocates their global objects in MSMC, and then assigns the use of the QMSS Transport module (TransportQMSS) at the transport layer. Interrupts are tied to queue push actions at the transport layer so the Notify later is not required.

Changing the GEM Interrupt Used by the QMSS Transport Module & Other TransportQmssSetup Parameters

TransportQmssSetup.dspIntVectId = 8  /* Desired GEM interrupt */

Adding the latter line to the .cfg file after creating the TransportQmssSetup variable allows the application developer to specify which GEM interrupt is used by the QMSS Transport module.

TransportQmssSetup.descMemRegion = 0;

Adding the latter line to the .cfg file after creating the TransportQmssSetup variable allows the application developer to specify the memory region in which the descriptors were allocated.

TransportQmss Configuration Options

var TransportQmss = xdc.useModule('ti.transport.ipc.qmss.transports.TransportQmss');

The latter defines a TransportQmss variable in order to access and change the QMSS transport configurations. Use of the TransportQmssSetup module automatically includes the use of the TransportQmss module but this variable must be created in order to access all the TransportQmss transport configuration options.

TransportQmss.numDescriptors = 1024;

The latter option defines the total number of descriptors to be used by all cores. This value should match the number of descriptors inserted in the memory region by the application.

TransportQmss.descriptorIsInSharedMem = true;

The latter option defines whether the descriptors are placed into shared memory, such as MSMCSRAM or DDR3, or into local L2 memory. If the descriptors are in L2 memory task-to-task communication, within the same core, will only work.

TransportQmss.descriptorSize = 128;

The latter option defines the descriptor size in bytes. It is recommended this value be equivalent to the cache line size of 128 bytes.

TransportQmss.useAccumulatorLogic = false;

The latter option defines whether the QMSS transport uses the Accumulator or QPEND queues. If this value is set to false the QPEND queues will be used. If true, the Accumulator queues and logic will be used. As of now, the QPEND queue configuration offers higher throughput and lower latency.

TransportQmss.pacingEnabled = false;

The latter option defines whether the accumulator accumulation logic is enabled. If this value is set to true the accumulator will interrupt the DSP as soon as intThreshold (next parameter discussed) number of descriptors have been received. Enabling pacing will increase end-to-end delay.

This option is only valid when useAccumulatorLogic is true

TransportQmss.intThreshold = 100;

The latter option defines the number of descriptors that should be received by the accumulator prior to interrupting the DSP when accumulator pacing is enabled. If pacing is disabled this value should be left at its default of 1.

This option is only valid when useAccumulatorLogic is true

TransportQmss.timerLoadCount = 0;        // timer ticks. This value only has effect when the pacingEnabled is true.

The latter option defines the time the accumulator should wait prior to interrupting the DSP. If the accumulator has not received a number of descriptors equal to intThreshold within the timeout period the accumulator will interrupt the DSP.

This option is only valid when useAccumulatorLogic is true

TransportQmss.accuHiPriListSize = 204;  // this number should be >= (2*intThreshold)+2

The latter option defines the accumulator list size. The list is a ping pong buffer so the accumulator list should be sized as greater than or equal to twice the intThreshold+2. The +2 is for the words included at the start of the ping and pong buffers storing the number of entries in each buffer.

This option is only valid when useAccumulatorLogic is true

TransportQmss Queue Allocation Notes

The QMSS Transport does not hard code which high priority accumulator, or QPEND, queues it uses. The transport initialization code queries the QMSS LLD for the next available high priority, or QPEND, queue. When the queue number is returned by the QMSS LLD the DSP GEM Event to be tied to the specified GEM Interrupt is chosen based on the interrupt map tables in the SPRUGR9 - Keystone Architecture Multicore Navigator document. The tables of interest are in Section 5.3-Interrupt Maps. For the accumulator queues, Table 5-3 is for C6670 devices and Table 5-4 is for C6678 devices. For the QPEND queues, Table 5-6 is for C6670 devices and Table 5-7 is for C6678 devices.

Using and Configuring the sRIO Transport

The sRIO Transport can be used in place of the shared memory transports delivered as part of the IPC module. This section will describe how to enable the use of and configure the sRIO transport.

Following, snippets from the srioIpcBenchmark example project's RTSC configuration file, bench_srio.cfg, included as part of MCSDK will be used to show how an application can utilize and configure the sRIO transport for use in IPC. The srioIpcBenchmark example is found in pdk_C667#_w_x_y_z\packages\ti\transport\ipc\examples\srioIpcBenchmark.

Configure IPC to Use the sRIO Transport

/* Load and use the CPPI, QMSS, and SRIO packages */
var Cppi = xdc.loadPackage('ti.drv.cppi'); 
var Qmss = xdc.loadPackage('ti.drv.qmss');
var Srio = xdc.loadPackage('ti.drv.srio');
 
Program.sectMap[".qmss"] = new Program.SectionSpec();
Program.sectMap[".qmss"] = "MSMCSRAM";
 
Program.sectMap[".cppi"] = new Program.SectionSpec();
Program.sectMap[".cppi"] = "MSMCSRAM";
 
Program.sectMap[".srioSharedMem"] = new Program.SectionSpec();
Program.sectMap[".srioSharedMem"] = "MSMCSRAM";
 
var MessageQ                = xdc.module('ti.sdo.ipc.MessageQ');
MessageQ.SetupTransportProxy = xdc.useModule(Settings.getMessageQSetupDelegate());
 
var TransportSrioSetup = xdc.useModule('ti.transport.ipc.srio.transports.TransportSrioSetup');
MessageQ.SetupTransportProxy = TransportSrioSetup;

The latter code includes the CPPI, QMSS, and sRIO modules, allocates their global objects in MSMCSRAM, and then assigns the use of the sRIO Transport module (TransportSrio) at the transport layer. The Notify layer is not required since sRIO can interrupt the remote core directly via QMSS queue interrupt.

Changing the GEM Interrupt Used by the sRIO Transport Module & Other TransportSrioSetup Parameters

TransportSrioSetup.dspIntVectId = 8  /* Desired GEM interrupt */

Adding the latter line to the .cfg file after creating the TransportSrioSetup variable allows the application developer to specify which GEM interrupt is used by the sRIO Transport module.

TransportSrioSetup.descMemRegion = 0;

Adding the latter line to the .cfg file after creating the TransportSrioSetup variable allows the application developer to specify the memory region in which the descriptors were allocated.

TransportSrioSetup.numRxDescBuffs = 256;

Adding the latter line to the .cfg file after creating the TransportSrioSetup variable allows the application developer to specify the number of descriptor buffers that can be tied to sRIO receive-side descriptors. The number of receive buffers must be at least the number of receive descriptors (TransportSrio.srioNumRxDescriptors) times the number of cores on the local chip. There should be enough buffers such that buffers are still available for tying to receive descriptors while other buffers are being processed by the application.

TransportSrioSetup.messageQHeapId = 0;

Adding the latter line to the .cfg file after creating the TransportSrioSetup variable allows the application developer to specify the heap ID of the heap from which MessageQ is to allocate the receive-side buffers.

This head ID should not be used by any other module within the system. It is meant solely for the receive-side descriptor buffers.

TransportSrio Configuration Options

var TransportSrio = xdc.useModule('ti.transport.ipc.srio.transports.TransportSrio');

The latter defines a TransportSrio variable in order to access and change the sRIO transport configurations. Use of the TransportSrioSetup module automatically includes the use of the TransportSrio module but this variable must be created in order to access all the sRIO transport configuration options.

TransportSrio.srioNumTxDescriptors = 4;
TransportSrio.srioNumRxDescriptors = 4;

The latter options define the number of transmit and receive descriptors to be used by each core. For example, if there are two cores in the system each core would be assigned 4 transmit and 4 receive descriptors. The number of descriptors inserted in the memory region by the application should be greater than or equal to ((srioNumTxDescriptors + srioNumRxDescriptors) * number of cores used on chip).

TransportSrio.descriptorSize = 128;

The latter option defines the descriptor size in bytes. It is recommended this value be equivalent to the cache line size of 128 bytes.

TransportSrio.pacingEnabled = true;

The latter option defines whether the accumulator accumulation logic is enabled. If this value is set to true the accumulator will interrupt the DSP as soon as intThreshold (next parameter discussed) number of descriptors have been received. Enabling pacing will increase end-to-end delay.

TransportSrio.intThreshold = 100;

The latter option defines the number of descriptors that should be received by the accumulator prior to interrupting the DSP when accumulator pacing is enabled. If pacing is disabled this value should be left at its default of 1.

TransportSrio.timerLoadCount = 0;        // timer ticks. This value only has effect when the pacingEnabled is true.

The latter option defines the time the accumulator should wait prior to interrupting the DSP. If the accumulator has not received a number of descriptors equal to intThreshold within the timeout period the accumulator will interrupt the DSP.

TransportSrio.accuHiPriListSize = 204;  // this number should be >= (2*intThreshold)+2

The latter option defines the accumulator list size. The list is a ping pong buffer so the accumulator list should be sized as greater than or equal to twice the intThreshold+2. The +2 is for the words included at the start of the ping and pong buffers storing the number of entries in each buffer.

TransportSrio.srioMaxMtuSizeBytes = 256;

The latter option defines the maximum transmissible unit by sRIO in bytes. The maximum value that can be specified is 256 bytes.

TransportSrio.numTxDescToCleanUp = 1;

The latter option defines the number of descriptors to cleanup each time TransportSrio_put is called. After sRIO sends out data associated with a descriptor provided by the TransportSrio_put function, sRIO will put the descriptor into a transmit completion queue. The next time TransportSrio_put is invoked it will check the transmit completion queue for descriptors, and their associated buffers, to clean up. If the number of descriptors in the transmit completion queue equals this setting it will cleanup the the defined number of descriptors and buffers.

TransportSrio.srioGarbageQ = "defined SRIO garbage queue value";

The latter option defines the sRIO garbage queue for which the SRIO transport should check for descriptors to cleanup. The sRIO hardware can be assigned up to six separate QMSS queues which are used as repositories for descriptors which failed to send because of different errors. The sRIO transport has the ability to check one of these queues for descriptors, and their associated buffers, to clean up. The application can specify six separate queues for each sRIO failure type or can tie one or more failure types to a single garbage queue. This allows the SRIO transport to clean up anywhere from one to all six failure types. The cleanup process occurs every TransportSrio_put operation.

TransportSrio Core Map Configuration and IPC Cluster Parameters

The sRIO transport is a multi-chip transport, allowing communication between two or more cores on separate chips. This attribute means that each chip running the sRIO transport must contain a copy of the core address array configurations. This copy must be exactly the same across all chips. The multi-chip capabilities of the sRIO transport are facilitated by the IPC cluster support. The IPC cluster support allows the core map to remain the same across all chips. Based on the IPC cluster base defined for each chip the sRIO core map is indexed in the transport to find the proper address for the destination core.

TransportSrio Single Device Core Map and IPC Cluster Configuration

This section covers the sRIO transport core map and IPC cluster configuration for a system that contains two cores within the same device communicating with one another. This scenario is illustrated by the srioIpcBenchmark example project and the code covered below is taken directly from the bench_srio.cfg file.

Program.global.Srio8BitDeviceId1 = 0xAB;

The latter operation defines the only valid device ID for data routed through the sRIO IP block. This value or any other device IDs must match with any device IDs used to set the sRIO TLM Base Routing Pattern Match information. In the srioIpcBenchmark example the pattern match information is set in the SrioDevice_init function in device_srio.c.

TransportSrio.srioMaxNumSystemCores = 2;

The latter option defines the total number of cores across all chips contained in the system. For this case, there is only one chip with only two cores on the chip being utilized.

TransportSrio.srioCoreTT.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreTT[0] = 0;
TransportSrio.srioCoreTT[1] = 0;

The srioCoreTT array specifies whether each core's socket uses 16 or 8-bit identifiers (deviceIDs as named in this example). The srioCoreTT array should have as many entries as there are cores in the system. The srioCoreTT array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreTT settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreDeviceId.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreDeviceId[0] = Program.global.Srio8BitDeviceId1;
TransportSrio.srioCoreDeviceId[1] = Program.global.Srio8BitDeviceId1;

The srioCoreDeviceId array specifies the deviceID assigned to each core's sRIO socket. The srioCoreDeviceId array should have as many entries as there are cores in the system. The srioCoreDeviceId array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreDeviceId settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreMailbox.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreMailbox[0] = 0;
TransportSrio.srioCoreMailbox[1] = 0;

The srioCoreMailbox array specifies the mailbox number assigned to each core's sRIO socket. The srioCoreMailbox array should have as many entries as there are cores in the system. The srioCoreMailbox array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreMailbox settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreLetter.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreLetter[0] = 0;
TransportSrio.srioCoreLetter[1] = 1;

The srioCoreLetter array specifies the letter number assigned to each core's sRIO socket. The srioCoreLetter array should have as many entries as there are cores in the system. The srioCoreLetter array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreLetter settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreSegMap.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreSegMap[0] = 0;
TransportSrio.srioCoreSegMap[1] = 0;

The srioCoreSegMap array specifies the segmentation mapping for core's sRIO socket. The srioCoreSegMap array should have as many entries as there are cores in the system. The srioCoreSegMap array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreSegMap settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

var procName = null;

This option can be used to define the MultiProc ID for cores prior to runtime. Typically, this option is set to null and the MultiProc ID for each core is set at runtime.

var procNameList = [];
procNameList = ["CORE0", "CORE1"];

This option defines the number of cores on this chip that will be used.

var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');

The latter option defines a MultiProc variable for use in setting the cluster configurations.

MultiProc.numProcessors = TransportSrio.srioMaxNumSystemCores;

The latter option sets the number of processors in the entire system, across all chips. For this case the number of cores is 2, or srioMaxNumSystemCores.

baseIdOfCluster and numProcessors must be set BEFORE setConfig is run

MultiProc.baseIdOfCluster = 0;

The latter option sets the base cluster ID for this chip. In this case, there is only one chip with two cores. The base ID is zero.

baseIdOfCluster and numProcessors must be set BEFORE setConfig is run

MultiProc.setConfig(procName, procNameList);

The latter function sets up the MultiProc module using the specified processor and cluster information.

TransportSrio Multi-Device Core Map and IPC Cluster Configuration

This section covers the sRIO transport core map and IPC cluster configuration for a system that contains two devices with two cores each, for a total four cores, communicating with one another. This scenario is illustrated by the srioIpcChipToChipExample project.

Device One (Producer) Configuration

This section covers the core map and IPC cluster configuration settings for the first, producer device within the system. As previously noted, each device .cfg file must map every core within the system. This scenario is illustrated by the SrioIpcChipToChipExample\producer example project and the code covered below is taken directly from the producer_srio.cfg file.

Program.global.Srio8BitDeviceId1 = 0xAB
Program.global.Srio8BitDeviceId2 = 0xCD

The latter operations define the only valid device IDs for data routed through the sRIO IP block. These values or any other device IDs must match with any device IDs used to set the sRIO TLM Base Routing Pattern Match information. In the srioIpcBenchmark example the pattern match information is set in the SrioDevice_init function in device_srio.c.

TransportSrio.srioMaxNumSystemCores = 4;

The latter option defines the total number of cores across all chips contained in the system. There are two cores on device one and two cores on device two, for a total of four cores being utilized.

TransportSrio.srioCoreTT.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreTT[0] = 0;
TransportSrio.srioCoreTT[1] = 0;
TransportSrio.srioCoreTT[2] = 0;
TransportSrio.srioCoreTT[3] = 0;

The srioCoreTT array specifies whether each core's socket uses 16 or 8-bit identifiers (deviceIDs, as named in this example). The srioCoreTT array should have as many entries as there are cores in the system. The srioCoreTT array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreTT settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreDeviceId.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreDeviceId[0] = Program.global.Srio8BitDeviceId1;
TransportSrio.srioCoreDeviceId[1] = Program.global.Srio8BitDeviceId1;
TransportSrio.srioCoreDeviceId[2] = Program.global.Srio8BitDeviceId2;
TransportSrio.srioCoreDeviceId[3] = Program.global.Srio8BitDeviceId2;

The srioCoreDeviceId array specifies the deviceID assigned to each core's sRIO socket. The srioCoreDeviceId array should have as many entries as there are cores in the system. The srioCoreDeviceId array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreDeviceId settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreMailbox.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreMailbox[0] = 0;
TransportSrio.srioCoreMailbox[1] = 0;
TransportSrio.srioCoreMailbox[2] = 0;
TransportSrio.srioCoreMailbox[3] = 0;

The srioCoreMailbox array specifies the mailbox number assigned to each core's sRIO socket. The srioCoreMailbox array should have as many entries as there are cores in the system. The srioCoreMailbox array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreMailbox settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreLetter.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreLetter[0] = 0;
TransportSrio.srioCoreLetter[1] = 1;
TransportSrio.srioCoreLetter[2] = 0;
TransportSrio.srioCoreLetter[3] = 1;

The srioCoreLetter array specifies the letter number assigned to each core's sRIO socket. The srioCoreLetter array should have as many entries as there are cores in the system. The srioCoreLetter array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreLetter settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

TransportSrio.srioCoreSegMap.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreSegMap[0] = 0;
TransportSrio.srioCoreSegMap[1] = 0;
TransportSrio.srioCoreSegMap[2] = 0;
TransportSrio.srioCoreSegMap[3] = 0;

The srioCoreSegMap array specifies the segmentation mapping for core's sRIO socket. The srioCoreSegMap array should have as many entries as there are cores in the system. The srioCoreSegMap array is sized to the maximum number of system cores prior to assigning a value to each entry in the array. For information on valid srioCoreSegMap settings please refer to pdk_C667#_w_x_y_z\packages\ti\transport\ipc\srio\transports\TransportSrio.xdc.

var procName = null;

This option can be used to define the MultiProc ID for cores prior to runtime. Typically, this option is set to null and the MultiProc ID for each core is set at runtime.

var procNameList = [];
procNameList = ["CORE0", "CORE1"];

This option defines the number of cores on this chip that will be used.

var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');

The latter option defines a MultiProc variable for use in setting the cluster configurations.

MultiProc.numProcessors = TransportSrio.srioMaxNumSystemCores;

The latter option sets the number of processors in the entire system, across all chips. For this case the number of cores is 2, or srioMaxNumSystemCores.

baseIdOfCluster and numProcessors must be set BEFORE setConfig is run

MultiProc.baseIdOfCluster = 0;

The latter option sets the base cluster ID for this chip. In this case, the Producer chip contains the first two cores in the system. Therefore, the cluster base ID for this chip is 0.

baseIdOfCluster and numProcessors must be set BEFORE setConfig is run

MultiProc.setConfig(procName, procNameList);

The latter function sets up the MultiProc module using the specified processor and cluster information.

Device Two (Consumer) Configuration

This section covers the core map and IPC cluster configuration settings for the second, consumer device within the system. As previously noted, each device .cfg file must map every core within the system. This scenario is illustrated by the SrioIpcChipToChipExample\consumer example project and the code covered below is taken directly from the consumer_srio.cfg file.

Program.global.Srio8BitDeviceId1 = 0xAB
Program.global.Srio8BitDeviceId2 = 0xCD
 
TransportSrio.srioMaxNumSystemCores = 4;
 
TransportSrio.srioCoreTT.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreTT[0] = 0;
TransportSrio.srioCoreTT[1] = 0;
TransportSrio.srioCoreTT[2] = 0;
TransportSrio.srioCoreTT[3] = 0;
 
TransportSrio.srioCoreDeviceId.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreDeviceId[0] = Program.global.Srio8BitDeviceId1;
TransportSrio.srioCoreDeviceId[1] = Program.global.Srio8BitDeviceId1;
TransportSrio.srioCoreDeviceId[2] = Program.global.Srio8BitDeviceId2;
TransportSrio.srioCoreDeviceId[3] = Program.global.Srio8BitDeviceId2;
 
TransportSrio.srioCoreMailbox.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreMailbox[0] = 0;
TransportSrio.srioCoreMailbox[1] = 0;
TransportSrio.srioCoreMailbox[2] = 0;
TransportSrio.srioCoreMailbox[3] = 0;
 
TransportSrio.srioCoreLetter.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreLetter[0] = 0;
TransportSrio.srioCoreLetter[1] = 1;
TransportSrio.srioCoreLetter[2] = 0;
TransportSrio.srioCoreLetter[3] = 1;
 
TransportSrio.srioCoreSegMap.length = TransportSrio.srioMaxNumSystemCores;
TransportSrio.srioCoreSegMap[0] = 0;
TransportSrio.srioCoreSegMap[1] = 0;
TransportSrio.srioCoreSegMap[2] = 0;
TransportSrio.srioCoreSegMap[3] = 0;

All the latter commands match exactly with what was defined for the producer device. For the sRIO transport to work all device's must have the same knowledge of the global core map. As a result, all the latter information must not change between device .cfg files.

var procName = null;
var procNameList = [];
 
procNameList = ["CORE0", "CORE1"]; 
 
var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
MultiProc.numProcessors = TransportSrio.srioMaxNumSystemCores;
MultiProc.baseIdOfCluster = 2;
MultiProc.setConfig(procName, procNameList);

The latter options configure MultiProc for the Consumer chip. For this case, the Consumer chip contains the last two cores in the system. Therefore, the cluster base ID for this chip is 2.

baseIdOfCluster and numProcessors must be set BEFORE setConfig is run

TransportSrio Queue Allocation Notes

The sRIO transport does not hardcode which general purpose, sRIO, or high priority accumulator queues it uses. The transport initialization code queries the QMSS LLD for the next available queues. When the queue number is returned for the high priority accumulator queues by the QMSS LLD the DSP GEM Event to be tied to the specified GEM Interrupt is chosen based on the interrupt map tables in the SPRUGR9 - Keystone Architecture Multicore Navigator document. The tables of interest are in Section 5.3-Interrupt Maps. Table 5-3 is for C6670 devices and Table 5-4 is for C6678 devices.

TransportSrio Application Configuration Requirements

In order to use the sRIO IPC transport to communicate with a core off-chip a couple rules must be followed when settings up the transport in the application.

1. A core to be used to communicate with an off-chip core must attach to at least one local core prior to communicating off-chip. The first invocation of Ipc_attach for a core will result in the sRIO transport starting up and configuring itself for send/receive. The IPC cluster mechanism does not enable attaching to core's off-chip. Those connection are setup manually. Therefore, at least one local IPC attach is required in order to setup and configure the sRIO transport. This local attach must be done in the context of main prior to BIOS_start enabling interrupts.

2. A core's connections to off-chip cores must be registered manually. Manual registration must be done after the local Ipc_attach is performed and before BIOS_start runs, enabling interrupts. A connection must be registered for each off-chip core that is to be communicated with. The following code gives an example of how to manually register an off-chip core connection:

/* NameServerMessageQ and SRIO Transport handles are global so they can be deleted
 * in task context when execution completes. */
NameServerMessageQ_Handle nsHandle = NULL;
TransportSrio_Handle srioHandle = NULL;
 
Int main(Int argc, Char* argv[])
{
  Error_Block eb;
 
  ...
 
  Attach_to_local_cores();
 
  ...
 
  /* Create messageQ to remote proc .  This will use srioTransport to send/receive nameserver
   * messages to/from remote chip.  A MessageQ heap must be registered prior to calling 
   * NameServerMessageQ_create()*/
  Error_init(&eb);    
  nsHandle = NameServerMessageQ_create(off_chip_core_multiProc_id, NULL, &eb);
  if (nsHandle == NULL) 
  {
    System_abort("NameServerMessageQ_create() failed");
  }
  /* Register a transport for messages received from off-chip cores */
  Error_init(&eb);
  srioHandle = TransportSrio_create(off_chip_core_multiProc_id, NULL, &eb);
 
  ...
 
  /* Start BIOS and all defined tasks.  Function will not return since it acts as the scheduler. */
  BIOS_start();
 
  /* should not reach here */
  return (0);
}

3. Attempts to open a MessageQ located on an off-core chip must be done after the manual connection to the off-chip core has been created and after BIOS_start() has enabled interrupts. When a core attempts to open an MessageQ located on an off-chip core, the NameServerMesssageQ uses the sRIO transport to send a NameServer request message to the off-chip core. In order to service the request and send a response back the remote off-chip core must have the sRIO transport up and running and have a manual connection to the requesting core created. If a requesting core tries to make a NameServer request to an off-chip core that is not ready yet, the NameServerMessageQ request functionality will timeout. At that point the application can wait then try to open the MessageQ at a later time. The timeout period to wait for a NameServer response can be configured in the .cfg file with the following commands. The resolution of the timeout value is microseconds.

var NameServerMessageQ = xdc.useModule('ti.sdo.ipc.nsremote.NameServerMessageQ');
NameServerMessageQ.timeoutInMicroSecs = 1000000; /* 1 sec */

For a working example of how to use the multi-chip IPC and the sRIO transport for device to device communication please examine the producer and consumer RTSC projects in the directory pdk_C667#_w_x_y_z\packages\ti\transport\ipc\examples\srioIpcChipToChipExample. The project .cfg and .c files have been highlighted in the latter sections but contain more in-line comments regarding the use of the sRIO transport.




Programming Model using OpenMP

OpenMP is the industry standard for shared memory parallel programming in C, C++, or Fortran. It provides portable high-level programming constructs that enable users to easily expose a program's task and loop level parallelism in an incremental fashion. With OpenMP, users specify the parallelization strategy for a program at a high level by annotating the program code with compiler directives that specify how a region of code is executed by a team of threads. The compiler works out the detailed mapping of the computation to the machine. The OpenMP programming API enables the programmer to perform the following:

  • Create and manage threads
  • Assign and distribute work (tasks) to threads
  • Specify which data is shared among threads and which data is private
  • Coordinate thread access to shared data

As shown in the following figure, OpenMP is a thread-based programming language. The master thread executes the sequential parts of a program. When the master thread encounters a parallel region, it forks a team of worker threads that along with the master thread execute in parallel.

Threading model.jpg

There is a fairly easy migration for existing code base - C/C++ based directives (#pragma) - used to express parallelism. OpenMP directives specify that a well-structured region of code is executed by a collection of threads that share in the work. Worksharing directives are provided to effect a distribution of work among the participating threads. The programmer incrementally adds OpenMP pragmas to an existing sequential application allowing them to quickly port code to a multicore platform.

The following figure is an example of data-parallelism. A parallel-for loop where each thread executes a chunk of the loop and their intermediate results are reduced to a final result. A single copy of x[] and c[] is shared by all the threads.

Parallel for with reduction.jpg

The following figure shows the OpenMP solution stack. The OpenMP API is made up of directives(#pragmas), function calls, and environment variables. The compiler translates the OpenMP API into multi-threaded code with calls to a custom runtime library that implements support for thread management, shared memory and synchronization.

The OpenMP run-time for SYS/BIOS (OMP) library implements the bottom two layers of the OpenMP solution stack. Currently, OpenMP is supported on TI DSPs only for SYS/BIOS operating system. All OpenMP programs must be linked with the OMP run-time library.

OpenMP Solution Stack.jpg


See also:


Compiling OpenMP code with the TI compiler using Makefile

The TI compiler (version 7.4 or higher) includes support for OpenMP 3.0.

To enable support for OpenMP in the compiler you will need to use the --openmp command line option.

The number of threads available to an OpenMP program is determined by the configuration of the OMP run-time.

Hello World example OpenMP program:

/* omp-hello.c */
#include <stdlib.h>
#include <stdio.h>
#include <ti/omp/omp.h>
#include <ti/omp/libgomp_g.h>
 
int main (int argc, char *argv[]) {
 int nthreads, tid;
 
 /* Fork a team of threads giving them their own copies of variables */
#pragma omp parallel private(nthreads, tid)
 {
 
 /* Obtain thread number */
 tid = omp_get_thread_num();
 printf("Hello World from thread = %d\n", tid);
 
 /* Only master thread does this */
 if (tid == 0)
 {
 nthreads = omp_get_num_threads();
 printf("Number of threads = %d\n", nthreads);
 }
 
 } /* All threads join master thread and disband */
 
 return 0;
}

You may generate prebuilt C libraries against which an OpenMP application can be compiled and linked. A typical build flow involves building the prebuilt library once for a given device (i.e. evm6678) and for a specific RTSC configuration.

The files needed to generate the prebuilt libraries can be found in [OMP_INSTALL_DIR]\preconfig directory.

1) Edit ompdefault.cfg as needed to match your desired RTSC configuration.

2) Edit the makeomplibs file as needed:

a. Point to your BIOS, IPC, PDK, XDCTools and OMP products

b. Change the build profile as needed

c. Change the build platform as needed

3) Build the prebuilt libraries

$ make -f makeomplibs omp-evm6678

4) Edit Makefile as follows:

a. Edit the path to the C6x OpenMP-aware codegen tools

b. Add application build goals to the Makefile using the example for ‘omp_hello’ provided as a guideline.

5) Build the application: 
$ make omp_hello.xe66

The above procedure would produce a hello.out core executable which needs to be loaded and run on CORE0 only.

Using OpenMP on TI devices

Memory Coherency

OpenMP has shared and private variables. Each thread has its own copy of a private variable that the other threads cannot access. OpenMP specifies a relaxed consistency shared memory model. Threads executing in parallel have a temporary view of shared memory until they reach memory synchronization or flush points in the execution flow.

  • It is currently the programmers responsibility to maintain the consistency of shared variables that are allocated to cachable memory. Something like:
/* process elements of shared_array in parallel*/
#pragma omp parallel for
 for (i=0; i<N; i++)
 shared_array[i] = do_stuff(shared_array[i]);
 
 /* write-back invalidate each thread/core's cache */
#pragma omp parallel
 {
 Cache_wbInvAll();
 _mfence();
 }
  • All global and static variables are shared. All dynamically allocated memory is shared.
  • Stacks must also be placed in shared memory since a stack variable can be shared.
  • If a variable is smaller than a cache line it is possible for two cores to cache the line that contains the variable. In this case, the last core to write the cache line will over-write in shared memory the other core's version of the variable.
Threadprivate Memory
  • The compiler allocates threadprivate variables into the .threadprivate section. The execution model assumes that the .threadprivate section is allocated by the linker into the L2 private memory.
  • The above restriction will be removed once the compiler tools implement support for thread local storage.
  • When using threadprivate, only one thread can be assigned to each core.
Known issues
  • The collapse clause is not supported
  • Error messages are sparse
  • Goto in/out of a parallel region is not flagged as an error


Examples

The example programs are designed to familiarize you with the various steps required to create, compile, and run and OpenMP program. Besides these examples are are additional examples included under the OMP (e.g.,\OMP_xx_xx_xx\packages\examples). 

Multicore Hello World Example

This is the first example OpenMP program. It's purpose is to get you used to creating projects in CCS, building an executable and then running it on your EVM.

1. The first step is to create a project in CCS for this example. To do so follow the steps below.

  • Open CCS (preferably with a new workspace).
  • Open File->New->CCS Project and in the project name field enter HelloWorld_example.
  • In the CCS project window, select Project Type: as C6000.
  • In the New CCS Project, select Device Variant: as Generic C66xx Device.
  • In the Project Templates window select Empty RTSC Project and hit Next. See figure below.
  • Configure your RTSC settings. The packages that need to be selected, are as per the snapshot in instruction #2 below.
  • It should open an empty project with name HelloWorld_example.


Import OpenMPEx1Project.JPG


2. Configure your RTSC settings. The following packages needs to be selected as shown in the snapshot below: BIOS, IPC, OpenMP, PDK, and MCSDK:

MCSDK components.JPG

3. Now that we have a project, we are going to create a source file for the project.

  • Select File->New->Source File, enter Source File name as helloworld.c, then hit Finish.
  • It should open helloworld.c empty file in the eclipse editor. Paste following source code in the editor
/******************************************************************************
 * FILE: omp_hello.c
 * DESCRIPTION:
 * OpenMP Example - Hello World - C/C++ Version
 * In this simple example, the master thread forks a parallel region.
 * All threads in the team obtain their unique thread number and print it.
 * The master thread only prints the total number of threads. Two OpenMP
 * library routines are used to obtain the number of threads and each
 * thread's number.
 * AUTHOR: Blaise Barney 5/99
 * LAST REVISED: 04/06/05
 * UPDATED: For BIOS MCSDK
 ******************************************************************************/
#include <ti/omp/omp.h>
 
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <time.h>
#include "ti/platform/platform.h"
#include "ti/platform/resource_mgr.h"
 
#define NTHREADS 8
 
void main()
{
 
 int nthreads, tid;
 
 nthreads = NTHREADS;
 
 omp_set_num_threads(NTHREADS);
 
 /* Fork a team of threads giving them their own copies of variables */
#pragma omp parallel private(nthreads, tid)
 {
 
 /* Obtain thread number */
 tid = omp_get_thread_num();
 printf("Hello World from thread = %d\n", tid);
 
 /* Only master thread does this */
 if (tid == 0)
 {
 nthreads = omp_get_num_threads();
 printf("Number of threads = %d\n", nthreads);
 }
 
 } /* All threads join master thread and disband */
 
}


4. Create a new .cfg File by right clicking your project and selecting New --> File. Name this file helloworld.cfg and copy the source code:

/*
 * Copyright 2012 by Texas Instruments Incorporated.
 *
 */
var OpenMP = xdc.useModule('ti.omp.utils.OpenMP');
var System = xdc.useModule("xdc.runtime.System");
var SysMin = xdc.useModule("xdc.runtime.SysMin");
System.SupportProxy = SysMin;
SysMin.bufSize = 0x8000;
 
/* Increase local heap size */
var BIOS = xdc.useModule('ti.sysbios.BIOS');
BIOS.heapSize = 0x20000;
 
/* Use more efficient Notify driver */
var Notify = xdc.module('ti.sdo.ipc.Notify');
Notify.SetupProxy = xdc.module('ti.sdo.ipc.family.c647x.NotifyCircSetup');
 
/* Use more efficient MessageQ transport */
var MessageQ = xdc.module('ti.sdo.ipc.MessageQ');
MessageQ.SetupTransportProxy = xdc.useModule('ti.sdo.ipc.transports.TransportShmNotifySetup');
 
var System = xdc.useModule('xdc.runtime.System');
System.extendedFormats = "%f";
 
OpenMP.setNumProcessors(8);
 
/* Create HeapOMP for shared heap */
var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
var HeapOMP = xdc.useModule('ti.omp.utils.HeapOMP');
HeapOMP.sharedRegionId = 2;
HeapOMP.localHeapSize  = 0x20000;
HeapOMP.sharedHeapSize = 0x1000000;
// Specify the Shared Region
SharedRegion.setEntryMeta( HeapOMP.sharedRegionId,
                           {   base: 0x90000000,
                               len:  HeapOMP.sharedHeapSize,
                               ownerProcId: 0,
                               createHeap: true,
                               isValid: true,
                               name: "HeapOMP",
                           }
                          );
var Cache        = xdc.useModule('ti.sysbios.family.c66.Cache');
Cache.setMarMeta(0x90000000, 0x10000000, Cache.PC | Cache.WTE );

5. Enable OpenMP compile option by right clicking your project and selecting Properties. Navigate to: Build --> C6000 Compiler --> Advanced Options --> Advanced Optimizations. Tick the checkbox that says "Enable support for OpenMP 3.0 (--openmp, --omp)".

OpenMPEx1Project EnableOMPCompile.JPG

6. Build your project by right clicking your project and select Build Project.

7. Connect and power your device. Launch your configuration file and connect to core0. For more information on connecting your device with CCS, refer to the 2.0.x User Guide.

8. Load your helloworld program: select the core 0 and select Run --> Load --> Load program. Browse and select the .out program you compiled in step 6.

9. Press run (the green triangle). You should see the following output:

OpenMPEx1Project Output.JPG

Notes:

  • The number of cores available available to an OpenMP program is determined by the configuration of the OpenMP run-time using OpenMP.setNumProcessors. As an example, you can change OpenMP.setNumProcessors to a lower value and try running the Hello World again and see the number of print out change.

OMP Integration for Advanced Users

If you are already familiar with OpenMP and TI BIOS MCSDK software, then please see OpenMP Integration in existing applications for more information.



Multi-core Application Image Creation

The standard TI compiler and linker create 'single' *.out files which can be loaded independently and run synchronously on the various cores through CCS or bootloaders. This can be cumbersome when attempting to load a multicore application through CCS and requires additional support infrastructure to boot the complete application.

Packaged with the MCSDK is a collection of tools, called Multi-core Application Deployment (MAD) utilities, that allows a user to create a single loadable/bootable multicore application image from one or more standard *.out files generated by the compiler and linker. The generated multicore image can be loaded and run using CCS. In addition, the IBL provided as part of the MCSDK supports loading of MAD generated multicore application images hence provides a complete infrastructure for booting multicore applications.

MAD is a collection of utilities intended to support a broad range of multicore use cases. More details can be found here in the MAD Utils User Guide.

See also:

An example of an MCSDK application that uses MAD is the Image Processing Demo Guide.

Booting and Flash

Boot Overview

The MCSDK includes a Tools Package which provides POST, boot loader and boot utilities for use with the TI EVMs and are intended to serve as example/reference for customers.


The MCSDK tools package is located in the C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools directory and includes:

  • POST: Power on Self Test application.
  • IBL: 1st stage and 2nd stage Bootloader for booting an application from the NOR/NAND flash or Ethernet over I2C EEPROM.
  • MAD: Multicore application deployment tool to support multicore booting.
  • Boot Examples: Example projects demonstrating the booting of an user application using the boot loader.
  • Writer Utilities: Utilities to program an application image to flash or EEPROM.
  • Other Utilities: Utilities to do file format conversion that are required by the boot examples. 

Power On Self Test (POST)

The Power-On Self Test (POST) boot is designed to execute a series of platform/EVM factory tests on reset and indicate a PASS/FAIL condition using the LEDs and write test result to UART. A PASS result indicates that the EVM can be booted. The POST application resides on the EEPROM of the EVM, therefore the size of the image has to be less than 64 KB.

POST will perform the following functional tests:

  • External memory read/write test
  • NAND read test
  • NOR read test
  • EEPROM read test
  • UART write test
  • Ethernet loopback test
  • LED test

Additionally, POST provides the following useful information:

  • FPGA version
  • Board serial number
  • EFUSE MAC ID
  • Indication of whether SA is available on SOC
  • PLL Reset Type status register
NoteNote: POST is not intended to perform functional tests of the DSP.

At power on, the DSP starts execution with bootrom which transfers execution to the POST boot program from EEPROM using the I2C slave bus address as 0x50. The POST will then run through a sequence of platform tests. Upon power on, all the 4 FPGA debug LEDs will be on by default, remain ON for approximately 10 sec, then turn OFF if all the tests complete successfully. If any of the tests fails, the LED(s) will blink.

Below is the LED status table showing the test status/result:

Test Result LED1 LED2 LED3 LED4
Test in progress on on on on
All tests passed off off off off
External memory test failed blink off off off
I2C EEPROM read failed off blink off off
EMIF16 NAND read failed off off blink off
SPI NOR read failed off off off blink
UART write failed blink blink off off
EMAC loopback failed off blink blink off
PLL initialization failed off off blink blink
NAND initialization failed blink blink blink off
NOR initialization failed off blink blink blink
EMAC loopback failed on blink blink blink
Other failures blink blink blink blink


NoteNote: POST should only be programmed to EEPROM I2C bus address 0x50 (please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\post\docs\README.txt on how to build POST and program POST to EEPROM), to execute the POST you must ensure the boot DIP switches for your platform are properly configured to boot from I2C master mode, bus address 0x50 (please refer to the C667x EVM technical reference manual and C667x device data sheet for the boot mode configurations). The POST will put board information and test result on the UART console.

post.jpg


Intermediate Boot Loader (IBL) and Examples

Below is the table showing the boot modes supported by the C66x EVMs:


Boot Mode TMDSEVM6678 TMDSEVM6670 TMDSEVM6618 TMDXEVM6657
NOR boot via IBL over I2C1 Yes Yes Yes Yes
NAND boot via IBL over I2C1 Yes Yes Yes Yes
TFTP boot via IBL over I2C1 Yes Yes Yes Yes
I2C POST boot2 Yes Yes Yes Yes
Ethernet boot Yes Yes Yes Yes
SRIO boot Yes Yes Yes Yes
PCIe boot Yes Yes Yes Yes

NoteNote:

  1. Support boot over I2C bus address 0x51
  2. Support POST boot over I2C bus address 0x50
  3. Only ELF and BBLOB images are supported for booting
  4. IBL is using the first 128KB L2 local memory, any application booting from IBL should NOT use the first 128KB L2 memory, OR should only use the first 128KB L2 memory for uninitialized data section



NAND Boot
Nandboot.jpg

NAND boot is a multi-stage process which is designed to boot an application from NAND flash after reset. Figure below illustrates the elements of the NAND boot process.

On reset the DSP starts execution with the bootrom which transfers execution to the secondary bootloader from EEPROM using the I2C slave bus address 0x51. The secondary bootloader loads the application program from NAND flash then transfers control to the application. To execute the NAND bootloader you must ensure the DIP switches for your platform are properly configured for I2C Master Boot and address 0x51, AND the boot parameter index dip switch should be set to 2 or 3.

NAND boot supports multiple images booting1. Depending on the boot parameter index dip switch, maximum 2 boot images can be supported. By default NAND boot only supports a BBLOB image format, if the customer wants to boot an ELF image,  the IBL configuration table needs to be modified and re-programmed to EEPROM.

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\examples\i2c\nand\docs\README.txt on how to build an Hello World example application and program it to NAND, and boot the Hello World image from the NAND flash.


NOR Boot
Norboot.jpg

NOR boot is a multi-stage process which is designed to boot an application from NOR flash after reset. Figure below illustrates the elements of the NOR boot process.

On reset the DSP starts execution with the bootrom which transfers execution to the secondary bootloader from EEPROM using the I2C slave address 0x51. The secondary bootloader loads the application program from NOR flash then transfers control to the application. To execute the NOR bootloader you must ensure the DIP switches for your platform are properly configured for I2C Master Boot and address 0x51, AND the boot parameter index switch should be set to 0 or 1.

NOR boot supports multiple images booting1. Depending on the boot parameter index dip switch, maximum 2 boot images can be supported.

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\examples\i2c\nor\docs\README.txt on how to build an Hello World example application and program it to NOR, and boot the Hello World image from the NOR flash.


NoteNote:

  1. Not supported in Beta-1 release
TFTP Boot
Emacboot.jpg

EMAC boot is a multi-stage process which is designed to boot an application from TFTP server after reset. Figure below illustrates the elements of the EMAC boot process.

On reset the DSP starts execution with the bootrom which transfers execution to the secondary bootloader from EEPROM using the I2C slave address 0x51. The secondary bootloader loads the application program from a remote TFTP server then transfers control to the application. To execute the EMAC bootloader you must ensure the DIP switches for your platform are properly configured for I2C Master Boot and address 0x51, AND the boot parameter index switch should be set to 4. By default EMAC boot only supports a BBLOB image format, if the customer wants to boot an ELF image, the IBL configuration table needs to be modified and re-programmed to EEPROM.

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\examples\i2c\emac\docs\README.txt on how to build an Hello World example application and boot the Hello World image from a remote TFTP server.


NoteNote:

Please refer to the boot mode dip switch settings for different boot mode on TMDSEVM6678L_EVM , TMDSEVM6670L_EVM , and TMDSEVM6657L_EVM that IBL supports.


NoteNote:

IBL is flashed into I2C EEPROM bus address 0x51. IBL provides a workaround for the PLL lockup issue (please refer to C6678 errata document, February 2011, advisory 8 for details on the PLL lockup issue). For ROM boot modes (EMAC,SRIO,PCIe,Hyperlink etc) and I2C boot mode with bus address 0x50, DSP will initially boot from I2C EEPROM bus address 0x51 which does the PLL reset workaround, updates the DEVSTAT for appropriate values based on the DIP switch settings (SW3 through SW6 settings) and then re enters the ROM to accomplish the desired boot mode. Please note that the re entry is done for all boot modes except for PCIe boot mode and I2C boot mode with bus address 0x51.

Below are the steps done in the IBL:

  1. FPGA samples the bootmode pins
  2. FPGA forces the DSP to boot via I2C bus address 0x51
  3. PLL is initialized correctly by the IBL on the I2C.
  4. IBL reads the sampled bootmode from an FPGA register.
  5. IBL checks the bootmode, if it is not I2C boot or it is I2C boot but with bus address 0x50, IBL writes bootmode into the DEVSTAT register
  6. IBL then checks if the bootmode is PCIE boot or not. If it is, it executes some PCIE workaround to configure the PCIE registers (mainly to accept spread spectrum clock) and stays inside IBL waiting for PCIe boot.
  7. If it is not PCIE boot mode, IBL writes the Boot ROM entry address into the DSP Program Counter, DSP executes the desired internal ROM boot mode or boot from I2C bus address 0x50 as normal.


Updating the IBL Ethernet Configurations

As of MCSDK 2.0.5.17, there are two ways to update the IBL ethernet configurations for ethernet boot.

Using CCS
Please follow the steps as mentioned under section IBLand follow steps 10 through 14. Please note that the i2cConfig.gel file can be modified via a text editor before loading and running the script in CCS. Please note that this gel file contains configuration settings for multiple devices and multiple boot modes.

Using iblConfig Utility Program
The second way to update the IBL ethernet configurations is to use iblConfig.out. This utility program is located under mcsdk_2_00_xx_xx\tools\boot_loader\ibl\src\util\iblConfig\build. In command line, use the "make" program with the given Makefile to generate iblConfig.out and input.txt. Please be sure to fill in the parameters for input.txt before running iblConfig.out; below is an example of input.txt:

file_name = ibl.bin
device = 6
offset = 0x500
ethBoot-doBootp = TRUE
ethBoot-bootFormat = ibl_BOOT_FORMAT_ELF
ethBoot-ipAddr = 192.168.1.3
ethBoot-serverIp = 192.168.1.2
ethBoot-gatewayIp = 192.168.1.1
ethBoot-netmask = 255.255.255.0
ethBoot-fileName =

The first 3 parameters must be filled in for iblConfig.out to work:

  • file_name refers to the IBL binary file to update. This file must be in the same directory as iblConfig.out.
  • device refers to the device being used. Please enter 6 for C6678, 7 for C6670, and 8 for C6657.
  • offset refers to an offset space in the IBL. The value is 0x500 for C6678, C6670, and C6657

The ethernet parameters (the entries beginning with ethBoot) refer to specific ethernet configurations. If they are not specified, they will be defaulted to the values in the mcsdk_2_00_xx_xx\tools\boot_loader\ibl\src\util\iblConfig\src\device.h file. In the example above, the ethernet boot file name will be defaulted to c6678-le.bin when iblConfig.out is run.

After running iblConfig.out and updating the IBL binary, you must flash the modified IBL binary to your EVM. You can do this as part of program_evm (refer to section Using Program Evm) or you can flash it individually using eepromwriter (refer to section IBL).
NoteNote: If you updated the IBL with iblConfig and flashed it with eepromwriter, you should NOT use i2cparam_0x51_c667#_le_0x500.out and iblConfig.gel - this would overwrite the changes you made to the IBL.

Flash and Flash Utilities

The following boot utilities for loading code into the EEPROM, NOR and NAND are provided as part of the Tools Package with the MCSDK. All source code is provided along with documentation so that customers can port to other environments as necessary or to make modifications and enhancements.

  • romparse: Utility which converts either the IBL or POST out files into an image format that can be writtent to the EEPROM using the EEPROM writer utility. This utility is specific to Microsoft Windows and generates an image format that MUST be loaded into CCS memory. Romparse utility is located under C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\ibl\src\util\romparse directory.
  • i2cConfig: Utility for writing the IBL boot parameter configuration tables to the I2C EEPROM. The configuration table configures the IBL to boot the image from NOR, NAND or EMAC based on the boot priority. This utility executes on the EVM using CCS and JTAG. i2cConfig utility is located under C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\ibl\src\util\i2cConfig directory.
  • EEPROM Writer: Utility for writing to the EEPROM. This utility executes on the EVM using CCS and JTAG and it is located under C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\writer\eeprom\evmc6678l\bin directory.
  • NOR Writer: Utility for writing to the NOR flash. This utility executes on the EVM using CCS and JTAG and it is located under C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\writer\nor\evmc6678l\bin directory.
  • NAND Writer: Utility for writing to the NAND flash. This utility executes on the EVM using CCS and JTAG and it is located under C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\writer\nand\evmc6678l\bin directory.
Helpful tips image.jpg

Useful Tip

Starting in BIOS-MCSDK 2.1.1, the program_evm utility provides the ability to format the NAND (i.e., permanently erase the entire NAND device). Please refer to program_evm_userguide.pdf (located in the mcsdk_2_00_xx_xx\tools\program_evm\ directory) for more information.


Programming I2C EEPROM (address 0x51) with IBL and boot configuration table1

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\ibl\doc\README.txt on how to build IBL and program IBL and boot parameter configuration table to EEPROM bus address 0x51.


Programming I2C EEPROM (address 0x50) with POST boot1

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\post\docs\README.txt on how to build POST and program POST to EEPROM bus address 0x50.

Flashing NOR FLASH with a user application for NOR boot over I2C

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\writer\nor\docs\README.txt on how to program a user application to NOR.

Flashing NAND FLASH with a user application for NAND boot over I2C

Please refer to C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\writer\nand\docs\README.txt on how to program a user application to NAND.


NoteNote:

  1. If the customer wants to user their own EEPROM writer to write a raw binary file to the EEPROM, they can use the C:\Program Files\Texas Instruments\mcsdk_2_00_00_xx\tools\boot_loader\ibl\src\util\btoccs\ccs2bin utility to convert the .dat to .bin either with byte swapping or without swapping depending on the data format their EEPROM writer uses.


Technical Support and Product Updates

Technical Support and Forums

For technical discussions and issues, please visit

For local support in China, please visit

NoteNote: When asking for help in the forum you should tag your posts in the Subject with “MCSDK”, the part number (e.g. “C6678”) and additionally the component (e.g. “NDK”).

Helpful tips image.jpg

Useful Tip

You can always get the most recent version of this document on the Texas Instruments Embedded Processors Wiki. See the page titled BIOS MCSDK 2.0 User Guide for the most up to date revision.


Product Updates

There are various ways to receive updates for MCSDK. They are oulined in the following sections.

MCSDK Product Folder

NoteNote: The EVM comes with disks containing the MCSDK software and CCS. You can start with these or go to the MCSDK software download site listed above to check for the latest updates and version. The BIOS-MCSDK release download will also have pointers to applicable CCS and compiler release versions as well. Please review the release notes and software manifest before downloading and/or installing the software.

Eclipse Update Manager

The BIOS MCSDK utilizes Eclipse Update Manager in CCS to detect, download, and install updates in an automated fashion. Eclipse provides various controls for this process -- from manually checking for updates to periodically checking for updates. In the event you can not update via Eclipse using the Eclipse Update Manager, please visit the Texas Instruments software download site for MCSDK: http://focus.ti.com/docs/toolsw/folders/print/bioslinuxmcsdk.html

NoteNote: If you are running CCS on Linux, make sure you have write permissions to CCS folders before doing Eclipse updates. If you installed CCS with root permission, please launch CCS with root permission before updating. Incompatible write permissions will prevent CCS's update plugin to update your files correctly.

Eclipse Update (Automatic)

  1. Please make sure the MCSDK 2x box is checked in the available software sites of CCS, before clicking check for updates using the CCS help menu.
  2. After CCS re-starts it should recognize MCSDK and can check its update site using the Eclipse Update Manager
  3. When the Update Manager connects you will have the option to download the updated release of BIOS MCSDK
  4. After downloading, CCS will shut down and run the updated BIOS MCSDK installer
  5. After installation, CCS will be re-started and updated BIOS MCSDK content will be installed

NoteNote: For the Eclipse update to work you must have Eclipse Updates enabled. You may also have it set to check on a periodic basis. If so, you may need to run the Update Manager to get the update immediately from "Help/Check for Update" as shown in the picture below:

Figure 3: Check for Updates in CCS Help Menu

Eclipse Update (Manual)

If automatic update does not work, or you wish to just search for an update to MCSDK, do the following, after installing MCSDK.

  1. Start CCS, and select Window->Preferences
  2. In the left pane select and expand Install/Update, then select Available Software Sites

Figure 4: Install/Updates in CCS Preferences Menu

  1. It will open a list of avilable software sites
  2. In the list find and check URL http://software-dl.ti.com/sdoemb/sdoemb_public_sw/bios_mcsdk/eclipse/mcsdk2x/, the Enabled column should change to Enabled. You can also enter a name for the site but its not required.

Figure 5: Available Software updates in CCS Preferences Menu

  1. Select OK to close the window
  2. Then select Help->Install New Software… , In the Work with: select the above URL from the drop down menu

Figure 6: Available Software Installation in CCS

  1. Check the URL in Name and select Finish
  2. The CCS should discover new MCSDK release to install

Frequently Asked Questions

Q: How can I get the EVM back to factory default state?

To flash the EVM to its factory defaults, refer to the program_evm.pdf document located in the\factory_images\ folder from the DVD that came with the EVM. If you have misplaced the DVD, this folder can be downloaded directly from the EVM manufacturer site: TMDSEVM6678,TMDSEVM6670, TMDXEVM6657 (TBD).

After successfully flashing, the EVM will be restored to its original NOR, NAND, and EEPROM binaries.

Q: I have just updated my BIOS MCSDK software, how do I load it to my EVM?

Setup the boot mode to No Boot mode by having the dip switches as the following for updating the images to EVM's flash area:

No Boot mode DIP SW Settings
Pin#
1    2    3    4
1    2    3    4
1    2    3    4
1    2    3    4
State
OFF-ON-ON-ON
ON-ON-ON-ON
ON-ON-ON-ON
ON-ON-ON-ON
Switch
SW3
SW4
SW5
SW6


NoteNote: Pin 1 of SW3 is the endian switch - when set to OFF put the EVM into Little Endian Mode and ON puts the EVM into Big Endian Mode.

Using Program EVM

As of BIOS MCSDK 2.0.5, there exists a convenient script in the mcsdk_2_00_xx_xx\tools\ directory to update all the images automatically via command line. Follow the steps in program_evm_userguide.pdf (located in the mcsdk_2_00_xx_xx\tools\program_evm\ directory) to flash the new images. The images that are loaded are kept in the .\program_evm\binaries\evm66xxl\ directory; you can substitute any image here.

Helpful tips image.jpg

Useful Tip

To avoid updating CCS from the version that came with the EVM, you can use the program_evm tool found on the EVM DVD and substitute newer images in the binaries\evm66xxl\ directory.


NoteNote: The NAND image for the Linux kernel is not provided with the BIOS MCSDK release.

NoteNote: The DSS script under program_evm directory is using the default ccxml files that are created under CCS 5.0.3; So, for CCS 5.1 please provide the customized ccxml file that user created; Example steps below are for a Windows PC for C6670 EVM XDS560V2 mezzanine card. Please follow similar steps for using the dss script for CCS 5.1 under Linux.

  1. program_evm>set PROGRAM_EVM_TARGET_CONFIG_FILE=C:\Documents and Settings\user\CCSTargetConfigurations\evmc6670_CCS51_mezzanine.ccxml (note that there are no double quotes to be given in this path)
  2. program_evm>set DSS_SCRIPT_DIR="C:\ti\ccsv5\ccs_base\scripting\bin" (please observe the double quotes in the path here)
  3. program_evm>%DSS_SCRIPT_DIR%\dss.bat program_evm.js TMDSEVM6670Le-Le

Q: Can I update the new images individually instead of using Program EVM?

Yes. Setup your EVM to No Boot mode as described in the previous question. Then follow the instructions for the EEPROM/NOR/NAND images:

Updating EEPROM Images

The EEPROM images are IBL (intermediate boot loader) and Power On Self Test (POST). The IBL/POST is often updated with MCSDK releases. Follow these instructions to update the EVM to the newer IBL and POST images: IBL is flashed at EEPROM 0x51 address and POST is flashed at EEPROM 0x50 address.

NoteNote: For MCSDK version 2.0.3 and prior, .dat files are provided instead of .bin files. If you are using MCSDK version 2.0.3 or prior, please follow the instructions provided here by replacing .bin with .dat

IBL

  1. Copy i2crom_0x51_c667#_le.bin from mcsdk_2_00_xx_xx\tools\boot_loader\ibl\src\make\bin to mcsdk_2_00_xx_xx\tools\writer\eeprom\evmc667#l\bin. Rename this copied file to app.bin.
  2. Open eepromwriter_input.txt in mcsdk_2_00_xx_xx\tools\writer\eeprom\evmc667#l\bin. Set file_name equal to app.bin and bus_addr equal to 0x51. Make sure start_addr and swap_data are set to 0. Save and close eepromwriter_input.txt.
  3. Turn on and connect your EVM. Open CCSv5, load the appropriate Target Configuration, connect to Core 0, and load the corresponding GEL file.
  4. Load the EEPROM writer program by going to Run -> Load Program and browse for the eeprom writer DSP executable. For e.g, eepromwriter_evm667#l.out in the same folder as app.bin for C667# EVM.
  5. View the memory browser (go to View -> Memory Browser). Browse to address 0x0C000000.
    NoteNote: For BIOS-MCSDK 2.0.8 and prior, please use address 0x80000000 instead of 0x0C000000.
  6. Right click on the memory window and select Load Memory. Select app.bin (By default, the browse menu only displays .dat files. You will have to change the option TI Data Format (*.dat) to Raw Data Format (*.bin) to find your binary file.)
    NoteNote: If you are loading a .dat file, check the box for the option to "Use the file header information to set the start address and size of the memory block to be loaded." This option will not be available for .bin files.
  7. Click "Next".
  8. Change the Start Address to 0x0C000000 if it is not already. Leave the swap checkbox unchecked. Click "Finish". Please select 32-bits for Type-Size option in CCS.
    NoteNote: For BIOS-MCSDK 2.0.8 and prior, please use address 0x80000000 instead of 0x0C000000.
  9. Run the program. This will program the EEPROM.
    A sample successful eeprom writer output would like as below.
    [C66xx_0] EEPROM Writer Utility Version 01.00.00.05[C66xx_0] [C66xx_0] Writing 52264 bytes from DSP memory address 0x0c000000 to EEPROM bus address 0x0051 starting from device address 0x0000 ... [C66xx_0] Reading 52264 bytes from EEPROM bus address 0x0051 to DSP memory address 0x0c010000 starting from device address 0x0000 ... [C66xx_0] Verifying data read ... [C66xx_0] EEPROM programming completed successfully
    
  1. IBL Configuration needs to be programmed after successfully completing step 9. Go to Run -> Load Program and select i2cparam_0x51_c667#_le_0x500.out located in the mcsdk_2_00_xx_xx\tools\boot_loader\ibl\src\make\bin folder).
  2. Load the i2cConfig.gel GEL file, located in the mcsdk_2_00_xx_xx\tools\boot_loader\ibl\src\make\bin folder.
  3. Run the program. The following message will be printed on the CCS console
    Run the GEL for the device to be configured, press return to program the I2C.
    

NoteNote: DO NOT PRESS ENTER UNTIL STEP 14.

  1. Run the GEL script"EVM c6678 IBL" -> setConfig_c6678_main.
  2. Now press "Enter" in the CCS console window, and the program will write the boot parameter table to the EEPROM. On success the message "I2c table write complete" will be printed on the CCS console.

POST

  1. Copy post_i2crom.bin from mcsdk_2_00_xx_xx\tools\post\evmc667#l\bin to mcsdk_2_00_xx_xx\tools\writer\eeprom\evmc667#l\bin.
  2. Open eepromwriter_input.txt in mcsdk_2_00_xx_xx\tools\writer\eeprom\evmc667#l\bin. Set file_name equal to post_i2crom.bin and bus_addr equal to 0x50. Make sure start_addr and swap_data are set to 0. Save and close eepromwriter_input.txt.
  3. Turn on and connect your EVM. Open CCSv5, load the appropriate Target Configuration, connect to Core 0, and load the corresponding GEL file.
  4. Load the EEPROM writer program by going to Run -> Load Program and browse for the eeprom writer DSP executable. For e.g, eepromwriter_evm667#l.out in the same folder as post_i2crom.bin for C667# EVM.
  5. View the memory browser (go to View -> Memory Browser). Browse to address 0x80000000.
  6. Right click on the memory window and select Load Memory. Select post_i2crom.bin (By default, the browse menu only displays .dat files. You will have to change the option TI Data Format (*.dat) to Raw Data Format (*.bin) to find your binary file.) NoteNote: If you are loading a .dat file, check the box for the option to "Use the file header information to set the start address and size of the memory block to be loaded." This option will not be available for .bin files.
  7. Click "Next".
  8. Change the Start Address to 0x80000000 if it is not already. Leave the swap checkbox unchecked. Click "Finish".
  9. Run the program. This will program the EEPROM.
    A sample successful eeprom writer output would like as below.
[C66xx_0] EEPROM Writer Utility Version 01.00.00.04
[C66xx_0]
[C66xx_0] Writing 49752 bytes from DSP memory address 0x80000000 to EEPROM bus address 0x0051 starting from device address 0x0000 ...
[C66xx_0] Reading 49752 bytes from EEPROM bus address 0x0051 to DSP memory address 0x80010000 starting from device address 0x0000 ...
[C66xx_0] Verifying data read ...
[C66xx_0] EEPROM programming completed successfully

Updating NOR/NAND Images

The NOR/NAND writers support reading a binary image directly. Please rename the DSP executable xxx.out to app.bin and use the writers to directly write a binary image file to the NAND or NOR. Please refer to writer\nand\docs\README.txt or writer\nor\docs\README.txt for details.


Helpful tips image.jpg

Useful Tip

If booting from NOR Flash on a 6670 EVM is failing the DDR3 test with Bios MCSDK 2.0.2 or earlier, an update to the Intermediate Bootloader is available which will fix it. If you have a more recent version of the BIOS MCSDK, this fix is included in your installation. See the instructions for applying the update here. Once you have updated the files, come back to this page and follow the instructions for updating the IBL EEPROM image

Q: How do I use JTAG with CCS?

Did you know that CCS will execute all code up to the cinit when loading an out file through the JTAG? This is an option that is enabled, by default, in the Target Configuration file. Initialization code may sometimes execute before this. For example if you hook a function into the SYS/BIOS startup function list it will execute before cinit. If you need to debug that code or it is causing your load to hang (i.e. you do not get the run button highlighted) change the default setting.

Solving the Verify_Init: warnings when executing Demos/NDK Examples from CCS

If you get Verify_Init: warnings while executing the Demos/NDK examples (the sample warning output is shown below)

[C66xx_0] Verify_Init: Expected 16 entry count for gTxFreeQHnd queue 736, found 62 entries
[C66xx_0] Verify_Init: Expected 0 entry count for gRxQHnd= 704, found 22 entries
[C66xx_0] Verify_Init: Expected 0 entry count for Queue number = 0, found 1 entries
[C66xx_0] Verify_Init: Expected 0 entry count for Queue number = 704, found 22 entries
[C66xx_0] Verify_Init: Expected 0 entry count for Queue number = 4095, found 1 entries
[C66xx_0] Verify_Init: Expected 0 entry count for Queue number = 8192, found 1 entries
[C66xx_0] Warning:Queue handler Verification failed

Please make sure the following when an application is run from CCS environment.

  1. SW3, SW4, SW5 and SW5 switches are all set to (ON, ON, ON, ON) mode, the only exception is the SW3[1] switch which is intended to control the endian mode of the EVM. This selects EMIF16 or Emulation Boot mode and bypasses the iBL interfearing with the CCS executable loaded via CCS.
  2. Do a system reset between multiple load and executes of the demo/ndk examples programs
  3. Please make sure the corresponding GEL file is executed before the program gets loaded and executed from CCS.


Q: Is there a simple way to access documents provided in the release?

Once BIOS-MCSDK is installed in the system, many of the documents can be accessed from CCS->Help->Help Contents.

Ccs-help.png


Q: How do I uninstall the BIOS-MCSDK?

The BIOS MCSDK installer installs the un-installer in mcsdk_##_##_##_## directory. The name of the un-installer is uninstall-bios_mcsdk_2.##.##.##.exe. It also adds links of the un-installer in Programs->Texas Instruments->BIOS Multicore SDK program menu and in Windows Add and Remove Programs menu with name TI BIOS Multicore SDK. Selecting any one of the links will start the un-installer and remove the BIOS-MCSDK components from the system.

NoteNote: Some packages are installed as separate packages (e.g., EDMA3 LLD, DSPLIB, IMGLIB, MATHLIB, SYS/BIOS, IPC) in the system. Due to this, some of the component package installers are not removed after the MCSDK installer is complete; also, to uninstall these packages, please run the corresponding uninstaller.

NoteNote: The un-installer for MCSA will be under CCSv5 installation directory with name uninstall_dvt.exe.

Q: Are there example code for various device peripherals?

GPIO

  1. The GPIO documentation for KeyStone devices is available from the link General-Purpose Input/Output (GPIO) forKeyStone Devices User's Guide
  2. The GPIO implementation is provided in file pdk_C66##_1_0_0_##\packages\ti\platform\evmc66##l\platform_lib\src\evmc66x_gpio.c
  3. The FPGA implementation is provided in file pdk_C66##_1_0_0_##\packages\ti\platform\evmc66##l\platform_lib\src\evmc66x_fpga.c
  4. In particular the LED operations are in function fpgaControlUserLEDs() of file pdk_C66##_1_0_0_##\packages\ti\platform\evmc66##l\platform_lib\src\evmc66x_fpga.c

Timer

  1. The link SYSBIOS_Training:Timers and Clocks provides detail presentation on configuring timer to get peoridic interrupt
  2. An older document on SYSBIOS timer implementation is in DSP/BIOS Timers and Benchmarking Tips

DDR3

  1. The DDR3 controller users guide is in DDR3 Memory Controller for KeyStone Devices User's Guide
  2. The DDR3 initialization can be found in the GEL file of the evm
  3. The C implementation is in pdk_C66##_1_0_0_##\packages\ti\platform\evmc66##l\platform_lib\src\platform.c, function platform_init(); Look for if (p_flags->ddr) section in the function for the sample code

UART

  1. The UART users guide is in Universal Asynchronous Receiver/Transmitter (UART) for KeyStone Devices UG
  2. The sample code is in pdk_C66##_1_0_0_##\packages\ti\platform\evmc66##l\platform_lib\src\evmc66x_uart.c

Q: How do I speed up downloading the BIOS-MCSDK installer?

The size of the BIOS-MCSDK installer is large since we want to provide one bundle for all the components. The bad side of this is that if you are manually downloading the BIOS-MCSDK (or CCS) installer, you may run into issues such as download stall or slow download. One simple solution is to run a download manager/accelerator. One open source solution is http://www.freedownloadmanager.org/.

Q: Can I use CCS 5.1 with BIOS MCSDK 2.0?

Starting with BIOS-MCSDK 2.0.5, we support both CCS 5.0.3 and CCS 5.1.0. We are planning on maintaining CCS 5.0.3 support through all the BIOS-MCSDK 2.0.x releases; it will be dropped in the next major release, v2.1. However, the recommended version of CCS is v5.1.0 to benefit from the latest updates of features and bug fixes.

Two notes:

  1. Starting from CCS 5.1.0, the MCSA component, which is installed in the CCS directory, is bundled with CCS and installing the version from the BIOS-MCSDK installer into CCS 5.1.0 results in the BIOS-MCSDK installer to crash. The BIOS-MCSDK 2.0.5 installer has MCSA unselected, but previous versions need to be manually unchecked.
  2. CCS 5.1 may include a different version of CGT than the version validated with BIOS MCSDK. See the respective release notes to find the actual versions. If there is a mismatch, it is recommended that you use the version that BIOS MCSDK lists as a dependency, and ensure that CCS projects are configured for the appropriate version when building projects.

Q: How can I connect and use two emulators of the same type in the same CCS instance?

For the development of some applications involving board to board communications such as SRIO or Hyperlink it may be desirable to simultaneously connect to two boards while running a single instance of Code Composer Studio. The following steps document how to create and use a Target Configuration that allows connect, program load, and debug capabilities on two boards simultaneously. To document these steps the following hardware and software was used.

  • 2x c6678 boards with attached Blackhawk XDS560v2-USB Mezzanine Emulator
  • Code Composer Studio v5.0.3.00028

Steps to connect to two boards with the same target configuration:

1. Make sure the boards and emulators are powered up and ready to be launched for a debug session. The device manager should show two Blackhawk XDS560v2-USB Mezzanine Emulators under the BlackHawk tab.

Figure 1: Emulators Displayed in Device Manager

2. Start CCS and open the Target Configurations tab, View -> Target Configurations.

3. Right-click within the Target Configurations tab and select "New Target Configuration". Give the target configuration a name and click "Finish".

4. In this, and the following step, we'll set up the configuration for the first target. The second target will be added later. In the "Connection" drop down menu select 'Blackhawk XDS560v2-USB Mezzanine Emulator' or the emulator type you're using.

Figure 2: First Target Configuration

5. In the Device selection window check the TMS320C6678 box, or the box of the processor you're using, and click "Save".

6. In the following steps we'll add the second board to the target configuration. Click the "Advanced" tab at the bottom of the "board_name".ccxml file display.

7. Highlight the first Blackhawk connection and Click "New...".

Figure 3: Create New Connection

8. Select "Blackhawk XDS560v2-USB Mezzanine Emulator", or the second emulator type you're using, and click "Finish".

9. Right Click the new Blackhawk connection and select "Add...".

Figure 4: Add New Processor to Connection

10. In the Device selection tab highlight the TMS320C6678, or the processor you're using, and click "Finish". You're target configuration should now have two Blackhawk emulators each with a c6678 device.

Figure 5: Target Configuration With Two Boards

11. Once again, highlight the second Blackhawk Emulator so that the "Connection Properties" show.

Figure 6: Second Connection's Properties

12. Under the Emulator I/O Port Number drop down menu change the setting to "I/O Port = 1" and then click "Save".

Figure 7: Change Connection Port

13. Start the new target configuration by right-clicking the target configuration in the "Target Configuration" tab and selecting "Launch Selected Configuration". When the launch completes you'll see sixteen cores, for two c6678 boards, in the Debug tab.

Figure 8: Sixteen Cores

14. Connect to the desired cores.

Figure 9: Connected to Cores

Q: How do I get the latest GEL files for these EVMs?

The GEL files for supported EVMs are provided separately from the MCSDK. If you use CCS 5.1, use the Eclipse Update Manager to check for new updates and follow installation instructions if there is an update. If you use CCS 5.0, or have any problems with using the Eclipse Update Manager in CCS 5.1, you can manually download the GEL updates. See the MCSDK download page listed above for details.

Q: How do I change SoC speed on my EVM?

The SoC speed for the EVM can be changed by setting appropriate PLL multiplier and Divider values. Please refer to the device data sheet for details on setting the Multiplier and Divider values. The Gel file from the emupack also has sample multiplier and divider values for a given SoC speed.

Please refer to section 2.5.3 section of the TMS320C6678 data sheet for the sample multiplier and divider values.

Please refer to section 2.4.3 section of the TMS320C6670 data sheet for the sample multiplier and divider values.

This can be changed in

  • platform library (If platform library is used to program the PLL settings)
    • please update multiplier and divider values in platform_init() function, located under pdk_C667#_1_0_0_##\packages\ti\platform\evmc667#l\platform_lib\src\platform.c file. Please rebuild platform library after this change.
  • GEL file (If GEL files are used to program the PLL)
    • please update PLL1_M and PLL1_D values in evmc667#l.gel file, located under \ccsv5\ccs_base\emulation\boards\evmc667#l\gel file. Please reload the gel file after this change.
  • IBL (If IBL is used for PLL settings, e.g., for i2c boot modes)
    • please update the ibl.pllConfig[ibl_MAIN_PLL].prediv variable for the divider and ibl.pllConfig[ibl_MAIN_PLL].mult variable for multiplier values in c667#_ibl_config() function located under mcsdk_2_00_##_##\tools\boot_loader\ibl\src\util\iblconfig\src\device.c file. Please rebuild ibl after this change.

E2e.jpg
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article BIOS MCSDK 2.0 User Guide here.

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity