Difference between revisions of "Nvidia Jetson TX1 and TX2"

From ERIKA WIKI
Jump to: navigation, search
Line 9: Line 9:
 
== Platform setup ==
 
== Platform setup ==
  
Use [https://developer.nvidia.com/embedded/jetpack Nvidia Jetpack 3.1] to flash the Linux distribution by Nvidia onto the TX1 platform.<br>
+
Use [https://developer.nvidia.com/embedded/jetpack Nvidia Jetpack 3.1] to flash the Linux distribution by Nvidia onto the TX1 platform.
 
JetPack is a tool that runs on an Ubuntu host machine and installs Linux on the TX1 platform.
 
JetPack is a tool that runs on an Ubuntu host machine and installs Linux on the TX1 platform.
Note that the host machine and the platform must be connected through an OTG USB cable.
+
Note that the host machine and the platform must be connected through an OTG USB cable during flashing.
 +
 
 +
Once the platform has been flashed, refer to [https://github.com/evidence/linux-jailhouse-tx1/blob/master/README.md our README on GitHub] for connecting the serial cable and static IP configuration.
  
 
== Jailhouse support ==
 
== Jailhouse support ==

Revision as of 17:36, 12 March 2018

Introduction

The ERIKA3 RTOS can be run as a guest OS of the Jailhouse hypervisor on the Nvidia Tegra Jetson TX1 board.
Such support has been developed in the context of the HERCULES European project. It has been also shown through a YouTube video.

This section explains how to build and install Jailhouse on the TX1 target and how to create an ERIKA3 guest (AKA Jailhouse inmate).

Platform setup

Use Nvidia Jetpack 3.1 to flash the Linux distribution by Nvidia onto the TX1 platform. JetPack is a tool that runs on an Ubuntu host machine and installs Linux on the TX1 platform. Note that the host machine and the platform must be connected through an OTG USB cable during flashing.

Once the platform has been flashed, refer to our README on GitHub for connecting the serial cable and static IP configuration.

Jailhouse support

For installing Jailhouse on the TX1 platform, please refer to the README available on the Jailhouse tree on our GitHub. It also provides information about serial port and static IP configuration.

Note that the information is provided for the default Linux kernel provided by Nvidia (not Vanilla). You can refer to the original project page in case you run a Vanilla Linux kernel.

ERIKA3 on Jailhouse

Once Jailhouse has been successfully installed on the platform, you have to set-up the RT-Druid development environment and the compile the ERIKA3 RTOS.

Given the processing performance of the TX1 platform, as well as the availability of a real OS like Linux, we aim at doing a native compilation rather than a cross-compilation. Unfortunately, the Eclipse IDE requires an x86 platform with a fair amount of resources (in terms of both processing and memory). We therefore need to set-up a host-target environment, where the x86 host runs the Eclipse IDE (with the RT-Druid plugin for code generation) and the TX1 target performs the final step of compilation.

The Remote projects on RT-Druid page explains how to set-up the RT-Druid package for such an environment.

Simple example

We now illustrate how a simple example of two tasks printing a message on the serial interface can be run on the Nvidia TX1 platform.

On the target:

  1. Configure and install Jailhouse following the instructions on the README file available on the Jailhouse tree on our GitHub
  2. Get a copy the ERIKA3 RTOS from GitHub:
    $ cd /home/nvidia
    $ git clone https://github.com/evidence/erika3.git
    
  3. Create the project directory:
    $ mkdir /home/nvidia/erika3/pkg/arch/aarch64/examples/test/
    
  4. Create the /home/nvidia/erika3/pkg/arch/aarch64/examples/test/main.c file with the following content:
    #include "ee.h"
    #include <inmate.h>
    
    static volatile u32 counter = 0;
    
    DeclareTask(Task1);
    DeclareTask(Task2);
    
    /* First task */
    TASK(Task1)
    {
            GetResource(SharedUartResource);
            printk("Hello world from Task1! (%lu)\n", counter);
            counter++;
            ReleaseResource(SharedUartResource);
            TerminateTask();
    }
    
    
    /* Second task */
    TASK(Task2)
    {
            GetResource(SharedUartResource);
            printk("Hello world from Task2! (%lu)\n", counter);
            counter++;
            ReleaseResource(SharedUartResource);
            TerminateTask();
    }
    
    
    void idle_hook(void);
    
    void idle_hook(void)
    {
            /* endless loop*/
            while(1) {
                    asm volatile("wfi": : : "memory");
            }
    }
    
    
    int main(void)
    {
            printk("Starting OS...\n");
            StartOS(OSDEFAULTAPPMODE);
            return 0;
    }
    
  5. Create the /home/nvidia/erika3/pkg/arch/aarch64/examples/test/conf.oil file with the following content:
    CPU mySystem {
    
      OS myOs {
    
        /* EE_OPT = "OS_EE_VERBOSE"; */
        EE_OPT = "OSEE_DEBUG";
        EE_OPT = "OS_EE_APPL_BUILD_DEBUG";
        EE_OPT = "OS_EE_BUILD_DEBUG";
        EE_OPT = "OSEE_ASSERT";
    
        CPU_DATA = AARCH64 {
          MULTI_STACK = TRUE;
          COMPILER = GCC;
          IDLEHOOK = TRUE {
            HOOKNAME = "idle_hook";
          };
        };
    
        SOC_DATA = NVIDIA_TEGRA_X1;
    
        KERNEL_TYPE = OSEK {
          CLASS = ECC1;
        };
      };
    
      COUNTER SystemTimer {
        MINCYCLE = 1;
        MAXALLOWEDVALUE = 2147483647;
        TICKSPERBASE = 1;
        TYPE = HARDWARE {
          SYSTEM_TIMER = TRUE;
          PRIORITY     = 1;
          DEVICE       = "GTIMER";
        };
        SECONDSPERTICK = 0.001;
      };
    
      ALARM AlarmTask1 {
        COUNTER = SystemTimer;
        ACTION = ACTIVATETASK {
          TASK = Task1;
        };
        AUTOSTART = TRUE {
          ALARMTIME = 500;
          CYCLETIME = 100;
        };
      };
    
      ALARM AlarmTask2 {
        COUNTER = SystemTimer;
        ACTION = ACTIVATETASK {
          TASK = Task2;
        };
        AUTOSTART = TRUE {
          ALARMTIME = 500;
          CYCLETIME = 100;
        };
      };
    
      TASK Task1 {
        PRIORITY = 1;
        STACK = PRIVATE {
          SIZE = 1024;
        };
        SCHEDULE = FULL;
        APP_SRC = "main.c";
        RESOURCE = SharedUartResource;
      };
    
      TASK Task2 {
        PRIORITY = 2;
        STACK = PRIVATE {
          SIZE = 1024;
        };
        SCHEDULE = FULL;
        RESOURCE = SharedUartResource;
      };
    
      RESOURCE SharedUartResource { RESOURCEPROPERTY = STANDARD; };
    };
    

Then, on the host:

  1. Run Eclipse and follow the instructions at Remote projects on RT-Druid to set-up a remote project on Eclipse.
    Specify
    • /home/nvidia/erika3/pkg/arch/aarch64/examples/test/ as project directory
    • /home/nvidia/erika3/pkg/arch/aarch64/examples/test/conf.oil as oil file
  2. Generate the project configuration files from Eclipse.

Finally, on the target:

  1. Set the JAILHOUSE_DIR environment variable equal to the path where Jailhouse has been built:
    $ export JAILHOUSE_DIR=...
    
  2. Set the JAILHOUSE_VERSION environment variable equal to the Jailhouse version (e.g. 0.7):
    $ export JAILHOUSE_VERSION=...
    
  3. Enter the project directory and build the ERIKA3 binary:
    $ cd /home/nvidia/erika3/pkg/arch/aarch64/examples/test/out/
    $ make
    
  4. Create the jailhouse cell:
    $ sudo jailhouse cell create jailhouse/configs/jetson-tx1-demo.cell
    
  5. Load the ERIKA3 binary:
    $ sudo jailhouse cell load jetson-tx1-demo /home/nvidia/erika3/pkg/arch/aarch64/examples/test/out/erika_inmate.bin
    
  6. Start ERIKA3:
    $ sudo jailhouse cell start jetson-tx1-demo 
    

    On the serial console you should see the two tasks printing a "Hello world" message with a counter:

    Hello world from Task1! (1)
    Hello world from Task2! (2)
    Hello world from Task1! (3)
    Hello world from Task2! (4)
    Hello world from Task1! (5)
    Hello world from Task2! (6)