Skip to content

Add TI CC13x2 and CC13x4 device support - #61

Draft
pradeep-hn wants to merge 6 commits into
CiscoDevNet:mainfrom
TexasInstruments:main_ti
Draft

Add TI CC13x2 and CC13x4 device support#61
pradeep-hn wants to merge 6 commits into
CiscoDevNet:mainfrom
TexasInstruments:main_ti

Conversation

@pradeep-hn

@pradeep-hn pradeep-hn commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

PR Overview: TI SimpleLink Wi-SUN FAN Platform Support

This PR adds support for TI's CC13xx/CC26xx microcontrollers (running a Wi-SUN FAN mesh network) as a new target platform for csmp-agent-lib.

New Files / Key Additions:

osal/ti_simplelink_wisun/

  • New OS Abstraction Layer wiring the library's socket, thread, mutex, timer, and storage APIs to FreeRTOS and the vendor networking stack.
  • A compile guard prevents a duplicate main() symbol when the library is linked into our firmware that already defines its own main().

sample/tlvs/ti_simplelink_wisun_tlvs.c

  • Platform-specific TLV callbacks: network status, routing data, interface metrics, firmware version, and hardware description.

Vendors/TI/application/

  • Router node application: joins the mesh, opens a UDP socket to the NMS, starts the CSMP agent.
  • Includes RF/PHY config for 915 MHz North America and mesh auth certificates.
  • sntp_sync.c/.h: lightweight NTP client that syncs time right after mesh join. Falls back to a compile-time epoch if the server is unreachable (needed for accurate OTA scheduling).

tools/tpd_config_cc13xx.json

  • Config for wrapping the signed firmware binary before uploading to the management server for OTA.

Vendors/TI/README.md

  • Full setup guide: network architecture, build steps, device provisioning, flashing, IPv6 routing, NTP setup, and OTA upgrade walkthrough.

Vendors/TI/OpenCSMP_01.00_manifest.html

  • Open-source manifest required for public release.

Board Support

5 LaunchPad variants supported (LP_CC1312R7, LP_CC1352P7_1, LP_EM_CC1314R10, LP_EM_CC1354P10_1, LP_EM_CC1354P10_6). Each board only carries its own config and compiler flags; all application code is shared.

The entire networking stack comes from TI simplelink sdk.

Build System

  • build.sh ti_simplelink_wisun builds all 5 boards in one command.
  • Root Makefile defaults the platform to SECUREBOOT so the signed firmware binary is always produced.
  • Firmware is signed via MCUBoot; version stamp is auto-generated from build date so no manual bumps are needed between OTA cycles.
  • Heap and timer stack sizes increased across all board configs to accommodate SNTP and OTA memory usage.

Changes to Existing Shared Files

osal/osal.h Added TI spcific defines
include/iana_pen.h Added vendor IANA PEN entry
sample/CsmpAgentLib_sample.c Added #ifdef guard around main()
sample/Makefile Added clean target for the new platform
src/coap/coapclient.c Minor fix
Makefile / build.sh Added new platform target and entry

Here is the summary of the test results, grouped by functional area:

  • Device Registration & Inventory: Verified that freshly flashed devices successfully join the Wi-SUN network, register with the FND, and appear in the inventory with correct metadata and an "up" status.
  • Metrics Reporting & Stability: Confirmed that devices reliably report periodic CSMP and Wi-SUN-specific metrics (such as WpanStatus and InterfaceMetrics) without drops, maintaining stable connectivity during a 24-hour soak test.
  • Firmware Information Accuracy: Validated that the FND correctly reads and displays the current running firmware version and slot table data before any OTA processes begin.
  • OTA Transfer & Activation: Successfully tested full OTA cycles, ensuring all 1060 blocks are received and validated, followed by successful device reboots and version updates in the FND.
  • OTA Resilience & Recovery: Verified system robustness through mid-download power cycles (resuming from missing blocks), superseding pending activations with new versions, and performing 10 consecutive stress cycles.
  • Multi-Device Scalability: Demonstrated that the FND and border router can handle simultaneous OTA updates and concurrent metric reporting from multiple devices without interference or registration failures.

@manojnacsl manojnacsl added the TI Texas Instruments | ti.com label Jun 26, 2026
@manojnacsl
manojnacsl force-pushed the main branch 2 times, most recently from 6d88bcf to 2548fd1 Compare August 19, 2026 11:44
@manojnacsl
manojnacsl force-pushed the main branch 3 times, most recently from 6dbd890 to c2c1170 Compare August 30, 2026 17:31

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojnacsl At some point we'll need to rework that file. We cannot have vendor specific defines in that file.

It would probably make sense to move the main function (among others TBD) to a vendor specific folder of the sample application.

@manojnacsl
manojnacsl self-requested a review September 3, 2026 07:15
@manojnacsl
manojnacsl marked this pull request as draft September 3, 2026 07:15
Comment thread osal/osal.h

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojnacsl We should probably consider moving those vendor specific defines in another file.

{
return -1;
}
return osal_sendto(sockd, msg.msg_iov[0].iov_base, msg.msg_iov[0].iov_len,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoAP responses clip tokens and payloads.
osal_sendmsg() sends only msg_iov[0], while the server constructs up to four iovecs for the CoAP header, token, payload marker, and body. Normal responses are therefore truncated or malformed.
Flatten the buffers or handle iovec before sending.
osal_ti_simplelink_wisun.c#L305-L315
coapserver.c#L151-L202

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed this by flattening the msg_iov entries into a single contiguous buffer before calling osal_sendto(). I’ve also bounded this buffer to 1280 bytes (matching our existing RX buffer size) to ensure safety. Thank you for the precise line references

return (r == NVS_STATUS_SUCCESS) ? OSAL_SUCCESS : OSAL_FAILURE;
}

/* No-op: MCUBoot handles firmware rollback natively; SetBackupRequest (TLV 70) is accepted but ignored */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate and clarify why SetBackupRequest is accepted but ignored (no-op). Isn't the image to be backed-up be written onto a persistent storage(flash) for later recovery?
A LoadRequest from backup storage slot would load this image onto the active run slot.

Either implement backup-slot storage/activation through MCUboot or reject/disable backup operations for this platform.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for spelling out that risk so clearly. On reflection, you are right, allowing a "silent success" could lead to a corrupted BACKUP_IMAGE slot, potentially bricking the device.

Since this platform currently lacks dedicated physical storage for a backup slot, I have implemented your alternative suggestion: osal_copy_firmware() now returns a failure when BACKUP_IMAGE is involved. This ensures SetBackupRequest is correctly rejected with RESPONSE_INVALID_REQ

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing this - osal_copy_firmware() now rejects unsupported backup operations.

However, the previous false-success path for SetBackupRequest is partly fixed - sample_data_init() still initializes the upload and backup headers by copying the running-image header, marking nonexistent images as complete. That can cause FND to see erased slots as valid firmware. CsmpAgentLib_sample.c#L89-L105

We'll need to review and handle this scenario.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a short-term fix, we can patch application.c to clear those slots back to empty/incomplete right after sample_data_init() if they still match the running image's hash. A complete fix would be in CsmpAgentLib_sample.c itself zeroing the slot and marking it FWHDR_STATUS_DOWNLOAD in the fallback branch instead of copying the running image's header which would fix this for all platforms hitting that path

Comment thread include/iana_pen.h
*/

/** Set Vendor-ID to Vendor's IANA PEN-ID. Refer include/iana_pen.h */
#define VENDOR_ID CISCO

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define VENDOR_ID TI

Vendor ID to be changed to TI

@manojnacsl

Copy link
Copy Markdown
Collaborator

Please add a detailed PR description capturing the overall changes for TI platform integration, development/build toolchain used, testing performed, known caveats if any. Thanks.

@manojnacsl manojnacsl added the osal OS Abstraction Layer label Sep 8, 2026

@manojnacsl manojnacsl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ti-aryan @pradeep-hn - There have been recent commits to CiscoDevNet:main by Renesas and Cisco.

Suggest that you update/sync TexasInstruments:main_ti fork to latest CiscoDevNet:main and push the updated code to PR61 to ensure you are working your changes on top of the latest repo.

11 commits behind CiscoDevNet:main : TexasInstruments/csmp-agent-lib@main_ti...CiscoDevNet:csmp-agent-lib:main
Image

Comment thread include/iana_pen.h
* RFC 9371
* URL: https://www.iana.org/assignments/enterprise-numbers/
*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Socket-close abstraction seems broken
The PR replaces osal_socket_close() with raw close():

  • coapclient.c#L45-L50
  • coapserver.c#L45-L50
  • coapserver.c#L77-L81
    On TI, the handle is a Nanostack socket, not a POSIX descriptor:
  • osal_socket() returns socket_open() for the server.
  • The client receives a synthetic handle equal to g_ns_sock + 64.
  • close() cannot correctly close either handle, especially the synthetic client handle.
  • g_sock_alloc_count is never reset, so reopening after a stop will not call socket_open() again.

The TI OSAL should implement osal_socket_close() using Nanostack’s socket_close(), reset the socket/channel state, and the common CoAP code should retain the OSAL abstraction.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same root cause as the other comment our PR predated upstream's osal_socket_close() abstraction, so our OSAL still had raw close() calls and no TI implementation. We've since rebased onto the latest upstream and implemented osal_socket_close() for the TI platform using Nanostack's socket_close(), with per-channel state tracking so the server and client channels can open/close independently and correctly reopen via socket_open() afterward. Should be resolved now.

Comment thread include/iana_pen.h
CISCO = 5771,
TI = 294,
SILABS = 39873,
ITRON = 1233,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

External receive-task/API regression issue to be reviewed
The main branch supports USE_EXTERNAL_RECV_TASKS by:

  • Not creating an internal receive task when the macro is defined.
  • Exposing coapclient_process_response() and coapserver_process_datagram() for the application to call.
  • Closing sockets through osal_socket_close().
    The updated PR still removes that behavior:
  • coapclient_open() always creates recv_fn; coapserver_listen() always creates recv_thread.
  • The receive functions always call the private-renamed process_response() / process_datagram().
  • The public processing functions are removed from both headers.
  • coapclient_stop() and coapserver_stop() unconditionally cancel recvt_id_task.
    Relevant code:
  • coapclient.c#L42-L79
  • coapserver.c#L31-L92
  • coapclient.c#L240-L275
  • coapserver.c#L95-L132

This breaks existing users that define USE_EXTERNAL_RECV_TASKS: their application receiver and the newly created internal receiver will race for packets, and existing calls to the public processing APIs will no longer compile.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our PR was originally based on an older upstream revision, before USE_EXTERNAL_RECV_TASKS support, the public coapclient_process_response()/coapserver_process_datagram() APIs, and the osal_socket_close() abstraction were added to main. We've since rebased onto the latest upstream and pulled in all of that verified our coapclient.c/coapserver.c/headers now match main exactly on this behavior. Should be resolved on our side now.

@manojnacsl manojnacsl self-assigned this Sep 8, 2026
a1257330 and others added 6 commits September 8, 2026 15:59
  Introduce the TI CC13xx/CC13x4 Wi-SUN FAN family as a supported
  csmp-agent-lib target. The implementation uses SDK-only prebuilt
  libraries (no external source repositories required); all Wi-SUN
  MAC, Nanostack, and TLS symbols are supplied by the SDK's
  maclib_secure, wisun_rn_mbed_ns_tls_lib, and wisun_ncp_lib
  archives, selected automatically by SysConfig via
  ti_utils_build_linker.cmd.genlibs.

  Five LaunchPad variants are supported and built in a single
  ./build.sh ti_simplelink_wisun invocation by a BOARD_DIRS wildcard
  over Vendors/TI/*/csmp_example_tirf/freertos/ticlang/. Adding a
  new board requires only placing a directory there.

    osal/ti_simplelink_wisun:
    - osal_ti_simplelink_wisun.c: FreeRTOS/Nanostack OSAL implementation;
      socket, thread, mutex, timer, and NV-storage bindings for CC13xx
    - osal_platform_types.h: platform type definitions and mbed_tracef
      forward declaration; guards main() in CsmpAgentLib_sample.c via
      OSAL_TI_SIMPLELINK_WISUN so the library compiles without a duplicate
      entry point when linked into the board firmware
    - ti_simplelink_wisun.mak: SDK include paths for device headers,
      FreeRTOS portable layer, Nanostack public API, mbedTLS, and NVOCMP;
      supports CC13X4, CC13X2X7, CC13X2, and CC13X1 via DEVICE_FAMILY

    sample/tlvs/ti_simplelink_wisun_tlvs.c:
    - TI-specific TLV callbacks: wpanstatus, RPL, interface metrics,
      firmware image info, and hardware description; reads live data
      from Nanostack ws_management_api and nwk_stats_api
    - g_tx_power_dbm: file-scoped variable set by application.c from
      CONFIG_TRANSMIT_POWER; extern declaration removed from the shared
      CsmpAgentLib_sample_tlvs.h to keep platform-specific symbols out
      of the common header

    Vendors/TI/application (shared across all boards):
    - main.c / application.c: Wi-SUN border router node application;
      initialises mesh_system, opens UDP socket to NMS, starts CSMP
      agent task; sets g_tx_power_dbm from SysConfig CONFIG_TRANSMIT_POWER
    - mbed_config_app.h / advanced_config.h: Wi-SUN PHY configuration
      (FAN 1.1, North America 915 MHz, FH mode)
    - wisun_certificates.h / ws_router_fan_cert_certificates.h: device
      and CA certificate buffers for WPA2 network authentication
    - defines/router.opts: compile-time CSMP options; NMS address set
      via -DCSMP_AGENT_NMS_ADDRESS; device type OPENCSMP

    Vendors/TI/<BOARD>/csmp_example_tirf:
    - Five board configurations: LP_CC1312R7, LP_CC1352P7_1 (Cortex-M4F,
      CC13X2X7) and LP_EM_CC1314R10, LP_EM_CC1354P10_1, LP_EM_CC1354P10_6
      (Cortex-M33, CC13X4); each board carries only its board-specific
      csmp_example.syscfg (--board target) and ticlang/makefile (CPU
      flags, device include paths, linker command file)
    - M4F boards: -mcpu=cortex-m4 -march=armv7e-m -mfpu=fpv4-sp-d16,
      cc13x2x7_cc26x2x7.cmd, ARM_CM4F FreeRTOS port
    - M33F boards: -mcpu=cortex-m33 -mfpu=fpv5-sp-d16,
      cc13x4_cc26x4.cmd, ARM_CM33/non_secure FreeRTOS port
    - genLibs: TI154Stack.genLibs = "none" removed from syscfg so
      SysConfig emits prebuilt .a paths into genlibs; build previously
      required compiling ~250 MAC/Nanostack/TLS source files from the
      wisunfan development repo — now resolved entirely from SDK

    ti_simplelink_wisun.target / sample/ti_simplelink_wisun.target:
    - Root library target builds csmp_agent_lib_ti_simplelink_wisun.a
      using TI ARM Clang; board target loops over BOARD_DIRS and invokes
      each board makefile with CSMP_AGENT_LIB_INSTALL_DIR and SDK paths
    - Tool paths (SYSCONFIG_TOOL, TICLANG_ARMCOMPILER) sourced from
      SDK's imports.mak; user edits SIMPLELINK_SDK_LINUX in two .target
      files and imports.mak once per machine

    Vendors/TI/README.md:
    - Complete setup guide covering network architecture (Linux Host
      container + wfantund container two-container model), build
      configuration, TPD pre-provisioning, border router setup,
      flashing, IPv6 routing, and end-to-end verification

    build.sh / sample/Makefile / Makefile:
    - sample/Makefile clean: invoke ti_simplelink_wisun.target clean to
      remove board .obj, .hex, .out, and SysConfig-generated files
    - Board makefile clean uses *.obj glob instead of $(OBJECTS) to
      catch stale artifacts from previous full-source builds

  Signed-off-by: Aryan Arora <a1257330@ti.com>
  Extend the TI SimpleLink Wi-SUN example with clock synchronisation,
  over-the-air firmware upgrade support

  Changes:
  - application/sntp_sync.c, sntp_sync.h: new SNTP client (RFC 4330)
    that queries the IPv6 NTP server (default fd00::1) immediately after
    Wi-SUN join; falls back to CSMP_BUILD_EPOCH if the server is
    unreachable, keeping FND OTA schedule timers accurate
  - application/application.c: replace fixed CSMP_APPROX_EPOCH seed with
    sntp_sync() call; patch default_run_slot_image with TI-specific
    hwid/filename/version before sample_data_init() writes NV on first
    boot; add ti_ota_check_pending_activation() after osal_kernel_start()
  - all board makefiles: add application_sntp_sync.obj to object lists;
  - all board csmp_example.syscfg: increase FreeRTOS heapSize from
    0x8000 to 0xC000 and timerStackSize from 0x800 to 0x1000 to
    accommodate the additional SNTP and OTA stack usage
  - all board SecureBoot.mak: fix SDK env var (SCCM_ → SIMPLELINK_);
    embed build-date version stamp via $(shell date +%Y%m%d)
  - Makefile: default ti_simplelink_wisun target to CONFIG=SECUREBOOT
    so the signed MCUBoot binary is always produced alongside the hex
  - tools/tpd_config_cc13xx.json: new TPD header config used by
    add_tpdheader.py to wrap the signed .bin before FND upload;
    hwid="CC13XX" must match hw_info in the FND cc13xx device meta file
  - Vendors/TI/README.md: add Part C FND device type provisioning steps
    (addGenericEndpoints.sh, cc13xxMeta.json, CSV import); add Step B.2
    IANA PEN change (CISCO → TI); add Step F.5 Linux host mesh route;
    add Step F.10 ntpd server setup; add Part H OTA firmware update
    walkthrough (Steps H.1–H.13 covering build, flash, wrap, upload,
    and verify)

  Signed-off-by: Aryan Arora <a-arora@ti.com>
  Drop the manual CsmpAgentLib_sample.c version-string step from the
  OTA upgrade guide - FND reads the version from the signed image
  header, so the source edit was redundant and error-prone.

  Renumber the OTA checklist steps (H.3-H.13 → H.3-H.12) and correct
  the flash artifact reference from ns_node_csmp.hex to ns_node_csmp.bin.

  Replace the hardcoded SecureBoot.mak imgtool version (2.0.0) with
  1.0.0+<YYYYMMDD> so each build carries a unique build number without
  requiring a manual version bump between OTA cycles.

  Remove the stale ti_ota_check_pending_activation() call from
  application.c that is now handled elsewhere in the startup sequence.
…ti (#2)

Add missing TI Text license headers to TI Wi-SUN platform source
files that were previously shipped without them. Also bump the copyright
end-year from 2025 to 2026 in the CC13x2x7/CC13x4 linker command files
for all supported LaunchPad boards. Add the OpenCSMP 01.00 open-source
manifest HTML required for the public release. Rename the Vendors/TI
directory to Vendors/ti to match the lowercase convention used across
the rest of the repository.

Files updated:
- Vendors/TI/application/sntp_sync.{c,h}
- osal/ti_simplelink_wisun/osal_platform_types.h
- osal/ti_simplelink_wisun/osal_ti_simplelink_wisun.c
- sample/tlvs/ti_simplelink_wisun_tlvs.c
- LP_CC1312R7, LP_EM_CC1314R10, LP_EM_CC1354P10_{1,6} .cmd files
- Vendors/TI/OpenCSMP_01.00_manifest.html (new)
- Vendors/TI/ renamed to Vendors/ti/ (all 41 files, case correction)

JIRA: WISUN-1211

Signed-off-by: Aryan Arora <a-arora@ti.com>
* ti: add license headers, update copyright year, rename Vendors/TI to ti

Add missing TI Text license headers to TI Wi-SUN platform source
files that were previously shipped without them. Also bump the copyright
end-year from 2025 to 2026 in the CC13x2x7/CC13x4 linker command files
for all supported LaunchPad boards. Add the OpenCSMP 01.00 open-source
manifest HTML required for the public release. Rename the Vendors/TI
directory to Vendors/ti to match the lowercase convention used across
the rest of the repository.

Files updated:
- Vendors/TI/application/sntp_sync.{c,h}
- osal/ti_simplelink_wisun/osal_platform_types.h
- osal/ti_simplelink_wisun/osal_ti_simplelink_wisun.c
- sample/tlvs/ti_simplelink_wisun_tlvs.c
- LP_CC1312R7, LP_EM_CC1314R10, LP_EM_CC1354P10_{1,6} .cmd files
- Vendors/TI/OpenCSMP_01.00_manifest.html (new)
- Vendors/TI/ renamed to Vendors/ti/ (all 41 files, case correction)

JIRA: WISUN-1211
Signed-off-by: Aryan Arora <a-arora@ti.com>

* ti: fix CoAP sendmsg truncation and reject unsupported backup image

osal_sendmsg() only forwarded the first iovec, truncating CoAP
responses that carry a token or body. It now flattens all iovecs
into one buffer before sending.

osal_copy_firmware() falsely reported success for SetBackupRequest
even though BACKUP_IMAGE has no storage backing on this platform.
It now returns OSAL_FAILURE so backup requests are rejected instead
of silently faking completion.

JIRA: WISUN-1211
Signed-off-by: Aryan Arora <a-arora@ti.com>

---------

Signed-off-by: Aryan Arora <a-arora@ti.com>
osal_socket_close() was missing for ti_simplelink_wisun after
rebasing on upstream, which added the OSAL socket-close abstraction
and switched coapclient.c/coapserver.c to call it instead of raw
close(). Implemented it using nanostack's socket_close(), tracking
the server and client channel open state independently since they
open and close in either order and share one physical socket.

Also corrects leftover Vendors/TI path references in board
makefiles, the target file, and README that should have used the
lowercase Vendors/ti directory name.

JIRA: WISUN-1211
Signed-off-by: Aryan Arora <a-arora@ti.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

osal OS Abstraction Layer TI Texas Instruments | ti.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants