Introduction
SysConfig is a tool that helps simplify the configuration of your application on a SimpleLink device.
The basic idea of SysConfig is to allow intuitive and natural configuration of key components in an application. The SysCofnig tool will generate source code to configure these components (e.g. TI Drivers, networking stacks) based on the settings in the SysConfig configuration file (i.e. .syscfg). This generated code is then included in the application. For example, SysConfig will create and fill in all the 'C' structures needed by the TI Driver modules.
This lab is an introduction to SysConfig and will focus on its integration with TI Drivers modules (e.g. UART, I2C, etc.). Additional labs will be available for other key components (e.g. Networking stacks, BLE stack, etc.) but this lab is considered the starting point to understand and learn the power of SysConfig.
SysConfig is not dependent on an RTOS, compiler toolchain, or IDE. Additionally SysConfig is available
- with CCS Desktop (which this lab will focus on).
- with CCS Cloud
- as a stand-alone desktop tool
- as a cmdline tool
The tasks in this lab session are targeted to be completed within an hour time frame.
What SysConfig is not
Currently SysConfig is generally focused on generating configuration code. For example, the tool generates the configuration code for TI Drivers, but it does not generate code for the Driver init or open calls. For example, the application writer can use SysConfig to configure an I2C peripheral, but the writer must supply the calls to I2C_init
, I2C_open
, and I2C_transfer
. Please refer to the documentation for each component in SysConfig for more information.
Here's what we'll learn
- Introduction to SysConfig
- Learn how to use SysConfig to configure TI Drivers in your application
Preview Disclaimer
Currently the SysConfig tool is available in CCS 8.2 (and higher). The SimpleLink SDKs are shipping TI Drivers examples (and a few others) in the examples/syscfg_preview
directory that use SysConfig to setup the TI Drivers.
These examples are not currently available via Resource Explorer.
Therefore to play with SysConfig, the easiest way is to import an examples/syscfg_preview
example directly into CCS as described below in this lab. Note: this currently requires that you have CCS and the SimpleLink SDK installed on your computer.
The documentation for SysConfig is still being developed. For now we have the following site that offers more details: SysConfig Preview.
Please note, not all boards are currently supported. Over the following quarters, the SimpleLink SDK will expand the use of SysConfig to include all boards, things like stack configuration, RTOS configuration, etc. Additional SimpleLink Academy labs will be rolled out as the new functionality becomes available.
Prerequisites
Recommended background reading
- SimpleLink SDK User Guide's SysConfig section
- SysConfig Preview
Software for development
- Desktop Code Composer Studio 8.2 or higher
- Any SimpleLink SDK v2.30 or higher installed on your computer
Hardware requirements
You can use this workshop with any cc13xx, CC26xx, MSP432, or CC32xx LaunchPad Development Kit.
TI Driver Configuration
TI Drivers rely on the application to supply the driver configuration. The majority of this configuration is supplied in 'C' structures and arrays. For example, the below code sets up a I2C peripheral to be used in a TI Drivers example for the CC26X2R1_LAUNCHXL board.
This approach minimizes runtime allocation and overall footprint of the application.
The following two sections show the two ways this configuration is supplied
- Current/Legacy: application supplies the source code
- SysConfig: source code is generated based on configuration in SysConfig
Runtime usage of the TI Drivers
To use a TI Driver instance, you still must open it (e.g. UART_open
must be called by the application) regardless of the method used to supply the TI Driver configuration.
Current/Legacy Approach
Projects must supply the needed TI Driver configuration in the Board source files. For example, here is the empty
project for the CC26X2R1_LAUNCHXL. The Board source files that contain the TI Drivers configuration are circled.
Generally, the Board source file are the same for all TI Driver examples for a given board.
SysConfig Approach
With SysConfig, the configuration of the TI Drivers is the same, but instead of having the application writer supply the 'C' structures/arrays, the SysConfig tool generates the 'C' code for you instead.
The .syscfg file in a project holds all the configuration for the TI Drivers that will be used by the application. As part of the build, SysConfig will parse the .syscfg file and generate the needed 'C' structures/arrays for the TI Drivers.
Editing the .syscfg file
TI recommends that the .syscfg file only be modified via the SysConfig tool.
Then if you peek into Board.c
for this example, we only see the configuration that is needed for the application (e.g. no I2C configuration since the empty
example does not use I2C).
/*
* ======== Board.c ========
* Configured TI-Drivers module definitions
*
* DO NOT EDIT - This file is generated for the CC26X2R1_LAUNCHXL
* by the SysConfig tool.
*/
#include <stddef.h>
#ifndef DeviceFamily_CC26X2
#define DeviceFamily_CC26X2
#endif
#include <ti/devices/DeviceFamily.h>
#include "Board.h"
/*
* =============================== GPIO ===============================
*/
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOCC26XX.h>
/*
* ======== gpioPinConfigs ========
* Array of Pin configurations
*/
GPIO_PinConfig gpioPinConfigs[] = {
/* Board_GPIO_LED0 : LaunchPad LED Red */
GPIOCC26XX_DIO_06 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW,
};
/*
* ======== GPIOCC26XX_config ========
*/
const GPIOCC26XX_Config GPIOCC26XX_config = {
.pinConfigs = (GPIO_PinConfig *)gpioPinConfigs,
.callbacks = NULL,
.numberOfPinConfigs = 1,
.numberOfCallbacks = 0,
.intPriority = (~0)
};
/*
* =============================== PIN ===============================
*/
#include <ti/drivers/PIN.h>
#include <ti/drivers/pin/PINCC26XX.h>
const PIN_Config BoardGpioInitTable[] = {
/* LaunchPad LED Red, Parent Signal: Board_GPIO_LED0 GPIO Pin, (DIO6) */
Board_PIN0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MED,
PIN_TERMINATE
};
const PINCC26XX_HWAttrs PINCC26XX_hwAttrs = {
.intPriority = (~0),
.swiPriority = 0
};
/*
* =============================== Power ===============================
*/
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26X2.h>
#include "Board.h"
extern void PowerCC26XX_standbyPolicy(void);
extern bool PowerCC26XX_calibrate(unsigned int);
const PowerCC26X2_Config PowerCC26X2_config = {
.enablePolicy = true,
.policyInitFxn = NULL,
.policyFxn = PowerCC26XX_standbyPolicy,
.calibrateFxn = PowerCC26XX_calibrate,
.calibrateRCOSC_LF = true,
.calibrateRCOSC_HF = true
};
/*
* ======== Board_initHook ========
* Perform any board-specific initialization needed at startup. This
* function is declared weak to allow applications to override it if needed.
*/
#if defined(__IAR_SYSTEMS_ICC__)
__weak void Board_initHook(void)
#elif defined(__GNUC__) && !defined(__ti__)
void __attribute__((weak)) Board_initHook(void)
#else
#pragma WEAK (Board_initHook)
void Board_initHook(void)
#endif
{
}
/*
* ======== Board_init ========
* Perform any initialization needed before using any board APIs
*/
void Board_init(void)
{
/* ==== /ti/drivers/Power initialization ==== */
Power_init();
/* ==== /ti/drivers/PIN initialization ==== */
if (PIN_init(BoardGpioInitTable) != PIN_SUCCESS) {
/* Error with PIN_init */
while (1);
}
Board_initHook();
}
Board.c
The SysConfig approach has the following advantages over having the application writer supply source code:
- Adding a driver instance is easier.
- Reduces the number of mistakes since the 'C' code is generated instead of hand-written (or copied/pasted).
- The Board source files are specifically tailored to your application with SysConfig. With the legacy approach, TI Drivers examples have worst-case coverage (e.g. I2C configuration is present even if not using it).
- SysConfig reduces the number of Board source files from 3 to 2 for TI Driver's configuration.
- Changes between versions are handled more seamlessly. Note: this is not a common occurrance, but annoying when it happens!
How is .syscfg different from .cfg (for TI-RTOS users)
The TI-RTOS configuration file (.cfg) is used to configure the kernel. Similar to the .syscfg file, the .cfg file is parsed and source files are generated. Currently the SysConfig tool does not configure TI-RTOS, so the .cfg file is still needed for TI-RTOS based applications.
Quiz
Does SysConfig change the runtime usage of TI Drivers?
Lab: Getting started
For this lab, we are going to import the Empty
example from the examples\syscfg_preview
directory. We'll do the following things in the below tasks
- Investigate the .syscfg file
- Configure the
Display
module in SysConfig - Configure the
Watchdog
module in SysConfig - Add a button via SysConfig that will stop the tickling/feeding of the Watchdog timer.
The below steps will use simplelink_cc26x2_sdk_2_40 along with the CC26X2R1_LAUNCHXL LaunchPad board. So some of the pictures/directory names/line numbers/sizes/etc. might be slightly different if you are using a different board or version.
Task 1 - Importing an Example
Start your Desktop CCS and import the TI-RTOS empty
project from your SimpleLink SDK. Since SysConfig is still preview, it has not been incorporated
into Resource Explorer, so we'll import via the CCS Project tab. Please make sure to select the syscfg_preview directory!
- Select
Project
→Import CCS Project...
in CCS and navigate to<SL_SDK>\examples\syscfg_preview\rtos\CC26X2R1_LAUNCHXL\drivers\empty\tirtos\ccs
- Select the project and hit Finish
After importing, you should see two projects in Project Explorer...empty (the application project) and kernel project. Also note the Debug
directory is empty.
The generated TI Drivers Board files will go into the Debug\syscfg
as part of the build.
Task 2 - Verifying the Example Works
To test that the software and hardware pre-requisites are fulfilled, we are going to build and run the project before going forward. This will generate the Board.c
and Board.h
files also.
Our first mission is to build the imported project. Select the project in Project Explorer and choose
Project
→Build Project
from the menu. Notice the beginning of the application project build log that SysConfig generates the Board files (which are now in theDebug/syscfg
directory). Note: as more SDK components start to be integrated with SysConfig, more files will be generated.When the project is built, we are going to make sure that the hardware and debugger work.
- Make sure the target is connected to the computer via the appropiate USB cable (please refer to the
Board.html
file in the empty project to locate the USB connector used for emulation). - To start debugging, select
Run
→Debug
, or press F11.
- Make sure the target is connected to the computer via the appropiate USB cable (please refer to the
- When the download is finished, press F8 or the green play icon to run.
- You should see an LED toggle every second. Here is the code for the toggling in
empty.c
. Remember the constantBoard_GPIO_LED0
! We'll see where it comes from in the next step...while (1) { sleep(time); GPIO_toggle(Board_GPIO_LED0); }
Quiz
Board.c
and Board.h
are the only files ever generated by SysConfig?
Task 3 - Exploring SysConfig (Software)
Now that we've confirmed the setup is working, now let's actually look at the SysConfig GUI Tool in CCS. We'll see where the Board_GPIO_LED0
constant was defined and how the GPIO configuration was done also.
Double-click the
empty.syscfg
file in the Project Explorer. After a couple seconds you should see this window.Let's look at a preview of the TI Driver configuration code that is going to be generated by the
empty.syscfg
file. Select the<>
icon on the top right of the SysConfig GUI. Note: all SysConfig generated files can be previewed here. For exampleti_ndk_Config.c
file for MSP432E4 Networking configuration.Click the Board.c file. This opens the preview of the generated
Board.c
. In later tasks in this lab, you'll see this file updated as we change the TI Driver configuration. As you look at theBoard.c
, you'll notice it is rather empty (as expected...the project is called Empty after all). Let's look at a couple key items in this file- Generation Disclaimer: At the top, you'll see the disclaimer to not modify this file since it is generated. Any changes made to this file will be wiped out when it is re-generated. We'll show how to modify these generated files later on in this lab (spoiler...add the files to the project and exclude the .syscfg file).
Configuration of the LED: The configuration for the LED that this example uses.
Device/Board Specific
Since the low level driver configuration is device/board specific, if you are using a different device or board, your generated
Board.c
will have different names for the constants and data structures.
Select the GPIO module in the Software view. Here is the configuration for there the LED that the example uses.
Where did the LaunchPad LED Red in the Use Hardware field in the above picture come from?
Next section:)
Quiz
We've still not really answered where Board_GPIO_LED0
is defined. We see it in the GPIO configuration in the GUI, but where is the actual source code for it!
Task 4 - Exploring SysConfig (Hardware)
Select the Hardware view. The hardware components on this LaunchPad are defined under this section. You can see that the
LaunchPad LED Red
is being currently used (green check-mark) and shows the software configuration of it.
Custom Hardware
SysConfig supports all the SimpleLink LaunchPads and many BoosterPacks. Documentation (and a SimpleLink Academy Lab) will be provided in the future to show how to integrate in your custom board(s).
Task 5 - Output via the Display Module
Let's start using SysConfig to configure new things! First let's add a Display_printf
to see output via the UART. All SimpleLink LaunchPads have a back-channel UART via the emulation USB cable.
Have the
Board.c
preview open in SysConfig. We can see theDisplay
source code configuration get added when you do the next step!In SysConfig, click the + icon next to the Display module and then select
XDS110 UART
in the Use Hardware drop-down and save the file. When you hit the + icon, you'll see theBoard.c
file change in the preview.Now let's add the usage of the
Display
module into theempty.c
file.Add Display.h header
#include <ti/display/Display.h>
empty.c Add in with other #includes
Add initialization of the Display instance. Also add a count variable that will be used in the
Display_printf
.Display_init(); Display_Handle hSerial = Display_open(Display_Type_UART, NULL); uint32_t count = 0;
empty.c :: mainThread() in the function before the
while
loop.Add the
Display_print
call into thewhile
loop.while (1) { sleep(time); GPIO_toggle(Board_GPIO_LED0); Display_printf(hSerial, 1, 0, "LED Toggle %d", count++); }
empty.c :: mainThread() the new while loop
Rebuild/load/run the application.
Open your favorite terminal application (e.g. PuTTY, CCS Terminal). You'll probably need to use Device Manager (if using Windows) to determine the correct COM port.
with the following settings (note your COM port will most likely be different!).
You should see the output in the terminal session
The TI Drivers and Display module are covered in the <SimpleLink_SDK_Install_Dir>/docs/tidrivers/tidriversAPIs.html
file. You can get to a specific module via SysConfig.
In the module view, click the ?
Here is the description text and link for the Display
module.
Task 6 - Add Watchdog
Most production applications include some type of Watchdog timer to help in unexpected behavior. We are going to add a Watchdog timer into the application. We'll keep it simple and not have it restart the application. It will only set a flag to denote that it had expired.
In SysConfig, click the + icon next to the
Watchdog
module and then change the Period to 1500.Now let's add the usage of the
Watchdog
module into theempty.c
file.Add header and some global variables
#include <ti/drivers/Watchdog.h> volatile uint8_t serviceFlag = 1; volatile uint8_t watchdogExpired = 0; Watchdog_Handle watchdogHandle;
empty.c Add in with other #includes
Open the Watchdog peripheral
Watchdog_init(); Watchdog_Params params; Watchdog_Params_init(¶ms); params.callbackFxn = (Watchdog_Callback)watchdogCallback; params.resetMode = Watchdog_RESET_OFF; watchdogHandle = Watchdog_open(Board_WATCHDOG0, ¶ms); if (watchdogHandle == NULL) { /* Error opening Watchdog */ while (1); }
empty.c :: mainThread() in the function before the
while
loop.Add the Watchdog callback. Note this function is specified in the Watchdog parameters above.
void watchdogCallback(uintptr_t unused) { /* Clear watchdog interrupt flag */ Watchdog_clear(watchdogHandle); watchdogExpired = 1; serviceFlag = 1; }
empty.c above the mainThread function
Add the tickling/feeding of the Watchdog timer and debug output to show that the Watchdog timer expired in the while loop.
while (1) { sleep(time); GPIO_toggle(Board_GPIO_LED0); Display_printf(hSerial, 1, 0, "LED Toggle %d", count++); if (watchdogExpired) { Display_printf(hSerial, 1, 0, "Watchdog expired!"); watchdogExpired = 0; } if (serviceFlag) { Watchdog_clear(watchdogHandle); Display_printf(hSerial, 1, 0, "Cleared WD"); } }
empty.c modified while loop
Rebuild/load/run the application.
Quiz
Why does the Watchdog never expire?
Watchdog configuration vary per device
Please consult Watchdog API reference and TRM for more details on the Watchdog for your device.
Task 7 - Add a button
Let's add a button to the application. When pressed, it will disable the tickling/feeding of the Watchdog in the while
loop.
Have the
Board.h
preview open in SysConfig. We can see the name of the button get modified as we change it!In SysConfig, let's add a button via the Hardware view instead of Software.
- Select Hardware and click the + icon next to LaunchPad Button BTN-1 (left).
- Change the name of the constant to Board_WDBUTTON. Note: you'll see the name change in the
Board.h
preview window. - Select
Pull Up
for the Pull field andFailing Edge
for the Interrupt Trigger. Note: your board might have different requirements. Finally, set the button callback to
stopTicklingWatchdog
Now let's add the usage of the button into the
empty.c
file.Add the enabling of the callback. Note the name of the constant is from the SysConfig Name setting.
GPIO_enableInt(Board_WDBUTTON);
empty.c after the
GPIO_setConfig
Add the callback (note the name must match the SysConfig Callback Function setting).
void stopTicklingWatchdog(uint_least8_t index) { serviceFlag = 0; }
empty.c above the mainThread function
Rebuild/load/run the application.
Hit BTN-1 (or whatever button you specify) refer to Board.html for details. Your output should denote that the Watchdog did expire.
Quiz
Click on the "Show Board". What is this for?
Task 8 - How to “disable” SysConfig
Great! You have your configuration setup, but you'd like to add some comments in the Board.c
or Board.h
files or simply "freeze" them. How do you do this?
Copy the source files from Debug/syscfg into your project.
Right-click on empty.syscfg and "Exclude from Build". Note: the empty.syscfg file will be greyed out when excluded.
Rebuild/load/run the application. It will behave the same except the files will not be generated.
Task 9 - Moving to a new SDK Version
You have everything configured via SysConfig with a specific version of the SDK and the application is working well...great! What happens when you move to a newer version of the SDK? Here are the high-level steps that you need to do:
Install the new SDK and have CCS discover it.
Move the working application to the new SDK (refer to the SimpleLink User Guide for details on how to do this).
Rebuild the application. This will regenerate the files based on the new content in the new SDK. Please note that SysConfig really has two pieces
- The SysConfig GUI/cmdline tool (available in CCS or as a stand-alone tool).
- The meta-data in the SimpleLink SDKs that the SysConfig tool reads to build up the views (e.g. the
Display
module in the SDK specifies that it supports, UART, Console and LCD).
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.