Skip to content

Commit

Permalink
[TI] CC13xx Factory Data Tool (#31117)
Browse files Browse the repository at this point in the history
* dac tool functionally working for cc13x2 and cc13x4

* updated documentation, added dac tool to all examples

* removed old memmap image

* code clean up

* updated cc13x4 memmap

* more code cleanup

* added in Thor modifications to oad and factory data merge tool python script

* ti_simplelink_executable.gni fix

* factory data overlap in ota merge tool fixed

* added debug statement in ti simplelink exec

* added in custom factory data flag to pump controller

* added public creds header files

* code review updates and cc13x2 em file fix

* fixed pump controller app build issues when using factory data

* added back in ota linker file for cc13x4

* spelling fixes

* Restyled by whitespace

* Restyled by clang-format

* Restyled by prettier-markdown

* Restyled by autopep8

* Restyled by isort

* spelling fix

* Restyled by prettier-markdown

* pr review feedback

* Restyled by clang-format

* more pr feedback

* empty commit

---------

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Apr 16, 2024
1 parent 8dce480 commit 4660035
Show file tree
Hide file tree
Showing 81 changed files with 2,556 additions and 1,285 deletions.
Binary file added docs/guides/ti/images/cc13x2_memmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/guides/ti/images/cc13x4_memmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/guides/ti/images/factory_data_overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 127 additions & 0 deletions docs/guides/ti/ti_factory_data_user_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Texas Instruments Matter Factory Data Programming User Guide

This document describes how to use the factory data programming feature for
Matter example applications from Texas Instruments.

## Background

The Matter specification lists various information elements that are programmed
at the factory. These values do not change and some are unique per device. This
feature enables customers developing Matter products on TI devices to program
this data and use this as a starting point towards developing their factory
programming infrastructure for their Matter devices.

## Solution Overview:

TI Matter examples allow the use of factory data in the following two ways:

- **Example Out of Box Factory Data** : Use TI example DAC values to get
started. This is intended to be used when just starting with Matter or
during development until customer or product specific data is not required.
- **Custom factory data** : Allows users to configure custom factory data via
a JSON file. The custom values are then processed by a script provided by TI
and merged with the Matter application to create a binary that can be
flashed on to devices.

### Solution Block Diagram

![Block Diagram](images/factory_data_overview.png)

Each element is described in more detail below:

1. Factory Data JSON: This file is located at src/platform/cc13xx_26xx.
Developers can configure this per device. Elements in this file are from the
specification.
2. Matter Application with dummy factory data: Any TI Matter example application
3. `BIM`/MCUBoot: Boot Image Manager/MCUBoot image used for OTA. This is built
with the Matter application and does not require additional build steps from
developers.
4. create_factory_data.py: Processes a factory data JSON file and generates a
hex file with the unique factory data values configured in the JSON file.
5. factory_data_trim.py: When using the custom factory data option, this script
removes the dummy factory data which is required to be able to successfully
compile the application.
6. `oad`\_and_factory_data_merge_tool.py: Merges the factory data hex, Matter
application without factory data and `BIM`/MCUBoot image to generate a
functional hex that can be programmed onto the device.

## Flash memory layout

![Memory Layout 1](images/cc13x2_memmap.png)

![Memory Layout 2](images/cc13x4_memmap.png)

## How to use

Out of box factory data location is configured to be on second last page of
flash. For CC13x2, the starting address is `0xAC000`. For CC13x4, the starting
address is `0xFE800`. This can be configured in the linker file.

To configure:

1. Linker file: Set the start address for factory data in the linker file being
used by the application

```
FLASH_FACTORY_DATA (R) : ORIGIN = 0x000ac000, LENGTH = 0x00000900
```

```
/* Define base address for the DAC arrays and struct */
PROVIDE (_factory_data_base_address =
DEFINED(_factory_data_base_address) ? _factory_data_base_address : 0xAC000);
```

2. create_factory_data.py: Set the address of the start of the factory data
elements. Refer to the comments in the script.

```
# there are 17 elements, each element will need 8 bytes in the struct
# 4 for length of the element, and 4 for the pointer to the element
# factory data starts at 0xAC000 or 0xFE800, so the elements will
# start 136 bytes after the start address
factory_data_dict = json.load(args.factory_data_json_file[0])
factory_data_schema = json.load(args.factory_data_schema[0])
validate(factory_data_dict, factory_data_schema)
factory_data = factory_data_dict['elements']
struct_idx = 0
values_idx = 0
if device_family == 'cc13x2_26x2':
value_address = 0xAC088
else:
value_address = 0xFE888
```

```
if device_family == 'cc13x2_26x2':
subprocess.call(['objcopy', 'temp.bin','--input-target','binary','--output-target', 'ihex', args.factory_data_hex_file, '--change-addresses=0xac000'])
else:
subprocess.call(['objcopy', 'temp.bin','--input-target','binary','--output-target', 'ihex', args.factory_data_hex_file, '--change-addresses=0xfe800'])
```

3. In the example's args.gni file, set 'custom_factory_data' to true

It is recommended to keep a dedicated page (2 pages for CC13x4) for factory
data.

### Formatting certs and keys for JSON file

To format the DAC, private key and PAI as hex strings as shown in the Factory
Data JSON file, use the chip-cert tool located at src/tools/chip-cert and run
the _convert-cert_ command, and list -X, or X.509 DER hex encoded format, as the
output format. These strings can then be copied into the JSON file.

The SPAKE parameters should be converted from base-64 to hex as well before
being copied into the JSON file.

### Creating images

The example application can be built using the instructions in the example's
README. The factory data from the JSON file will be formatted into a hex file
that will then be merged into the final executable. The final executable will be
named _{example-application}-`bim`.hex_ for CC13x2 and
_{example-application}-mcuboot.hex_ for CC13x4, and the factory data that was
inputted into the JSON file will be named
_{example-application}-factory-data.hex_.
4 changes: 4 additions & 0 deletions examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ ti_simplelink_executable("all-clusters-app") {
deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ]
}

if (custom_factory_data) {
defines = [ "CC13XX_26XX_FACTORY_DATA" ]
}

include_dirs = [
"${project_dir}",
"${project_dir}/main",
Expand Down
2 changes: 2 additions & 0 deletions examples/all-clusters-app/cc13x2x7_26x2x7/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ matter_device_vid = "0xFFF1"
matter_device_pid = "0x8006"
matter_software_ver = "0x0001"
matter_software_ver_str = "1.0d1"

custom_factory_data = true
16 changes: 13 additions & 3 deletions examples/all-clusters-app/cc13x2x7_26x2x7/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ int AppTask::Init()
;
}

// Initialize device attestation config
#ifdef CC13X2_26X2_ATTESTATION_CREDENTIALS
#ifdef CC13XX_26XX_FACTORY_DATA
SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
SetCommissionableDataProvider(&mFactoryDataProvider);
#else
SetDeviceAttestationCredentialsProvider(CC13X2_26X2::GetCC13X2_26X2DacProvider());
#endif
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

ret = PlatformMgr().StartEventLoopTask();
if (ret != CHIP_NO_ERROR)
{
Expand Down Expand Up @@ -259,9 +272,6 @@ int AppTask::Init()

ConfigurationMgr().LogDeviceConfig();

// Initialize device attestation config
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());

// We only have network commissioning on endpoint 0.
emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include <ti/drivers/apps/Button.h>

#ifdef CC13XX_26XX_FACTORY_DATA
#include <platform/cc13xx_26xx/FactoryDataProvider.h>
#endif

class AppTask
{
public:
Expand Down Expand Up @@ -62,6 +66,10 @@ class AppTask
bool mFunctionTimerActive;

static AppTask sAppTask;

#ifdef CC13XX_26XX_FACTORY_DATA
chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider;
#endif
};

inline AppTask & GetAppTask(void)
Expand Down
4 changes: 4 additions & 0 deletions examples/all-clusters-app/cc13x4_26x4/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ ti_simplelink_executable("all-clusters-app") {
deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ]
}

if (custom_factory_data) {
defines = [ "CC13XX_26XX_FACTORY_DATA" ]
}

include_dirs = [
"${project_dir}",
"${project_dir}/main",
Expand Down
2 changes: 2 additions & 0 deletions examples/all-clusters-app/cc13x4_26x4/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ matter_device_vid = "0xFFF1"
matter_device_pid = "0x8006"
matter_software_ver = "0x0001"
matter_software_ver_str = "1.0.1+1"

custom_factory_data = true
20 changes: 13 additions & 7 deletions examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@ int AppTask::Init()
;
}

// Initialize device attestation config
#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS
#ifdef CC13XX_26XX_FACTORY_DATA
SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
SetCommissionableDataProvider(&mFactoryDataProvider);
#else
SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider());
#endif
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

// Init ZCL Data Model and start server
PLAT_LOG("Initialize Server");
static chip::CommonCaseDeviceServerInitParams initParams;
Expand All @@ -259,13 +272,6 @@ int AppTask::Init()

ConfigurationMgr().LogDeviceConfig();

// Initialize device attestation config
#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS
SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider());
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

// We only have network commissioning on endpoint 0.
emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);

Expand Down
8 changes: 8 additions & 0 deletions examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include <ti/drivers/apps/Button.h>

#ifdef CC13XX_26XX_FACTORY_DATA
#include <platform/cc13xx_26xx/FactoryDataProvider.h>
#endif

class AppTask
{
public:
Expand Down Expand Up @@ -62,6 +66,10 @@ class AppTask
bool mFunctionTimerActive;

static AppTask sAppTask;

#ifdef CC13XX_26XX_FACTORY_DATA
chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider;
#endif
};

inline AppTask & GetAppTask(void)
Expand Down
4 changes: 4 additions & 0 deletions examples/lighting-app/cc13x2x7_26x2x7/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ ti_simplelink_executable("lighting_app") {
deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ]
}

if (custom_factory_data) {
defines = [ "CC13XX_26XX_FACTORY_DATA" ]
}

include_dirs = [
"${project_dir}",
"${chip_root}/examples/providers/",
Expand Down
2 changes: 2 additions & 0 deletions examples/lighting-app/cc13x2x7_26x2x7/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ matter_device_vid = "0xFFF1"
matter_device_pid = "0x8005"
matter_software_ver = "0x0001"
matter_software_ver_str = "1.0d1"

custom_factory_data = true
20 changes: 13 additions & 7 deletions examples/lighting-app/cc13x2x7_26x2x7/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@ int AppTask::Init()
;
}

// Initialize device attestation config
#ifdef CC13X2_26X2_ATTESTATION_CREDENTIALS
#ifdef CC13XX_26XX_FACTORY_DATA
SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
SetCommissionableDataProvider(&mFactoryDataProvider);
#else
SetDeviceAttestationCredentialsProvider(CC13X2_26X2::GetCC13X2_26X2DacProvider());
#endif
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

ret = ThreadStackMgr().InitThreadStack();
if (ret != CHIP_NO_ERROR)
{
Expand Down Expand Up @@ -226,13 +239,6 @@ int AppTask::Init()

Server::GetInstance().Init(initParams);

// Initialize device attestation config
#ifdef CC13X2_26X2_ATTESTATION_CREDENTIALS
SetDeviceAttestationCredentialsProvider(CC13X2_26X2::GetCC13X2_26X2DacProvider());
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

// Initialize LEDs
PLAT_LOG("Initialize LEDs");
LED_init();
Expand Down
8 changes: 8 additions & 0 deletions examples/lighting-app/cc13x2x7_26x2x7/src/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include <ti/drivers/apps/Button.h>

#ifdef CC13XX_26XX_FACTORY_DATA
#include <platform/cc13xx_26xx/FactoryDataProvider.h>
#endif

// Application-defined error codes in the CHIP_ERROR space.
#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01)
#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02)
Expand Down Expand Up @@ -85,6 +89,10 @@ class AppTask
bool mFunctionTimerActive;

static AppTask sAppTask;

#ifdef CC13XX_26XX_FACTORY_DATA
chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider;
#endif
};

inline AppTask & GetAppTask(void)
Expand Down
4 changes: 4 additions & 0 deletions examples/lighting-app/cc13x4_26x4/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ ti_simplelink_executable("lighting_app") {
deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ]
}

if (custom_factory_data) {
defines = [ "CC13XX_26XX_FACTORY_DATA" ]
}

include_dirs = [
"${project_dir}",
"${chip_root}/examples/providers/",
Expand Down
2 changes: 2 additions & 0 deletions examples/lighting-app/cc13x4_26x4/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ matter_device_vid = "0xFFF1"
matter_device_pid = "0x8005"
matter_software_ver = "0x0001"
matter_software_ver_str = "1.0.1+1"

custom_factory_data = true
20 changes: 13 additions & 7 deletions examples/lighting-app/cc13x4_26x4/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,19 @@ int AppTask::Init()
;
}

// Initialize device attestation config
#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS
#ifdef CC13XX_26XX_FACTORY_DATA
SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
SetCommissionableDataProvider(&mFactoryDataProvider);
#else
SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider());
#endif
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

// Init ZCL Data Model and start server
PLAT_LOG("Initialize Server");
static CommonCaseDeviceServerInitParams initParams;
Expand All @@ -225,13 +238,6 @@ int AppTask::Init()

Server::GetInstance().Init(initParams);

// Initialize device attestation config
#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS
SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider());
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

// Initialize LEDs
PLAT_LOG("Initialize LEDs");
LED_init();
Expand Down
Loading

0 comments on commit 4660035

Please sign in to comment.