Skip to content

SDK Upgrade Manifest (.slcu)

The SDK upgrade manifest file has the .slcu extension. It describes transformations to be performed on projects to make them compatible with a later version of the SDK.

An upgrade manifest consists of an object with a single top-level property upgrade. This property contains an array, where each item corresponds to a single upgrade transformation from one SDK/Extension version to another. The target SDK/Extension version is given by the sdk property, while the source SDK/Extension version is implicit, and will vary depending on whether the previous SDK/Extension or any intermediate SDK/Extension required any upgrade rules to be defined.

For the SDK itself, the sdk field in the .slcp is used to determine the source sdk id and version. For any extensions being upgraded, the sdk_extension listing in the .slcp is used per extension being upgraded to determine which upgrade rules are applicable.

Status Types

Upgrade rules that take a status field will default to automatic if not supplied. The meanings of each status is defined below:

Status Description
nothing No action was actually taken. This rule is purely an informational (like triggering on the presence of a component just to say something about it for the new sdk.)
automatic This rule performs actions of which the only thing to communicate to the customer is 'what we did'.
user_verification This rule performs an action that could have consequences that cannot be worked around easily, but would not go as far as to completely break a customer project. It signals to the UX to draw more attention to the situation, via a warning and not a standard informational, before clarifying their intentions.
impossible This rule only exists to tell a customer they should really not upgrade their project to a new sdk. For instance, an entire suite of components have been removed and there is no replacement at all. In this case, the customer would have to opt-in to forcing the upgrade anyway before they are even allowed to follow through. This will never 100% block a tool from allowing it, but the most stringent of blockades will be put up for any customer to let an upgrade go through if there are any impossible statuses.

The general UX that a tool shows based on status is determined by the worst status out of a group of rules being executed. This field is entirely about helping to communicate to tooling how to interpret certain rules and has no bearing on their execution, only the hoops a customer has to go through to execute them at all.

Sdk Key

The sdk key, as defined earlier, can refer to either an sdk or an extension.

Key Description
id Id of the sdk or extension this upgrade is applicable to
version Version of the sdk or extension this upgrade is applicable to

Component upgrade

The "component" property contains a list of component upgrades. A declarative upgrade has the format

Property Required Type Description
trigger Yes string Rule is triggered if component with this ID is present in the project
description Yes string Description of the upgrade rule, to be shown to the user
status No enum One of nothing, automatic, user_verification, impossible. If this upgrade rule is triggered, this status will affect the UX. See above table for what each enum is semantically intended to mean.
remove No list[string] List of components to remove if rule is triggered. Typically includes the trigger component.
add No list[string] List of components to add if rule is triggered.

A scripted upgrade has the format

Property Required Type Description
script Yes string Path to the upgrade script relative to the upgrade manifest file
description Yes string Description of the upgrade rule, to be shown to the user

Configuration upgrade

The "configuration" property contains a list of configuration upgrades. A declarative upgrade has the format

Property Required Type Description
name Yes string Configuration option to replace
replacement Yes string New configuration option name
value No map[string,string] Map of replacement options where the key is the old configuration value and the value is the new configuration value
description Yes string Description of the upgrade rule, to be shown to the user
status No enum One of nothing, automatic, user_verification, impossible. If this upgrade rule is triggered, this status will affect the UX. See above table for what each enum is semantically intended to mean.

A scripted upgrade has the format

Property Required Type Description
script Yes string Path to the upgrade script relative to the upgraded manifest file
description Yes string Description of the upgrade rule, to be shown to the user

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
upgrade:
  # Upgrade to SDK 3.0.1
  - sdk:
      id: gecko_sdk
      version: "3.0.1"
    component:
      # Example declarative rule to perform simple component replacement
      - trigger: component_a
        description: >
          Component A has been separated into Component X and Component Y.
        remove:
          - component_a
        add:
          - component_x
          - component_y
      # Example scripted rule to perform advanced transformation, e.g. inspecting config
      - script: upgrade_component_b.lua
        description: >
          Component B has been overhauled by doing X, Y and Z.
    configuration:
      # Example declarative rule to perform simple config rename, with optional value remapping
      - name: C_FOO
        replacement: D_FOO
        value:
          C_FOO_ONE: D_FOO_ONE
          C_FOO_TWO: D_FOO_TWO
        description: C_FOO is no longer used due to changes in F_SHARP. Usage of standard C_FOO values are updated to refer to the new D_FOO ones.
        status: user_verification
      # Example scripted rule to perform advanced config change
      - script: upgrade_config_c.lua
        description: Some very important details about what that lua script actually does.
  # Upgrade to SDK 3.1.0
  - sdk:
      id: gecko_sdk
      version: "3.1.0"
    component:
      - trigger: component_x
        description: >
          Component X has been renamed Component F.
        remove:
          - component_x
        add:
          - component_f
    configuration:
      - name: X_BAR
        replacement: F_BAR
        description: Replaces X_BAR with F_BAR 
      - script: upgrade_config_x.lua
        description: If using config D under situation A, applies fix L to config E to workaround the change using K.

Upgrade Scripts

Scripted upgrades are performed by calling Lua scripts implementing component upgrades, configuration upgrades, or both.

Namespaces

Global (SLC)

The SLC namespace provides functions to work on the project that is being upgraded. It has the following interface:

Method Arguments Return Type Description
component id (string) ID of component Component Returns a component object representing the component.
config id (string) - ID of configuration option Configurable Returns a Configurable object representing the configuration, or nil if not defined.
component_selected id (string) ID of component bool Returns true if the given component is selected in the project. Implementations should also allow is_selected as an alias for consistency with the Validation API.
is_provided id (string) Name of provide bool Returns true if the given feature is provided in the project.

Component

The component object represents a component from the SDK. It has the following interface:

Member Type Description
id string The ID of the component
label string The display name of the component
instances list[string] List of selected instances in the active project if the component is instantiable.
is_instantiable bool True if the given component is instantiable.

Configurable

Member Type Description
id string Returns the name of the configuration option, i.e. <id> from #define <id> if the option is a CMSIS annotated configuration macro
value string Returns the current value of the configuration option

Generic Upgrade Script Return Type

Both component and configuration upgrade scripts return different values, since they modify different things. However, it may come up that a script finds that it actually cannot perform an upgrade correctly. For both configuration and component upgrade scripts, it is possible to instead return an object that includes ONLY a description and status. This effectively becomes a 'user alert' that specifies either some basic information they should be aware of, or more likely that this particular configuration for their particular project simply cannot be upgraded at all.

Key Type Mandatory Description
status enum Yes One of nothing, automatic, user_verification, impossible. This return value affects UX presentation -- see above status table for more information.
description string Yes A reason why the upgrade could not be performed, or some additional information a user should be aware of about why an upgrade couldn't be more properly done.

Component Upgrade Script

The component upgrade script is a Lua script. It returns a table of change actions to perform on the project.

A project change action is a table with the following data:

Key Type Mandatory Description
component string Yes ID of the component whose state should be modified in the project.
action string Yes One of "add" or "remove", to add or remove the component from the project.
instance list[string] No List of instance names to modify. If component is instantiable and this is not given for a "remove" action, all instances will be removed.
status enum No One of nothing, automatic, user_verification, impossible. This return value affects UX presentation -- see above status table for more information.
description string No If present, provides a description of what this change ended up doing.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
local changeset = {}

if slc.is_selected('foo') then
  -- Replace foo with bar
  table.insert(changeset, {
    ['component'] = 'foo',
    ['action'] = 'remove',
  })
  table.insert(changeset, {
    ['component'] = 'bar',
    ['action'] = 'add',
  })
end

if slc.config('FOO_OPTION').value == '42' then
  -- Add the 'one' and 'two' instances of baz if FOO_OPTION is 42
  table.insert(changeset, {
    ['component'] = 'baz',
    ['instance'] = {'one', 'two'},
    ['action'] = 'add'
  })
end

if slc.is_selected('quux') and slc.component('quux').instances['cake'] then
  -- Remove the 'cake' instance of quux, leaving other instances alone
  table.insert(changeset, {
    ['component'] = 'quux',
    ['instance'] = {'cake'},
    ['action'] = 'remove'
  })
end

return changeset

Configuration Upgrade Script

The configuration upgrade script implements a function def configuration_upgrade(project), where project is an instance of Project representing the project being upgraded. The function returns a list of change actions to perform on the project.

A configuration change action is a map with the following data, containing keys from either A or B:

Key Type Mandatory Description
option string Always Configuration option to modify
action string A Value of "remove" to remove the configuration option from the project
value string B Set the value of the configuration option to this.
status enum No One of nothing, automatic, user_verification, impossible. This return value affects UX presentation -- see above status table for more information.
description string No If present, provides a description of what this change ended up doing.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
local changeset = {}

local old_config = slc.config('FOO_OPTION')

if (old_config ~= nil) then
  -- FOO_OPTION had a non-default value
  table.insert(changeset, {
    ['option'] = 'FOO_OPTION',
    ['action'] = 'remove'
  })
  table.insert(changeset, {
    ['option'] = 'BAR_OPTION',
    ['value'] = tostring(tonumber(old_config.value) * 3)
  })
else 
  if slc.is_selected('foo') then
    -- The 'foo' component is present, but had a default value for FOO_OPTION
    -- The new 'bar' defaults deviate from the foo defaults, so we need to explicitly set them
    table.insert(changeset, {
      ['option'] = 'BAR_OPTION',
      ['value'] = '62'
    })
  end
end

return changeset
Back to top