DM37x Software Design Guide
The purpose of this software design guide is to walk developers through the various stages of designing software for this set of devices. The guide follows the structure shown in the Software Design Timeline below. Each design stage in the Timeline links to a collection of useful documentation, application notes, and design recommendations pertaining to that stage. Using this Guide, software designers can efficiently locate a resource (or collection of resources) they need at each stage in the software development process.
Note: This guide is not as a replacement for information specified in the data manual nor is it designed as a replacement for information on TI.com, rather is should be used as a companion guide to point to existing information. If there are ever any discrepancies, the data-sheet and reference manuals should be considered the official source.
Software Design Timeline →
Determine Top Level Software Hierarchy
General Purpose Operating System (OS)
General Purpose Operating Systems (GPOS) are typically chosen to run on General Purpopse Processors (GPPs) such as ARM cores. These processors and corresponding operating systems are suitable for many varied tasks, hence the 'general purpose' descriptiors. Popular GPOSs include Android, Linux, and WinCE though there are many more including some specifically suitable for certain industries.
The following matrix lists General Purpose Operating Systems are available for Sitara, C6-Integra and DaVinci Devices
Real Time Operating System (RTOS)
Real Time Operating Systems are often common in processors with a particular specialty. Numerous RTOS are supported on the Sitara, C6-Integra and DaVinci devices including, but not limited to:
These RTOS solutions can be used in a host a embedded applications and can be obtained directly from the vendors. Many times, a free trial BSP is available for download.
The following matrix lists additional Real Time Operating Systems are available for Sitara Devices
No Operating System
Software development on a device without the use of any operating system is typically done when a very minimal code footprint is needed, or an operating system may add unnecessary complexity that is not needed. Development with no operating systems are typically discouraged as processors become more powerful and typically involve more lines of code because it requires an application to rely solely on interrupts for scheduling. While this approach does work, it quickly becomes a heavy burden on the developer to appropriate structure code to manage all events, when the code will need to manage for future undefined programs.
As the application scales to meet additional demands of your customers, additional demands of not using an operating system may sideline you into differentiating your products from those your competitors provide.
Software Hierarchy Providing specific for DM37x
TI provide the following software development packages specific for DM37x
RTOS Support for DM37x
- DSP/BIOS Platform Support Package for DM37x is an advanced, real-time operating system for use in a wide range of DSPs, ARMs, and microcontrollers. It is designed for use in embedded applications that need real-time scheduling, synchronization, and instrumentation. It provides preemptive multitasking, hardware abstraction, and memory management.
GPOS Support for DM37x
- Android Software Development Kit for DM37x
- Linux Software Development Kit for DM37x
- WindowsCE Software Development Kit for DM37x
Non-OS Examples for DM37x
- None available
Download, Purchase, or Install Appropriate IDE & Tool Chain(s)
Once you have decided on the appropriate software hierarchy that is appropriate for your design, the next step is to pick to tool chain that will quickly assist you in developing your end applications. Integrated Development Environments (IDEs) provide a software developer a base set of software which allows a programmer to get started writing and testing code. IDEs typically include a Text Editor, The software tool chain, and a debugging environment all in a single application that typically runs from a host PC.
A tool chain typically consists of at least one C compiler, an Assembler, and a Linker. The tool chain is CPU architecture dependent, so the right tool chain is dependent on the CPU of choice as well as any additional constraints imposed by the host operating system.
Sitara, C6-Integra and DaVinci Devices offer wealth of various tools chains and IDEs due to the integration of both the ARM CPU core and the DSP core, both of which have a different instruction set architecture (ISA)
Integrated Development Environments supported by TI
- Code Composer Studio (CCS) Integrated Development Environment (IDE)
- Inclusive of TMS320 Optimizing C6000 Optimizing Compiler, C6000 Assembler, & C6000 Linker
- Inclusive of TMS470 Optimizing ARM Optimizing Compiler, ARM Assembler, & ARM Linker
- Inclusive of Cycle Accurate Simulators for both the ARM and C674x DSP Cores
- Integrated support for DSP/BIOS Real Time Operating System
- Integrated support XDS Series Emulators/Debuggers
- Additional Introductory Information on the Code Composer can be referenced in the following wiki articles
Stand Alone Tool Chains supported by TI outside of CCS
- C674x DSP CPU Tool Chain
- TMS320 Optimizing C6000 C/C++ Compiler
- TMS320 Optimizing C6000 Assembler
- TMS320 Optimizing C6000 Linker
- ARM9, Cortex-A8 CPU Tool Chain
- TMS470 Optimizing ARM C/C++ Compiler
- TMS470 Optimizing Assembler
- TMS470 Optimizing Linker
Additional 3rd Party Tool Chains available (not supported by TI)
Download, Purchase, or Install Additional Packages / Dependencies
TI offers wealth of additional Application Programming Interfaces (APIs) and tools which serve to abstract programming each register at the bit level as well as to provide a well defined method to program the our devices. There are various software packages available for download which can help you jump start your software development based upon your preferences.
For a list of all TI Provided API's specific to the DM37x please visit the DM37x Software and Tools on TI.com
Procure Hardware Development Platforms & Emulation Tools
Hardware Development Platforms are designed, developed, and tested by 3rd Party Design Houses in order to provide the software architect team with the ability to develop their code in parallel with the hardware design of the Printed Circuit Board (PCB). Hardware Development platforms are preferable vs simulators because they actually reflect how the device will behave in the end product and take into account system latencies for cache misses and off chip memory accesses.
IDE tools normally provide options for developing directly on a hardware platform or indirectly in a software simulator if a hardware platform is not available. When developing directly on a hardware platform, the IDE must have some way of connecting and communicating with the hardware; this communication path is often provided via
- ARM and DSP based JTAG emulators: Often the only option for debugging boot code before any kernel level code is available
- USB, UART, Ethernet: this options are often available for debugging GPP procesors such as ARM and are often the least expensive route and adopted by many developers particularly in the application space, but also used to develop and debug kernel space.
Below are some examples of JTAG emulators compatible with TI devices.
TI XDS Hardware Emulators
XDS100 Class Emulators (Version 1, Version 2)
XDS510 Class Emulators
XDS560 Class Emulators
Adaptive Clocking JTAG Emulator Adaptors
3rd Party Emulator Drivers Updates
For additional updates and drivers please consult the Official Support Pages from 3rd Party Emulator Providers
For additional information on Emulation refer to Emulators/Analyzers Page on TI.com and additional wiki articles about TI JTAG Emulators & JTAG Schematics The following hardware development kits are recommended by TI for the DM37x
Software Development Platforms for DM37x
Since code development is application specific, and a variety of code development tools can be used to program the Sitara, C6-Integra and DaVinci devices, this section will focus on providing generic C reference code for exercising or interfacing to certain peripherals and functionality. In addition, there are more examples for reference available inside the corresponding product SDK.
DM37x Specific Code Development Guides
Debugging your code is an integral part of code development and a skill that takes time to develop. The goal of this section is not to make you an expert software debugger, but rather to help you understand steps that you can perform on your application code to determine the root cause of your issue. This can be especially helpful if you are using package dependencies (such a drivers) that were not developed by you.
This section is organized as a crash course into a collection of basic philosophies about debugging your applications on TI devices.
This page is dedicated to helping the software development team find the "root case" of the broken system code and provide explicit and useful feedback for others who can assist you in solving your integration challenges.
Typical Software Systems
Often the software development is split into various software components; code is developed for each individual software component (CPU Interrupt Service Routines, DMA Transfers, 3rd Party I/O peripheral drivers) by various team members and then collectively integrated into the final application.
Why is this important?
TI provides a well integrated and tested SDK; however, often there is a need for developers who are too far in the development process to upgrade one software component while keeping all the rest. In addition, there is also the need for developers to pull in software components developed by 3rd parties or open source software. All these scenerious open the door for software imcompatibilities.
So now what....?
For this reason it is very important to read the software release notes for all corresponding software components when mixing and matching components; these documents often cite dependencies on particular versions of other software components as well as too-chains and being aware of this information will allow developers to make better decisions about tradeoffs and chosing the right components before spending much development time only to find out they went down the wrong path.
Debugging code is commonly done by eliminating variables (one at a time if necessary) to assist you in determining where the error occurs.
Check the Basics
This seems silly, but taking a step back from the specific problem you are facing can be very beneficial.
Verify device clocking trees are configured correctly Sitara, C6-Integra, and DaVinci devices are not just the run-of-the-mill clocking structure of a simplistic 8 bit microcontroller. The hardware domains inside of these devices do not run off a single clocking frequency, but rather a tree of related clocking domains that are derived from a main system clock inputs. Additionally, some peripherals (USB, EMAC, McASP, RTC) often involve being clocked from the main system clock, as well as a second clock source from an external crystal.
Incorrect configuration of the device clock tree could result in missed servicing of peripherals (even though the peripheral may be configured correctly otherwise).
For an overview of your device specific clocking structure, refer to the corresponding Device Specific Technical Reference Manual
Verify Power Domains are Active Sitara, C6-Integra, and DaVinci devices consist of multi-core, multi-frequency hardware blocks (CPUs, DMAs, Peripherals), its important to note these blocks can be individually powered down to conserve additional power & reduce heat. The ROM code of these devices typically enables as few blocks as necessary to boot the device. As a result, it is up to the application developer to power on any additional hardware blocks in order to run their application.
For an overview of your device specific power structure, refer to your Sitara, C6-Integra, and DaVinci device Specific Technical Reference Manual
Is this issue always reproducible? If the issue is not always reproducible under the same conditions, this typically means it's a timing issue due to asynchronous timing between events. Unfortunately, this also means that the issue is typically harder to debug.
Testing the same code on a second hardware platform (if available) is also a quick sanity check to make sure your software issue is not board dependent.
Narrow the Scope of the Problem
Once you have determined that you device is operating and you have confirmed the basics are covered, the next step is to narrow down to scope of the problem to eliminate as many variables as possible.
Narrowing the scope of the problem is typically done by removing as many variables from your software application while still being able to reproduce the problem.
NOTE: Removing code segments is most easily done by using (#ifdef / #endif) around your existing code. The idea behind removing your code is not to make you do more work by rewriting your source code.
Some examples of this would be to occluding various unnecessary I/O operations, bypassing unnecessary DMA transfers, and/or masking off unnecessary interrupt service routines in the CPUs.
Once the unnecessary operation of software is eliminated, it becomes much easier to see where the problem is occuring.
Divide and Conquer
Once the scope of the probem has been narrowed, its important to identify all the various hardware blocks that remain.
Once you identify the remaining variables in your program, you can systematically disect the operation of each of the hardware blocks to verify correct operation.
If you have an CPU with multiple interrupts, you can individual mask all but one interrupt at a time to determine if that particular ISR is properly being executed as expected. This process can be repeated through the other remaining interrupt services routines until you find the interrupt service routine that does not perform as expected.
If you have a DMA that is not making the necessary transfers, you can break the overall transfer down into various sets.
- Step 1: Is event that starts the DMA transfer being reached by the DMA Engine
- Step 2: Is the DMA Transfer source / destination addresses being properly configured
- Step 3: Is the source destination RAM accessible by the DMA controller? Some Memory Mapped Registers are only addressable by certain device masters. It's important to check to make sure that the Memory Mapped Registers you write to are accessible by the DMA controller.
If you have a I/O Peripheral that is not transmitting/receiving in a consistent manner, there are several steps you can make
- Step 1: Are the clocks to the peripheral correctly set up
- Step 2: Are the buffers properly being serviced in time. Some peripherals (such as McASP) have a limited time window in which you need to service the buffers before a transmit overrun, or underrun condition will cause the state machines to generate an error. You can then use this information to back track and determine why the buffers are not being serviced in time by the CPU or DMAs
Obtaining Additional Assitance with your Investigation
Using the Divide and Conquer approach above you will typically be able to determine what the cause of the errant behavior is provide corrective action within your code, however if you are using a driver or code package that was developed by a 3rd Party, you may need to seek assistance from the developer.
It is important to remember that just because the problem is resolved in your particular software application, it may not be able to be reproduced on a different software and/or hardware application. Because of this, it is very critical for you to provide evidence that you have tracked down the culprit to their specific code.
Sending simple oscilloscope captures is the most useful way to see how your system is specifically behaving is some of the best insight you can produce. Oscilloscope captures can be as simple as triggering on a GPIO toggle when a particular event -or- error occurs.
Oscilloscope captures allow multiple parties to concurrently debug the problem while
- Guaranteeing Inherent Protection of your code (no risk in allowing others to see the source code)
- Showing the specific timing relationship between an event (or sequence of events)
- Showing how specific events are mitigated or exacerbated with code tweaks.
In addition to sending conclusive evidence, it's also important to remember that the more information you can provide upfront about your specific application, the more likely you will get fast help from the developer.
Remember, someone who has written the code is an expert at the code, and has likely come across (and successfully debugged)many of the issues you are currently seeing. The more information you can provide, them the faster they will be able to provide useful feedback to help you solve your integration challenges.
When providing evidence of a issue one should provide at the bare minimum the following information:
- Hardware Platform
- Silicon Part Number (including Package, Version, & Additional Package Markings)
- Are you working with a TI Hardware Development Platform -or- is this a custom board?
- Software Version
- Full Names & Versions of all software packages that were used to create the software application.
- Full Names of IDEs, Tools Chains, & Debugging Equipment (JTAG Emulators)
- Oscilloscope screen captures of the timing before, during, and after the error occurs.
- Additional Observations that may lead to insight into the issue.
List any debug tools available such as register dump tools...
Once the software is developed and debugged, the final step in the software development process is to take the code you've developed and port it to the actual hardware that will be integrated into your project.
IMPORTANT: If your software development made use of functions executed by a GEL file, this functionality must be incorporated into the software application itself before you can generated a bootable image. Since GEL files rely on an emulator for execution, this functionality must be replaced by the application code in your end product.
Understanding how the DM37x Boot Sequence Works
An brief overview of the boot sequence for the DM37x can be found in the following DM37x Boot Sequence
Generating the Boot Image
The PSP user guide provides a good overview of the steps needed to rebuild the software, including the boot Image
Programming the Image into non-volatile memory
Once a bootable image has been created, we need to flash your image into non-volatile memory that run on top of your Host PC.
Flashing using u-boot
- one method to flash your code is to use the features in u-boot; please see [AM35x-OMAP35x-PSP_04.02.00.07_UserGuide#Flashing_from_u-boot How to flash from u-boot]
Serial Flashing Utility
Optionally, instead of using u-boot to flash, the Serial Flashing Utility can be used to flash parallel DM37x devices using a standard UART serial cable connected to a host PC running Windows or Linux.
- Fast Flashing Time
- No Connection is required to CCS or to JTAG via an Emulator
- The Serial Flash Utility only supports flashing EVMs without code modifications for user specific boards.
- The build environment needs to be downloaded to there user PC.
Flashing via JTAG using CCS
Various CCS Projects have been developed to flash non-volatile memory via the JTAG connection using Code Composer Studio. These projects can be found in the Software Development Kit for NAND, NOR, or SPI Flash.
- Source Code is easy to modify
- No additional build environment tools to install
- Slow flashing times
- Requires a JTAG connection
Serial Port Boot Utility
When debugging, it is often useful to boot over the serial port rather than reflashing the image each time a modification is made. The Serial Flashing Utility enables this.