• MACHINE DRIVER: Getting Started


OVERVIEW


This blog uses a simplified example that utilizes the Machine Driver feature on neqto:, focusing on its technical aspects to help you get started.

With the Machine Driver feature on neqto:, users can deploy firmware updates to their neqto: integrated devices remotely.

EXAMPLE


To explain how Machine Driver works, this simple example uses an Nvidia Jetson Nano as a component device connected to a neqto: Bridge. The data is transferred using UART over USB. The setup is as follows:

  • The Nvidia Jetson Nano is connected to the neqto: Bridge via its I/O board USB port (the UART interface of the neqto: Bridge module is connected to the USB terminal of the neqto: Bridge I/O board via a USB serial conversion IC).
  • Note: Other common interfaces like (UART, RS232, RS485, SPI, and I2C) can also be used
  • A camera is connected to the Nvidia Jetson Nano which is configured to take pictures with a frequency defined as one picture per second in a 'firmware' file.
  • The objective is to increase the frequency of this operation to two pictures per second.

HOW MACHINE DRIVER OPERATES


The user can upload the new firmware files on the cloud conveniently using the neqto: Console or the neqto: API along with a configured JavaScript script, fup.js.

When the user gives the Machine Driver command from the console, the main script (run.js) is halted and the fup.js script is downloaded from the cloud. Then, the fup.js script initiates the download of the new firmware, and writes it to the device (component).

CODE


The following scripts are required to execute Machine Driver on Nvidia Jetson Nano.

Files on the Bridge

firmware.py - The new firmware
  • This is the new firmware that the user wants to flash onto their device.
                  frequency=2
                
fup.js - The file that handles FOTA
  • This file does the following in sequential order:
    • reads the binary contents of the firmware file
    • converts the contents to string format
    • sends the converted data to the connected device via the communication protocol
    • returns the result to the cloud
                  // ----------------------------------------------------------------
                  // UART
                  // ----------------------------------------------------------------
                  nqEx.enUART(true);
                  var uart = new UART(2);
                  var BAUDRATE = 921600; //device baudrate.
                  uart.open(BAUDRATE, false, 0);

                  // Sending function - send converted data to the connected device via the UART communication protocol
                  var uart_sendData = function (data) {
                      uart.send(data + '\n', false);
                      // print(new Date().toString() + ': UART Sent | ' + data);
                  };

                  //----------------------------------------------------------------
                  // FOTA Object - only one file per object
                  //----------------------------------------------------------------
                  var fota = new nqFOTA('firmware.py');

                  // Conversion function - converts the contents to string format
                  var bin2string = function(ab) {
                      var ret_str = '';
                      uint8_a = new Uint8Array(ab);
                      for (var i = 0; i < uint8_a.length; i++) {
                          ret_str += (String.fromCharCode(uint8_a[i]));
                      }
                      return ret_str;
                  }

                  // Update function - reads and calls the conversion and sending functions
                  var updateReading = function (custom_func) {
                      uart_sendData("--FOTA START--");
                      var buff = fota.binRead(); // reads the contents of the firmware file
                      while (buff != null) {
                          uart_sendData(bin2string(buff));
                          buff = fota.binRead();
                      }
                      uart_sendData("--FOTA END--");
                      return 1;
                  }

                  //----------------------------------------------------------------
                  // Main
                  //----------------------------------------------------------------
                  var dl_data_len = fota.fileDownload(); // download the firmware file from the cloud
                  if (dl_data_len > 0) {
                      var result = updateReading(send_string); // the result
                      if (result != 1) { // send result to cloud
                          fota.reportResult('UPDATE FAILED ', TARGET_VER);
                      } else {  //success
                          fota.reportResult('UPDATE SUCCESSFUL ', TARGET_VER);
                      }
                  }

                  //----------------------------------------------------------------
                  // Termination
                  //----------------------------------------------------------------
                  uart.close();
                

Files on Jetson Nano

firmware.py - The old firmware
  • This is the old firmware that needs to be upgraded.
                  frequency=1
                
program.py - A file dependent on the firmware settings
  • This is an example file that is dependent on the firmware settings.
                  import firmware
                  take_picture(firmware.frequency)
                
fota_daemon.py - A file that receives data from the neqto: Bridge on Machine Driver
  • On the component side, a daemon is required that can recognize that the neqto: Bridge is initiating FOTA (and the settings of the FOTA request), and then proceed to decode and write the contents received over UART to the specified location.
  • Additionally, the handler should be able to know when the FOTA request has ended. On completion, the main program is resumed.
                  import serial
                  ser = serial.Serial('/dev/ttyUSB0', 921600)
                  fota = False
                  while(True):
                      data = ser.readline()[:-1].decode()
                      if data == "--FOTA START--":
                          fota = True
                          firmware = open("firmware.py", 'w+')
                      if data == "--FOTA END--":
                          fota = False
                          firmware.close()
                      if fota and data != "--FOTA START--":
                          firmware.write(data)
                

CONCLUSION


This simple example shows the simplicity of Machine Driver to update the firmware remotely with the click of a button.

With neqto:, debugging and repair during system failures can be monitored and resolved with minimal effort, saving precious time and money. Also, with advancement in technology, devices need firmware upgrades to keep up in terms of security, features, etc.; neqto: can enable the user to deliver these updates using Machine Driver.

A number of sectors will benefit from this feature. For instance, in the automobile industry, modern cars are built around the idea of automatic/remote control and come with some important features like over-the-air (OTA) updates. This allows manufacturers to update the car firmware to deploy security updates and new software features remotely. However, for already-existing designs and entry-level automobiles these features can be difficult and expensive to develop and integrate. For such cases, with its ability to integrate on top of existing systems, neqto: easily enables OTA firmware updates using its Machine Driver feature.

In future blogs we will talk in detail about more use cases and how neqto: raises the bar for IoT by closely integrating with these devices.

↑ TOP