PEmicro Blog

Cyclone Control SDK: Automated Flash Programming with Rust

Jul 01, 2024

The Cyclone Control SDK is a software development kit with a comprehensive API that allows developers to seamlessly integrate Cyclone LC and Cyclone FX programmers into their applications. They can manipulate SAP images, launch SAP images, retrieve programming results, and update settings. This blog post demonstrates the use of the SDK in a Rust application.

NOTE: The examples in this blog post are developed in Rust. The Cyclone Control SDK also includes interface code and example applications for GCC, Microsoft Visual C, Microsoft Visual C#, Delphi/FPC, Python, Labview, and Microsoft Visual Basic.

Cyclone Control Suite: Cyclone Control SDK

The Cyclone Control SDK is one of the three main components of the Cyclone Control Suite

The Cyclone LC and Cyclone FX user manuals contain detailed descriptions of the Cyclone Control SDK application programming interface.

Contents

What files are provided?

Introduction to the Rust Interface

Example - Connecting to a Cyclone

Example - Managing SAP Images

Example - Launching a SAP Image

Example - Gang Operation of Multiple Cyclones

Example - Serial Numbers, Dynamic Data, and Overlay Data

Example - Reading and Writing Properties

Using api_example.rs

Cyclone Control SDK and Licensing

Conclusion

--------------------------------------------------------------------------------------------

What files are provided?

The following files are provided by the Cyclone Control SDK as part of the Cyclone installation software. They are all elements of a Rust Cargo package (simply named “rust”).

  • Rust interface (cyclone_control_sdk.rs)

  • Interface constants (cyclone_control_sdk_constants.rs)

  • Example application (api_example.rs)

Introduction to the Rust Interface

This article assumes that the reader is already familiar with the process of creating stand alone programming (SAP) images. If not, the reader should please refer to the Image Creation Utility section of the Cyclone user manual.

The Rust interface and example application are developed using 64-bit Rust Version 1.78.0. The example application is written for Windows.

NOTE: The libloading crate should be imported into the Cargo.toml file for this demonstration application.

The user creates a CycloneControlSDK object to load the DLL and gain access to its exported functions.

       let cyclone_control_sdk_obj = CycloneControlSDK::new();

As functions are members of the struct, you can access each function with the syntax cyclone_control_sdk_obj.function_name() after the DLL is successfully loaded.

It is highly recommended that, after creating the object, all CycloneControlSDK code is written in an if block with the conditional statement:

       if cyclone_control_sdk_obj.check_lib_loaded()

After that, the first step is to scan and initialize all the Cyclones connected to your ports.

       cyclone_control_sdk_obj.enumerateAllPorts();

Then it is possible to connect to a Cyclone to erase SAP images, add SAP images, start programming, retrieve error codes, and to perform any other functionality provided by the SDK. When the program is complete, the DLL can be unloaded from memory.

       cyclone_control_sdk_obj.unloadLibrary();

Example - Connecting to a Cyclone

The user can connect to a single Cyclone using the connectToCyclone() function, which returns a handle that identifies the Cyclone in all subsequent function calls. A typical way to do this is to connect to the Cyclone by its name (“Fixture1Cyclone1”).

       let handle = cyclone_control_sdk_obj.connectToCyclone(“Fixture1Cyclone1”). 

The Cyclone can also be opened by its port number, also known as port identifier, ("USB1", "ETHERNET1", or "COM1") or the IP address ("192.168.1.10") of the Cyclone if the connection is Ethernet. There is no guarantee that a Cyclone will always enumerate with the same port number. When managing multiple units, we recommend identifying them by name or IP address. 

NOTE: Any Cyclones that fail to connect will have the handle 0.

Example - Launching a SAP Image

For this example, the user will connect to a Cyclone and execute a SAP image that has been configured with the Image Creation utility.

  1. Open the desired Cyclone by specifying its name (“Fixture1Cyclone1”).

  2. Send a command to the Cyclone to begin the programming operations specified in image with ID# 1.

  3. Wait for the Cyclone to complete the programming operations before proceeding.

  4. Check to see if any errors occurred during programming and display the error code.

  5. Terminate connection to Cyclone.

Example - Managing SAP Images

For this example, the user will connect to a Cyclone and add a SAP image that has been configured with the Image Creation utility

  1. Open the desired Cyclone by specifying its name (“Fixture1Cyclone1”).

  2. Compare the SAP file ("C:\PEmicro\cyclone\workspace\KL25Z128.SAP") with image ID# 1.

  3. If the image is different, erase image ID#1.

  4. Add the new image to the Cyclone.

  5. Check to see if any errors occurred while adding the image and display the error code.

Example - Gang Operation of Multiple Cyclones

The discussion has been on how to control a single Cyclone up to this point. Since the host PC only sends a minimal amount of control data, it is capable of controlling multiple Cyclones simultaneously.

The user can connect to multiple Cyclones using the connectToMultipleCyclones() function. This function takes two parameters. The first is a &str list of Cyclone names, port identifiers, or IP addresses separated by commas, and the second is a mutable vector that will hold the handles of the Cyclones. 

NOTE: The Cyclone handle array is cleared when this function is called.

For this example, the user will connect to 3 separate Cyclone units. The same SAP image (although they could be different) is added to each Cyclone and then programming is started simultaneously. The loop waits for their completion before proceeding to check for errors. This setup can be extended simultaneously to many Cyclones on a network. 

Example - Serial Numbers, Dynamic Data, and Overlay Data

The SDK can also program dynamic data such as serial numbers, manufacturing dates, encryption keys, etc. after the static data has been programmed by the SAP image. In this example, the application calls the startDynamicDataProgram() function to program a 3 byte serial number.

Note: The following are placeholder functions used to simplify the example, and are not provided by the automated control package:

  • get_serial_from_file

  • increment_serial_number

  • save_serial_back_to_file

Similar to the first example, the application connects to one Cyclone and executes a SAP image. After the programming is finished, the error code is checked. Then a serial number array (or vector) is created with getSerialNumberFromFile(). The array/vector is turned into a byte slice to pass to startDynamicDataProgram() and programmed to address 0x2100 of the target. The serial number is then incremented and written back to the file.

  1. Open the desired Cyclone by specifying its name (“Fixture1Cyclone1”). 

  2. Send a command to the Cyclone to begin the programming operations specified in image with ID# 1.

  3. Wait for the Cyclone to complete the programming operations before proceeding.

  4. Check to see if any errors occurred during programming and display the error code.

  5. Retrieve serial number and program dynamic data array.

  6. Check to see if any errors occurred during serialization and display the error code.

  7. Increment and save the new serial number.

A similar outcome is achieved using overlay data. Overlay data must be programmed prior to image execution and launch.

Example - Reading and Writing Properties

Your Cyclone and its resident SAP images have settings, configuration, and other information stored as properties. The getPropertyList() function returns a list of properties that are available for a category. Properties can be viewed with the getPropertyValue() function. Some properties can also be modified with the setPropertyValue() function.

In this example, the user will connect to a Cyclone, get a list of CycloneProperties, retrieve the nameProperty, and then change the name of the Cyclone.

Using api_example.rs

The api_example.rs application shows the usage of the Rust interface. Many of the typical functions that the user will need are already implemented, such as connecting to a Cyclone, adding a SAP image, retrieving a list of SAP images, launching a SAP image, programming dynamic data, programming overlay data, resetting the cyclone, and more. The application can be further modified to suit specific needs.

NOTE: To experiment with the Rust interface, this application cannot be run using the "cargo run" command line. After compiling the application using the "cargo build" command line, move into the "target" directory, and then the "debug" directory. Then, simply call ".\rust.exe" and any other command line parameters.

Cyclone Control SDK and Licensing

The examples shown here use a mix of standard and advanced features of the SDK. The standard features of the SDK will work with any Cyclone unit, regardless of model or purchase date (no license required). The advanced features of the SDK require a Cyclone FX programmer (no license required) or a Cyclone LC programmer with the Advanced Control License.

Conclusion

Rust is a fast growing language, especially in the world of embedded systems. We anticipate that the addition of this Rust interface and project to the Cyclone Control SDK will allow developers to decrease their development time and bring their production online much more quickly.


NOTE: Developers wishing to use the cycloneSpecialFeatures() function must implement it themselves.

Tags related to this Blog Post

Cyclone     Cyclone FX     ARM     NXP     Production Programming     Automated Control