TI-RTOS Kernel (SYS/BIOS) User's Guide: Device Addendum

Table of Contents

General Introduction

This document will highlight device specific items in TI-RTOS. Please note that “TI-RTOS” and “SYS/BIOS” are interchangeable terms for the sake of this document.

ARM CortexM Introduction

TI-RTOS runs on several different Texas Instrument devices that have an ARM CortexM core.

This section will highlight some of the device specific items when running TI-RTOS on a CortexM device.

CortexM Hardware Interrupt (Hwi) Handling

The CortexM CPU natively supports efficient interrupt handlers written in C. In order to support the 3-tiered threading model provided by the SYS/BIOS Kernel (Hwis, Swis, and Tasks), the native interrupt support provided by the CortexM core must be augmented with a few housekeeping functions that enforce the expected thread execution behavior.

To consolidate the overhead of these housekeeping functions and provide a standardized set of instrumentation features, the SYS/BIOS Kernel uses a centralized interrupt dispatcher that invokes the application’s custom ISR (Hwi) functions.

The interrupt dispatcher provides the following functionality:

By default, all SYS/BIOS Kernel managed interrupts are routed to the interrupt dispatcher, which subsequently invokes the user’s interrupt handler.

The low-level Hwi module used on the CortexM devices is the ti.sysbios.family.arm.m3.Hwi module. For more details, please read the CDOC pages.

Hwi MaskingOptions and Priorities

Supported MaskingOptions

The CortexM’s Nested Vectored Interrupt Controller (NVIC) natively supports configurable interrupt priorities.

The SYS/BIOS Kernel interrupt dispatcher used in CortexM devices is designed to support the native interrupt nesting functionality of the NVIC. Consequently, only the Hwi.MaskingOption_LOWER enumeration is honored for an individual Hwi’s params.maskingOption setting. No support is provided for the following Hwi masking options:

Supported Priority Values

While the CortexM can support up to 256 priority settings, the amount of internal chip real-estate required to support this number of priorities is exceedingly large. Since most embedded system applications can be fully supported with much fewer interrupt priorities, only 8 priority levels are supported on the TI CortexM devices (except the Ducati and Benelli cores which support 16).

The 3 bits of priority required to define the 8 priority values occupy bits [7:5] of the 8-bit priority value rather than bits [2:0] as one might expect. Consequently, the values of the 8 supported priorities are not 0x00 through 0x07 but 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, and 0xe0, where 0x00 is the highest priority and 0xe0 the lowest priority.

Additionally, the NVIC design defines interrupt priority groups within a given priority setting. The Hwi.priGroup module configuration parameter allows you to specify which of the 3 significant bits of the priority setting are group bits and which are priority bits. For a full discussion of NVIC’s priority and priority-group behavior, see the “NVIC register descriptions” section of the ARM Cortex-M3 documentation.

No validity checking is performed on the Hwi_params.priority setting. You should make sure the configured interrupt priorities will be effective for your application.

Zero Latency Interrupt Support

The Hwi module used by CortexM devices supports Zero Latency (unmanaged ) Interrupts. When configured, a Zero Latency Interrupt is never disabled internally by SYS/BIOS Kernel functions, not even during critical thread execution (thus the name Zero Latency). Thus, a zero latency interrupt handler should never call any BIOS APIs. See Configuring a Zero Latency Interrupt for an example of configuring a zero latency interrupt.

CortexM Operating Modes and Stack Usage

Operating Modes

Internally, the CortexM supports two operating modes: Thread mode and Handler mode. Within Thread mode, the CortexM code can run in either Privileged or User mode. By definition, Handler mode code always runs in Privileged mode.

Within the SYS/BIOS Kernel:

Stacks

The CortexM internally supports two stacks: the Main stack and the Process stack.

After reset and throughout the entire boot up sequence prior to the BIOS_start() invocation in main(), the CortexM core runs in Thread mode using the Main stack.

The Main stack always refers to the stack buffer that is defined and managed by the Codegen Tools. This is the buffer that is placed in the .stack section with its size configured using the -stack XXX linker command option.

If Tasks are supported by the application (because BIOS.taskEnabled = true), then within the Task_startup() function, which is called by BIOS_start(), the CortexM processor is configured to use the Process stack while in Thread mode and to automatically switch to the Main stack when an interrupt occurs (that is, when transitioning to Handler mode). When execution is subsequently passed to a Task thread, the Process stack then becomes dedicated to Task threads and the Main stack becomes dedicated to Hwi and Swi threads.

As opposed to Hwi threads, which automatically switch to the Main stack when Handler mode is entered, the Swi scheduler manually switches the processor to and from the Main stack before and after Swi threads are run.

If Tasks are not supported by the application (because BIOS.taskEnabled = false), the split between the Process stack and Main stack is not made. All threads run on the Main stack. Consequently, all configured Idle functions (that is, the application’s background functions) share the same stack as Hwi and Swi threads.

Within the SYS/BIOS Kernel:

CortexM Timer Usage by SYS/BIOS

Kernel Module Overview (all devices)

There are high-level timing modules and low-level timer implementations modules. The following is an overview of these two groups of modules.

High-Level SYS/BIOS Kernel Timing Modules

This section talks generically about SYS/BIOS timing services. Other sections will go into specific details about which timers are used on the various devices.

Kernel Module Description
ti.sysbios.knl.Clock The Clock module is responsible for timed services in the TI-RTOS kernel. It generates the periodic system tick. The application can plug in functions that will be called once or periodically by the Clock module.
ti.sysbios.hal.Timer This module presents a standard interface for using all timer peripherals.
ti.sysbios.hal.Seconds This module generates a custom time() function in the configuration-generated .c file.
xdc.runtime.Timestamp This module provides timestamping services.
POSIX The POSIX interface offers several timing services (clock, timer, sleep). These reside on top of the TI-RTOS timing services.

Please refer to Changing the Timer used by the Timing Modules

Low-Level TI-RTOS Kernel Peripheral Timer Implementations

Kernel Module Description
ti.sysbios.family.arm.m3.Timer SysTick
ti.sysbios.family.arm.lm3.Timer General Purpose (GP) timers
ti.sysbios.family.arm.lm4.Timer General Purpose (GP) timers
ti.sysbios.family.arm.msp432.Timer TimerA (same as MSP430)
ti.sysbios.family.arm.cc26xx.Timer RTC timer
ti.sysbios.family.arm.cc32xx.Timer RTC timer

Note: there are Real Time Clock (RTC) peripherals for the MSP432E4 and MSP432P4 devices. The kernel’s Seconds module for these devices uses the RTC timer directly.

Kernel Module Details (all devices)

The following goes into more detail about the kernel’s timing services. For more complete details, please refer to the TI-RTOS Kernel API Reference.

Clock Module

The TI-RTOS kernel, by default, uses one timer peripheral to drive system timings (e.g. Task_sleep(), Semaphore_pend() with a timeout, etc.). The timer is managed by the Clock module (full-name is ti.sysbios.knl.Clock). The Clock module allows the multiplexing of that single timer for application usage. With the Clock Module, applications can create one-shot and/or periodic functions that will be called by the kernel.

The basic unit of the Clock module is the tick. For most devices, the default duration of a tick is 1ms. This value is controlled by the Clock.tickPeriod variable in the TI-RTOS kernel configuration file.

The CC13xx/CC26xx devices the Clock period is generally set to 10us. More on this in the device section below.

All timed kernel actions take place on a tick. For example, when a task sleeps for three ticks (Task_sleep(3)), it will be made ready on the third tick after calling Task_sleep().

Let’s look at an example where the application has created two Clock functions: myClockA and myClockB. myClockA is a one-shot function that will execute once in 100 ticks. myClockB is a periodic function that will first execute in 5000 ticks and then every 100 ticks after that.

CortexM_Clock_ROV

The above ROV picture was taken when running this code and halting at BIOS_start().

#include <ti/sysbios/knl/Clock.h>
#include <xdc/runtime/Error.h>
Void myClockA(UArg arg1)
{
    // my one-shot timer. arg1 will be 'A'
    // do processing...
    return;
}

Void myClockB(UArg arg1)
{
    // my periodic timer. arg1 will be 'B'
    // do processing...
    return;
}

int main(void)
{
    Clock_Params clockParams;

    Clock_Params_init(&clockParams);
    clockParams.period = 0;        // 0 is the default, but added for completeness
    clockParams.startFlag = TRUE;
    clockParams.arg = 'A';
    Clock_create(myClockA, 100, &clockParams, Error_IGNORE);

    clockParams.period = 100;
    clockParams.startFlag = TRUE;
    clockParams.arg = 'B';
    Clock_create(myClockB, 5000, &clockParams, Error_IGNORE);

Low power is a key area for all the SimpleLink devices (excluding the MSP432E4). The Clock module for the CC13xx, CC26xx, and MSP432P4 devices uses a timer that supports “dynamic” mode. Dynamic mode is also called “tickless” mode. When in dynamic mode, the timer interrupt only fires when there is an expected action (e.g. a Task_sleep() should expire) instead of firing at the configured Clock period. Please refer to the docs/tidrivers/Power_Management.pdf file in your SimpleLink SDK for more details.

As shown above, applications can create Clock functions that will be called once or periodically. Doing so allows an application to share the kernel’s timer instead of using a different one. If two functions expire on the same Clock tick, the order of execution will match the creation order. All timing must be a multiple of the Clock tick period (e.g. Clock.tickPeriod * N when N is a natural number). Please note, there is jitter with using Clock functions: the time when a Clock function executes is between N-1 and N Clock ticks. For example, let’s look at the myClockA Clock function mentioned above. Let’s say the Clock_create as called when the current Clock tick was 50. The 50th tick might have just happened or the 51st tick might just be ready to happen. So the actual execution of the myClockA function will be during the 150th Clock tick, but that duration between creation and execution is between 99ms and 100ms. If the time variance is not acceptable for a specific timing requirement, use the Timer module to get a dedicated timer instead of sharing the Clock’s timer.

Additionally, drift can occur when using a timer that does not supply an exact Clock tick period. For example, when the Clock tick is set to 1ms and a 2768Hz timer is used, drift will occur.

The Clock module can be configured to not allocate a timer. The application must then call Clock_tick() to provide the timing for the kernel. Please refer to the Clock module in the API Reference for more details.

So in summary, the Clock module can allow an application to essentially share the timer used by the kernel.

HAL Timer

The Hardware Abstract Layer “HAL” Timer module allows an application to generically use a Timer. The full-name for this module is ti.sysbios.hal.Timer. Underneath, it uses a device-specific “family” Timer (e.g. the ti.sysbios.hal.Timer module for the MSP432E4 device uses the ti.sysbios.family.arm.lm4.Timer module by default). The underlying device-specific Timer module is controlled by the Timer.TimerProxy setting in the .cfg file.

Please note, a device-specific timer can be created instead of using the HAL Timer module. This is generally done when the device-specific Timer module has configuration and/or features not exposed in the HAL Timer module.

HAL Seconds

Much like the Timer module, the Seconds (full-name ti.sysbios.hal.Seconds) module resides on top of device-specific “family” Seconds modules (e.g. the ti.sysbios.hal.Seconds module for the CC32xx device uses ti.sysbios.family.arm.cc32xx.Seconds module by default). The underlying device-specific Seconds module is controlled by the Seconds.SecondsProxy setting in the .cfg file.

Timestamp

The Timestamp (full-name is xdc.runtime.Timestamp) module provides 32-bit and 64-bit timestamps. The Timestamp module uses a device-specific TimestampProvider (e.g. for CC26xx devices xdc.runtime.Timestamp module uses the ti.sysbios.family.arm.cc26xx.TimestampProvider module). That provider may create a new timer to drive the timestamps or use an existing timer depending on it’s configuration. Please refer to the Timestamp module in the API Reference for more details.

Please note that the Timestamp module may be automatically linked into an application when the application uses other modules that require it, for example UIA modules like LoggingSetup.

POSIX

There are various timing support services in the POSIX shim on top of TI-RTOS. This table shows the underlying TI-RTOS module for each of the support POSIX timing services.

POSIX API Underlying TI-RTOS Module
timer_create Clock
sleep/usleep Clock (via Task_sleep)
clock_gettime (CLOCK_MONOTONIC) Clock
clock_gettime (CLOCK_REALTIME) Seconds

Device Details

Now we have the basics of the timing modules and the actual timer implementations, let’s look at each CortexM device specifically to understand how it works.

The below tables show the default timers used for each of the kernel’s timing services (e.g. Clock). Please refer to the documentation on the timing service for details on how to configure the module to use a different timer.

CC13xx/CC26xx

The sub-1GHz and BLE devices are very focused on low power while also having strict timing requirements. The RTC peripheral (ti.sysbios.family.arm.cc26xx.Timer) is designed to meet these requirements.

The Clock module uses the RTC peripheral in a “dynamic” mode with a period of 10us. Please note that the 10us period does not imply that the interrupt rate is 10us. It means that the peripheral should support 10us granularity. TI recommends that customers use the RTC for the Clock module and leave the period at 10us for optimal accuracy for the radio stacks. Please refer to the docs/tidrivers/Power_Management.pdf file in your SimpleLink SDK for more details.

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.cc26xx.Timer RTC timer supports dynamic mode
Timer ti.sysbios.family.arm.m3.Timer SysTick (so only one instance is available). We recommend you use the Clock module for your timing services since the SysTick timer will be reset when going in/out of standby sleeps cycles.
Seconds ti.sysbios.family.arm.cc26xx.Timer Shares the Clock’s RTC timer.
Timestamp ti.sysbios.family.arm.cc26xx.Timer By default the Timestamp module shares the Clock’s RTC timer. This is configurable in the ti.sysbios.family.arm.cc26xx.TimestampProvider module.

The image below shows the Runtime Object View for the demos/port example for the CC1350 LaunchPad. The debug kernel project was used to enable UIA (please refer to the SimpleLink SDK User Guide for more details on how to change kernel projects). The portable example uses the default Clock module settings, Timestamp (via UIA) and creates a POSIX timer to be used by the application. The image shows one timer (and multiple drivers) in the Hwi view and then one timer in the Timers view.

CortexM_CC13xx_ROV

Note: the Clock timer function is ti_sysbios_knl_Clock_doTick__I, but the Hwi stub is ti_sysbios_family_arm_cc26xx_Timer_dynamicStub__E. TI-RTOS plugs the stub function into the vector table. When that interrupt is asserted, the stub function runs and then calls the Clock’s timer function.

CC32xx

Low power is a key area for the CC32xx devices.

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.m3.Timer SysTick
Timer ti.sysbios.family.arm.lm4.Timer Device general purpose timer.
Seconds RTC The Seconds module for the CC32xx devices uses the RTC timer. It does not use the ti.sysbios.family.arm.cc32xx.Timer module. Instead it directly interfaces with the peripheral to minimize code footprint and optimize performance.
Timestamp ti.sysbios.family.arm.m3.Timer By default, the Timestamp module shares the Clock’s SysTick timer. This is configurable in the ti.sysbios.family.arm.m3.TimestampProvider module.

The SysTick timer does not continue to increment in LPDS. The kernel uses the RTC to re-adjust the Clock tick after the device comes out of LPDS. Please refer to the docs/tidrivers/Power_Management.pdf document for more details.

The image below shows the Runtime Object View for the sysbios/StairStep example. The StairStep example uses the default Clock module settings, Timestamp (via UIA) and creates a timer to be used by the application. It shows two timers in the Hwi view and then one timer for the ti.sysbios.family.arm.lm4 view and one ti.sysbios.family.arm.m3 view. More specifically, the timers used are as follows:

CortexM_CC32xx_ROV

Note: the runMode for the Clock’s timer is RunMode_CONTINUOUS. This is because the SysTick does not support “dynamic” mode.

Note: the application’s timer function is timerFunc, but the Hwi stub is ti_sysbios_family_arm_lm4_Timer_isrStub__E. TI-RTOS plugs the stub function into the vector table. When that interrupt is asserted, the stub function runs and then calls the timer function.

MSP432P4

Low power is a key area for the MSP432P4 devices. The SysTick timer does not does not continue to count on low power modes. Therefore a GP Timer (ti.sysbios.family.arm.msp432) is used as the default Clock timer. On the MSP432P401x devices, power constraint are used to prevent going into LPM3 and LPM4 levels because TimerA is frozen in those levels. For the MSP432P4x1x devices, the TimerA continues to run in LPM3. For more details on the MSP432P4 constraints, please refer to the docs/tidrivers/Power_Management.pdf file in your SimpleLink SDK.

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.msp432.Timer This timer is used instead of SysTick since SysTick does not does not continue to count in low power modes. On the MSP432P, the clock timer is driven by a 32768 Hz crystal. The timer period is set to 32 which results in an actual period of .9766ms. This mean that 1000 ticks would actually only be 976ms rather than 1000ms.
Timer ti.sysbios.family.arm.msp432.Timer GP Timer
Seconds RTC The Seconds module for the MSP432P4 device uses the RTC timer. It directly interfaces to the peripheral to minimize code footprint and optimize performance.
Timestamp ti.sysbios.family.arm.m3.Timer The default TimestampProvider is ti.sysbios.family.arm.m3.TimestampProvider. This provider by default will allocate a m3 Timer (SysTick). Note: the SysTick count does not increase during deep sleep states, so the default Timestamps are only valid for active states of the device.

The image below shows the Runtime Object View for the sysbios/StairStep example. The StairStep example uses the default Clock module settings, Timestamp (via UIA) and creates a timer to be used by the application. The image shows three timers in the Hwi view and then two timers for the ti.sysbios.family.arm.msp432 view and one ti.sysbios.family.arm.m3 view. More specifically, the timers used are as follows:

CortexM_MSP432P4_ROV

Note: the runMode for the Clock’s timer is RunMode_DYNAMIC. This is because the Power Module is enabled.

Note: the application’s timer function is timerFunc, but the Hwi stub is ti_sysbios_family_arm_msp432_Timer_isrStub__E. TI-RTOS plugs the stub function into the vector table. When that interrupt is asserted, the stub function runs and then calls the timer function.

MSP432E4 & TivaC (TM4C)

Generally, low power is not a key concern with these devices.

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.lm4.Timer The Clock modules grabs an available GP timer. You can set a specific one via the Clock.timerId in the .cfg file.
Timer ti.sysbios.family.arm.lm4.Timer Allows an application to use a GP timer.
Seconds RTC The Seconds module for the MSP432E4 device uses the RTC timer. It directly interfaces with the peripheral to minimize code footprint and optimize performance.
Timestamp ti.sysbios.family.arm.m3.Timer By default, the Timestamp module uses a GP timer. The default TimestampProvider (ti.sysbios.family.arm.lm4.TimestampProvider) can be configured to share the timer used by the Clock module instead.

The image below shows the Runtime Object View for the sysbios/StairStep example. The StairStep example uses the default Clock module settings, Timestamp (via UIA) and creates a timer to be used by the application. The image shows three timers in the Hwi view and then three timers for the ti.sysbios.family.arm.lm4 view:

CortexM_MSP432E4_ROV

Note: the application’s timer function is timerFunc, but the Hwi stub is ti_sysbios_family_arm_lm4_Timer_isrStub__E. TI-RTOS plugs the stub function into the vector table. When that interrupt is asserted, the stub function runs and then calls the timer function.

Concerto (F28M35x and F28M36x devices)

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.m3.Timer SysTick
Timer ti.sysbios.family.arm.lm3.Timer General Purpose (GP) timers
Seconds ti.sysbios.hal.SecondsClock Uses Clock module
Timestamp ti.sysbios.family.arm.f28m35x.TimestampProvider Uses M clock control registers

TMS320F2838X

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.m3.Timer SysTick
Timer ti.sysbios.family.arm.m3.Timer SysTick (so only one instance is available). We recommend you use the Clock module for your timing services.
Seconds ti.sysbios.hal.SecondsClock Uses Clock module
Timestamp ti.sysbios.family.arm.f2838x.TimestampProvider Uses M clock control registers

OMAP4430, OMAP5430, DRA7XX, TMS320CDM7xx, TMS320TI81xx and TMS320C6A8149

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.ducati.Timer CTM timers
Timer ti.sysbios.family.arm.ducati.Timer CTM timers
Seconds ti.sysbios.hal.SecondsClock Uses Clock module
Timestamp ti.sysbios.family.arm.ducati.TimestampProvider CTM timers

AM65x and J7

Kernel Module Default Timer Notes
Clock ti.sysbios.family.arm.m3.Timer SysTick
Timer ti.sysbios.family.arm.m3.Timer SysTick
Seconds ti.sysbios.hal.SecondsClock Uses Clock module
Timestamp ti.sysbios.family.arm.m3.TimestampProvider By default, the Timestamp module shares the Clock’s SysTick timer. This is configurable in the ti.sysbios.family.arm.m3.TimestampProvider module.

SYS/BIOS in ROM

Some of the SYS/BIOS Kernel modules are included in ROM for the CC13xx and CC26xx devices. This was done to allow more flash memory for the application.

To place the kernel in ROM, some that kernel’s configuration was fixed. For example, BIOS.assertsEnabled was set to false. For these fixed configuration items, if the application wants to change them, they must use the kernel in flash. Please refer to Placing the kernel in Flash for more details.

See Debugging code in ROM for more details on which parameters are fixed in the ROM’s kernel.

Even if the application is using the kernel in ROM, it must have a .cfg file. Additionally, even though the kernel is in ROM, there are some kernel items that are placed in flash (and RAM) as part of the build.

Placing the kernel in Flash

By default, the kernel in the ROM is not used. The following can be included in the kernel configuration file (e.g. .cfg file) to make the application use the kernel in the ROM.

var ROM = xdc.useModule('ti.sysbios.rom.ROM');
if (Program.cpu.deviceName.match(/CC2640R2F/)) {
    ROM.romName = ROM.CC2640R2F;
}
else if (Program.cpu.deviceName.match(/CC26.2/)) {
    ROM.romName = ROM.CC26X2V2;
}
else if (Program.cpu.deviceName.match(/CC13.2/)) {
    ROM.romName = ROM.CC13X2V2;
}
else if (Program.cpu.deviceName.match(/CC26/)) {
    ROM.romName = ROM.CC2650;
}
else if (Program.cpu.deviceName.match(/CC13/)) {
    ROM.romName = ROM.CC1350;
}

For the SimpleLink SDK examples, above lines (or some subset of it) are in the supplied .cfg file. Therefore the SDK’s examples for the CC13xx and CC26xx use the kernel in the ROM.

If the above lines are commented out (or removed), when the kernel is built, the kernel’s code will be placed in flash. Since the kernel is being regenerated when the build occurs, the application can configure the kernel as desired.

Note: since most of the debug features are disabled in the ROM’s kernel, we recommend using a generated kernel in flash with debug features enabled when trying to debug application issues. For example, make sure enabled asserts in the .cfg file: BIOS.assertsEnabled = true.

Debugging code in ROM

When debugging an application that is using the kernel in ROM, only addresses are shown in the disassembly view and the call-stack view for the kernel code in ROM.

All SYS/BIOS Kernel code in ROM starts with address 0x1001xxxx. In order to make sense of the ROM’ed code, you need to include the symbol files in your debug session. Please refer to this table for the location of the ROM image for your device.

ROM Image Devices
packages\ti\sysbios\rom\cortexm\cc13xx\golden\CC13xx CC13x0
packages\ti\sysbios\rom\cortexm\cc26xx\golden\CC26xx CC26x0
packages\ti\sysbios\rom\cortexm\cc26xx\r2\golden\CC26xx CC2640R2
packages\ti\sysbios\rom\cortexm\cc26xx\cc26x2v2\golden\CC26xx CC13x2 and CC26x2

There are several useful files in the above directory. Note: <device> means either CC13xx or CC26xx. Directories are based on packages\ti\sysbios\rom\cortexm\<device>

ROM Image Devices
<device>.cfg Kernel configuration used to generated the ROM
golden\<device>\romFuncs.txt List of kernel functions in the ROM
golden\<device>\rtos_rom.xem[3 or 4f] Kernel binary in ROM. Useful for the next section

Importing in CCS

  1. While in debug mode, click the drop-down button next to the Load Program icon.
  2. Select Add Symbols.
  3. Select Browse and find correct ROM image. For example for the CC1352, select <SDK_INSTALL_DIR>\kernel\tirtos\packages\ti\sysbios\rom\cortexm\cc26xx\cc26x2v2\golden\CC26xx\rtos_rom.xem4f.

CCS menus for adding symbols

Import in IAR

  1. In the project options, go to Debugger->Images, then add the correct image. For example for the CC1352, <SDK_INSTALL_DIR>\kernel\tirtos\packages\ti\sysbios\rom\cortexm\cc26xx\cc26x2v2\golden\CC26xx\rtos_rom.xem4f.
  2. Check the box for Debug info only, and use Offset = 0.

IAR Options dialog for debugger

FAQ

Here are some TI-RTOS CortexM FAQs. Additionally, on the E2E site is a growing list of TI-RTOS FAQs.

Configuring a Zero Latency Interrupt

To define an interrupt that is never disabled by the SYS/BIOS Kernel, use the Hwi.create() configuration API or Hwi_create() C API, and set the params.priority value to anything less than the Hwi.disablePriority setting. By default, priority 0 is reserved for zero latency interrupts.

Remember that zero latency interrupts are not handled by the SYS/BIOS Kernel interrupt dispatcher and are never disabled. Consequently, in order to guarantee the integrity of the SYS/BIOS Kernel thread schedulers, zero latency interrupt handlers are severely restricted in terms of the SYS/BIOS Kernel APIs they can invoke. Specifically the following APIs can not be called within a zero latency interrupt handler:

This configuration example maps the function myZeroLatencyHwi() to the GPIO Port A interrupt (id = 16):

var Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
var hwiParams = new Hwi.Params();
hwiParams.priority = 0;
Hwi.create(16, '&myZeroLatencyHwi', hwiParams);

Below is the corresponding C code for dynamically configuring the same interrupt:

include <xdc/std.h>
include <xdc/runtime/Error.h>
include <ti/sysbios/BIOS.h>
include <ti/sysbios/family/arm/m3/Hwi.h>

Int main(Int argc, Char* argv[]) {
    Hwi_Params params;
    Hwi_Params_init(&params);
    params.priority = 0;
    Hwi_create(16, myZeroLatencyHwi, &params, Error_IGNORE);
    BIOS_start();
}

Configure Divide-by-Zero to be an Exception

By default, out of reset, the M3 core does not treat Divide-by-Zero as an exception. To configure the M3 to treat Divide-by-Zero as an exception, add the following to your configuration script:

var Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi'); Hwi.nvicCCR.DIV_0_TRP = 1;

Building Applications to Run from RAM Rather than FLASH

To reduce Flash programming cycles during development, you can place all the application’s code and data in IRAM rather than in FLASH. Assuming your device has enough internal RAM to contain all of your application, add the following to your configuration script to force all code/data to be placed into IRAM. Please note this is assuming IRAM is defined in your linker file.

var Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
Hwi.resetVectorAddress = 0x20000000;
Program.sectMap[".text"] = "IRAM";
Program.sectMap[".stack"] = "IRAM";
Program.sectMap[".bss"] = "IRAM";
Program.sectMap[".neardata"] = "IRAM";
Program.sectMap[".rodata"] = "IRAM";
Program.sectMap[".cinit"] = "IRAM";
Program.sectMap[".init_array"] = "IRAM";
Program.sectMap[".const"] = "IRAM";
Program.sectMap[".data"] = "IRAM";
Program.sectMap[".fardata"] = "IRAM";
Program.sectMap[".switch"] = "IRAM";
Program.sectMap[".sysmem"] = "IRAM";
Program.sectMap[".far"] = "IRAM";
Program.sectMap[".args"] = "IRAM";
Program.sectMap[".cio"] = "IRAM";
Program.sectMap["xdc.meta"] = "IRAM";

Changing the Timer used by the Timing Modules

The timing modules (Clock, Timer, Timestamp, and Seconds) have default underlying implementations. The application can change these as needed in the kernel configuration file (i.e. .cfg). For example

/* Setting the Timer Module's underlying implementation */
var halTimer = xdc.useModule('ti.sysbios.hal.Timer');
halTimer.TimerProxy = xdc.useModule('ti.sysbios.family.arm.m3.Timer');

/* Setting the Clock Module's underlying implementation */
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
Clock.TimerProxy = xdc.useModule('ti.sysbios.family.arm.m3.Timer');

/* Setting the Timestamp Module's underlying implementation */
var Timestamp = xdc.useModule('xdc.runtime.Timestamp');
var TimestampProvider = xdc.useModule('ti.sysbios.family.arm.cc26xx.TimestampProvider');

/* Setting the Seconds Module's underlying implementation */
var Seconds = xdc.useModule('ti.sysbios.hal.Seconds');
Seconds.SecondsProxy = xdc.useModule('ti.sysbios.hal.SecondsClock');

To Learn More

You can view the Intro to TI-RTOS Kernel Workshop to learn more. The TI-RTOS Kernel Workshop covers the TI-RTOS Kernel operating system available for all TI embedded processors (e.g. C28x, SimpleLink, CortexM, CortexA, C6000, and MSP430 ).

Related Documentation From Texas Instruments

Additional information about the SYS/BIOS Kernel can be found in the TI-RTOS Kernel User’s Guide. If you have questions, you can ask them on the forum for your target device in TI’s E2E community.

If you have questions, you can ask them in the forums in TI’s E2E community. Additionally on the E2E site is a growing list of TI-RTOS FAQs