diff --git a/content/hardware/04.pro/boards/portenta-x8/essentials.md b/content/hardware/04.pro/boards/portenta-x8/essentials.md index a7593b5820..a34d4c6c3a 100644 --- a/content/hardware/04.pro/boards/portenta-x8/essentials.md +++ b/content/hardware/04.pro/boards/portenta-x8/essentials.md @@ -1,6 +1,6 @@ - - A quick guide to installing your board with the Arduino IDE. + + A full guide to the basics of the Portenta X8 This article contains information about the fundamental concepts of the Portenta X8. @@ -12,13 +12,7 @@ - Some containers examples for Portenta X8, this containers are accessible through your Foundries.io factory. - - - Releases section from the lmp-manifest repo, lists all the builds also available on the Foundries.io factory. - - - This repository contains a Repo manifest and setup scripts for the Linux microPlatform build system. If you want to modify, extend or port Linux microPlatform to a new hardware platform, this is the manifest repository to use. + Some containers examples for Portenta X8, these containers are accessible through your Foundries.io factory. diff --git a/content/hardware/04.pro/boards/portenta-x8/product.md b/content/hardware/04.pro/boards/portenta-x8/product.md index 8c9030d4d1..c669de5116 100644 --- a/content/hardware/04.pro/boards/portenta-x8/product.md +++ b/content/hardware/04.pro/boards/portenta-x8/product.md @@ -1,7 +1,7 @@ --- title: Portenta X8 url_shop: https://store.arduino.cc/portenta-x8 -url_guide: /software/ide-v1/tutorials/getting-started/cores/arduino-mbed_portenta +url_guide: /tutorials/portenta-x8/user-manual core: arduino:mbed_portenta certifications: [CE] productCode: '125' diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Docker_host.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Docker_host.png new file mode 100644 index 0000000000..4aa7ee8fc5 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Docker_host.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Embedded_Linux_Start.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Embedded_Linux_Start.png new file mode 100644 index 0000000000..13061a0c46 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Embedded_Linux_Start.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB-succesful-OS-update.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB-succesful-OS-update.png new file mode 100644 index 0000000000..109c214abe Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB-succesful-OS-update.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_alpine_shell.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_alpine_shell.png new file mode 100644 index 0000000000..dd8ebac423 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_alpine_shell.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_board_manager_factory_challenge.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_board_manager_factory_challenge.png new file mode 100644 index 0000000000..4da62e6d9f Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_board_manager_factory_challenge.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_board_manager_factory_registration.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_board_manager_factory_registration.png new file mode 100644 index 0000000000..bc3a22a8ec Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_board_manager_factory_registration.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_API_copy.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_API_copy.png new file mode 100644 index 0000000000..28167ef520 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_API_copy.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_device_name.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_device_name.png new file mode 100644 index 0000000000..8ad7e5cbd6 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_device_name.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_generate_API.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_generate_API.png new file mode 100644 index 0000000000..0e9abfd094 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_generate_API.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_organization_ID.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_organization_ID.png new file mode 100644 index 0000000000..c73776bfd8 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_organization_ID.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_success.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_success.png new file mode 100644 index 0000000000..99a8cdd223 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_cloud_success.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_example_dashboard_launch.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_example_dashboard_launch.png new file mode 100644 index 0000000000..31db7a604a Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_example_dashboard_launch.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage.png new file mode 100644 index 0000000000..944f7677f7 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_Wifi.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_Wifi.png new file mode 100644 index 0000000000..77849a2d65 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_Wifi.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_cloud.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_cloud.png new file mode 100644 index 0000000000..8bbecb5430 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_cloud.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_portenta_x8_manager.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_portenta_x8_manager.png new file mode 100644 index 0000000000..64a0be0b61 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_portenta_x8_manager.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_shell.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_shell.png new file mode 100644 index 0000000000..482a9fba0b Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_homepage_shell.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_update_select.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_update_select.png new file mode 100644 index 0000000000..7c205e6442 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_update_select.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_SSID.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_SSID.png new file mode 100644 index 0000000000..5a8641b148 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_SSID.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_connected.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_connected.png new file mode 100644 index 0000000000..4fd8e387e6 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_connected.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_selection.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_selection.png new file mode 100644 index 0000000000..1091f8892b Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/OOTB_wifi_selection.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Virtual_Machine_Containers.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Virtual_Machine_Containers.png new file mode 100644 index 0000000000..c9131e796d Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Virtual_Machine_Containers.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Yocto_Architecture.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Yocto_Architecture.png new file mode 100644 index 0000000000..82b7a55a35 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/Yocto_Architecture.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-connection.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-connection.png new file mode 100644 index 0000000000..19ed480460 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-connection.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-command.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-command.png new file mode 100644 index 0000000000..3707bbdadd Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-command.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-os-release.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-os-release.png new file mode 100644 index 0000000000..73fa155491 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-os-release.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-real-time-tasks.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-real-time-tasks.png new file mode 100644 index 0000000000..ac23316ead Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-shell-real-time-tasks.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-sudo-su.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-sudo-su.png new file mode 100644 index 0000000000..6fb4092b5e Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-sudo-su.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-tcp-port.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-tcp-port.png new file mode 100644 index 0000000000..7ca3c8f551 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/adb-tcp-port.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/cloud_dashboard_working.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/cloud_dashboard_working.png new file mode 100644 index 0000000000..2e9dbf12bb Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/cloud_dashboard_working.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/cloud_thing_created.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/cloud_thing_created.png new file mode 100644 index 0000000000..7484b771dd Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/cloud_thing_created.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/images_containers.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/images_containers.png new file mode 100644 index 0000000000..060f235f09 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/images_containers.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/linux_arduino_RPC.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/linux_arduino_RPC.png new file mode 100644 index 0000000000..284d907b71 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/linux_arduino_RPC.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/m4-proxy.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/m4-proxy.png new file mode 100644 index 0000000000..217afb1b9b Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/m4-proxy.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/portenta_x8_call_outs.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/portenta_x8_call_outs.png new file mode 100644 index 0000000000..cd1d7cc565 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/portenta_x8_call_outs.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/portenta_x8_leds.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/portenta_x8_leds.png new file mode 100644 index 0000000000..ffc12be11e Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/portenta_x8_leds.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/shared-space-settings.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/shared-space-settings.png new file mode 100644 index 0000000000..5a18fb0a96 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/shared-space-settings.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_Cloud_login.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_Cloud_login.png new file mode 100644 index 0000000000..e69d1c9e94 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_Cloud_login.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_cloud_integration.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_cloud_integration.png new file mode 100644 index 0000000000..2759026074 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_cloud_integration.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challange_connect.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challange_connect.png new file mode 100644 index 0000000000..0bd7feab6c Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challange_connect.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challenge.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challenge.png new file mode 100644 index 0000000000..c35692c08e Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challenge.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challenge_approved.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challenge_approved.png new file mode 100644 index 0000000000..ae2dd8b0bc Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_challenge_approved.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device-overview.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device-overview.png new file mode 100644 index 0000000000..a2b4feb297 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device-overview.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device.png new file mode 100644 index 0000000000..7343412ea2 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device_specs.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device_specs.png new file mode 100644 index 0000000000..3a4fa8f1d2 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_device_specs.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_member.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_member.png new file mode 100644 index 0000000000..66dfe94a1e Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_member.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_name.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_name.png new file mode 100644 index 0000000000..1d7878b2d6 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_name.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_overview.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_overview.png new file mode 100644 index 0000000000..c67d795a0a Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_overview.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_target.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_target.png new file mode 100644 index 0000000000..c1751e2b8f Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_target.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_team_roles.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_team_roles.png new file mode 100644 index 0000000000..d93071b946 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_team_roles.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_update_history.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_update_history.png new file mode 100644 index 0000000000..2dfef94096 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_factory_update_history.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_foundries_login.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_foundries_login.png new file mode 100644 index 0000000000..256d3cb4b6 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_foundries_login.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_signup.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_signup.png new file mode 100644 index 0000000000..4db0d289d2 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_signup.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_team.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_team.png new file mode 100644 index 0000000000..ad58083fc5 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_board_manager_team.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_key.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_key.png new file mode 100644 index 0000000000..122d5d829d Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_key.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_key_PDF.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_key_PDF.png new file mode 100644 index 0000000000..2e8e0a3b8a Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_key_PDF.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_name.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_name.png new file mode 100644 index 0000000000..4c83cae2d8 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_API_name.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_homepage.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_homepage.png new file mode 100644 index 0000000000..787fedcaa2 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_homepage.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_new_api.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_new_api.png new file mode 100644 index 0000000000..17606c1ebf Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_new_api.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_signin.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_signin.png new file mode 100644 index 0000000000..5c884f26da Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/web_cloud_signin.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/assets/x8-board-manager.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/x8-IDE.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/assets/x8-board-manager.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/x8-IDE.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/x8-terminal-ADB-push.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/x8-terminal-ADB-push.png new file mode 100644 index 0000000000..079a8d7443 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/assets/x8-terminal-ADB-push.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/content.md new file mode 100644 index 0000000000..aae3ffa543 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/content.md @@ -0,0 +1,1148 @@ +--- +beta: true +title: '01. Portenta X8 User Manual' +description: 'Get a general overview of Portenta X8 and its features' +difficulty: intermediate +tags: + - Embedded Linux + - Containers + - Firmware + - Pins + - Connections +author: 'Marta Barbero' +hardware: + - hardware/04.pro/boards/portenta-x8 +software: + - ide-v1 + - ide-v2 + - iot-cloud +--- + + +## Introduction +Portenta X8 is a powerful, industrial-grade System on Module with Linux OS preloaded onboard, capable of running device-independent software thanks to its modular container architecture. In this user manual, we will go through the foundations of the Portenta X8 to help you understand how the board works and how you can benefit from its advanced features. + +## Required Hardware + +* 1x [Portenta X8](https://store.arduino.cc/products/portenta-x8) board +* 1x USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) +* 1x Wi-Fi® Access Point or Ethernet with Internet access + +## Required Software +* Arduino IDE 1.8.10+, Arduino IDE 2.0+, or Arduino Web Editor +* Latest "Arduino Mbed OS Portenta Boards" Core > 3.0.1 +* Latest Linux image available, check [this section](#portenta-x8-os-image-update) to verify if your Portenta X8 is already updated. + +## Product Overview + +Portenta X8 offers the best of two approaches: flexibility of usage of Linux combined with real-time applications through the Arduino environment. Developers can now execute real-time tasks, while simultaneously performing high-performance processing on Linux cores. +So, let's have a look at its technical specification. + +### Architecture Overview + +Portenta X8 is a powerful, industrial-grade System on Module combining a Yocto Linux distribution with the well-known Arduino environment. + + +![Portenta X8 Tech Specs](assets/portenta_x8_call_outs.png "Portenta X8 Tech Specs") + +As you can see, Portenta X8 features two powerful computing units: +* **NXP® i.MX 8M Mini** Cortex®-A53 quad-core up to 1.8GHz per core + 1x Cortex®-M4 up to 400 MHz. This microprocessor is the one where the Yocto Linux distribution is running together with Docker containers (check [this section](#linux-environment) of this user manual to learn more). +* **STMicroelectronics STM32H747XI** dual-core Cortex®-M7 up to 480 MHz + M4 32 bit Arm® MCU up to 240 MHz. This microcontroller is the one where the "Arduino Mbed OS Portenta Boards" Core is running. M4 core is accessible and programmable by the user, while M7 is dedicated to establishing and guaranteeing the communication between i.MX 8M Mini and M4 as well as to manage peripherals through RPC. Check [this section](#arduino-environment) of this user manual to learn more. + +The two computing units are responsible for different tasks, which are summarized in the table below. + + | NXP® i.MX 8M Mini | STMicroelectronics STM32H747XI (M4) | + | ------------------------------------------------------- | -------------------------------------------------------------- | + | Running Yocto Linux distribution with Docker containers | Running Arduino sketches with the Mbed OS Portenta Boards Core | + | Dedicated to high level tasks | Dedicated to real-time tasks | + | Manage network connectivity | No direct connection to any network stack | + | Manage network-based buses (e.g. Modbus TCP, etc.) | Manage field buses (e.g. Modbus RTU, CANbus, etc.) | + | Access to peripherals without concurrent access control | Access to peripherals without concurrent access control | + +In addition to the above features, Portenta X8 guarantees security over time. A crypto element (i.e. [NXP® SE050C2](https://www.nxp.com/docs/en/data-sheet/SE050-DATASHEET.pdf)) ensures a secure connection at the hardware level and allows the board to be PSA certified from ARM® (click [here](https://www.psacertified.org/products/portenta-x8/) to learn more). + +Moreover, Portenta X8 can be further customized to get a continuously maintained Linux kernel distribution and to keep security at first by Over-The-Air (OTA) device updates and fleet management. In order to activate these features, you need to create an Arduino Cloud for business account including the so-called **Portenta X8 Board Manager**. Portenta X8 Board Manager has been developed together with [Foundries.io](https://foundries.io/)) and allows a user to: +* Securely maintain Linux distribution inside a FoundriesFactory, i.e. a dedicated workspace where all your Portenta X8 are provisioned and maintained. +* Deploy and update applications packaged into containers, including both containers provided by Arduino or custom containers. +* Get individual provisioning keys for each device. +* Perform secure Over-the-air (OTA) updates to target Portenta X8 devices/fleets + +***Click [here](https://cloud.arduino.cc/plans#business) to learn more about Arduino Cloud for business and the Portenta X8 Board Manager add-on. Otherwise, check the [dedicated section](#working-with-portenta-x8-board-manager) of this user manual to start working with Portenta X8 Manager.*** + +### Pinout + +The full pinout is available and downloadable as PDF from the link below: +* [Portenta X8 Pinout](https://docs.arduino.cc/static/019dd9ac3b08f48192dcb1291d37aab9/ABX00049-full-pinout.pdf) + +### Datasheet + +The full datasheet is available and downloadable as PDF from the link below: +* [Portenta X8 Datasheet](https://docs.arduino.cc/static/77d2be9902708fcb73b19d0f1173c6bb/ABX00049-datasheet.pdf) + +### Schematics + +The full schematics are available and downloadable as PDF from the link below: +* [Portenta X8 Schematics](https://docs.arduino.cc/static/c92dbfc6c6a7c3f79c9987d36f017e48/ABX00049-schematics.pdf) + +### STEP Files + +The full _STEP_ files are available and downloadable from the link below: +* [Portenta X8 STEP files](https://docs.arduino.cc/static/5d95e348688a9678e04d6f4d0b994844/ABX00049-step.zip) + +### Linux Environment + +As you already know, Portenta X8 is based on a Yocto Linux distribution. + +Before going into the details of Yocto distribution, it is important to understand how embedded Linux works. +The term **Embedded Linux** is used to define embedded systems based on the Linux Kernel and other open-source components. Over the years, Linux has established itself as the best operating system to be installed on embedded devices. This achievement is due to the fact that Linux is an open-source and completely free operating system. + +An **Embedded Linux** system is composed of the following items: +* **Bootloader:** The first program executed right after powering the board. It has the task of initializing the hardware and loading the operating system loading the **device tree** and its configuration file into the RAM. The **device tree** is basically a database containing information on the hardware components of the board and it is used to forward information from the bootloader to the Kernel at the hardware level. +* **Linux Kernel:** The core of the operating system. It deals with resource management, scheduling, hardware access and all the low-level operations which the user does not want to worry about. In particular, the Linux Kernel manages all the hardware resources, like CPU, memory and I/Os, and it provides a set of APIs that abstracts those resources allowing the user applications and libraries to be easily deployed. +* **Root Filesystem:** It contains all system programs and utilities, configurations and user data (roughly speaking, the equivalent of the `C:\` drive on Windows). The Root Filesystem can be mounted from a USB stick, SD card or flash memory, being the case of the Portenta X8. + +![Embedded Linux Start-Up](assets/Embedded_Linux_Start.png "Embedded Linux Start-Up") + +#### Linux Yocto Distribution + +In order to install a Linux operating system on a board, you need to decide which packages, applications and libraries you want to use, so basically you need to decide which Linux distribution better suits your needs. As a matter of fact, a Linux distribution is an operating system consisting of the Linux Kernel, GNU tools, additional software and a package manager. It may also include a display server and a desktop environment for using it as a regular desktop operating system. +There are more than 300 Linux distributions available in the market, like Ubuntu, Debian, Fedora, Red Hat, etc. + +Portenta X8 is running a [Yocto Linux distribution](https://www.yoctoproject.org/). Yocto is built on the basis of [OpenEmbedded (OE)](http://www.openembedded.org/wiki/Main_Page), which uses [BitBake](https://docs.yoctoproject.org/bitbake/) build to generate a full Linux image. BitBake and OE are combined together to form the Yocto reference project, historically called [Poky](https://www.yoctoproject.org/software-item/poky/). + +In addition, a full selection of metadata is defined to select which tasks to be performed. The following metadata is used in a Yocto project: +* **Recipes:** They deliver information regarding each package (i.e. author, homepage, license, etc.), recipe version, existing dependencies, source code location and how to retrieve it, configuration settings and target path where the created package will be saved. Files with the `.bb` extension are recipe files. +* **Configuration file:** They contain metadata that define how to perform the build process. These files (with `.conf` file extension) determine the configuration options for the machine, the compiler, the distribution and general and user configurations. They allow you to set the target where you want to create the image and where you want to save the downloaded sources and other particular configurations. +* **Classes:** Class files, which have the extension `.bbclass`, contain common functionalities that can be shared between various recipes within the distribution. When a recipe inherits a class, it also inherits its settings and functions. +* **File append:** With the extension `.bbappend`, File append extends or overwrites information for an existing recipe. + +OpenEmbedded Core contains a recipe layer, classes and a set of associated files, common to all OE-based systems, including Yocto. This set of metadata is in fact maintained by both the Yocto project and the OpenEmbedded project. + +The development environment of the Yocto distribution is made up of various functional areas, as shown in the figure below. + +![Yocto Distribution Architecture](assets/Yocto_Architecture.png "Yocto Distribution Architecture") + +* **Layer:** The layers allow you to separate metadata by differentiating them according to: software, hardware information, metadata concerning distribution and adopted policies. Within each layer, there are the `conf` (with layer-specific configuration files) and `recipes-` directories. To illustrate how to use layers to maintain modularity, consider the example of recipes to support a specific target, which usually resides in a BSP layer. In this scenario, those recipes should be isolated from other recipes and supporting metadata, like a new Graphical User Interface (GUI). You would then have a couple of layers: one for the configurations of the machine and one for the GUI environment. This would allow a specific machine to present special GUI features within the BSP layer, without affecting the recipes inside the GUI layer itself. All of this is possible via an append file. +* **Source file:** To cross-compile any software module, being it a distribution or an application, we must have access to various source files. The latter can be sourced from three different upstream areas: Upstream Project Releases (archived at a specific location), Local Projects (available at a certain local path) and Source Control Managers (like GitHub). +* **Package feeds:** This area contains packages generated by the build system and they will be used later to generate operating system images or Software Development Kits (SDKs). +* **Build System:** The Build System macroblock is the heart of the Yocto distribution. It contains various processes controlled by BitBake, a tool written in Python language. The Build System is responsible for parsing the metadata, from which it extracts the list of tasks to be performed. BitBake checks the software build process by using the recipes and, for each successfully completed task, it writes a *stamp* file in the Build Directory. +* **Images:** They are compressed forms of the Root Filesystem, ready to be installed on the target. BitBake releases multiple lists of images saved into the Build Directory, including *kernel-image*, *root-filesystem-image* and *bootloaders*. +* **SDK:** From the SDK generation process you can get a standard SDK or an extensible SDK. In both cases, the output is an installation script of the SDK, which installs: a cross-development toolchain, a set of libraries and headers files; generating an environment setup script. The toolchain can be considered as part of the build system, while libraries and headers as target parts, since they are generated for the target hardware. + +***If you want to learn more about how to work with Yocto Distribution on your Portenta X8, please check the [dedicated section](#working-with-linux) of this user manual.*** + +#### Docker Containers + +With Portenta X8 it is possible to deploy device-independent software thanks to its modular container architecture. + +To explain how containers work, imagine the classic containers that transport goods around the world by ship. These containers "blocks" can be moved in multiple ways and to multiple locations: from a ship to a truck or from a truck to a warehouse. The same thing happens in computer science: you can consider an application, package it with everything needed to make it work and take it out of the environment in which it runs. This is a container! + +![Virtual Machine vs Containers](assets/Virtual_Machine_Containers.png "Virtual Machine vs Containers") + +On one side, classic virtualization is able to virtualize an entire machine; on the other side, containers are able to virtualize even just a small subset of resources of the same machine. + +Traditional virtual machines share hardware resources, but the operating system and applications are on the host. This translates into long start-up times (it takes minutes) and considerable use of resources (several Gigabytes). Containers, on the other hand, share the operating system as well as the infrastructure with the host. This means that start-up times are short (a few seconds) and dimensions are significantly reduced (even a few KB). + +Being able to "pack" applications and distribute them in any environment leads to a series of advantages in terms of: performance, time, costs and integration. As a matter of fact, containers can be an interesting way to simplify infrastructure complexity, provide maximum performance and optimize costs by eliminating virtual machine licenses. + +But let's see in detail some of the advantages of this technology: +* **Simple development, test and deployment:** The decoupling between applications and the environments in which they run allows you to deploy a container everywhere: on a public cloud, in a private data center or on a PC. Whatever the chosen environment, the container will always remain the same. This means that even applications updates can be released easily without involving the operating system hosting the container, or all the other containers in use. In a nutshell, if you have to update an application, it will not be necessary to restart the whole machine. +* **Control version:** In the case that the deployment of an update was not successful, thanks to the containers architecture it is easier to roll back and to have the previous version working again in few time. +* **Isolation and security:** In containers, applications and resources are isolated. This means that if an application has to be deleted, it will be sufficient to remove its container and the operation will delete everything that concerns it, such as temporary or configuration files. At the same time, since containers are isolated, each of them "sees" only their own processes, while the others will remain unknown. Security first! +* **Granularity:** It is possible to containerize not only an entire application, but also a single component. In this way, resources can be reduced into micro-services, guaranteeing greater control and improved performance. + +At this point, it is worth mentioning that Portenta X8 containers are based on [Docker](https://www.docker.com/). Docker is an open-source software platform, developed by the company with the same name, which allows you to create, test and distribute containerized applications. The goal of Docker is therefore to facilitate the creation and management of containers, in order to distribute the resources required for an application in any environment, always keeping the executed code under control. Docker containers can run everywhere, in on-premises data centers or in public and private clouds. Thanks to the virtualization at the operating system level, typical of this technology, Docker allows you to natively create containers in Linux environments. + +To understand the purpose of a platform like Docker, it is sufficient to focus on the differences between Docker containers and the more generic Linux containers. Docker mainly serves to simplify the construction and management of containers compared to the standard approach. Although it is based on the same technology, i.e. the **LXC (Linux Container)**, Docker guarantees a much more advanced experience than the standard implementation. LXC basically permits a light virtualization, independent from the underlying hardware, but basically cumbersome to implement. In other words, basic LXC presents critical issues in terms of user experience. + +Docker specifically facilitates the interface between the container and the end user, for example through a series of automated procedures that guide the user step-by-step during container development, with correct versioning of all the generated images. Docker also simplifies the management of the applications to be run on the different containers, to make the overall orchestration more practical and faster, especially when dealing with applications made of a very large number of components. + +The reasons for using Docker are therefore closely connected to the usefulness of the containers themselves, now indispensable tools for developing software based on a microservices architecture. In particular, this applies to the DevOps methodologies used for the development of native cloud applications, which provide for continuous integration / continuous deployment cycles, to guarantee the end user always and only the most up-to-date version. + +The technology behind containers, and therefore of Docker itself, can be extremely summarized in three key terms: +* **Builder:** tools used to create containers. In the case of Docker, this tool corresponds to the **Dockerfile**. +* **Engine:** it is the engine that allows you to run containers, as in the case of **Docker command** and **Docker Daemon**. +* **Orchestration:** technology used to manage containers, with full visibility of their execution status (tasks, servers / VMs, etc.), as in the case of **Docker Swarm** or the famous **Kubernetes**. + +The fundamental advantage of a container is that it makes both the application and the execution environment configuration available. This allows you to manage the various images as instances, without having to install the application each time, as happens in the case of traditional procedures. + +As already mentioned, containers running with Docker are absolutely isolated and independent from each other and it is therefore possible to have complete control over their visibility and management, without any constraints whatsoever. The advantages in terms of IT security are obvious: if a container is corrupted, for example by exploiting a vulnerability of the application it is running, this event does not affect the functioning of the other running containers. Isolation prevents, or at least makes it more difficult, the propagation of the threat within the host system, allowing Docker to terminate the corrupted instance and restart it in completely safe conditions, as well as having traces of what happened in the system logs. + +Thus, Docker is able to ensure application security without sacrificing anything in terms of portability, guaranteeing full operation both on-premise and in the cloud, using open and closed APIs to respond optimally to any business need. + +As shown in the image below, Docker needs to be installed in the host operating system and it is composed of three main items: +* ***docker-daemon:*** It is a service that runs on the host operating system and leverages Linux Kernel features to work. It allows the user to create a container and run it, starting from an image developed by the user or downloaded from a registry. +* ***docker-cli:*** It is a command-line tool that allows the user to properly communicate with the *docker-daemon*. As a matter of fact, any operation on images or containers always starts via *docker-cli*. When Docker is installed, both the *docker-daemon* and the *docker-cli* are installed together and any operation always takes place via *docker-cli*, even if managed via *docker-daemon*. +* ***docker-hub:*** It is a [Docker image repository](https://hub.docker.com/) from which it is possible to download all the images of interest and run them to create containers. Alternatively, a user can create the needed images through a *dockerfile*, using the repository only to download the required base images (like Linux-alpine). + +![Docker host](assets/Docker_host.png "Docker host vs client") + +Now it is time to highlight better which is the difference between an image and a container. In programming languages, an image can be assimilated to a class, while a container to an object. It is possible to create a container starting from an image and then run it, stop it or pause it. When it is no longer needed, it can be deleted without removing the corresponding image. + +As already mentioned, images can be downloaded from a registry like Docker or they can be defined through a *dockerfile*. A *dockerfile* is a text file that contains all the commands (*FROM, COPY, CMD, ENTRYPOINT, etc.*) that a user can call from the command line to build various image layers. The *dockerfile* represents a definition of the image but not the final image, which can be built through `docker build` command. + +A Docker image is made up of many layers and includes everything needed to configure a container. In particular, all the layers an image contains are read-only and, consequently, the image itself is also read-only. In this way, it is possible to launch the image several times always creating the same container. When the container is created, a thin writable layer will be placed on top of the existing image layers and will be prepared to execute the main process command. This last writable layer will contain any changes made when the container is running, but will not affect the original underlying image. When the container is deleted, this thin writable layer is removed. + +An important thing to keep in mind is that, even if Docker shares the Linux Kernel with the underlying host, it is always necessary to add a full operating system or a Linux distribution as the first layer. + +![Images and containers](assets/images_containers.png "Images vs containers") + +On the other hand, a container represents a process, which runs starting from an image. The important thing to understand is that a container has a lifecycle and, for this reason, it can reach different states depending on whether it is running or not. The lifecycle of a Container consists of the following states: +* **Created:** This is the first state of the container lifecycle and it occurs after an image has been created with the command `docker create`. A writable thin layer is created on the specified image and prepared to execute the main process commands. Consider that in this state the container is created but not started. +* **Running:** This is the state in which the container is actually running. A container created through `docker create` or interrupted can be restarted through the command `docker start`. +* **Paused:** A running container can be paused through the command `docker pause`. As a consequence, all the processes of the specified container are suspended or blocked. When a container is paused, both the file system and the RAM are not affected. +* **Stopped:** A stopped container does not have any running process. When a container is stopped through the command `docker stop`, the file system is not affected, but the RAM gets deleted. This is the main difference between stopped and paused states. +* **Deleted:** A container can be removed through the command `docker rm`. This implies the complete cancellation of all the data associated with the container, including file system, volume and network mapping. + +Let's now have a look at the main Docker commands. The full list can be found [here](https://docs.docker.com/engine/reference/commandline/docker/). +Through the command `docker image ls` it is possible to check all the images installed on your Portenta. These images may have been downloaded from a repository using the command `docker pull XXX` or created from scratch with the command `docker build XXX` starting from a *dockerfile*. + +Through the command `docker run XXX`, it is possible to run the image downloaded from the repository. But, if a user tries to launch a container through the command `docker run XXX` for a container whose image has not been downloaded yet, first the image will be downloaded and then the container will start running. + +To verify whether a container is running as expected, it is possible to launch the command `docker ps`. + +So, to summarize, Docker is a very powerful technology that allows a user to avoid installing an infinite number of servers and services on a machine. Furthermore, since it runs in an isolated environment makes it possible to move the container or rather the image to another machine or to a production server without friction. + +***If you want to learn more about how to work with Docker containers on your Portenta X8, please check the [dedicated section](#working-with-linux) of this user manual.*** + +### Arduino Environment + +In addition to what has been addressed before, the user has the possibility to upload sketches on **M4 core** of **STM32H7** through the **Arduino IDE 1.8.10 or above**. + +In order to do that, it is sufficient to open the Arduino IDE, make sure you have selected the Portenta X8 in the board selector and start writing your sketch. + +***Have a look at [this section](#portenta-x8-with-arduino-ide) of this user manual if you would like to start uploading your sketch on Portenta X8.*** + +From a user perspective, the process may appear to be the same as for other Arduino boards, but there are major differences in what happens behind the scenes: the Portenta X8 includes a service that waits for a sketch to be uploaded to a folder. This service is called `monitor-m4-elf-file.service`: it monitors the directory `/tmp/arduino/` looking for an updated version of the `m4-user-sketch.elf` and, each time it detects a new file, it proceeds to flash the M4 with the new sketch using `openOCD` (check [openOCD website](https://openocd.org/doc/html/About.html) if you want to learn more). + +### Communication Between Linux And Arduino + +The two processors inside Portenta X8 need a communication mechanism to exchange data with one another. The communication mechanism that is used is called **RPC (Remote Procedure Call)**. + +The expression RPC refers to the activation of a "procedure" or "function" by a program on a computer other than the one on which the program itself is executed. In other words, RPC allows a program to execute procedures "remotely" on "remote" computers (but accessible through a network). + +Essential to the concept of RPC is also the idea of transparency: the remote procedure call must in fact be performed in a way similar to that of the traditional "local" procedure call; the details of the network communication must therefore be "hidden" (i.e. made transparent) for the user. + +The RPC paradigm is particularly suitable for distributed computing based on the client-server model: the "call procedure" corresponds to the "request" sent by the "client" and the "return value" of the procedure corresponds to the "response" sent by the "server". In fact, distributed computing uses the resources of several computers connected to each other in a network (usually via the Internet) to solve large-scale computational problems. + +Although the ultimate goal of the RPC paradigm is to provide a remote procedure call mechanism whose semantics is essentially equivalent to that of the local procedure call (hence the aforementioned transparency of the mechanism), this equivalence is never fully achieved, due to difficulties that can arise in network communication (always subjected to failure). + +Since there is no single obviously "right" way to handle these complications, RPC mechanisms can differ subtly in the exact semantics of the remote call. Some mechanisms, for example, have "at most once" semantics: in other words, a remote procedure call can fail (i.e. not be executed) but it is guaranteed not to result in multiple activations. The opposite approach is represented by the "at least once" semantics, which guarantees that the procedure is called at least once (it could therefore happen that it is activated several times). + +As a consequence, there are multiple types of RPC implementations. In the case of Portenta X8, **MessagePack-RPC** is used (check the [library repository](https://github.com/msgpack-rpc/msgpack-rpc) to get more details). It is an RPC implementation that uses MessagePack as a serialization protocol, i.e. data exchange is encoded in MsgPack format. + +It is transported over different protocols: +* OpenAMP via Shared Memory +* SPI +* Linux Char Device +* TCP/IP + +![Linux Arduino RPC](assets/linux_arduino_RPC.png "Linux Arduino RPC") + +As you can see in the image above, the **M7 core** of **STM32H7** is used to facilitate the communication between the Linux and the Arduino environments. If an Arduino sketch is running on the **M4 core**, the **M7 core** will hand over any data/request between the M4 core and the Linux side. Due to this hardware design, traditional dual-core processing is not supported in the Portenta X8. + +At the same time, on the Linux side, there is a service that takes care of sending data between the two worlds, `m4-proxy`. + +So, the communication between Arduino and Linux side will proceed as follow (check the image below): +* A program registers as the RPC server on port X for a list of procedures that the M4 may call +* `m4-proxy` will forward the calls from the M4 to the registered program/port + +![RPC M4 proxy](assets/m4-proxy.png "RPC M4 proxy") + +***If you want to learn more about how to work with RPC on your Portenta X8, please check the [dedicated section](#working-with-arduino) of this user manual.*** + +## First Use Of Your Portenta X8 + +You can now start interacting with your Portenta X8. Portenta X8 comes with an embedded Out-of-the-box experience that will guide you step-by-step in the configuration of your board. + +### Power The Board + +Connect the Portenta X8 to your PC via a USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®). + +Once connected, you will see the Portenta X8 LEDs starting blinking. Portenta X8 features two LEDs, a Power LED and a Status LED, which can blink in parallel. + +![Portenta X8 LEDs](assets/portenta_x8_leds.png "Portenta X8 LEDs") + +The table below describes LEDs meaning and functionalities. + + | LED Type | Colour | Meaning | + | ------------ | ------------ | ------------------------------------------------| + | Power LED | Red | Power ON | + | Status LED | White | OS booting in progress | + | Status LED | Blue | Linux Kernel running | + | Status LED | Green | Board connected to the Internet | + | Status LED | Red | STM32H7 LED, blinking when triggered in the IDE | + +### Out-Of-The-Box Experience + +***Before following this tutorial, please update your Portenta X8 to the latest version. Check [this section](#portenta-x8-os-image-update) to learn how to do it.*** + +Once the Portenta X8 is correctly powered up, you can start interacting with it. + +In order to do that, you have the possibility to connect to your Portenta X8 through [**ADB**](https://developer.android.com/studio/command-line/adb). Android Debug Bridge (ADB) is a tool included in the SDK software (Software Development Kit) and used, inter alia, to make an Android device and a computer to communicate with each other. + +In the case of the Portenta X8, ADB allows to establish a reliable communication between Portenta X8 and a command-line interface of a computer. In order to check if you have already installed ADB on your computer, you have to verify you installed the latest **Mbed OS Portenta Core** from the IDE. Portenta core contains ADB in it. + +***If you need to install ADB, you can also download the right tool for your Operating System directly from the [official Android website](https://developer.android.com/studio/releases/platform-tools).*** + +At this point, you can open your terminal window and look for ADB inside the directory **Arduino15/packages/arduino/tools/adb/32.0.0**. + +***The Arduino15 folder may have a different location depending on the Operating System you are using. Check [this article](https://support.arduino.cc/hc/en-us/articles/360018448279-Open-the-Arduino15-folder) to learn where your Arduino15 folder is located.*** + +To check if ADB is working correctly, you can type `adb devices`. Your Portenta X8 will be listed there. + +![Connection with ADB](assets/adb-connection.png "Connection with ADB") + +To start the Out-of-the-box experience, you can continue typing in your terminal `adb forward tcp:8080 tcp:80`. With this command, ADB allows to forward the requests of the `8080 TCP-IP port` of your computer to the `80 TCP-IP port` of your device, that for this case it is the device with the name _Portenta X8_. + +![ADB forward command](assets/adb-tcp-port.png "ADB forward command") + +Now you can open your browser, go to [http://localhost:8080](http://localhost:8080) and the same Out-of-the-box dashboard will appear to allow you to configure your Portenta X8. + +![Out-of-the-box Homepage](assets/OOTB_homepage.png "Out-of-the-box Homepage") + +#### Portenta X8 Out-Of-The-Box Homepage + +This web page is hosted on the Portenta X8 and allows a user to: +- Get board details +- [Configure Portenta X8 Wi-Fi®](#wi-fi-configuration) +- [Interact with the board through the embedded Python® Alpine Shell](#portenta-x8-with-python-alpine-shell) +- [Provision your device to Arduino Cloud](#portenta-x8-with-arduino-cloud) +- Manage the Linux distribution with the dedicated [Portenta X8 Board Manager](#portenta-x8-board-manager) + +#### Wi-Fi Configuration + +Click **Wi-Fi Settings** to start configuring your network connectivity. Otherwise, you can also connect your Portenta X8 to the Internet through an Ethernet cable, using a USB-C® hub with an RJ45 port or a Portenta Carrier. In this tutorial, Wi-Fi® connectivity will be used. + +![Out-of-the-box Wi-Fi® Settings](assets/OOTB_homepage_Wifi.png "Out-of-the-box Wi-Fi® Settings") + +Select your Wi-Fi® SSID. You can either select a network from the available list or insert your SSID manually. + +![Out-of-the-box Wi-Fi® SSID set-up](assets/OOTB_wifi_selection.png "Out-of-the-box Wi-Fi® SSID set-up") + +Type your Wi-Fi® password. + +![Out-of-the-box Wi-Fi® password set-up](assets/OOTB_wifi_SSID.png "Out-of-the-box Wi-Fi® password set-up") + +Once it is connected, you will get a notification confirming your Portenta X8 is now connected to the selected network. + +Moreover, you can check the network you are connected to in the bottom left section of this dashboard. + +![Out-of-the-box Wi-Fi® connection successful](assets/OOTB_wifi_connected.png "Out-of-the-box Wi-Fi® connection successful") + +Now you can click **OK** and you will be redirected to the Out-of-the-box homepage shown below. + +![Out-of-the-box Homepage](assets/OOTB_homepage.png "Out-of-the-box Homepage") + +***You can change your network by clicking on the Wi-Fi Settings button and repeat the steps from above.*** + +#### Portenta X8 with Python Alpine Shell +Click the **Shell** button to start using your Portenta X8 with Python-Alpine. + +![Out-of-the-box Shell button](assets/OOTB_homepage_shell.png "Out-of-the-box Shell button") + +This shell is running in a Python-Alpine container embedded in Portenta X8. In this shell, you will find multiple examples under the directory `/root/examples`. Additionally, you can either add your own package through the command `apk add ` or start exploring the packages available online at [this link]( https://pkgs.alpinelinux.org/packages). + +![Out-of-the-box Python-Alpine Shell](assets/OOTB_alpine_shell.png "Out-of-the-box Python-Alpine Shell") + +#### Portenta X8 with Arduino Cloud + +***Note: this is an optional step. The Portenta X8 can be also used with a local IDE without the need for any internet connection.*** + +Making Portenta X8 compatible with Arduino Cloud means opening a wide range of new applications. This compatibility is guaranteed by a brand-new Python container, which includes a dedicated [Arduino IoT Cloud Python library](https://github.com/arduino/arduino-iot-cloud-py). Through Arduino Cloud APIs, the Python container ensures full interaction and simple porting of any Python developed application in the Arduino Cloud. + +***Check all the available Arduino Cloud plans [here](https://cloud.arduino.cc/plans#business) and create your Arduino Cloud account in a couple of steps (see the dedicated documentation at [this link](https://docs.arduino.cc/arduino-cloud/)).*** + +With the Out-of-the-box experience, your Portenta X8 can be securely self-provisioned in Arduino Cloud, you just need to create API keys and the Python container running on X8 will do the rest. When provisioned, you can start directly interacting with an example Thing and Dashboard that will be automatically generated for you to guide you step-by-step in this new journey. + +Click the **Arduino Cloud** button to start provisioning your Portenta X8 in Arduino Cloud. + +![Out-of-the-box Arduino Cloud](assets/OOTB_homepage_cloud.png "Out-of-the-box Arduino Cloud") + +Start setting up the device name for your Portenta X8 (in this case *portenta-x8-test*) and click on **CONTINUE**. The same device name will be used and visualized into your Arduino Cloud space, but you can freely change it in the future. + +![Out-of-the-box Arduino Cloud Device Name](assets/OOTB_cloud_device_name.png "Out-of-the-box Arduino Cloud Device Name") + +At this point, you will be asked to insert your API Key credentials and Organization ID. Organization ID is optional and should be filled in only in case you are using a Shared Space in Arduino Cloud for Business. + +![Out-of-the-box Arduino Cloud API Keys](assets/OOTB_cloud_generate_API.png "Out-of-the-box Arduino Cloud API Keys") + +In order to get API keys, you need to log into your Arduino Cloud account and select the Space you would like your X8 to be provisioned into. + +Thus, click on **GENERATE API KEY** in your Out-of-the-box dashboard. A new window will open in your web browser to allow you to login to your Arduino Cloud space. + +***If you want to learn more about what API keys are and how they work, please take a look at the dedicated documentation available at [this link](https://docs.arduino.cc/arduino-cloud/getting-started/arduino-iot-api).*** + +![Arduino Cloud Login](assets/web_Cloud_login.png "Arduino Cloud Login") + +Click on **SIGN IN**. If you do not have an Arduino Cloud account yet, create a new one from the same webpage. + +Sign in to your Arduino Cloud account by adding your credentials, i.e. Username/email and Password. + +![Arduino Cloud Sign in](assets/web_cloud_signin.png "Arduino Cloud Sign in") + +You are now logged into your Arduino Cloud space. Go on by clicking on **API keys** in the bottom left-hand corner. + +![Arduino Cloud Homepage](assets/web_cloud_homepage.png "Arduino Cloud Homepage") + +It is time to generate your API keys. Click on **CREATE API KEY** in the upper right-hand corner. + +![Arduino Cloud New API Key](assets/web_cloud_new_api.png "Arduino Cloud New API Key") + +Define a name for your API key, in this case *portenta-x8-test-API*, and click on **CONTINUE**. These API Keys are personal and visible just from your account. + +![Arduino Cloud API Key name](assets/web_cloud_API_name.png "Arduino Cloud API Key name") + +At this point, your API key has been created. Save the correspondent credentials in a safe storage space by clicking on **download the PDF**. + +Keep this file safely stored, your API credentials cannot be recovered otherwise. If you lose it, you will have to generate new API keys by repeating the above procedure. + +![Arduino Cloud API Key](assets/web_cloud_API_key.png "Arduino Cloud API Key") + +The PDF file will look like the image below and it will include the credentials you need to copy and paste into the Out-of-the-box page. + +![Arduino Cloud API Key PDF](assets/web_cloud_API_key_PDF.png "Arduino Cloud API Key PDF") + +Thus, copy the **Client ID** and the **Client Secret** credentials and paste them into your Out-of-the-box dashboard as shown below. + +![Out-of-the-box with API Keys](assets/OOTB_cloud_API_copy.png "Out-of-the-box with API Keys") + +If you are using an Arduino Cloud for Business account with Shared Spaces, you need to add also the Organization ID you would like your Portenta X8 to be provisioned into by clicking on **ADD ORGANIZATION**. + +![Out-of-the-box successful Cloud provisioning](assets/OOTB_cloud_success.png "Out-of-the-box successful Cloud provisioning") + +In order to recover the Organization ID of your Shared Space on Arduino Cloud for Business, open your Arduino Cloud homepage and navigate to **Settings > General Settings** in the sidebar on the left. +![Space ID on Cloud Settings](assets/shared-space-settings.png "Space ID on Cloud Settings") + +At this point, you can copy the **Space ID** of your Shared Space and paste it into your Out-of-the-box dashboard together with your API keys. + +![API keys and Organization ID](assets/OOTB_cloud_organization_ID.png "API keys and Organization ID") + +Click on **SETUP DEVICE** and you are ready to go, your Portenta X8 is now provisioned into your Arduino Cloud space. + +![Out-of-the-box successful Cloud provisioning](assets/OOTB_cloud_success.png "Out-of-the-box successful Cloud provisioning") + +Once provisioned, the Portenta X8 will be automatically linked to an example [Thing](https://create.arduino.cc/iot/things) and [Dashboard](https://create.arduino.cc/iot/dashboards). You can freely check them by clicking on the corresponding links embedded in the Out-of-the-box. + +![Portenta X8 example Thing](assets/cloud_thing_created.png "Portenta X8 example Thing") + +As already said, Arduino provides you with an example dashboard that will automatically set up and be visible live after your Portenta X8 has been provisioned. In order to make this dashboard to automatically update its data, you need to go back to your Out-of-the-box and launch the example. + +To do so, it is sufficient to copy the shown code `python3 examples/arduino_iot_cloud_example.py` and click on **Launch Example**. An Alpine-Python shell will open and you will have to paste the previous code here to launch the example. + +![Launching dashboard example](assets/OOTB_example_dashboard_launch.png "Launching dashboard example") + +Now you can navigate to your dashboard [here](https://create.arduino.cc/iot/dashboards) to see your Portenta X8 LED blinking as well as the live temperature inside the microprocessor. + +![Portenta X8 dashboard working](assets/cloud_dashboard_working.png "Portenta X8 dashboard working") + +***If you face any issues during the provisioning of your Portenta X8, feel free to repeat the procedure above.*** +***If you would like to customize your Portenta X8 Things/Dashboards with your own data, check [this section](#working-with-arduino-cloud) of the user manual.*** + +#### Portenta X8 Board Manager + +***Note: this is an optional step. Although the Portenta X8 Board manager opens a wide range of possibilities that are important for business applications, the Portenta X8 can be used for free without the need of any additional payed license*** + +Now you can start connecting your Portenta X8 to the Portenta X8 Board Manager. To enjoy this feature, you need an Arduino Cloud for business account. + +Check the Arduino Cloud for business plan with Portenta X8 Manager [here](https://cloud.arduino.cc/plans#business) and create your Arduino Cloud account in a couple of steps (see the dedicated documentation at [this link](https://docs.arduino.cc/arduino-cloud/)). + +When your Arduino Cloud for business account is correctly set up, log into it [here](https://cloud.arduino.cc/home/) and click on **Portenta X8 Board Manager**. + +![Arduino Cloud homepage with Portenta X8 Manager](assets/web_board_manager_cloud_integration.png "Arduino Cloud homepage with Portenta X8 Manager") + +At this point, you will be asked to create a new account on [Foundries.io](https://foundries.io/) platform. It is recommended to register with the same email address you are currently using in your Arduino Cloud for business account. + +![Foundries.io login](assets/web_board_manager_foundries_login.png "Foundries.io login") + +Add all your credentials and click on **Sign up**. + +![Foundries.io sign up](assets/web_board_manager_signup.png "Foundries.io sign up") + +So, let's create your brand new FoundriesFactory. Select **Arduino Portenta X8**, define a **Factory name** for your Factory and then click on **Create Factory**. + +![FoundriesFactory name](assets/web_board_manager_factory_name.png "FoundriesFactory name") + +Your FoundriesFactory is correctly set-up. As you can see, the Factory does not have any device connected to it. + +![FoundriesFactory homepage with no devices](assets/web_board_manager_factory_overview.png "FoundriesFactory homepage with no devices") + +To provision your Portenta X8, you need to go back to your Out-of-the-box webpage and click on **Portenta X8 Manager** button. + +![Out-of-the-box Portenta X8 Manager](assets/OOTB_homepage_portenta_x8_manager.png "Out-of-the-box Portenta X8 Manager") + +Enter the Factory name you have just registered, in this case *user-test*, and assign a Board Name to your Portenta X8. This Board Name will be used to correctly identify your Portenta X8 into your FoundriesFactory. You can now click on **REGISTER**. + +![Out-of-the-box Factory and device registration](assets/OOTB_board_manager_factory_registration.png "Out-of-the-box Factory and device registration") + +To complete the registration of the Board with the FoundriesFactory, copy the code that appeared in your Out-of-the-box. + +![Out-of-the-box Factory code challenge](assets/OOTB_board_manager_factory_challenge.png "Out-of-the-box Factory code challenge") + +Click on **COMPLETE REGISTRATION** to be re-directed to the Foundries.io activation page. + +Paste your token in the text box and press **Next**. + +***The token code is valid for 15 minutes; if you do not paste it in this time span, you have to repeat all the above registration steps in your Out-of-the-box to generate a new code.*** + +![FoundriesFactory pasted token](assets/web_board_manager_factory_challenge.png "FoundriesFactory pasted token") + +Confirm the addition of your Portenta X8 by pressing **Connect**. + +![FoundriesFactory device confirmation](assets/web_board_manager_factory_challange_connect.png "FoundriesFactory device confirmation") + +Go to your FoundriesFactory by clicking on **Factories Page**. + +![FoundriesFactory device registration completed](assets/web_board_manager_factory_challenge_approved.png "FoundriesFactory device registration completed") + +Now you will see the number of devices associated with your FoundriesFactory to be equal to 1. + +![FoundriesFactory with 1 device](assets/web_board_manager_factory_device.png "FoundriesFactory with 1 device") + +Your Portenta X8 is correctly provisioned into your FoundriesFactory. + +To verify your device status, click on your FoundriesFactory, go to **Devices** section and check its target update and the installed containers Apps. + +![FoundriesFactory device overview](assets/web_board_manager_factory_device-overview.png "FoundriesFactory device overview") + +***If you want to learn more about Portenta X8 Manager features, check the dedicated section of this user manual called [Working with Portenta X8 Board Manager](#working-with-portenta-x8-board-manager).*** + +### Portenta X8 with Arduino IDE + +In this section you will learn how to upload a sketch to the M4 core on the STM32H747XI MCU. + +Open the Arduino IDE and make sure you downloaded the latest Arduino Mbed OS Portenta Boards Core. Learn how to do it by following [this tutorial](https://docs.arduino.cc/software/ide-v1/tutorials/getting-started/cores/arduino-mbed_portenta). + +Select Portenta X8 in the board selector. + +![IDE Board Selector](assets/x8-IDE.png "IDE Board Selector") + +Create a custom sketch or open one of the example sketches e.g. the blink sketch: + +```arduino +void setup(){ + pinMode(LED_BUILTIN ,OUTPUT); +} + +void loop(){ + digitalWrite(LED_BUILTIN , HIGH); + delay(1000); + digitalWrite(LED_BUILTIN , LOW); + delay(1000); +} +``` + +At this point, select the port of your device in the port selector menu and then press the Compile and Upload button. + +Behind the curtains, the sketch gets compiled into a binary. That binary file is then uploaded to the Linux side of the Portenta X8. The flashing is done on the board itself by the RPC service running on Linux (see [Communication between Linux and Arduino section](#communication-between-linux-and-arduino) of this user manual to learn more). + +When the sketch has been uploaded successfully, the onboard LED of your Portenta X8 will start blinking at an interval of one second. + +You can also upload the firmware manually if you like. To do so, you first need to compile the sketch: select **Export compiled binary** from the Sketch menu in the Arduino IDE. It will compile the sketch and save the binary file in the sketch folder. Alternatively, you can use the [Arduino CLI](https://arduino.github.io/arduino-cli/0.29/) to create an `elf` file. + +To upload the firmware you can use the ADB tool that has been installed as part of the Portenta X8 core. It can be found at `Arduino15\packages\arduino\tools\adb\32.0.0`. + +From that directory, you can use the `adb` tool. To upload your compiled sketch, you just need to type the following command into your terminal window: +``` +adb push /tmp/arduino/m4-user-sketch.elf +``` + +![ADB upload with a terminal](assets/x8-terminal-ADB-push.png) + +## Working with Linux + +Now it is time to start interacting with the Linux OS embedded in your Portenta X8. To do that, you need to open your terminal window and look for ADB inside the directory **Arduino15/packages/arduino/tools/adb/32.0.0**. + +To check if ADB is working correctly, you can type `adb devices`. Your Portenta X8 will be listed there. + +![Connection with ADB](assets/adb-connection.png "Connection with ADB") + +At this point, you can type `adb shell` to start communicating with your Portenta X8. + +![ADB shell command](assets/adb-shell-command.png "ADB shell command") + +As it is a Linux device, you can do tasks like creating files, changing directories, etc. + +To gain admin (root) access, type `sudo su -` and the password, which by default is `fio`. After that, the terminal prefix should turn red. + +![ADB shell with admin access](assets/adb-sudo-su.png "ADB shell with admin access") + +You can now freely program your Portenta X8 Linux OS. In the sections below you can check some basic commands to get started. + +### Manage Your Network Via CLI + +In order to connect to a Wi-Fi® Access Point via CLI, you can use the network manager tool **nmcli**. These are some of the most used commands: +* `nmcli device Wi-Fi connect password ` to connect to a specific SSID +* `nmcli de` to check the connection status +* `nmcli connection show` to visualize the active network interfaces (and their types) on your Portenta X8 + +### Inspect Real-Time Tasks And Logs Via CLI + +Run `journalctl -f` to check the status of active services and possibly their errors, but also various system event logs. + +![ADB shell journalctl package](assets/adb-shell-real-time-tasks.png "ADB shell journalctl package") + +By calling `journalctl` it is possible to take a look at the log of all the running activities, by specifying also the type of log you are looking for. Some logs may be a warning which can be ignored or some may be critical errors. Type `journalctl -p 0` to view emergency system messages, otherwise change the number 0 with the error code you want to investigate according to the following error code numbers: + +| Error code | Meaning | +|------------|-----------| +| 0 | Emergency | +| 1 | Alerts | +| 2 | Critical | +| 3 | Errors | +| 4 | Warning | +| 5 | Notice | +| 6 | Info | +| 7 | Debug | + +When you specify the error code, it shows all messages from that code and above. For example, if you specify error code 2, then it shows all messages with priority 2, 1 and 0. + +Additionally, you can also view logs for a specific time and date duration. You can use the `-- since` switch with a combination of `"yesterday"`, `"now"`, or a specific date and time `"YYYY-MM-DD HH:MM:SS"`. + +An example of how to use the command: + +```arduino +journalctl --since "2022-12-22 12:20:00" --until yesterday +``` +### Create And Upload Docker Containers To Portenta X8 + +We created dedicated tutorials covering this topic. Go check them out: +* [Managing Containers with Docker on Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/docker-container) +* [Create and Upload a Custom Container to the Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/custom-container) +* [Running Wordpress and Database Containers on the Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/wordpress-webserver) + +### Output Video Content On A Screen + +The USB-C® port on your Portenta X8 supports video output. As a consequence, you can freely connect a USB-C® monitor or a USB-C® to HDMI hub to your Portenta X8 to start visualizing video or other visual renders. + +Here you can find a list of validated compatible USB-C® to HDMI hubs: +* [ACT AC7022](https://www.act-connectivity.com/en-us/usb-c-to-hdmi-multiport-adapter-4k-usb-hub-pd-pass-ac7022) +* [ACT AC7041](https://www.act-connectivity.com/en-us/usb-c-to-hdmi-multiport-adapter-with-ethernet-ac7041) +* [ACT AC7042](https://www.act-connectivity.com/en-us/usb-c-to-hdmi-multiport-adapter-with-ethernet-and-ac7042) + +***Learn more on how to output WebGL content on a screen with Portenta X8 by checking the [dedicated tutorial](https://docs.arduino.cc/tutorials/portenta-x8/display-output-webgl).*** + +### Build A Custom Image For Portenta X8 + +You may want to build a custom image for the Portenta X8 with the source code provided in the public [GitHub repository of lmp-manifest](https://github.com/arduino/lmp-manifest). Building an image locally can help debug certain aspects of the system, such as the bootloader or kernel support. + +***Have a look at [this dedicated tutorial](https://docs.arduino.cc/tutorials/portenta-x8/image-building) to understand how to build your own custom image.*** + +### Additional Tutorials + +If you want to continue working with your Portenta X8, you can find tons of additional tutorials in the **Tutorials** section of our [Arduino Docs](https://docs.arduino.cc/hardware/portenta-x8). Go check them out! + +## Working With Arduino + +You have learned how to use your Portenta X8 with the Arduino IDE in the section [Portenta X8 with Arduino IDE](#portenta-x8-with-arduino-ide), but you can do much more with the Arduino environment, in particular leveraging the RPC communication between the Arduino layer and the Linux layer. + +You can have a look at this [GitHub repository](https://github.com/arduino/ArduinoCore-mbed/tree/master/libraries/RPC/examples) to have access to multiple IDE examples showing how to use RPC communication with Portenta X8. + +***Check [Communication between Linux and Arduino](#communication-between-linux-and-arduino) section of this user manual to learn more about RPC.*** + +You can build an Arduino sketch to manage all the tasks requiring real-time, including sensors communication, Fieldbus management, etc., and then send those data to a Cloud or remote server via multiple connectivity options, by leveraging the high-performance network management capabilities of Linux OS. + +For instance, try [Data Exchange Between Python® on Linux and an Arduino Sketch](https://docs.arduino.cc/tutorials/portenta-x8/python-arduino-data-exchange) tutorial to learn how to exchange sensor data between the Python® container embedded on Portenta X8 and an Arduino sketch. + +Additionally, if you are a more advanced user, you can check [Multi-Protocol Gateway With Portenta X8 & Max Carrier](https://docs.arduino.cc/tutorials/portenta-x8/multi-protocol-gateway) tutorial to develop your own multi-protocol gateway: receive data from a sensor with the Arduino layer via MQTT protocol, take advantage of RPC to establish communication between Arduino and Linux, and then send the acquired data to The Things Network via LoRaWAN® managed by the Linux layer. + +## Working With Arduino Cloud + +To start using your Portenta X8 with Arduino Cloud, provision your device as described in [this section](#portenta-x8-with-arduino-cloud). + +Once ready, you will have the chance to customize Portenta X8 example Thing and Dashboard. This can be done by writing your own Python script leveraging the [Arduino IoT Cloud Python library](https://github.com/arduino/arduino-iot-cloud-py). Check the documentation and the examples inside the library to learn more about how to create your own Python application. + +When your Python script is ready, you have to create a dedicated Dockerfile integrating your new script. The Dockefile needs the Out-of-the-box Python container (i.e. `arduino-ootb-python-devel`) to be able to correctly interact with your Arduino IoT Cloud account. + +So, open a terminal window and create a Dockerfile integrating the following code together with your Python script: + +```arduino +FROM arduino/arduino-ootb-python-devel:latest +# Copy custom python cloud scripts +COPY ./custom-examples /root/custom-examples +RUN chmod -R 755 /root/custom-examples +``` + +### Build Your Container + +You can create your own custom container and build them inside the Portenta X8. Since Portenta X8 is based on an arm64 architecture, you can use the command `build` only if you are actually building the container directly on an arm64 architecture (e.g. Macbook based on M1/M2 processor or Portenta X8). Open a terminal window and type: + +```arduino +docker build . -t x8-custom-devel +``` +Otherwise, if you are using a different architecture or building machine, use `buildx` command to specify which architecture your build should compile for: + +```arduino +docker buildx build --platform linux/arm64 -t x8-custom-devel --load . +``` +In this way, your Docker image will be built and tagged with the name `x8-custom-devel`. + +Now it is time for you to deploy the newly created Docker image. To do so, you need to save it somewhere and then deploy it on your Portenta X8. + +### Deploy Your Container With Docker Hub + +If you have a [Docker Hub account](https://hub.docker.com/), you can freely upload your Docker image to your registry (e.g. `yourhubusername`): + +```arduino +docker push yourhubusername/x8-custom-devel +``` +Your image is now available in your Docker Hub registry `yourhubusername`. + +At this point, you can directly pull the image to your Portenta X8. To do so, connect to your Portenta X8 through ADB. It can be found at `Arduino15\packages\arduino\tools\adb\32.0.0`. + +From that directory, you can pull the image to the location you prefer. + +```arduino +adb shell +portenta-x8$: docker pull x8-custom-devel +``` +Now your image is correctly deployed on your Portenta X8. + +### Deploy Your Container Without Docker Hub + +If you do not have a Docker Hub account, you can also save the Docker container locally as a .tar archive, and then you can easily load that to an image. + +To save a Docker image after you have built it, you can use the `docker save` command. For example, let's save a local copy of the `x8-custom-devel` docker image you made: + +```arduino +docker save x8-custom-devel:latest | gzip > x8-custom-devel_latest.tar.gz +``` + +At this point, you can directly pull the image to your Portenta X8. To do so, connect to your Portenta X8 through ADB. It can be found at `Arduino15\packages\arduino\tools\adb\32.0.0`. + +```arduino +portenta-x8$: docker import /home/fio/x8-custom-devel_latest.tar.gz x8-custom-devel:latest +``` +Now your image is correctly deployed on your Portenta X8. + +### Launch Your Container + +In order to launch your brand new image, you need to create a new `docker-compose.yml`. To do so, first you must stop the current `docker-compose.yml`. + +```arduino +portenta-x8$: cd /var/sota/compose-apps/arduino-ootb && docker compose stop +``` + +You can now create the path for the new `docker-compose.yml`: + +```arduino +portenta-x8$: mkdir /var/sota/compose-apps/custom-devel && cd /var/sota/compose-apps/custom-devel && touch docker-compose.yml +``` +Before uploading, open the `docker-compose.yml` and edit it as follow to make it use the Docker image you have just created: + +```arduino +services: + custom: + container_name: custom-devel + hostname: "portenta-x8" + image: x8-custom-devel:latest + + restart: unless-stopped + tty: true + read_only: false + user: "0" + volumes: + #- '/dev:/dev' + - '/run/arduino_hw_info.env:/run/arduino_hw_info.env:ro' + - '/sys/devices:/sys/devices' + - '/sys/class/pwm:/sys/class/pwm' + - '/sys/bus/iio:/sys/bus/iio' + - '/var/sota:/var/sota' + - './keys:/tmp/keys:ro' + devices: + - '/dev/gpiochip5' + - '/dev/tee0' +``` + +It is now time to upload the new `docker-compose.yml` to your Portenta X8: + +```arduino +portenta-x8$: docker-compose up --detach +``` + +And you are ready to go! Your Portenta X8 Dashboards and Things can be customized multiple times with the same process. + +***If you are using the Portenta X8 Manager, go to [this documentation](https://docs.foundries.io/latest/tutorials/getting-started-with-docker/getting-started-with-docker.html) to learn how to upload the newly created container in your FoundriesFactory.*** + +## Working With Portenta X8 Board Manager + +As already mentioned, Portenta X8 Board Manager allows you to easily keep your Portenta X8 Linux image and corresponding containers up to date, even from remote through Over-The-Air (OTA) updates (via wireless connectivity). + +Subscribe to an *Arduino Cloud for business* plan with Portenta X8 Board Manager to have access to all these features. Take a look at [this section](#portenta-x8-board-manager) of the user manual to learn more. + +### Device And Fleet Management With Portenta X8 Board Manager + +Verify that your Portenta X8 is correctly added to your FoundriesFactory by checking if it is listed among the available devices under the **Devices** section. + +![FoundriesFactory device overview](assets/web_board_manager_factory_device-overview.png "FoundriesFactory device overview") + +If you want to check if your Portenta X8 is updated according to the latest available Target (i.e. update), you can check the color of the bulb under the status column. There are three main color options: + +| Bulb color | Meaning | +|-------------|--------------------------------| +| Green | Device online and updated | +| Yellow | Device online and not updated | +| Red | Device offline and not updated | + +In this case, the Portenta X8 is connected to the network (and so to the FoundriesFactory), but it is not updated. + +You can see the Target uploaded on your device under the Target column, i.e. *portenta-x8-lmp-569*, and get additional information about what is included in this specific Target by clicking on it. + +![FoundriesFactory device target specs](assets/web_board_manager_factory_device_specs.png "FoundriesFactory device target specs") + +The above window also shows you all the container apps you have installed on your device and you can start using. + +If you scroll down in the same window, you can also have a look at the update history of that specific device. + +![FoundriesFactory device update history](assets/web_board_manager_factory_update_history.png "FoundriesFactory update history") + +At this point, you can compare the Target uploaded on your Portenta X8 with the Target available in the **Targets** section and decide whether to update your device or not. + +![FoundriesFactory target overview](assets/web_board_manager_factory_target.png "FoundriesFactory target overview") + +***Learn how to update your Portenta X8 with your FoundriesFactory by checking the [dedicated section](#portenta-x8-os-image-update) of this user manual.*** + +This **Target** page contains the Linux images built each time something is committed in the repositories available under the **Source** section. In this section, you can find the four repositories that are used to customize the images: +* **ci-scripts.git:** Scripts that define the platform and container build jobs on the FoundriesFactory system. +* **containers.git:** This is where containers and docker-compose apps are defined. It allows you to define which containers to build/deploy and how to orchestrate them on the platform. +* **lmp-manifest.git:** The repo manifest for the platform build. It defines which layer versions are included in the platform image. This includes **meta-partner-arduino**, the layer containing Arduino-specific customizations (machine definition, device drivers, etc.). +* **meta-subscriber-overrides.git:** *OE* layer that defines what is included in your FoundriesFactory image. You can add board-specific customizations and overrides or add and remove packages provided in the default Linux microPlatform. + +Committing to **lmp-manifest.git** or **meta-subscriber-overrides.git** repositories will create a platform Target, i.e. base Linux platform image. On the other hand, committing to **containers.git** will create a container Target including all the containers and docker-compose apps you would like to upload on your Portenta X8. Both these Targets will generate the artifacts specified in the **ci-scripts.git**, which includes all the required files to program the Target in case of platform build. + +### RBAC With Portenta X8 Board Manager + +You do not have to be the only one in your organization with permission to update your Portenta X8 devices. The FoundriesFactory integrates a Role-Based-Access-Control functionality (RBAC) to allow users to add multiple teams with multiple members each. + +You can start defining a new team by clicking on **Teams** section. + +![FoundriesFactory Teams](assets/web_board_manager_team.png "FoundriesFactory Teams") + +The level of access and specific permissions are defined by the team’s role in the FoundriesFactory. As you can notice from the image below, multiple roles and permissions are available. + +![FoundriesFactory Team roles and permissions](assets/web_board_manager_factory_team_roles.png "FoundriesFactory Team roles and permissions") + +Once you created the team, you can go to the **Members** section of your FoundriesFactory to invite new members to the team. + +![FoundriesFactory new member](assets/web_board_manager_factory_member.png "FoundriesFactory new member") + +You can type the email addresses of your teammates and they will receive an automatic email with the invitation to join the corresponding team in your FoundriesFactory. + +### FoundriesFactory FIOCTL + +The FoundriesFactory includes a command line tool called [FIOCTL](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) which allows you to manage your Portenta X8 through your CLI. + +With this tool, you can easily upload containers to a board that is linked to your FoundriesFactory just by stating the FoundriesFactory name, the board name and the app you would like to upload. + +***Learn how to use this tool by checking the dedicated tutorial at [this link](https://docs.arduino.cc/tutorials/portenta-x8/custom-container) or the corresponding [Foundries documentation](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html).*** + +## Portenta X8 OS Image Update + +It is recommended to check every now and then if your Portenta X8 image version is up to date, in order to have the latest security updates. + +In the next sections, three major ways to update your Portenta X8 are described: +* Update through Out-of-the-box experience (available for OS release XXXX or newer) +* Update through Portenta X8 Manager in your Arduino Cloud for Business account (available for all OS releases) +* Update for OS release V.399 + +### Check Portenta X8 OS Release + +In order to verify which OS release is flashed on your Portenta X8, you need to connect to your board through **ADB**, as explained in [this section](#working-with-linux) of this user manual. + +At this point, you can type `cat /etc/os-release` in your command line window to get the OS release currently running on your device. + +![Get OS release](assets/adb-shell-os-release.png "Get OS Release") + +As shown in the image above, the OS release of this Portenta X8 corresponds to `IMAGE_VERSION=569`. + +### Update Through Out-Of-The-Box Experience + +Leverage the integrated Out-of-the-box experience to update your Portenta X8 to the latest release. + +***Warning: The Out-of-the-box update feature is not a complete Over-The-Air (OTA) update, it allows the user to update only Portenta X8 default image and containers. It will overwrite any custom container application. Thus, it is recommended to make a local copy of your containers before updating your Portenta X8.*** + +Open your Out-of-the-box as explained in [this section](#first-use). + +![Out-of-the-box homepage](assets/OOTB_homepage.png "Out-of-the-box homepage") + +Click on **CHECK FOR UPDATES** in the lower right corner. + +At this point, you have to select whether you would like to proceed with the update. If yes, click on **UPDATE**. + +![Proceed with update](assets/OOTB_update_select.png "Proceed with update") + +During the update, do not turn off your Portenta X8 or disconnect it from the network. This process may take few minutes. + +![Successful update](assets/OOTB-succesful-OS-update.png "Successful update") + +Once the update is finished, your Portenta X8 will automatically restart with the new Linux image in place. + +At this point, if you would to continue to use your Out-of-the-box, you can open a new command line window and launch again the command `adb forward tcp:8080 tcp:80`. Now open your browser, go to [http://localhost:8080](http://localhost:8080) and the same Out-of-the-box dashboard will appear. + +#### Troubleshooting + +If something gets wrong during the update, you still have the possibility to manually flash your Portenta X8 with the latest Linux image provided at [this link](https://github.com/arduino/lmp-manifest/releases). Follow [this tutorial](https://docs.arduino.cc/tutorials/portenta-x8/image-flashing) to learn how to flash your device manually. + +### Update With Portenta X8 Board Manager + +If you have an *Arduino Cloud for business* account with the Portenta X8 Manager, check if the target installed on your Portenta X8 is the latest one available in your FoundriesFactory. + +![FoundriesFactory device overview](assets/web_board_manager_factory_device-overview.png "FoundriesFactory device overview") + +If this is not the case, you can update your device using FoundriesFactory **Waves** functionality. Check [this tutorial](https://docs.arduino.cc/tutorials/portenta-x8/waves-fleet-managment) to read the complete instructions. More information about Waves can be found in the official Foundries documentation at [this link](https://docs.foundries.io/latest/reference-manual/factory/fioctl/fioctl_waves.html?highlight=wave). + +### Update For OS Release V.399 + +If your Portenta X8 is flashed with the OS release V.399, open a new Command Line window and type the following commands on your PC: + +```arduino +user-pc$: wget https://downloads.arduino.cc/portentax8image/update-latest.tar.gz +user-pc$: wget https://downloads.arduino.cc/portentax8image/aklite-offline-399.tar.gz + +user-pc$: adb push update-latest.tar.gz /home/fio +user-pc$: adb push aklite-offline-399.tar.gz /home/fio +``` + +These commands will make your V.399 compatible with [aklite-offline](https://docs.foundries.io/latest/user-guide/offline-update/offline-update.html) tool and will allow you to update your Portenta X8 to the latest image version Arduino released at that point in time. Arduino provides this tool for free for any Portenta X8 user to enable offline secure updates to all devices, even if those devices are not connected to any FoundriesFactory. + +After the updates have been correctly downloaded to your PC, you can open a Command Line window and connect to your Portenta X8 through `ADB Shell`, as explained in [this section](#working-with-linux) of this user manual. + +Once your Portenta X8 is correctly connected to your PC, launch the following commands to update your device to the latest released OS image version: + +```arduino +user-pc$: adb shell + +portenta-x8$: cd /home/fio +portenta-x8$: tar -xvf update-latest.tar.gz -C . +portenta-x8$: tar -xvf aklite-offline-399.tar.gz -C . +portenta-x8$: export LD_LIBRARY_PATH=usr/lib/ +portenta-x8$: usr/bin/aklite-offline install --src-dir /var/rootdirs/home/fio/offline-updates/ +``` + +After the update process is finalized, you need to restart your Portenta X8 by pressing its button for around 10 seconds. Once restarted, your Portenta X8 will immediately start running the latest OS release. + +## Pins + +In order to learn how to properly call GPIOs or other peripherals both in the Arduino environment or in Linux, with or without a carrier, you can check the following pinout diagrams: +* [Portenta X8 pinout](https://docs.arduino.cc/static/019dd9ac3b08f48192dcb1291d37aab9/ABX00049-full-pinout.pdf) +* [Portenta Breakout pinout](https://docs.arduino.cc/static/1d4277f47a3df614b726a89b2129ec69/ASX00031-full-pinout.pdf) +* [Portenta Max Carrier pinout](https://docs.arduino.cc/static/d0bd73b17e97af0fe376b7d518b18660/ABX00043-full-pinout.pdf) + +## Communication + +In this section you will learn how to make your Portenta X8 to communicate with multiple types of sensors or other external devices, leveraging the vast variety of supported interfaces: +* [SPI](#SPI) +* [I2C](#I2C) +* [UART](#UART) +* [Bluetooth®](#Bluetooth®) + +### SPI + +In this case, a Portenta X8 with Portenta Breakout board is used to connect an external SPI device. + +#### SPI With Linux + +You need to enable SPI support before using SPI devices. + +Open Portenta X8 Shell as explained [here](#working-with-linux). + +```arduino +sudo madprobe spi-dev +``` +Insert the user password `fio`. + +An upcoming image release for the X8 will load the `spi-dev` modules automatically at boot. In the current version, please create a `/etc/modules-load.d/spi-dev.conf` file with the following content: + +```arduino +spi-dev +``` + +and restart the board. + +```arduino +echo "spi-dev" | sudo tee > /etc/modules-load.d/spi-dev.conf +sudo systemctl reboot +``` + +Add the device you want to communicate within a container in a `docker-compose.yml` file: + +```arduino +services: + my_spi_service: + devices: + - /dev/spi-1 + - /dev/spi-2 + - /dev/spi-3 +``` + +If the Linux user on which the container is running is not `root`, you need to set up the permissions for the user to access the SPI devices. You might add the required comments to an `entrypoint.sh` shell file (to be added to the `Dockerfile` or the `docker-compose.yml` file). + +```arduino +#!/usr/bin/env sh + +# entrypoint.sh example + +chgrp users /dev/spi-* +chmod g+rw /dev/spi-* +usermod -aG users + +# Possible command to execute your application as a non-privileged user with gosu +# Check https://github.com/tianon/gosu for more information +gosu /usr/bin/python my_spi_service.py +``` + +#### SPI Port Mapping + +| Linux | Arduino Portenta Breakout | +|-------|---------------------------| +| 134 | **`SPI1 CK`** | +| 135 | **`SPI1 COPI`** | +| 136 | **`SPI1 CIPO`** | +| 137 | **`SPI1 CS`** | + + +#### SPI With Arduino + +The `SPI` object is [mapped](https://github.com/arduino/ArduinoCore-mbed/blob/23e4a5ff8e9c16bece4f0e810acc9760d3dd4462/variants/PORTENTA_X8/pins_arduino.h#L85) as follows on the Portenta Breakout Board and can be deployed as usual: + +| SPI Pin | Arduino Portenta Breakout | +|---------|---------------------------| +| CIPO | Pin 0 (Header GPIO0) | +| COPI | Pin A6 (Header Analog) | +| SCK | Pin A5 (Header Analog) | +| CS | Pin 1 (Header GPIO0) | + + +### I2C + +In this case, a Portenta X8 with Portenta Breakout board is used to connect an external I2C device. + +#### I2C With Linux + +You need to enable I2C support before using I2C devices. + +Open Portenta X8 Shell as explained [here](#working-with-linux). + +Thus, execute the following command: + +```arduino +sudo madprobe i2c-dev +``` + +Insert the user password `fio`. + +An upcoming image release for the X8 will load the `i2c-dev` modules automatically at boot. In the current version, please create a `/etc/modules-load.d/i2c-dev.conf` file with the following content: + +```arduino +i2c-dev +``` + +and restart the board. + +```arduino +echo "i2c-dev" | sudo tee > /etc/modules-load.d/i2c-dev.conf +sudo systemctl reboot +``` + +Add the device you want to communicate within a container in a `docker-compose.yml` file: + +```arduino +services: + my_i2c_service: + devices: + - /dev/i2c-1 + - /dev/i2c-2 + - /dev/i2c-3 +``` + +If the Linux user on which the container is running is not `root`, you need to set up the permissions for the user to access the I2C devices. You might add the required comments to an `entrypoint.sh` shell file (to be added to the `Dockerfile` or the `docker-compose.yml` file). + +```arduino +#!/usr/bin/env sh + +# entrypoint.sh example + +chgrp users /dev/i2c-* +chmod g+rw /dev/i2c-* +usermod -aG users + +# Possible command to execute your application as a non-privileged user with gosu +# Check https://github.com/tianon/gosu for more information +gosu /usr/bin/python my_i2c_service.py +``` + +#### I2C Port Mappings + +| Linux | Arduino Portenta Breakout | Notes | +|------------|---------------------------|---------------| +|`/dev/i2c-1`| **`I2C1`** | | +|`/dev/i2c-2`| **`I2C0`** | Recommended | +|`/dev/i2c-3`| **`I2C1`** | | + +#### Examples + +Examples of using SMBus-compatible [libraries](https://github.com/kplindegaard/smbus2): + +```arduino +from smbus2 import SMBus + +# Connect to /dev/i2c-2 +bus = SMBus(2) +b = bus.read_byte_data(80, 0) +print(b) +``` + +Example of using [python-periphery](https://python-periphery.readthedocs.io/en/latest/index.html): + +```arduino +from periphery import I2C + +# Open i2c-0 controller +i2c = I2C("/dev/i2c-2") + +# Read byte at address 0x100 of EEPROM at 0x50 +msgs = [I2C.Message([0x01, 0x00]), I2C.Message([0x00], read=True)] +i2c.transfer(0x50, msgs) +print("0x100: 0x{:02x}".format(msgs[1].data[0])) + +i2c.close() +``` + +#### I2C With Arduino + +The `Wire` object is [mapped](https://github.com/arduino/ArduinoCore-mbed/blob/23e4a5ff8e9c16bece4f0e810acc9760d3dd4462/variants/PORTENTA_X8/pins_arduino.h#L113) to pins `PWM6` (I2C `SCL`) and `PWM8` (I2C `SDA`) on the Portenta Breakout Board and can be deployed as usual. + +Since one of the `I2C` pins is GPIO-multiplexed, you need to detach it from the other GPIO. Just add the following line in the `setup()` definition to have it fully functional for `I2C` operations. + + ```arduino + void setup() + { + pinMode(PA_12, INPUT); + } + ``` + +### UART + +In this case, a Portenta X8 with Portenta Breakout board is used to explore UART communication. + +#### UART With Linux + +A standard UART is available as `/dev/ttymxc1` in Linux and is mapped to the **`UART1`** port on the Portenta Breakout. + +#### UART With Arduino + +The `Serial1` object in the Arduino sketch is mapped to the **`UART0`** port on the Portenta Breakout. + +Please note that the Arduino RS485 (thus the Arduino Modbus library) library is not supported on the Arduino core of the X8. + +### Bluetooth + +Portenta X8 supports Bluetooth connectivity just on the Linux side. + +In order to communicate with Bluetooth devices via the Portenta X8 Shell, you can use the Bluetooth utility **bluetoothctl**. These are some of the most used commands: +* `bluetoothctl devices` to list all the available Bluetooth devices +* `bluetoothctl pair [mac_address]` to pair with a specific device through its MAC address +* `bluetoothctl connect [mac_address]` to connect to a paired device +* `bluetoothctl disconnect [mac_address]` to disconnect from a paired device + +***Do you want to send data from your Nicla to Portenta X8 via BLE? Check [this link](https://github.com/Zalmotek/arduino-environmental-monitoring-with-arduino-pro) to get started.*** diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/hero-banner.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/hero-banner.png new file mode 100644 index 0000000000..e0b1122094 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/01.user-manual/hero-banner.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/x8-fundamentals/assets/factory-page.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/02.x8-fundamentals/assets/factory-page.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/x8-fundamentals/assets/factory-page.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/02.x8-fundamentals/assets/factory-page.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/02.x8-fundamentals/portenta-x8-fundamentals.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/02.x8-fundamentals/portenta-x8-fundamentals.md new file mode 100644 index 0000000000..b90000f1df --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/02.x8-fundamentals/portenta-x8-fundamentals.md @@ -0,0 +1,85 @@ +--- +title: '02. How to Use the Portenta X8 Manager' +difficulty: beginner +tags: [Linux, containers, factories, foundries] +description: 'This article contains information about how to use the Portenta X8 Manager.' +author: Benjamin Dannegård +hardware: + - hardware/04.pro/board/portenta-x8 +software: + - fioctl + +--- + +## Overview + +The **Portenta** X8 is one of the more advanced boards available from Arduino. And with that comes some new concepts that are not standard for Arduino boards. In this article, we will go through some of the foundations of the Portenta X8 and help you understand how the board works and how you can benefit from its advanced features of this board. You will learn about FoundriesFactory® and how containers on the Portenta X8 work. + +## Goals + +- Get in-depth information about how the Portenta X8 works +- Learn how containers work + +### Required Hardware and Software + +- [Portenta X8](https://store.arduino.cc/portenta-x8) +- [fioctl](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) + +## Instructions + +If you need help setting up your board, please have a look at the "Getting Started" tutorial. That tutorial will show you how to set up your board with FoundriesFactory and install containers on it. + +## Embedded Linux + +There are a few things to consider to work in an embedded Linux environment. When approaching Linux-based embedded devices software solutions, you need to provide a base distribution, a mechanism to update it, and some applications that can run on the board. The X8 uses a Linux distribution built with the Yocto Project® as the base platform, with applications that are installed and packaged as confined containers. + +A readily-available Linux distribution that packages everything seems most attractive for end users but you need to find a distribution that implements the function that you need. If you need to tweak them, you may end up in a mess of patches on the top of someone else's build system. On the other hand, a generic distribution has some problems since installing software over it may pollute the original system and cause issues when updating the base platform. For example, if you install a new application, the older one no longer works. + +In addition, you have to implement lots of things like cybersecurity functions and system updates. Finally, your solution may rely on a too "generic" distribution, with tons of software you don't need. So you may end up removing a lot of software on the target and turning features on and off. Until you break the configuration or need to update the system and begin restarting with a new fresh image, consequently beginning everything from zero again. + +### Benefits of Foundries.io + +Foundries.io™ created their custom distribution based on Yocto with minimal software installed, by default implementing top-level cybersecurity features like OP-TEE and OSTREE that makes their solution ideal for professional applications. + +A custom Over-The-Air (OTA) system update mechanism that is based on a client running on target and a robust cloud server. And they married Docker-compose as a way to deploy a software solution to a target. This is like having an app store for a particular device with the difference that we're not installing an app but a container that may contain a whole distribution or a minimal distribution running only our app or our set of apps. + +Additionally, they developed the cloud side as well. You can use what's called FoundriesFactory, a cloud DevSecOps subscription service to build, test, deploy, and maintain secure, updatable IoT and Edge products. It provides a unique id and automatic builds of the base system and containers for this system in one place. Let's now take a look at the Foundries.io Factory page. + +### Foundries.io Factory + +With the help of the Arduino Cloud integration with *Foundries.io*, you can easily create your Factory right from the Arduino Cloud page. You can set your Factory's platform and name. The Portenta X8 will be the platform in this case. + +![Factory page](assets/factory-page.png) + +Your Factory page allows you to add members so that you can easily keep track of the members of your team that should have access to the Portenta X8's that are linked to your Factory. You can also set up teams for better management. On the page, you can also find a list of all devices linked to the Factory, along with their name and version of the container currently uploaded to the board. On the containers page, you can find all the different versions of containers uploaded to the Factory. + +On the "source" page of your Factory, you can find the four repositories that are used to customize the images. These are: + +- **ci-scripts.git**: Scripts that define the platform and container build jobs to the FoundriesFactory continuous integration system. +- **lmp-manifest.git**: The repo manifest for the platform build. It defines which layer versions are included in the platform image. This includes **meta-partner-arduino**, the layer containing Arduino specific customizations (machine definition, device drivers, etc). +- **meta-subscriber-overrides.git**: OE layer that defines what is included in your Factory image. You can add board-specific customizations and overrides. Also, add and remove packages provided in the default Linux microPlatform base. +- **containers.git**: This is where containers and docker-compose apps are defined. It allows us to define what containers to build, and how to orchestrate them on the platform. + +While the "targets" page contains the images built by the Continuous integration system each time something commits in the repositories. Committing to **lmp-manifest.git** or **meta-subscriber-overrides.git** repositories will create a platform target while committing to **containers.git** will create a container target. These targets will generate the artifacts for the platforms as specified in the **ci-scripts.git**, including all the required files to program the target in case of platform builds. You can inspect your FoundriesFactory targets on the "targets" page. + +## Containers + +Containers allow for easy deployment of Linux-based processes, uploaded through git, which can then be tracked on your Factory page. A Linux container is a process isolated from the rest of the system. A container is an image file conformed of the necessary files to run it. This makes the Linux containers portable and consistent throughout development, testing, and production. Making them much quicker to use than development pipelines that rely on replicating traditional testing environments. + +*Foundries.io* provides a service that builds images using the Yocto Project and is specifically built around the Linux microPlatform (LmP) distribution they maintain. LmP contains an extensive set of software components needed for IoT applications. + +Using [fioctl](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) allows you to manage your boards through CLI. It makes it easy to upload containers to a board linked to your Factory. When the board is online and connected to the Factory, you can easily push new apps to the board. Using the fioctl command lines, you only need to state the Factory, board, and app. + +### Benefits of Containers + +For example, if you are developing an application on a laptop and your environment has a specific configuration. Other developers may have slightly different configurations. The application will rely on your configuration and be dependent on specific files, libraries, and dependencies. On the other hand, your business has development and production environments with their configurations and supporting files. You would want to emulate that environment as much as possible locally. + +With containers, you can make your app work across environments, pass quality assurance and deploy as fast as possible effortlessly. + +The container image contents can be compared to an installation of a Linux distribution complete with RPM packages, configuration files, etc. However, a container image distribution is easier to install than setting a whole new copy of the operating system. + +A Linux container is a good solution that requires portability, configurability, and isolation. The idea behind Linux containers is to help develop solutions faster to meet business needs as they arise. In certain scenarios, when real-time data streaming is implemented, containers are a dominant solution to provide the scalability that the application needs. Regardless of the infrastructure on-site, in the cloud, or a mix of both. + +## Conclusion + +In this tutorial, we have expanded on how the Portenta X8 works with factories and containers. This article also gives a better picture of how to utilize the Portenta X8 to its full potential. Please check out our other tutorials with the Portenta X8 to see how factories and containers are applied in a real-world example. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/assets/x8-board-manager.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/assets/x8-board-manager.png new file mode 100644 index 0000000000..2a9d91d514 Binary files /dev/null and b/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/assets/x8-board-manager.png differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/assets/x8-terminal-ADB-push.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/assets/x8-terminal-ADB-push.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/assets/x8-terminal-ADB-push.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/assets/x8-terminal-ADB-push.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/content.md new file mode 100644 index 0000000000..fc02ad2a80 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/03.uploading-sketches-m4/content.md @@ -0,0 +1,87 @@ +--- +title: '03. Uploading Sketches to the M4 Core on Arduino Portenta X8' +description: 'This tutorial explains how to upload Arduino sketches to the M4 core.' +difficulty: intermediate +tags: + - Firmware + - M4 +author: 'Pablo Marquínez' +hardware: + - hardware/04.pro/boards/portenta-x8 +software: + - ide-v1 + - ide-v2 + - cli +--- + +## Overview + +In this tutorial, we will go through the process of uploading sketches to the M4 core on the STM32H747XI MCU. For the user, the process is the same as usual but it differs quite a bit in regards to what happens behind the scenes compared to other Arduino boards. + +## Goals + +- Learn how to use the Arduino IDE to compile and upload a sketch +- Learn how to compile the sketch binaries with the Arduino IDE and upload them manually via ADB + +### Required Hardware and Software + +- [Portenta X8](https://store.arduino.cc/products/portenta-x8) +- USB-C® cable (either USB-A to USB-C® or USB-C® to USB-C®) +- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino CLI](https://github.com/arduino/arduino-cli) +- Latest "Arduino Mbed OS Portenta Boards" Core + +## Instructions + +### Standard Arduino IDE Upload + +It is a straightforward process to upload to M4 Core using Arduino IDE. You will have to select the Portenta X8 in the board selector inside the Arduino IDE. + +![IDE board selector](assets/x8-board-manager.png) + +Create a custom sketch or open one of the example sketches. For example, we will use the blink sketch: + +```arduino +void setup(){ + pinMode(LED_BUILTIN ,OUTPUT); +} + +void loop(){ + digitalWrite(LED_BUILTIN , HIGH); + delay(1000); + digitalWrite(LED_BUILTIN , LOW); + delay(1000); +} +``` + +1. Select the port of your device in the port selector menu +2. Press the Compile and Upload button + +The sketch gets compiled into a binary. That binary file is then uploaded to the Linux side of the Portenta X8 via an `adb` SSH connection. The flashing is done on the board itself by active service on Linux. When the sketch has been uploaded successfully, check if the onboard LED is blinking at an interval of one second. + +### Upload Manually Using ADB + +An alternative to using the standard Arduino IDE upload procedure is by uploading the sketch manually using ADB. First, we need to compile the sketch. In the Arduino IDE, select "Export compiled binary" from the Sketch menu. It will compile the sketch and save the binary file in the sketch folder. Alternatively, you can use the [Arduino CLI](https://arduino.github.io/arduino-cli/) to create an `elf` file. + +To upload the firmware, you can use the ADB tool that has been installed as part of the Portenta X8 core. It can be found at `Arduino15\packages\arduino\tools\adb\32.0.0`. + +From that directory, you can use the `adb` tool. To upload your compiled sketch, you will need to use the following command: + +``` +adb push /tmp/arduino/m4-user-sketch.elf +``` + +![ADB upload with a terminal](assets/x8-terminal-ADB-push.png) + +## How Does It Work? + +The Portenta X8 has a service that waits for a sketch to be uploaded to a folder. If it detects changes, the device will flash the M4 with the uploaded firmware. This works thanks to the following service: + +* **monitor-m4-elf-file.service**: this service monitors the directory `/tmp/arduino/m4-user-sketch.elf` and each time it detects a new file, it will proceed to flash the M4 using `openOCD` with the sketch that has been pushed. + +## Conclusion + +In this tutorial, you have learned how to upload a sketch to the M4 core, by using the standard Arduino IDE procedure and manually with ADB. Now for example you can connect an I2C sensor and interact with it. + +## Troubleshooting + +- If you cannot use the `ADB` tool and the folder `Arduino15\packages\arduino\tools\adb\32.0.0` is empty, remove the Mbed Portenta Core and install it again. \ No newline at end of file diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/assets/component-placement.svg b/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/component-placement.svg similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/assets/component-placement.svg rename to content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/component-placement.svg diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/py-serialrpc.zip b/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/py-serialrpc.zip similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/py-serialrpc.zip rename to content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/py-serialrpc.zip diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/assets/python-sensor-rpc.zip b/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/python-sensor-rpc.zip similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/assets/python-sensor-rpc.zip rename to content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/python-sensor-rpc.zip diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/assets/sensor-wiring-breakout.svg b/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/sensor-wiring-breakout.svg similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/assets/sensor-wiring-breakout.svg rename to content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/assets/sensor-wiring-breakout.svg diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/content.md new file mode 100644 index 0000000000..320df5128d --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/04.python-arduino-data-exchange/content.md @@ -0,0 +1,134 @@ +--- +title: '04. Data Exchange Between Python® on Linux & Arduino Sketch' +description: 'This tutorial will show you how to run a Python® application that exchanges data with an Arduino Sketch.' +tags: + - RPC + - Python® +author: 'Sebastian Romero' +hardware: + - hardware/04.pro/boards/portenta-x8 +--- + +## Overview + +The container infrastructure provided by Arduino contains a pre-built Python® image that you can use to run Python® applications on the Portenta X8. In this tutorial, we're going to build a container based on a provided one. + +While all the peripherals are accessible from the iMX8 processor running the Linux environment, it can be useful to let the onboard microcontroller take care of certain peripheral handling and exchange only the required data between the microcontroller and the Python® application. + +Thus you will learn how to do that. If you haven't done so, read through the [foundations article](/tutorials/portenta-x8/x8-fundamentals) to understand the fundamental concepts of the X8 and the provided infrastructure. + +## Goals + +- Learn how the RPC mechanism on the X8 works +- Learn how to exchange sensor data between Linux and an Arduino sketch +- Learn how to modify a container and run it +- Learn how to use commands to debug the container and service infrastructure + +### Required Hardware and Software + +- [Portenta X8](https://store.arduino.cc/products/portenta-x8) board +- [Portenta breakout](https://docs.arduino.cc/hardware/portenta-breakout) board +- Any sensor (in this example, we'll use an [BME680](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme680/) I2C module) +- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor) + +## Python® on the X8 + +Python® is a modern and powerful scripting language used for a wide range of applications. In this tutorial, we only read sensor data from an Arduino sketch, but you could extend the example and process the data further. + +### Communication Between Linux and Arduino Sketches + +The Python® script will run on the Linux side and therefore on the iMX8 processor. The Arduino sketch, on the other hand, will run on the STM32H747 microcontroller. It allows for real-time processing on the Arduino side while running a fully-fledged operating system on iMX8. + +However, the two processors need a communication mechanism to exchange data with one another. RPC (Remote Procedure Call) is the communication mechanism for this task. To facilitate communication, the M7 core on the STM32H747 microcontroller is used to hand over any data/request to the M4 core. That means your Arduino sketch will solely run on the M4 core. Dual-core processing on the Arduino side is currently not supported. + +On the Linux side, there is a service that takes care of sending data between the two worlds. It's called `m4-proxy`. You can check if the service is running by logging into the X8 via `adb shell` and then executing `sudo journalctl -fu m4-proxy`. If the service has stopped unexpectedly, you can restart it with `sudo systemctl restart m4-proxy`. + +## The Arduino Sketch + +The Arduino sketch to read sensor data doesn't look much different from an ordinary sketch. The only difference is that we expose the sensor data via RPC. + +```arduino +RPC.bind("temperature", []{ return bme.temperature; }); +RPC.bind("humidity", []{ return bme.humidity; }); +RPC.bind("pressure", []{ return bme.pressure / 100.0F; }); +RPC.bind("gas", []{ return bme.gas_resistance / 1000.0; }); +RPC.bind("altitude", []{ return bme.readAltitude(SEALEVELPRESSURE_HPA); }); +``` + +Two additional header files need to be included to enable the RPC mechanism on Portenta X8: + +```arduino +#include +#include +``` + +The `RPC.bind()` method makes the data available via the specified name e.g. "temperature". In our example, an anonymous function is created to return the corresponding sensor property whenever requested. Alternatively, you could bind the name to an existing, named function instead. The data can then easily be requested using that name (e.g. "humidity") by querying the `m4-proxy` service. Once data is requested, it is packaged as a message and sent over SPI to the iMX8. + +![The iMX8 and the STM32H747 processor communicate via SPI](assets/component-placement.svg) + +You can find the sketch in the software package [here](assets/python-sensor-rpc.zip). You may need to change the sketch depending on the choice of the sensor to read from. If you're using an I2C sensor, you can connect SCL to **PWM6** and SDA to **PWM8** on the Portenta breakout. That's because the labeled I2C pins on the Portenta Breakout are only available on the Linux side. If you're using an analog sensor, you can connect it to any analog pin. Please refer to the pinout diagram on the Portenta Breakout [documentation page](/hardware/portenta-breakout). + +![Wiring diagram of an I2C sensor attached to the X8 via Portenta Breakout](assets/sensor-wiring-breakout.svg) + +Make sure you have installed the "Arduino Mbed OS Portenta Boards" core and upload the sketch to the X8 in the Arduino IDE or via Arduino CLI. + +### Debugging the Arduino Sketch + +To check if the Arduino sketch is working correctly, you may want to read the messages from the `Serial.println` statements. You cannot currently read them directly in the serial monitor of the Arduino IDE. Instead, you can use a simple service called `py-serialrpc`, which listens for those messages and prints them to the console. + +This service needs to run on the Linux side of the X8. You can get the files [here](assets/py-serialrpc.zip). From the command prompt of your local machine, navigate to the adb tool folder and upload the files to the X8 with `adb push /py-serialrpc /home/fio`. + +Log into the X8 shell with `adb shell` and navigate into the `serialrpc` folder. Build the container using `sudo docker build . -t py-serialrpc`. The `-t` flag assigns a tag to the container. Then run the container by executing `cd..` and then `sudo docker-compose up -d`. The `-d` flag detaches the container so it runs in the background. Note that this will run the docker container persistently across reboots by registering it as a systemd service. To stop the container, run `sudo docker-compose stop`. + +Check if the container is running by executing `sudo docker ps`. You can then access the log of this service at any time by executing `sudo docker-compose logs -f --tail 20` from the **same directory**. + +If you do not wish to run the container in the background, skip the `-d` flag, you will get the console output directly in the executing shell. Once the container is running, you will see the messages being sent from the M4. + +## The Python® Application + +The Python® application requests the sensor data from the M4 over RPC and unpacks the message. Data can be requested by calling the function exposed over RPC on the M4 e.g.: + +```python +m4_proxy_address = 'm4-proxy' +m4_proxy_port = 5001 +rpc_address = RpcAddress(m4_proxy_address, m4_proxy_port) +rpc_client = RpcClient(rpc_address) +temperature = rpc_client.call('temperature') +``` + +The complete Python® application files are in the same package as the Arduino sketch (see above). Like in the previous step, upload the `python-sensor-rpc` folder to the X8 via `adb push /python-sensor-rpc /home/fio`. Log into the X8 via `adb shell`. Then navigate into the `python-sensor-rpc` folder and execute `sudo docker build . -t python-sensor-rpc`. When it is finished, you can run the container with `sudo docker-compose up`. After a few seconds, you should see the output from the Python application featuring the sensor readings on the M4 that exchanges through the RPC mechanism. The output should look similar to the following: + +``` +python-sensor-rpc_1 | ============================================ +python-sensor-rpc_1 | == Portenta X8 Sensor reading == +python-sensor-rpc_1 | ============================================ +python-sensor-rpc_1 | +python-sensor-rpc_1 | Temperature: 25.904266357421875 +python-sensor-rpc_1 | Humidity: 25.564695358276367 +python-sensor-rpc_1 | Pressure: 976.4400024414062 +python-sensor-rpc_1 | Gas: 136.496 +python-sensor-rpc_1 | Altitude: 311.0769348144531 +``` + +Whenever you change anything in the Python® script on your computer, you will have to sync it back to the X8 and re-build the container. Following command sequence will help you to do this process: + +``` +# On your computer +adb push python-sensor-rpc /home/fio + +# On X8 +sudo docker-compose down +sudo docker build . -t python-sensor-rpc +sudo docker-compose up +``` + +Alternatively, you could modify the files directly on the X8 using an editor such as VIM, so you don't need to upload the files every time. Re-building the container will be necessary in any case though. If you wonder how to specify the Python® script that is executed when running a container, have a look at the `Dockerfile` file. There you'll find the `ENTRYPOINT` command that takes multiple arguments. In our example: `ENTRYPOINT [ "python3", "m4_to_python.py"]`. + +## Conclusion + +In this tutorial, you learned how to use the docker infrastructure to build a container that runs a Python® application. You have also learned how to use the RPC mechanism to exchange data between the microcontroller and the iMX8, which runs the Linux operating system. + +### Next Steps + +- You may now further process the data that you receive from the Arduino sketch and e.g. upload it to a cloud service or similar. +- Familiarize yourself with Docker commands to adjust the docker configuration to your needs. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-container-rm.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-container-rm.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-container-rm.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-container-rm.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-images.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-images.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-images.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-images.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-ps.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-ps.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-ps.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-ps.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-pull.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-pull.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-pull.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-pull.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-run.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-run.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/docker-container/assets/docker-run.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/assets/docker-run.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/content.md new file mode 100644 index 0000000000..c00074d325 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/05.docker-container/content.md @@ -0,0 +1,136 @@ +--- +title: '05. Managing Containers with Docker on Portenta X8' +description: 'This tutorial shows how to install and manage your containers using Docker.' +difficulty: beginner +tags: + - containers + - Docker + - Hello-World +author: 'Pablo Marquínez' +software: + - Terminal + - Docker +hardware: + - hardware/04.pro/boards/portenta-x8 +--- + +## Overview + +[Docker](http://docker.com) is a platform full of applications, called containers. Containers are isolated solutions, thus they don't have to depend on your environment. Making them portable and consistent throughout development, testing, and production. + +You can download, install, use, and share applications in the form of containers. You can find all the available container images on the [hub.docker.com](https://hub.docker.com) page. + +In this tutorial, we will go through the steps of how to install, run and remove Docker's official [Hello-World image](https://hub.docker.com/_/hello-world) + +## Goals + +- Learn how to list installed and active containers +- Learn how to install a container +- Learn how to run a container manually +- Learn how to uninstall a container + +### Hardware and Software Requirements + +- [Arduino® Portenta X8](https://store.arduino.cc/products/portenta-x8) +- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) +- Wi-Fi® Access Point with Internet Access +- ADB, [Check how to connect to your Portenta X8](/tutorials/portenta-x8/out-of-the-box#controlling-portenta-x8-through-the-terminal) +- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor) + +***Make sure to have the Portenta X8 with the latest image as well as bootloader. Please check [how to flash your Portenta X8](/tutorials/portenta-x8/image-flashing) to have latest version.*** + +## Using Docker + +The Portenta X8 provides Docker CLI by default. The following command will help you verify if it is installed correctly: + +``` +docker -v +``` + +***To use this tool, you will need to connect to your device first. Check [how to connect using adb/ssh](/tutorials/portenta-x8/out-of-the-box#controlling-portenta-x8-through-the-terminal).*** + +You can check the Docker's reference documentation, which covers all the features of the tool in depth at [docs.docker.com](https://docs.docker.com/). + +The following steps will show how to install, run and uninstall the "Hello World" container. + +### How to Install a Container + +First, you will need to search for ["Hello World" container image](https://hub.docker.com/_/hello-world). The container image can be found within Docker hub, where you will be able to find variety of readily-available container images. It will be used to verify docker is working as intended with the Portenta X8. + +The following command must be used to pull the `hello-world` image. The Docker hub page for images have the instructions to pull the image and deploy the container. + +``` +docker pull hello-world +``` + +![Docker CLI pulling a container](assets/docker-pull.png) + +### Run The Installed Container + +This is the command to begin the container instance. + +``` +docker run hello-world +``` + +![Docker CLI running Hello World app](assets/docker-run.png) + +***To be able to see an active container with `docker ps -a`, you will need to run it at least once with `docker run`*** + +### Listing The Installed Packages + +The following command will display the active containers and will show the `hello-world` container if it was able to run successfully. The `STATUS` message will let you know if the container is active or has finished operation depending on its purpose. + +``` +docker ps -a +``` + +![Docker CLI listing all the active containers](assets/docker-ps.png) + +The list of available images, including installed `hello-world` image can be verified using the following command: + +``` +docker images +``` + +![Docker CLI images](assets/docker-images.png) + +### How to Uninstall A Container + +You will need to obtain assigned `CONTAINER ID` to be able to remove a container of choice. The list of active containers provides this information. The remove (`rm`) command is then used with the desired container identifier to proceed with removal process. + +``` +docker container rm +``` + +For this example, the command `docker ps -a` will show the `CONTAINER ID` of the `hello-world` container designated as: `c44ba77b65cb`. If you encounter an error stating that the container cannot be removed, it may mean that the container has an actively ongoing operation which can be checked with `STATUS` message. + +Granted that this is the case, you will need to stop the container and verify with `STATUS` message that it has exited successfully. To do this, following command is used: + +``` +docker stop +``` + +***Every time the image is re-installed or re-ran, the `CONTAINER ID` will be different than the previous identifier*** + +![Docker CLI container uninstall](assets/docker-container-rm.png) + +Using the `docker ps -a` after container removal, the `hello-world` container should no longer be present as an active container. + +The same goes for the images if you would like to free some space. The removal command will now be as follows using `IMAGE ID` found within image table: + +``` +docker rmi +``` + +If you run `docker images` again, you will see that the `hello-world` image is not showing up anymore. + +## Conclusion + +In this tutorial, you have learned how to use Docker with Portenta X8. You have learned to download an image, manage, and deploy the container, and ultimately run on Portenta X8. You have also learned to remove the image and the container to control Portenta X8's available resources. + +### Next Steps + +- Now that you have the base of the workflow to use [Docker](https://docker.com), go to its docs page and make sure you understand all the features. +- Look for a container image from [Docker hub](http://hub.docker.com), install it and make your own application out of it. +- Create a container to run your custom made application. For this, it may interest you [Create and Upload a Custom Container to the Portenta X8](tutorials/portenta-x8/custom-container) tutorial. \ No newline at end of file diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/assets/foundriesfactory-device-group.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/assets/foundriesfactory-device-group.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/assets/foundriesfactory-device-group.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/assets/foundriesfactory-device-group.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/assets/foundriesfactory-waves-page.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/assets/foundriesfactory-waves-page.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/assets/foundriesfactory-waves-page.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/assets/foundriesfactory-waves-page.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/content.md new file mode 100644 index 0000000000..dcec608f61 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/06.waves-fleet-managment/content.md @@ -0,0 +1,139 @@ +--- +title: '06. Using FoundriesFactory® Waves Fleet Management' +description: 'Learn how to manage multiple Portenta X8 devices using FoundriesFactory® fleet management tool: Waves.' +difficulty: intermediate +tags: + - Embedded Linux + - Flashing + - Foundries.io +author: 'Benjamin Dannegård' +hardware: + - hardware/04.pro/boards/portenta-x8 +--- + +## Overview + +In a production environment, it is convenient to plan updates and have control over when and which devices are updated. FoundriesFactory® Waves is the feature for this. It allows you to easily define a group of Portenta X8 and then push updates to that specific group. The difference between standard updates and using Waves to update is that the Wave update will promote targets to production by double signing them, which makes the updates more manageable and controllable. + +This tutorial will show you how to define fleets and how to construct a Wave that can then be pushed to a group. + +## Goals + +- Learn how to use Waves fleet manager +- Learn how to assign a target to a Wave +- Learn how to push a Wave to a group of devices + +### Required Hardware and Software + +- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) +- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) +- Arduino Create account +- Arduino Cloud for business subscription with Portenta X8 Manager add-on: [Learn more about here](https://cloud.arduino.cc/plans#business) +- Foundries.io™ account (linked with the Arduino Cloud for business subscription) +- FoundriesFactory® and devices already attached to your Factory ([Check the Getting Started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box)) + +## Instructions + +### Setting Up the Terminal + +Waves fleet management requires us to have the X8 setup with FoundriesFactory. If you have not done so, please follow our [Getting Started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box), as it will walk you through setting up the X8 with your Factory. + +To use Waves, you need to have fioctl installed and configured. Follow this [guide](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) to do so. Creating Waves and device groups will be done via the host, which is your factory. As such, the following commands will be entered in a terminal using fioctl to connect to your Factory. + +### Rotating Our Keys + +For security purposes, we recommend that you rotate your FoundriesFactory keys. Rotation of the key will convert the root role's online key, which was generated during the bootstrap of your Factory, to an [offline key](https://docs.foundries.io/latest/reference-manual/security/offline-keys.html). + +First, we will rotate the root keys. These are the most important keys, as they are used to create new target keys. Rotate them with the command: + +``` +fioctl keys rotate-root --initial /absolute/path/to/root.keys.tgz +``` + +Now we can rotate the target-only keys with following command: + +``` +fioctl keys rotate-targets /absolute/path/to/root.keys.tgz +``` + +And finally, for security reasons, we separating the target keys from the root using the following command: + +``` +fioctl keys copy-targets /absolute/path/to/root.keys.tgz /path/to/target.only.key.tgz +``` + +Now we can move on to creating our Wave. + +### Creating a Dummy Wave for Production Targets + +Before a Factory can start making production OTAs, an initial production Targets file must be created. For more information, please check out [here](https://docs.foundries.io/latest/reference-manual/ota/production-targets.html). We can begin by creating a dummy wave with the command: + +``` +fioctl wave init -k /absolute/path/to/targets.only.key.tgz populate-targets +``` + +Then complete the Wave with: + +``` +fioctl wave complete populate-targets +``` + +This creates a new `targets.json` file for production devices, subscribing to the production tag. It will include a single Target from the CI build. + +### Creating a Wave + +Now we can start creating our Wave. The command below will create a Wave that is pushable to our devices. To create a Wave, we will sign it with a key, and here we will use the targets-only key. Then we give the Wave a name, target number, and tag. The `target number` needs to correspond to the target that we want the Wave to contain for our devices. The `tag` can be set as production or development. + +``` +fioctl wave init -k /absolute/path/to/targets.only.key.tgz +``` + +And then we can complete the Wave by passing the name to the "complete" function: + +``` +fioctl wave complete +``` + +If you decide to cancel, the following command will help you to do that: + +``` +fioctl waves cancel +``` + +After creating the Wave, you should see it on your Factory page. It should also be marked as complete after you call the Wave complete command. + +![The wave page on your FoundriesFactory](assets/foundriesfactory-waves-page.png) + +### Create the Device Group + +With this command, we create our group, giving it a name and a short description: + +``` +fioctl config device-group create "" +``` + +The name and the short description should be as explicit and concise as possible to highlight its group. Now to assign a device to our group we use the following command: + +``` +fioctl device config group +``` + +On your FoundriesFactory device page, you can sort and view devices by the group. + +![Device group sorting on the FoundriesFactory page](assets/foundriesfactory-device-group.png) + +To roll out our Wave to our device group, use the following command: + +``` +fioctl waves rollout +``` + +Every device in the device group should now have the target specified in the Wave creation. + +### Conclusion + +In this tutorial, we first looked at what is required to use the Wave tool. We then went through the process of creating a Wave and device group. Then we pushed a target to the device group using the Wave tool. With this, you have learned to use FoundriesFactory® Waves Fleet Management for multiple Portenta X8. + +## Troubleshooting + +- If you are having trouble with any fioctl commands you can use `fioctl wave --help` or `fioctl wave rollout --help` depending on the context. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-container-folder.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-container-folder.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-container-folder.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-container-folder.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-factory-git.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-factory-git.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-factory-git.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-factory-git.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-factory-page.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-factory-page.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-factory-page.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-factory-page.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-git.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-git.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/custom-git.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/custom-git.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/factory-user-settings.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/factory-user-settings.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/factory-user-settings.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/factory-user-settings.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/token-creation-page.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/token-creation-page.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/assets/token-creation-page.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/assets/token-creation-page.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/content.md new file mode 100644 index 0000000000..773fe7fff4 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/07.custom-container/content.md @@ -0,0 +1,221 @@ +--- +title: '07. Oversee a Custom Container with Portenta X8 Manager' +difficulty: intermediate +tags: [Linux, Python®, Containers, ADB] +description: 'This tutorial will show you how to create and upload your custom container to your Portenta X8.' +author: 'Benjamin Dannegård' +hardware: + - hardware/04.pro/boards/portenta-x8 +software: + - adb +--- + +## Overview + +In this tutorial, we will create a simple container and upload it to the Arduino Portenta X8 with its manager. A container consists of an image file and all its dependencies if required. This tutorial will go through the needed files to create a container and its functions. Building this container locally and then uploading it to a Portenta X8. Using docker with ADB to build, run and attach our container to the Portenta X8. + +## Goals + +- Learn how to create a container for use with the Portenta X8 +- Learn how to upload a container to the Portenta X8 + +### Required Hardware and Software + +- [Portenta X8](https://store.arduino.cc/portenta-x8) +- ADB +- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) +- Arduino Pro Cloud Subscription [Learn more about the Pro Cloud](https://www.arduino.cc/pro/hardware/product/portenta-x8#pro-cloud) +- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor) + +## Instructions + +An active container uses an isolated filesystem. The container image provides its custom filesystem. Since the image contains the container’s filesystem, it must have everything required to run an application - all dependencies, configuration, scripts, binaries, etc. The image also contains further configurations for the container, such as environment variables, a default command to run, and other metadata. + +## Container File Structure + +To create the container, we need to collect the necessary files. Creating a folder called **x8-custom-test**, the following files need to be in the folder: + +- docker-build.conf +- docker-compose.yml +- Dockerfile +- requirements.txt +- src folder +- main.py (This file should be inside the src folder) + +The complete folder will look like this: + +![Folder structure for container](assets/custom-container-folder.png) + +Let us go through what these files contain and do. + +### Container File: Docker-build.conf + +A file containing the minimal "unit test" command is to be executed on the container to prove it's working. Our file will make our containers minimal unit test a test of the Python3 help command. + +```python +TEST_CMD="python3 --help" +``` + +### Container File: Docker-compose.yml +This file defines the app name through the Factory, permissions, and settings for the involved containers. The argument in the image tag will make it, so our image file builds locally. + +```python +version: '3.6' + +services: + x8-custom-test: + image: blob-opera:latest + restart: always + tty: true + read_only: true + user: "63" + tmpfs: + - /run + - /var/lock + - /var/log + - /tmp +``` + +### Container File: Dockerfile + +This is used to build the container. A Dockerfile is a text file that contains all the instructions (FROM, COPY, COMMAND, ENTRYPOINT, etc.) that a user can use from the command line to create different image layers. Although the final image can be created using the docker `build` command, the dockerfile serves just as an image definition. + +```python +FROM python:3-alpine3.15 + +# Set our working directory +WORKDIR /usr/src/app + +# Copy requirements.txt first for better cache on later pushes +COPY requirements.txt requirements.txt + +# pip install python deps from requirements.txt on the resin.io build server +RUN pip install -r requirements.txt + +# This will copy all files in our root to the working directory in the container +COPY ./src/main.py ./ + +# Enable udevd so that plugged dynamic hardware devices show up in our container. +ENV UDEV=1 + +# main.py will run when container starts up on the device +CMD ["python","-u","main.py"] +``` + +### Container File: Requirements.txt + +The requirements text file defines needed dependencies. These dependencies serves as useful tools to build the application of the container. + +```python +Flask==0.12.3 +``` + +### Container File: Source + +Here we will keep the source code of the app you want to run in the container or a startup script. We will create a **main.py** file in this folder. This script will print "Hello World!" in the CLI window. + +```python +from flask import Flask +app = Flask(__name__) + +@app.route('/') +def hello_world(): + return 'Hello World!' + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=80) +``` + +## Uploading the Container Folder + +First, you will need to set up your board to a Factory setting, as shown in the [Portenta X8 Out of the Box tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box). + +Once finished, we will push our folder to a repository within the Factory. Let us place our folder "x8-custom-test" inside the "containers.git" repository. You can find this repository inside your Factory page under "Source". Then, on "container.git", the page URL will be used in the following command. + +![Source on Foundries.io Factory page](assets/custom-factory-page.png) + +![Where to find container.git](assets/custom-factory-git.png) + +![Container.git page](assets/custom-git.png) + +To pull or push repositories, you have to generate an API key. This is done by going to the user settings on the Factory page. Click on the user drop-down menu, go into the tokens page and follow the steps of creating a new API key. When creating the API key, please make sure to select the "Use for source code access" option and the correct Factory that you want to use the key for. This token will be used as the password for all git operations while the username can be anything, except an empty string. + +![User settings on your Factory page](assets/factory-user-settings.png) + +![Token creation section in Foundries.io](assets/token-creation-page.png) + +Use the following command in git on your machine. To get the repository on your machine, replace "YOUR_FACTORY" with the name of your Factory. The "-b" parameter specifies a branch to checkout after cloning the repository. Running this command will get the container repository, where we will put our folder. + +``` +git clone https://source.foundries.io/factories/YOUR_FACTORY/containers.git -b devel +``` + +Put the "x8-custom-test" folder in the repository and push it with git. When you have put the folder into the git folder, use `git status` to see the changed files in the folder, it will show the unadded changes in red, then use `git add` to add the changes you want to your git commit. Then use `git commit` and `git push` to finally push the changes to the repo. If you push the commit to "containers.git" a new target will automatically build on your FoundriesFactory, you can inspect it on the "Targets" page. + +### Building and Running the Container + +After the build finishes, it can take up to 10 minutes for your device to update over-the-air to this new version. You can inspect it via the "Devices" tab of your FoundriesFactory. After your device takes the update, navigate into the "x8-custom-test" folder, which should be located on your board now. This allows us to build our container with a simple command. Using ```docker build``` with a ```--tag``` will let us give the container a tag so we can easily keep track of what version of the build this is. + +```python +docker build --tag "x8-custom-test:latest" . +``` + +Now that it is built, we can run it with ```docker run```, finding it with the tag that we chose to give to the build we want to run. Here we need to enter the user information into the --user tag. This information is found inside the "docker-compose.yml" file. + +```python +docker run -it --rm --user "63" x8-custom-test:latest +``` + +### Using Docker-Compose + +An option for testing an app or container is to use "docker-compose". It is helpful when we have a lot of settings in our "docker-compose.yml" file since we don't have to use those settings in the run argument with this method. First, navigate into the container folder. + +```python +cd /home/fio/x8-custom-test +``` + +This docker-compose command will start your application and register it as a systemd service that will persist even when a reboot occurs. So at the next boot, your docker-compose app will run automatically. + +```python +docker-compose up --detach +``` + +To stop the docker-compose app from running, use the following command: + +```python +docker-compose stop +``` + +## Deploying with Docker Hub + +An alternative method to deploy the custom container is by using the Docker Hub platform. For this, it needs a [Docker Hub account](https://hub.docker.com/) to have your own repository to have the custom container uploaded. When you have the repository ready, the following command will let you upload the custom container image. + +``` +docker push HUB_USERNAME/x8-custom-test +``` + +The custom container image can now be found within `HUB_USERNAME` Docker Hub repository. The image can be accessed whenever any connectivity type grants access to the container image. To pull the image and deploy the container, you will need to connect the Portenta X8 via ADB and use following commands in sequence: + +``` +adb shell +docker pull x8-custom-test +``` + +It will pull the container image and deploy the container on your Portenta X8. + +***To know more about how to create and manage repositories on Docker Hub to manage your custom containers for Portenta X8, check out [here](https://docs.docker.com/docker-hub/repos/#:~:text=To%20push%20an%20image%20to,docs%2Fbase%3Atesting%20).)*** + +## Conclusion + +This tutorial covered what goes into a container, how the folder should be structured, and what files it should contain. It then explained the purpose of each file and what they should have for this example. Then we went through how this relates to the Factory, and how Foundries.io makes the whole process easier for us. We then showed how to build the container and run it on the Portenta X8. Lastly, we showed a useful testing feature with docker-compose, letting us test our container with a faster process. + +### Next Steps + +To get a better understanding of how to manage containers with Docker, take a look at our [Managing Containers with Docker on Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/docker-container). This tutorial will show some useful commands to use with the docker service and ADB or SSH. + +## Troubleshooting + +Here are some errors that might occur in the process of this tutorial: + +- Make sure you have followed our other tutorials that shows how to set up the [Portenta X8 out of the box](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box) +- If you are having issues with the adb shell, don't forget to try and use `sudo` and `su` diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/copy_files.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/copy_files.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/copy_files.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/copy_files.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/docker_build.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/docker_build.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/docker_build.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/docker_build.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/docker_volume_explorer.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/docker_volume_explorer.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/docker_volume_explorer.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/docker_volume_explorer.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/git_clone_lmp-manifest.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/git_clone_lmp-manifest.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/git_clone_lmp-manifest.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/git_clone_lmp-manifest.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/git_config.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/git_config.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/git_config.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/git_config.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/portenta-x8_build.sh b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/portenta-x8_build.sh similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/portenta-x8_build.sh rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/portenta-x8_build.sh diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/repo_init.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/repo_init.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/repo_init.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/repo_init.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/repo_sync.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/repo_sync.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/repo_sync.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/repo_sync.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/repo_sync_finished.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/repo_sync_finished.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/repo_sync_finished.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/repo_sync_finished.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/tools_build.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/tools_build.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/tools_build.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/tools_build.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/tools_distro_setup.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/tools_distro_setup.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/tools_distro_setup.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/tools_distro_setup.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/tools_finished.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/tools_finished.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/tools_finished.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/tools_finished.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/x8_build.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/x8_build.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/x8_build.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/x8_build.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/x8_build_finished.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/x8_build_finished.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/x8_build_finished.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/x8_build_finished.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/x8_distro_setup.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/x8_distro_setup.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/assets/x8_distro_setup.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/assets/x8_distro_setup.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/content.md new file mode 100644 index 0000000000..1a46b025d9 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/08.image-building/content.md @@ -0,0 +1,239 @@ +--- +beta: true +title: '08. How To Build a Custom Image for Your Portenta X8' +description: 'This tutorial teaches you how to compile a custom image for your Portenta X8.' +difficulty: advanced +tags: + - Embedded Linux + - Building + - Yocto-project +author: 'Pablo Marquínez' +hardware: + - hardware/04.pro/boards/portenta-x8 +--- + +## Overview + +In this tutorial, you will learn how to build an image for the Portenta X8 with the source code provided at our [GitHub repository for lmp-manifest](https://github.com/arduino/lmp-manifest). Building your image locally can help debug several aspects of the system, such as the bootloader or kernel support. + +***Images built locally cannot register with FoundriesFactory and will not be OTA compatible, but this is a good alternative for those who do not have a FoundriesFactory subscription.*** + +This tutorial targets customers that are not FoundriesFactory subscribers, but still want to extend the functionality of the Arduino pre-built sources by building their images. For FoundriesFactory subscribers, we strongly suggest making use of your Factory's continuous integration system for image creation. + +## Goals + +- Learn how to build a "builder" Docker image +- Learn how to get the required files +- Learn how to configure the build settings +- Learn how to build the image +- Learn how to save the needed files for flashing + +### Required Hardware and Software + +- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) +- [Docker Engine](https://docs.docker.com/engine/install/) +- ~60GB available space on your machine's drive + +## Instructions + +### Docker + +#### Build the Docker Image + +You will create a Docker image that has the dependencies needed to build your device image. To do so, you will need to clone our [lmp-manifest repository](https://github.com/arduino/lmp-manifest). The following steps will guide you through the process: + +First, clone the lmp-manifest repository with the following command: + +``` +git clone https://github.com/arduino/lmp-manifest.git +``` + +![Cloning lmp-manifest repository](assets/git_clone_lmp-manifest.png) + +After cloning the lmp-manifest repository successfully, we will proceed to build the Docker Image using following command sequence: + +``` +cd lmp-manifest +docker build -t yocto-build ./lmp-manifest +``` + +![Building a Docker Image](assets/docker_build.png) + +You will be able to see similar result if everything went successfully. + +#### Run The Docker Image (Builder) + +Once the *Docker Image* is ready, we will run the image with the `-v` argument to mount a volume. This allows you to use a host directory inside the Docker image, so you can store all the data and build artifacts safely. + +***If you do not use a volume while running the image, you will lose the data when the image stops*** + +Run the `yocto-build` builder image with following command: + +``` +docker run -v :/dockerVolume -it yocto-build bash +``` + +We need to switch to the `builder` user with the following command after the previous process, and the password is **builder**: + +``` +su builder +``` + +### Image Setup and Build + +***You can download a [bash script](assets/portenta-x8_build.sh) that wraps all the upcoming steps.*** + +#### Setup the Environment + +Now that you are running inside the Docker Image, you can use tools like **git-repo**, which is already installed. + +First, configure git with your credentials. They don't need to be the real ones but are required by `git-repo` to pull. The following commands can be used for this example: + +``` +git config --global user.email "you@example.com" +git config --global user.name "Your Name" +``` + +![Adding credentials to git config](assets/git_config.png) + +Change to the home directory, and initialize the repository using **repo**: + +``` +cd ~ +repo init -u https://github.com/arduino/lmp-manifest.git -m arduino.xml -b release +``` + +![Git-repo initialization](assets/repo_init.png) + +Then pull the needed files with: + +``` +repo sync +``` + +![Git-repo pulling all the repositories](assets/repo_sync.png) + +After completion, it should look like the following image: + +![Git-repo finished sync](assets/repo_sync_finished.png) + +***NOTE: If you are a FoundriesFactory subscriber and want to build your Factory sources locally, please use the manifest link for your Factory as below. This is not recommended as images built locally cannot register to the Factory and receive OTAs.*** + +#### Set Up the Portenta X8 Distribution + +It is recommendable to set `DISTRO` to either: + +- `lmp-base`: insecure image without ostree, developer-friendly, not OTA compatible +- `lmp`: secure image without xwayland +- `lmp-xwayland`: secure image with xwayland support + +It will help to classify the image if it follows any of the previous characteristics and with the following command: + +```bash +DISTRO=lmp-xwayland MACHINE=portenta-x8 . setup-environment +``` + +***`lmp-partner-arduino-image` will be better supported soon.*** + +It will then switch automatically to a new folder. Continuing, you can now proceed to accept the EULA using the following command: + +```bash +echo "ACCEPT_FSL_EULA = \"1\"" >> conf/local.conf +``` + +You will be able to see similar output as following after the previous steps: + +![Setup Portenta X8 DISTRO](assets/x8_distro_setup.png) + +#### Build an Image With Bitbake + +To start building the image, following command is used: + +``` +bitbake lmp-partner-arduino-image +``` + +***This process may take ~7 hours depending on the build host*** + +![Compile Portenta X8 image](assets/x8_build.png) + +If you want to use your computer while it builds, it is recommendable to lower the threads used since it takes a lot of resources and time. Do so by opening `conf/local.conf` and lowering the values of the following variables: + +- `BB_NUMBER_PARSE_THREADS = "4"` +- `BB_NUMBER_THREADS = "4"` + +And add: + +- `PARALLEL_MAKE = "-j 4"` + +If possible, it is a good practice to understand the available threads of your computer used for this process, to optimize the resources accordingly for optimal balance between build performance and side tasks while waiting for the build. Once it finishes you will see something similar to: + +![Portenta X8 Image finished compilation](assets/x8_build_finished.png) + +#### Setup Manufacturing Tools + +To flash your board, you will need to compile **lmp-mfgtool distro** to get additional tools. First, go into your home folder and change `DISTRO` following the command sequence: + +``` +cd .. +DISTRO=lmp-mfgtool MACHINE=portenta-x8 . setup-environment +echo "ACCEPT_FSL_EULA = \"1\"" >> conf/local.conf +echo "MFGTOOL_FLASH_IMAGE = \"lmp-partner-arduino-image\"" >> conf/local.conf +``` + +You should be able to see similar results as following image when successful: + +![Flashing tools DISTRO setup](assets/tools_distro_setup.png) + +#### Build Manufacturing Tools: Flash The Board + +To compile and get the tools required, we will use following command: + +``` +bitbake mfgtool-files +``` + +![Compiling flashing tools](assets/tools_build.png) + +After completion: + +![Tools compilation finished](assets/tools_finished.png) + +***This process may take ~2 hours depending on your build host*** + +#### Save Your Image For Flashing + +After a successful build, save the needed files to the host volume you mounted with `docker run`. Use the following commands to copy the files to your storage unit: + +``` +cd .. +mkdir ../../dockerVolume/flashing +DEPLOY_FOLDER=../../dockerVolume/flashing + +cp -L build-lmp-mfgtool/deploy/images/portenta-x8/mfgtool-files-portenta-x8.tar.gz $DEPLOY_FOLDER +cp -L build-lmp-xwayland/deploy/images/portenta-x8/imx-boot-portenta-x8 $DEPLOY_FOLDER +cp -L build-lmp-xwayland/deploy/images/portenta-x8/u-boot-portenta-x8.itb $DEPLOY_FOLDER +cp -L build-lmp-xwayland/deploy/images/portenta-x8/sit-portenta-x8.bin $DEPLOY_FOLDER +cp -L build-lmp-xwayland/deploy/images/portenta-x8/lmp-partner-arduino-image-portenta-x8.wic $DEPLOY_FOLDER + +cd $DEPLOY_FOLDER +tar xvf mfgtool-files-portenta-x8.tar.gz +``` + +![Copying compiled files](assets/copy_files.png) + +You will be able to see the copied files in your OS file explorer. + +![Checking copied files with file explorer](assets/docker_volume_explorer.png) + +## Conclusion + +In this tutorial, you have learned how to build a "builder" Docker image, get its required files, configure the build settings, build the image,a and to save the needed files for flashing. Now you have all the required files to flash the image you built onto the device. + +## Next Steps + +Please follow the [Flashing tutorial](image-flashing) to flash your device with your custom image. You can use the files provided from this build to flash the Portenta X8 following the tutorial's steps. + +## Troubleshooting + +- If you are having `do_fetch` issues, try to check your system's and virtual machine's DNS settings. \ No newline at end of file diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/breakout-dip-switches.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/breakout-dip-switches.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/breakout-dip-switches.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/breakout-dip-switches.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/lpm-manifest-overview.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/lpm-manifest-overview.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/lpm-manifest-overview.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/lpm-manifest-overview.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/max-carrier-dip-switches.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/max-carrier-dip-switches.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/max-carrier-dip-switches.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/max-carrier-dip-switches.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/uuu-flashing-success.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/uuu-flashing-success.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/assets/uuu-flashing-success.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/assets/uuu-flashing-success.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/content.md new file mode 100644 index 0000000000..7905d05ee2 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/09.image-flashing/content.md @@ -0,0 +1,100 @@ +--- +beta: true +title: '09. How To Flash Your Portenta X8' +description: 'This tutorial teaches you how to flash your Portenta X8 through USB.' +difficulty: intermediate +tags: + - Embedded Linux + - Flashing +author: 'Pablo Marquínez' +hardware: + - hardware/04.pro/boards/portenta-x8 +--- + +## Overview + +In this tutorial, you will learn how to manually flash your Portenta X8 with the image provided by Arduino. You will flash your board through USB using the Terminal. The instructions below are meant to be used with a **Windows Operating System**. + +## Goals + +- Learn how to get the required files +- Learn how to set up the correct structure of the files +- Learn how to set up the board +- Learn how to flash the device + +### Required Hardware and Software + +- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) +- [Portenta Breakout Board](https://store.arduino.cc/products/arduino-portenta-breakout) or [Arduino Portenta Max Carrier](https://store.arduino.cc/products/portenta-max-carrier) +- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) + +## Instructions + +### Arduino's Download Repository + +Go to [Arduino Download repository](https://downloads.arduino.cc/portentax8image/image-latest.tar.gz) and a compressed `.tar.gz` with latest version of all the required OS image files will be there to download. + +![lpm-manifest repository overview](assets/lpm-manifest-overview.png) + +Please extract the files after you have downloaded the compressed file. The extracted contents have the following structure. + +``` +Unzipped folder +├── imx-boot-portenta-x8 +├── lmp-partner-arduino-image-portenta-x8.wic.gz **(Compressed)** +├── mfgtool-files-portenta-x8.tar.gz **(Compressed)** +├── sit-portenta-x8.bin +└── u-boot-portenta-x8.itb +``` + +After verifying these files are available, you will need to decompress `mfgtool-files-portenta-x8.tar.gz` and `lmp-partner-arduino-image-portenta-x8.wic.gz`. Please make sure the `.wic` is in the unzipped folder in the main directory. The folder structure should share a similar following layout. + +``` +Unzipped folder +├── mfgtool-files-portenta-x8/ +├── imx-boot-portenta-x8 +├── lmp-partner-arduino-image-portenta-x8.wic +├── lmp-partner-arduino-image-portenta-x8.wic.gz **(Compressed)** +├── mfgtool-files-portenta-x8.tar.gz **(Compressed)** +├── sit-portenta-x8.bin +└── u-boot-portenta-x8.itb +``` + +### Setting the Portenta X8 to Flashing Mode + +Connect your Portenta X8 into your carrier of choice, either *Portenta Breakout* or *Portenta Max Carrier*, via High-Density connectors. After connecting the Portenta X8, you will need to set the `BOOT` DIP switches to the ON position. The `BOOT` switch configuration is important as it will put the board into Flashing mode. + +On the Portenta Max Carrier, the DIP switches are identified by the label `BOOT SEL` and `BOOT` as shown in the figure: + +![Max Carrier DIP switches](assets/max-carrier-dip-switches.png) + +On the Portenta Breakout, the DIP switches are identified by the label `BT_SEL` and `BOOT` as shown in the figure: + +![Breakout DIP switches](assets/breakout-dip-switches.png) + +You will need to connect one USB-C® end to the Portenta X8 and the other end (USB-C® or USB-A) to your computer. If the connection is established correctly, you will be able to see a newly connected device called `SE Blank M845S`. + +### Flashing the Portenta X8 + +To flash the Portenta X8, you need to begin by opening a terminal. Within the terminal, you need to change the directory to where `mfgtool-files-portenta-x8` file is located using the `cd` command. Once it is inside the directory where the previous file is included, the following command is used: + +``` +uuu full_image.uuu +``` + +When the flashing operation is finished, you should see a similar result as the following figure: + +![uuu tool flashing success output](assets/uuu-flashing-success.png) + +Once you have verified it has successfully flashed the Portenta X8, the `BOOT` DIP switches that have been configured to the ON position, now need to be set to the OFF position. Otherwise, you will always have the Portenta X8 in Flashing mode whenever it is attached to a carrier. Recycle the power for Portenta X8 by reconnecting the board to your computer and start using with the latest updates. + +***After booting, you will need to wait 10 seconds until the Portenta X8 starts blinking Blue LED. The Blue LED indicates it was able to boot successfully.*** + +## Conclusion + +In this tutorial, you have learned to flash the Portenta X8 by getting the latest image, setting up the adequate file structure and the board, and finally flashing the board with these files. + +## Troubleshooting + +- If you get an error while it is flashing, make sure your USB is correctly plugged in. Reconnect your board and try to flash it again. You may need to go through a few trials before successful flashing. +- If you get an error related to permissions, try to launch the `uuu` command as Super User (`sudo`). diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_01.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_01.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_01.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_01.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_02.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_02.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_02.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_02.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_03.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_03.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_03.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_03.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_04.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_04.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_04.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_04.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_05.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_05.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_05.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_05.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_06.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_06.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_06.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_06.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_07.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_07.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_07.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_07.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_08.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_08.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_08.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_08.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_09.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_09.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_09.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_09.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_10.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_10.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_10.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_10.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_11.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_11.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_11.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_11.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_12.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_12.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_12.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_12.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_13.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_13.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_13.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_13.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_14.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_14.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_14.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_14.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_15.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_15.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_15.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_15.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_16.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_16.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_16.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_16.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_17.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_17.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_17.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_17.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_18.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_18.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_18.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_18.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_19.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_19.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_19.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_19.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_20.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_20.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_20.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_20.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_21.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_21.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_21.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_21.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_22.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_22.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_22.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_22.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_23.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_23.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_23.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_23.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_24.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_24.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_24.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_24.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_25.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_25.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/assets/x8-data-logging-img_25.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/assets/x8-data-logging-img_25.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/content.md similarity index 83% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/content.md rename to content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/content.md index c3bfaa5ecd..ed4c6e024d 100644 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/datalogging-iot/content.md +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/10.datalogging-iot/content.md @@ -1,5 +1,5 @@ --- -title: 'Data Logging with MQTT, Node-RED, InfluxDB and Grafana' +title: '10. Data Logging with MQTT, Node-RED, InfluxDB and Grafana' description: 'This tutorial will show you how to set up a local data logging application using an MQTT broker, Node-RED, InfluxDB, Grafana, and the Arduino® Portenta X8.' difficulty: intermediate tags: @@ -9,7 +9,7 @@ tags: - Node-RED - InfluxDB - Grafana -author: 'José Bagur, Taddy Chung' +author: 'José Bagur and Taddy Chung' software: - Terminal - Docker @@ -20,9 +20,9 @@ hardware: ## Overview -This tutorial will set up a typical Internet of Things (IoT) application: an MQTT data logger. For this application, we are going to use what we call in the Arduino team the "IoT-Quartet," four common building blocks that are popular and regularly used in these types of applications: +This tutorial will set up a typical Internet of Things (IoT) application: an MQTT data logger. For this application, we are going to use what we call in the Arduino team the "IoT-Quartet", four common building blocks that are popular and regularly used in these types of applications: -- [Mosquitto](https://mosquitto.org/) (MQTT broker) +- [Mosquitto](https://mosquitto.org/) (MQTT broker) - [Node-RED](https://nodered.org/) - [InfluxDB](https://www.influxdata.com/) - [Grafana](https://grafana.com/) @@ -31,51 +31,51 @@ These four blocks will be running locally on the [Arduino® Portenta X8](https:/ ## Goals -- Install, configure and run Mosquitto (MQTT broker) locally in the Portenta X8 -- Install, configure and run Node-RED locally in the Portenta X8 -- Install, configure and run InfluxDB locally in the Portenta X8 -- Install, configure and run Grafana locally in the Portenta X8 +- Install, configure, and run Mosquitto (MQTT broker) locally in the Portenta X8 +- Install, configure, and run Node-RED locally in the Portenta X8 +- Install, configure, and run InfluxDB locally in the Portenta X8 +- Install, configure, and run Grafana locally in the Portenta X8 - Send data from an Arduino® MKR WiFi 1010 board to the data logging application running locally in the Portenta X8 -## Required Hardware and Software +### Required Hardware and Software - [Arduino® Portenta X8](https://store.arduino.cc/products/portenta-x8) - [Arduino® MKR WiFi 1010](https://store.arduino.cc/products/arduino-mkr-wifi-1010) - USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) -- Wi-Fi Access Point (AP) with Internet access +- Wi-Fi® Access Point (AP) with Internet access - ADB or SSH - Command-line interface - [Arduino IDE 2.0](https://www.arduino.cc/en/software) ***If you are new to the Portenta X8 board, check out this [getting started tutorial](/tutorials/portenta-x8/out-of-the-box#controlling-portenta-x8-through-the-terminal) on controlling your board using a terminal or command-line interface.*** -## IoT Architecture 101 +## IoT Architecture Basics -IoT applications and devices are everywhere nowadays, even where we don't think a device or application is connected to the Internet. Rather than a single technology, **IoT is a concept** that refers to the connection of everyday devices, just like your watch, to the Internet and how that Internet connection creates more and different ways to interact with your device and your environment. Interactions between humans and devices or applications create **data** (lots) that must be communicated and processed. +IoT applications and devices are everywhere nowadays, even where we don't think a device or application is connected to the Internet. Rather than a single technology, **IoT is a concept** that refers to the connection of everyday devices, just like your watch, to the Internet and how that Internet connection creates more and different ways to interact with your device and your environment. Interactions between humans and devices or applications create **data** (lots) that must be communicated and processed. How can we plan, build and deploy IoT solutions? To answer that question, we must think about **IoT architecture**. Due to the different IoT devices and applications that exist and can exist, there is not just one unique architecture for IoT devices and applications. But, we can talk about a base architecture that can be considered as a starting point for every IoT project. This base architecture consists of **three essential layers**: **perception** (or devices), **network**, and **application**. Let's talk more about these layers: - **Perception layer**: this is the sensor's layer, where data comes from. In this layer, data is gathered with one or more sensor nodes; actuators, that answer to data collected from sensor nodes, are also in this layer. -- **Network layer**: this is where sensor node data is recollected and transmitted to back-end services, such as databases. -- **Application layer**: this layer is what the device or application user sees and interacts with, for example, a dashboard. +- **Network layer**: this is where sensor node data is recollected and transmitted to back-end services, such as databases. +- **Application layer**: this layer is what the device or application user sees and interacts with, for example, a dashboard. -The three-layer IoT architecture can be a starting point for designing and implementing an IoT device or application. In this tutorial, we are going to take this base architecture and set up a data logging application, as shown in the image below: +The three-layer IoT architecture can be a starting point for designing and implementing an IoT device or application. In this tutorial, we are going to take this base architecture and set up a data-logging application, as shown in the image below: ![IoT application high-level architecture.](assets/x8-data-logging-img_01.png) In the high-level architecture described in the image above: -- The perception layer consists of an MKR WiFi 1010 board; this board will gather information from a sensor. -- The network layer consists of the MQTT broker (Mosquitto), the data forwarder (Node-RED), and the database (InfluxDB). -- The application layer consists of a dashboard (Grafana) where information from the sensor node is shown. +- The perception layer consists of an MKR WiFi 1010 board; this board will gather information from a sensor. +- The network layer consists of the MQTT broker (Mosquitto), the data forwarder (Node-RED), and the database (InfluxDB). +- The application layer consists of a dashboard (Grafana), where information from the sensor node is shown. -***For documentation purposes, we will to explain, step by step, the installation process of each part of the application (Mosquitto, Node-RED, InfluxDB, and Grafana); this process can be done quickly using a unique Compose `YAML` file.*** +***For documentation purposes, we will explain, step by step, the installation process of each part of the application (Mosquitto, Node-RED, InfluxDB, and Grafana); this process can be done quickly using a unique Compose `YAML` file.*** Let's start by configuring the MQTT broker! ## Installing Mosquitto -Let's start by creating a new directory in our Portenta X8 called `mqtt`; inside this directory, we are going to make a file named `docker-compose.yml`: +Let's start by creating a new directory in our Portenta X8 called `mqtt`; inside this directory, we are going to make a file named `docker-compose.yml`: ``` $ mkdir mqtt @@ -85,9 +85,9 @@ $ stty rows 36 cols 150 $ sudo vi docker-compose.yml ``` -***The `export TERM=xterm` and `stty rows 36 cols 150` commands enable VI editor full screen.*** +***The `export TERM=xterm` and `stty rows 36 cols 150` commands enable VI editor full screen.*** -Inside VI editor, copy and paste the following: +Inside the VI editor, copy and paste the following: ``` services: @@ -116,7 +116,7 @@ Save the file and exit the VI editor. Return to the `mqtt` directory and run the mqtt$ docker-compose up -d ``` -The Mosquitto broker should be available on your Portenta X8 `IP address`. You can retrieve the `IP Address` of your board with the `ping ` command: +The Mosquitto broker should be available on your Portenta X8 `IP address`. You can retrieve the `IP Address` of your board with the `ping ` command: ``` $ ping portenta-x8-a28ba09dab6fad9 @@ -144,7 +144,7 @@ Save the file and exit the VI editor. Now, let's restart the Mosquitto container ![Docker container ID.](assets/x8-data-logging-img_02.png) -Now, let's manage password files by adding a user to a new password file. For this, we need to run the `sh` command in the mosquitto container with the mosquitto `CONTAINER ID` found before, as shown below: +Now, we need to manage password files by adding a user to a new password file. For this, we need to run the `sh` command in the mosquitto container with the mosquitto `CONTAINER ID` found before, as shown below: ``` /mqtt/config$ docker exec -it CONTAINER ID sh @@ -152,8 +152,9 @@ Now, let's manage password files by adding a user to a new password file. For th ``` Let's dissect that command: + - `docker exec` runs a command in a running container (in this case, the Mosquitto container) -- `-it CONTAINER ID sh` attaches a terminal session into the running container so we can see what is going with the container and interact with it +- `-it CONTAINER ID sh` attaches a terminal session into the running container so we can see what is going on with the container and interact with it Now, in the terminal session with the Mosquitto container, run the following command: @@ -161,7 +162,7 @@ Now, in the terminal session with the Mosquitto container, run the following com / # mosquitto_passwd -c /mosquitto/config/mosquitto.passwd guest ``` -This command creates a new password file (`mosquitto.passwd`); if the file already exists, it will be overwritten; `guest` is the username. After entering the `username` we want, we must define a password for the username and then exit the terminal session with the `exit` command: +This command creates a new password file (`mosquitto.passwd`); if the file already exists, it will overwrite; `guest` is the username. After entering the `username` we want, we must define a password for the username and then exit the terminal session with the `exit` command: ``` / # mosquitto_passwd -c /mosquitto/config/mosquitto.passwd guest @@ -196,11 +197,11 @@ listener 9001 protocol websockets ``` -Let's test it! Save the file and exit the VI editor; also, we need to restart the Mosquitto container so the configuration file can start working. This can be done by using the `docker restart` command and the Mosquitto `CONTAINER ID`. After restarting the container, the local Mosquitto broker should be ready. +To test it, save the file and exit the VI editor; also, we need to restart the Mosquitto container so the configuration file can start working. This can be done by using the `docker restart` command and the Mosquitto `CONTAINER ID`. After restarting the container, the local Mosquitto broker should be ready. ### Testing Mosquitto -To test the Mosquitto broker, we need an MQTT client. We can use several ways to implement an MQTT client, one of the easiest ways is to install an MQTT client in our web browser and use it to test the connection between the local MQTT broker on the Portenta X8 board and the web-based MQTT client. This tutorial will use [MQTTBox](https://chrome.google.com/webstore/detail/mqttbox/kaajoficamnjijhkeomgfljpicifbkaf?hl=en), a Google Chrome extension that works as an MQTT client. +To test the Mosquitto broker, we need an MQTT client. We can use several ways to implement an MQTT client, one of the easiest ways is to install an MQTT client in our web browser and use it to test the connection between the local MQTT broker on the Portenta X8 board and the web-based MQTT client. This tutorial will use [MQTTBox](https://chrome.google.com/webstore/detail/mqttbox/kaajoficamnjijhkeomgfljpicifbkaf?hl=en), a Google Chrome extension that works as an MQTT client. In MQTTBox, let's start by configuring the settings of the MQTT client. The information we are going to need is the following: @@ -214,11 +215,11 @@ Leave everything else as default and save the settings of the client. If everyth ![MQTTBox graphical user interface (GUI).](assets/x8-data-logging-img_03.png) -When MQTTBox client connects to the local Mosquitto broker deployed in our Portenta X8 board, a blue "Not Connected" button should change to a green "Connected" button; also, notice that with the MQTTBox client, we are going to publish data to the `test` topic. Now, let's install Node-RED. +When MQTTBox client connects to the local Mosquitto broker deployed in our Portenta X8 board, a blue "Not Connected" button should change to a green "Connected" button; also, notice that with the MQTTBox client, we are going to publish data to the `test` topic. Now, let's install Node-RED. ## Installing Node-RED -Node-RED is an open-source programming tool that connects hardware with API's and online services. It is a visual tool designed for Internet of Things devices and applications, but it can also be used for other of applications. The simplest form to run Node-RED with Docker is by using the following command: +Node-RED is an open-source programming tool that connects hardware with API's and online services. It is a visual tool designed for Internet of Things devices and applications, but it can also be used for other applications. The simplest form to run Node-RED with Docker is by using the following command: ``` docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red @@ -240,14 +241,14 @@ Let's browse to `http://{your-portenta-ip}:1880`; this will open the Node-RED de ![Node-RED graphical user interface (GUI).](assets/x8-data-logging-img_04.png) -Node-RED desktop is a GUI that lets us work with Node-RED flows graphically. We can test Node-RED by connecting to the local MQTT broker we set up before using a Node-RED flow. In the `Nodes` section located in the left part of the browser, search for `network` and choose the `mqtt in` node and drop it in the workspace; we will use this node to connect to the local MQTT broker of the X8. To change the node's properties, double-click on it and define the following properties: +Node-RED desktop is a GUI that lets us work with Node-RED flows graphically. We can test Node-RED by connecting to the local MQTT broker we set up before using a Node-RED flow. In the `Nodes` section located in the left part of the browser, search for `network` and choose the `mqtt in` node and drop it in the workspace; we will use this node to connect to the local MQTT broker of the X8. To change the node's properties, double-click on it and define the following properties: - **Server**: `your-portenta-ip:1883` -- **Action**: `Subscribe to single topic` +- **Action**: `Subscribe to the single topic` - **Topic**: `test` - **QoS**: `0` - **Output**: `auto-detect (string or buffer)` -- **Name**: `MQTT Broker X8` +- **Name**: `MQTT Broker X8` Now, search for the `change` node and drop it in the workspace; we will use this node to change the data format from the MQTT broker (string to number). To change the node's properties, double-click on it and define the following properties: @@ -271,11 +272,11 @@ We should now see data in the debug interface of Node-RED, as shown in the image ![Debug interface of Node-RED showing data from the MQTT broker.](assets/x8-data-logging-img_08.png) -Success! We can now configure now InfluxDB. +We can now proceed to configure InfluxDB. ## Installing InfluxDB -InfluxDB is an open-source, high-performance, time series database; with InfluxDB data can be written and read in real-time, and data can be processed in the background for extract, transform and load (ETL) purposes or for monitoring and alerting purposes. User dashboards for visualizing and exploring data can also be set up. +InfluxDB is an open-source, high-performance, time series database; with InfluxDB data can be written and read in real-time, and data can be processed in the background for extract, transform, and load (ETL) purposes or for monitoring and alerting purposes. User dashboards for visualizing and exploring data can also be set up. The simplest form to run InfluxDB with Docker is by using the following command: @@ -286,7 +287,7 @@ docker run --detach --name influxdb -p 8086:8086 influxdb:2.2.0 This command will run an InfluxDB container **locally** in our Portenta X8 board. Let's dissect the command: - `--detach`: no terminal session is attached to the container -- `--name`: the container name +- `--name`: the container name - `-p 1880:1880`: InfluxDB local port `8086` connects to the exposed internal port `8086` The container should now be running in the background; let's test the local instance of InfluxDB! @@ -299,17 +300,17 @@ For testing the local instance of InfluxDB we are going to use its desktop and a InfluxDB desktop is a GUI that lets us work with InfluxDB graphically. -***The first time you enter the InfluxDB desktop, a username and a password must be set up.*** +***The first time you enter the InfluxDB desktop, a username, and a password must be set up.*** After setting up a username and a password, we are going to be redirected to the "Getting Started" page, as shown in the image below: ![Getting started page of the InfluxDB desktop.](assets/x8-data-logging-img_10.png) -In this example, we will send data from the MQTT broker to InfluxDB using Node-RED; Node-RED will act as a bridge between the MQTT broker and InfluxDB. Let's go to "Data" we are going to be redirected to the "Load Data" page, as shown in the image below: +In this example, we will send data from the MQTT broker to InfluxDB using Node-RED; Node-RED will act as a bridge between the MQTT broker and InfluxDB. Let's go to "Data" we are going to be redirected to the "Load Data" page, as shown in the image below: ![Load data page of the InfluxDB desktop.](assets/x8-data-logging-img_11.png) -Select "Buckets" and click in the "Create Bucket" button. This will create a new database where data from the MQTT broker will be saved. For this example, let's create a new bucket called `test`; now, we should see the bucket on the InfluxDB desktop: +Select "Buckets" and click on the "Create Bucket" button. This will create a new database where data from the MQTT broker will be saved. For this example, let's create a new bucket called `test`; now, we should see the bucket on the InfluxDB desktop: ![Test bucket in the load data page of the InfluxDB desktop.](assets/x8-data-logging-img_12.png) @@ -336,11 +337,11 @@ Now, connect the nodes as shown in the image below: ![Node-RED flow used for testing the Portenta X8 local InfluxDB instance.](assets/x8-data-logging-img_14.png) -Let's use the MQTT client described before to test the MQTT broker integration with Node-RED and InfluxDB. Remember to first deploy the flow in Node-RED and to subscribe to the `test` topic and publish any value in the MQTT client. Now, go to Data Explorer on the InfluxDB desktop; you should now see data from the MQTT client, as shown in the image below: +Let's use the MQTT client described before to test the MQTT broker integration with Node-RED and InfluxDB. Remember to first deploy the flow in Node-RED and subscribe to the `test` topic and publish any value in the MQTT client. Now, go to Data Explorer on the InfluxDB desktop; you should now see data from the MQTT client, as shown in the image below: ![Visualiazing data in a bucket of the Portenta X8 local InfluxDB instance.](assets/x8-data-logging-img_15.png) -Success! We can now configure now Grafana. +We can now proceed to configure Grafana. ## Installing Grafana @@ -355,7 +356,7 @@ docker run -d --name=grafana -p 3000:3000 grafana/grafana This command will run a Grafana container **locally** in our Portenta X8 board. Let's dissect the command: - `-d`: no terminal session is attached to the container -- `--name`: the container name +- `--name`: the container name - `-p 3000:3000`: Grafana local port `3000` connects to the exposed internal port `3000` The container should now be running in the background; let's test the local instance of Grafana! @@ -396,7 +397,7 @@ Now, in the Grafana GUI, create a new dashboard and add a new panel; in the conf ![Setting up a dashboard in Grafana via its GUI.](assets/x8-data-logging-img_21.png) -In the "Query inspector," paste the script we generated before with InfluxDB. You should now see data from the tests made earlier with the MQTT client: +In the "Query inspector," paste the script we generated before with InfluxDB. You should now see data from the tests made earlier with the MQTT client: ![Setting up data visualization in a Grafana dashboard via its GUI.](assets/x8-data-logging-img_22.png) @@ -404,17 +405,17 @@ Let's change how data is visualized. Select "Visualizations" and then search for ![Visualizing data with a gauge in a Grafana dashboard.](assets/x8-data-logging-img_23.png) -We can change the panel options, such as their title and description. Click on apply; we can now use the MQTT client described before to test the MQTT broker integration with Node-RED, InfluxDB, and Grafana. Remember first to deploy the flow in Node-RED, subscribe to the test topic, and publish any value in the MQTT client. Also, remember to change the dashboard time range and its refresh rate. +We can change the panel options, such as their title and description. Click on apply; we can now use the MQTT client described before to test the MQTT broker integration with Node-RED, InfluxDB, and Grafana. Remember first to deploy the flow in Node-RED, subscribe to the test topic, and publish any value in the MQTT client. Also, remember to change the dashboard time range and its refresh rate. ![Configured dashboard in Grafana.](assets/x8-data-logging-img_24.png) ## Sending Data Using the MKR WiFi 1010 Board -Now, it is time to test our entire data logging application. We will use an [MKR WiFi 1010](https://store.arduino.cc/products/arduino-mkr-wifi-1010); this board will periodically send the value of a counter to the Grafana dashboard via the local MQTT broker deployed in the X8. +Now, it is time to test our entire data-logging application. We will use an [MKR WiFi 1010](https://store.arduino.cc/products/arduino-mkr-wifi-1010); this board will periodically send the value of a counter to the Grafana dashboard via the local MQTT broker deployed in the X8. -First, let's ensure we have the require core for the MKR WiFi 1010 installed, the **Arduino SAMD boards (32-bits ARM Cortex M0+)**. Please, refer to [this guide](https://docs.arduino.cc/learn/starting-guide/cores#how-to-install-an-arduino-cores) if you are not familiar with the installation of additional cores in the Arduino IDE. We also need to install the libraries we will use to send data from the MKR WiFi 1010 board to the data logging application via MQTT. Go to **Tools > Manage libraries...**, search for **ArduinoMqttClient** and **WiFiNINA** and install the latest available version of both libraries. +First, let's ensure we have the required core for the MKR WiFi 1010 installed, the **Arduino SAMD boards (32-bit ARM Cortex M0+)**. Please, refer to [this guide](https://docs.arduino.cc/learn/starting-guide/cores#how-to-install-an-arduino-cores) if you are not familiar with the installation of additional cores in the Arduino IDE. We also need to install the libraries we will use to send data from the MKR WiFi 1010 board to the data logging application via MQTT. Go to **Tools > Manage libraries...**, search for **ArduinoMqttClient** and **WiFiNINA**, and install the latest available version of both libraries. -Now, let's open a new sketch and create a new header file called `arduino_secrets.h` in a separate tab; to create a separate tab in the Arduino IDE, click the arrow symbol underneath the Serial Monitor symbol, then click on the "New tab" option. In this header file, we are going to store our Wi-Fi credentials: +Now, let's open a new sketch and create a new header file called `arduino_secrets.h` in a separate tab; to create a separate tab in the Arduino IDE, click the arrow symbol underneath the Serial Monitor symbol, then click on the "New tab" option. In this header file, we are going to store our Wi-Fi® credentials: ```arduino #define SECRET_SSID "your-ssid" @@ -428,7 +429,7 @@ Now, let's program the following sketch in the MKR WiFi 1010 board: #include #include "arduino_secrets.h" -// Wi-Fi information +// Wi-Fi® information char ssid[] = SECRET_SSID; // Your network SSID, stored in the arduino_secrets.h file char pass[] = SECRET_PASS; // Your network password, stored in the arduino_secrets.h file WiFiClient wifiClient; @@ -453,7 +454,7 @@ void setup() { ; // Wait for serial port to connect, needed for native USB port only } - // Attempt to connect to the defined Wi-Fi network + // Attempt to connect to the defined Wi-Fi® network Serial.print("- Attempting to connect to WPA SSID: "); Serial.println(ssid); @@ -466,7 +467,7 @@ void setup() { Serial.println("- You're connected to the network!"); Serial.println(); - // Attempt to connect to the defined Wi-Fi network + // Attempt to connect to the defined Wi-Fi® network Serial.print("- Attempting to connect to the MQTT broker: "); Serial.println(broker); @@ -507,7 +508,7 @@ void loop() { } ``` -The sketch shown above connects the MKR WiFi 1010 to the local MQTT broker of the X8 and periodically sends the value of a counter to the topic `test`. +The sketch shown above connects the MKR WiFi 1010 to the local MQTT broker of the X8 and periodically sends the value of a counter to the topic `test`. ***Please read [this tutorial](https://docs.arduino.cc/tutorials/mkr-wifi-1010/mqtt-device-to-device#programming-the-publisher) for more in-depth information about MQTT and the MKR WiFi 1010 board.*** diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/assets/portentaX8-home-screen.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/assets/portentaX8-home-screen.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/assets/portentaX8-home-screen.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/assets/portentaX8-home-screen.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/assets/portentaX8_hub_screen.svg b/content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/assets/portentaX8_hub_screen.svg similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/assets/portentaX8_hub_screen.svg rename to content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/assets/portentaX8_hub_screen.svg diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/assets/vim-edit-dockerCompose.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/assets/vim-edit-dockerCompose.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/assets/vim-edit-dockerCompose.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/assets/vim-edit-dockerCompose.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/content.md new file mode 100644 index 0000000000..cfcdbac424 --- /dev/null +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/11.display-output-webgl/content.md @@ -0,0 +1,211 @@ +--- +title: '11. Output WebGL Content on a Screen' +description: 'This tutorial shows how to install and modify a container that outputs web browser and webGL content.' +difficulty: beginner +tags: + - containers + - Docker + - WebGL + - Vim +author: 'Pablo Marquínez' +software: + - Terminal + - Docker +hardware: + - hardware/04.pro/boards/portenta-x8 +--- + +## Overview + +The Arduino Portenta X8's processor **NXP® i.MX 8M Mini Processor** is capable of 3D rendering by using OpenGL to process the 3D-related calculations, allowing us to display 3D content on a screen or video output. + +In this tutorial, we will render web content from the internet using WebGL and display it on a screen, using a USB Hub. We will go through the steps to set up, install and modify the video output. + +## Goals + +- Learn how to setup the Video Output +- Learn how to get the required container +- Learn how to run the container +- Learn how to change the video output + +### Required Hardware and Software + +- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) +- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) +- USB-C® hub with HDMI +- External monitor +- HDMI cable + +## Instructions + +### Install The Container + +There are two ways to get the container, either through `foundriesFactories` or downloading the container from [portenta-containers repository](https://github.com/arduino/portenta-containers). + +**With Foundries.io:** + +If you use [Foundries.io](https://www.foundries.io), you can switch the current `target` of your device to `x-kiosk-imx8-webgl` by switching the app from a terminal on your computer: + +``` +//Change the app to an existing one +fioctl devices config updates --apps "x-kiosk-imx8-webgl" -f + +//Make a clean installation with no containers +fioctl devices config updates --apps "," -f + +//If you are getting issues doing so, make sure you are logged correctly with your token +//You can logout: +fioctl logout + +//Then log in again and follow the instructions +fioctl login +``` + +You will now see the home screen for a few seconds and then it will fade out and open the Aquarium 3D from [WebGL samples - Aquarium](https://webglsamples.org/aquarium/aquarium.html). + +**With downloaded repository:** + +If you downloaded the [portenta-containers repository](https://github.com/arduino/portenta-containers), you will need to connect your board directly to your computer and run the `adb shell`, then push the container to your Portenta X8. + +### Connect to a Wi-Fi® + +Check the available Wi-Fi® access points by using the `nmcli de wifi` command. You will be able to see an output laying out `BSSID`, `SSID`, and its other elements. + +``` +nmcli de wifi + +//Output +IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY + AA:BB:CC:DD:EE:FF Infra X 130 Mbit/s -- * WPA2 +``` + +The Wi-Fi® details can be saved using the following commands in sequence: + +``` +nmcli c add type wifi con-name ifname wlan0 ssid +nmcli con modify wifi-sec.key-mgmt wpa-psk +nmcli con modify wifi-sec.psk +nmcli con up + +//To disconnect from a custom connection +nmcli con down + +//To delete a saved connection +nmcli c delete +``` + +If the LED is illuminating Green, then we know it has been correctly connected. If you want to check it in your terminal, you can use the following commands: + +``` +nmcli de + +//Output +DEVICE TYPE STATE CONNECTION +usb0 ethernet connected usbrndis +usb1 ethernet connected usbecm +wlan0 wifi connected +docker0 bridge connected (externally) docker0 +``` + +The output table will display information regarding active connections as well as the Wi-Fi® connection in which we are interested. + +### Get Your Board's IP + +The IP information of the board can be obtained using `ifconfig wlan0` command. It will show different IP information composed of `inet`, `netmask`, and `broadcastIP`. + +``` +ifconfig wlan0 + +//Output +wlan0: flags=4163 mtu 1500 + inet netmask 255.255.255.0 broadcast +``` + +Test your IP connection by exiting the `adb shell`, you can use **CTRL+Z** or type `exit`, then try to connect through **SSH** using following command: + +``` +ssh fio@ +``` + +***To connect through SSH it will request the user's password, which is "fio". If you have trouble connecting with the SSH, please check the troubleshooting section at the end of this tutorial.*** + +### Copy/Push the Container + +You can push the container from your computer using a terminal on the container's directory. The following command is used to send the container to the Portenta X8: + +``` +scp fio@: +``` + +### Video Output Setup + +Now we need a USB Hub that has an available video output connector, for example, an HDMI cable. Connect the Portenta X8 to the USB Hub as a Host, the video connector to a display, and the power supply USB to your computer. It is optional but we could also connect a USB mouse to the hub. The setup should look like as follows: + +![X8 usb hub setup](assets/portentaX8_hub_screen.svg) + +***As a reference, a list of validated USB-C® to HDMI hubs that you can use are: [ACT AC7022](https://www.act-connectivity.com/en-us/usb-c-to-hdmi-multiport-adapter-4k-usb-hub-pd-pass-ac7022), [ACT AC7041](https://www.act-connectivity.com/en-us/usb-c-to-hdmi-multiport-adapter-with-ethernet-ac7041), [ACT AC7042](https://www.act-connectivity.com/en-us/usb-c-to-hdmi-multiport-adapter-with-ethernet-and-ac7042)*** + +By default, if you connect the board to a display, you will see the "home screen" with the `Arduino PRO` background wallpaper, and a bottom bar with real-time. + +***You can interact with the interface by plugging USB devices into your hub, like a mouse or a keyboard.*** + +![X8 home-screen](assets/portentaX8-home-screen.png) + +### Running The Container + +If you obtained the container from **Foundries.io**, it will run automatically after a few seconds. + +On the other hand, if you copied from the repository, you will need to initialize with **docker** by accessing your Portenta X8 through SSH, going to the directory where you have copied it, and running it from that directory using following commands: + +``` +//Connect to your device +ssh fio@ + +//Change directory +cd + +//Compose with docker +docker-compose up --detach + +//Stop the docker-compose +docker-compose stop +``` + +### Edit The Output + +It is possible to change the web output URL by editing the `docker-compose.yml` file, using the following commands: + +``` +//Connect to your device +ssh fio@ + +//Change directory +cd + +//Edit the file with VIM +vim docker-compose.yml +``` + +Once you are inside the **VIM** editor, to edit the file you will need to press **insert** and replace the URL as shown in the screenshot. + +![VIM editing docker-compose.yml](assets/vim-edit-dockerCompose.png) + +To save the changes, press the **ESC** key and type `:wq`. This will write and quit the **VIM** editor. After editing the file, you will need to compose the container again to make the changes take effect. + +## Conclusion + +In this tutorial, we went through how to connect the board and display something on a screen. Using a container from FoundriesFactories or by downloading it and uploading it to your Portenta X8. Lastly, we showed how to edit the video output by editing the container. + +### Next Steps + +- Make your own HTML content, push it to your device, and output the desired content. +- You could make an app that shows information about the weather on the web and have that on a display. + +## Troubleshooting + +- If you tried to connect with `ssh` and you get a **fingerprint** issue, you will need to remove the IP and fingerprint on your `.ssh` file. On Windows, the file is located at `C:\Users\\.ssh\known_hosts` and try again with the **ssh** connection. An example is as follows: + +``` +// +192.168.50.8 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAasdaddgre mqtt_client: + def on_connect(client, userdata, flags, rc): + if rc == 0: + logging.debug("Connected to MQTT Broker!") + else: + logging.debug("Failed to connect, return code %d\n", rc) + + client = mqtt_client.Client(mqtt_client_id) + client.username_pw_set(mqtt_username, mqtt_password) + client.on_connect = on_connect + client.connect(mqtt_broker, mqtt_port) + + # Thread in the background calling loop() in an automatic manner + client.loop_start() + return client + +def on_message(client, userdata, msg): + logging.debug(f"MQTT Client: `{msg.payload.decode()}` from `{msg.topic}` topic") + + decoded_mqtt_payload = json.dumps(EncodeFloat(msg.payload.decode("utf-8"))) + print("MQTT Payload Data=%.15g" % (float(decoded_mqtt_payload))) + + # `mqtt_data` is the payload decoded within receiving MQTT packet from a remote device + mqtt_data.append(float(decoded_mqtt_payload)) + client.loop_stop() + + return mqtt_data + +def subscribe(client: mqtt_client): + global mqtt_data + mqtt_timeout = time.time() + 60 + + client.subscribe(mqtt_topic) + client.on_message = on_message + + while len(mqtt_data) <= 0: + print(f"Awaiting MQTT packet before proceeding") + time.sleep(publish_interval) + if time.time() > mqtt_timeout: + print(f"No MQTT packet is received - Defaulting Data") + mqtt_data = [0.0] + break + else: + print(f"MQTT packet received") + + print(f"MQTT packet: ", mqtt_data[0]) +... +``` + +For LoRa® connectivity, to establish communication with *The Things Network*, we will use the Cayenne Low Power Payload Encoder as part of the process in this build. + +```python +... +frame = LppFrame() +frame.add_temperature(0, rpc_data[0]) +frame.add_humidity(1, rpc_data[1]) + +# MQTT payload as Generic 4-Byte Unsigned Integer +frame.add_generic(2, mqtt_data[0]) + +# Encoding packet for transmission +payload = bytes(frame) +lora_module.sendBytes(payload, len(payload), False) +... +``` + +#### Multi-Protocol Arduino (M4) Application + +For the full Arduino scripts, please refer to the files found inside [this compressed file](assets/Multi_Protocol_Gateway_X8.zip). + +The following sketch is for the Arduino layer to retrieve the data between Arduino and Linux layers. + +```arduino +/** + Multi-Protocol Gateway With Portenta X8 & Max Carrier + Name: m4_to_python + Purpose: Sketch to transport analog values for testing purposes. Sensor can be attached and + modified accordingly to transport data to Linux layer. This is to be used as a reference sketch + and can be adapted to required design specification on communicating M4 to Linux layer on + Portenta X8. + + @author Arduino +*/ +# Arduino side sketch +#include +#include + +const long interval = 1000; +unsigned long previousMillis = 0; + +void setup(){ + pinMode(PA_12, INPUT); + //RPC.begin(); + + Serial.begin(115200); + while (!Serial) {} + + Serial.println("M4 Layer - Multi Protocol Gateway"); + + RPC.bind("Data_0", []{ return analogRead(A0); }); + RPC.bind("Data_1", []{ return analogRead(A1); }); + + Serial.println("Service Begin"); +} + +void loop(){ + unsigned long currentMillis = millis(); + + if (currentMillis - previousMillis >= interval) { + previousMillis = currentMillis; + + //record random value from A0 and A1 + Serial.println(analogRead(A0)); + Serial.println(analogRead(A1)); + + } +} +``` + +The sketch above will help expose and transfer the data processed within the Linux side. Transferring data to the Linux side can be seen as a direct communication, as the sensor connected and monitored via the Arduino side will send this data over LoRa® connectivity. For this build, we will use Analog readings to emulate the functionality. + +Additionally, by exposing, you will bring forth the data received within the Linux side to the Arduino side to feed the local device as a control input. It can be used to display the data if you wish to for instance. The implementation is possible within this script if you wish to develop further desired multi-protocol gateway architecture. + +For MQTT publishing, we have also included a sketch that can be used with Arduino MKR WiFi 1010 to test the gateway build. Of course, the code can be extended and modified according to the requirements of the device that will collect data from a certain sensor to send over the MQTT protocol. + +```arduino +/** + Multi-Protocol Gateway With Portenta X8 & Max Carrier + Name: mqtt_publisher + Purpose: Simple MQTT publisher and can be used with Multi-Protocol Gateway process. It uses EMQX broker + but it can be changes to Mosquitto broker for example if required. + + @author Arduino +*/ + +#include +#include +#include "arduino_secrets.h" + +// Please enter your sensitive data in the Secret tab/arduino_secrets.h +char ssid[] = SECRET_SSID; // Your network SSID (name) +char pass[] = SECRET_PASS; // Your network password (use for WPA, or use as key for WEP) + +WiFiClient wifiClient; +MqttClient mqttClient(wifiClient); + +const char broker[] = "broker.emqx.io"; +int port = 1883; +const char topic[] = "multiPrGw/mqtt1"; + +//Set interval for sending messages (milliseconds) +const long interval = 50000; +unsigned long previousMillis = 0; + +int count = 0; + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // Wait for serial port to connect. Needed for native USB port only + } + + // Attempt to connect to Wifi network: + Serial.print("Attempting to connect to WPA SSID: "); + Serial.println(ssid); + while (WiFi.begin(ssid, pass) != WL_CONNECTED) { + // Failed, retry + Serial.print("."); + delay(5000); + } + + Serial.println("You're connected to the network"); + Serial.println(); + + Serial.print("Attempting to connect to the MQTT broker: "); + Serial.println(broker); + + if (!mqttClient.connect(broker, port)) { + Serial.print("MQTT connection failed! Error code = "); + Serial.println(mqttClient.connectError()); + + while (1); + } + + Serial.println("You're connected to the MQTT broker!"); + Serial.println(); +} + +void loop() { + // Call poll() regularly to allow the library to send MQTT keep alive which + // avoids being disconnected by the broker + mqttClient.poll(); + + unsigned long currentMillis = millis(); + + if (currentMillis - previousMillis >= interval) { + // Save the last time a message was sent + previousMillis = currentMillis; + + // Record random value from A0, A1 and A2 + float Rvalue = analogRead(A0); + + Serial.print("Sending message to topic: "); + Serial.println(topic); + Serial.println(Rvalue/10); + + // Send message, the Print interface can be used to set the message contents + mqttClient.beginMessage(topic); + mqttClient.print(Rvalue/10); + mqttClient.endMessage(); + + Serial.println(); + } +} +``` + +### Mounting the Multi-Protocol Gateway + +It is now time to make the multi-protocol gateway run and for this, you will need to build the Docker container that will help you operate in the background on the Linux layer. Using the terminal, you can use the following commands to get the multi-protocol gateway container up and running. + +You will need to have the files ready in a folder inside the `adb` directory within Arduino root. + +``` +C:\Users\#USERNAME#\AppData\Local\Arduino15\packages\arduino\tools\adb\32.0.0 +``` + +Having the files ready in that directory, you can use the following commands to push the files to the `fio` directory inside the Portenta X8. The second command will let you navigate inside the Portenta X8. + +``` +adb push multi-protocol-gateway /home/fio +adb shell +``` + +You will now build the container using the following commands. The following command will tag the container with `Multi_Protocol_Gateway_X8` as its name. + +``` +cd ../home/fio/Multi_Protocol_Gateway_X8 +#Multi_Protocol_Gateway_X8 sudo docker build . -t multi_gateway +``` + +You will be able to see the following results when the image is built successfully. + +![Multi-Protocol Gateway Docker Build Terminal Log](assets/docker-build.png) + +***If you have created the Docker container previously and want to re-create it with new changes made outside the shell, please check that the container and its build directory are stopped and removed. It is for the convenience of having a clean working environment*** + +After a successful container build, you will run the image. To do that, you can use the following command. This command will immediately give an output in your terminal, telling you how the Python® script is running. If you wish to have it running in the background, please add the `-d` flag at the end of the command. + +``` +#Multi_Protocol_Gateway_X8 sudo docker-compose up +``` + +Finally, you will have the multi-protocol gateway running, which uses Wi-Fi® and LoRa® connectivity. Also, RPC for exchanging data between its layers. However, there are cases where you would wish to make changes by adding more functionalities, such as including Cat. M1 or NB-IoT to expand its communication spectrum. For this, you will need to stop the image. To stop the image from running, you can use the following command. + +``` +#Multi_Protocol_Gateway_X8 sudo docker-compose down +``` + +Getting to know the status of the image is also crucial as it is the indicator of the state of operation. The following command brings up **active** containers and shows the status if the container restarted or stopped due to certain reasons. The second command lists built images and it will show you the components that go with the main image that you're building. + +``` +docker ps -a +docker images +``` + +![Multi-Protocol Gateway Active Docker Image](assets/docker-state.png) + +With all this, you have built a running multi-protocol gateway based on Portenta X8 and Max Carrier. You will be able to observe the data sent by the gateway with *The Things Network* platform End-Device section under Applications. + +If you are curious about what to expect from the build you have made in this tutorial, the following image shows you the terminal of the running multi-protocol gateway. + +![Multi-Protocol Gateway Run Log](assets/multi-protocol-gateway-example-run.png) + +## Conclusion + +In this tutorial, you have learned how to set up a Multi-Protocol Gateway composed of MQTT protocol, RPC, and LoRaWAN®, by using the Portenta X8 and the Portenta Max Carrier. You have built the gateway that will connect to *The Things Network* to send the desired data. Also, the gateway is capable of exchanging data between Arduino and Linux layers using RPC, in which you have exposed the ports to be able to receive data from the local sensor to be sent directly to *The Things Network*. + +### Next Steps +- Now that you have developed a multi-protocol gateway, using Wi-Fi® and LoRaWAN® connectivity, expand the gateway's capability by adding other connectivity types such as Cat. M1 and NB-IoT. +- Expand functionalities for data processing using RPC while using multi-protocol architecture. + +## Troubleshooting + +You might encounter some errors or misbehaviors while working on the code, preventing you from progressing in the development. You can try the following troubleshooting tips to solve the commonly known issues: + +* If the sketch upload process fails, check if your Portenta X8 is in bootloader mode. To put the Portenta X8 into Bootloader mode, double-press its RESET button and verify that the green LED is blinking. After this, you can try re-uploading the sketch for the Arduino layer. +* Check the position of the BOOT DIP switch of the Portenta Max Carrier. If the Portenta X8 gets into bootloader mode immediately after powering on, including when connected via USB-C®, change the position of the BOOT DIP switch to OFF. This case applies to the Arduino layer. +* If you encounter an issue regarding terminal input inconvenience, please enter `export TERM=xterm` as the command in the terminal to get readable inputs. +* In case an internal Wi-Fi® connection cannot be established through the command input due to "unavailable" SSID, although it is in range. Please try using a different SSID if available or a hotspot from a different device to host network connectivity. +* If you encounter a docker image conflict when running after building, please make sure you have used a name tag that matches the one from the `docker-compose.yml` file. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-connect-terminal.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-connect-terminal.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-connect-terminal.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-connect-terminal.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-container-install.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-container-install.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-container-install.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-container-install.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-mkdir.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-mkdir.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-mkdir.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-mkdir.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-wordpress-site.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-wordpress-site.png similarity index 100% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/assets/webserver-wordpress-site.png rename to content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/assets/webserver-wordpress-site.png diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/content.md similarity index 59% rename from content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/content.md rename to content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/content.md index ae6fa2912f..dd5a915549 100644 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/wordpress-webserver/content.md +++ b/content/hardware/04.pro/boards/portenta-x8/tutorials/13.wordpress-webserver/content.md @@ -1,11 +1,11 @@ --- -title: 'Running Wordpress and Database Containers on the Portenta X8' -description: 'Learn how to run a database and Wordpress container on the Portenta X8' +title: '13. Running WordPress & Database Containers on Portenta X8' +description: 'Learn how to run a database and WordPress container on the Portenta X8' difficulty: beginner tags: - containers - Docker - - Wordpress + - WordPress author: 'Benjamin Dannegård' software: - Terminal @@ -16,13 +16,13 @@ hardware: ## Overview -The Arduino Portenta X8 is a powerful board that has many features that can be easily utilized with the help of Docker containers. In this tutorial we will be using the Portenta X8 to host a webserver and run Wordpress using containers. This is a simple way to configure and run your own database server container and Wordpress page. We can then access the Wordpress site on the X8 through our web browser and begin setting it up. +The Arduino Portenta X8 is a powerful board that has many features that can be easily utilized with the help of Docker containers. In this tutorial, we will be using the Portenta X8 to host a web server and run WordPress using containers. This is a simple way to configure and run your own database server container and WordPress page. We can then access the WordPress site on the X8 through our web browser and begin setting it up. ## Goals - Create the file to install docker containers - Install and run the containers -- Connect to the Wordpress container running on the Portenta X8 +- Connect to the WordPress container running on the Portenta X8 ### Required Hardware and Software @@ -31,16 +31,16 @@ The Arduino Portenta X8 is a powerful board that has many features that can be e ## Instructions -First make sure your Portenta X8 is setup correctly by following the [getting started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box). +First, make sure your Portenta X8 is set up correctly by following the [getting started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box). ### Creating the Docker-compose.yml File -The Wordpress container we use is a multi-container application, which also requires a database server container. The Wordpress multi-container application uses Apache as its web server. This is required to make the service work and it is already included in the container, so it is nothing for us to worry about. We will be using **mariadb** as our database server container. This container can run on the Portenta X8's architecture. All we need to start using these containers is to write a **docker-compose.yml** file. This file will contain information about what image we want to install and some important configuration information, such as the username for the database, password, timezone and database name. The same goes for the Wordpress container: it will contain the password and username and we will also enter the database host name and which container it will use as database. We recommend that you change the default passwords to more secure ones by replacing the default ones that are stated in the file below. +The WordPress container we use is a multi-container application, which also requires a database server container. The WordPress multi-container application uses Apache as its web server. This is required to make the service work and it is already included in the container, so it is nothing for us to worry about. We will be using **MariaDB** as our database server container. This container can run on the Portenta X8's architecture. All we need to start using these containers is to write a **docker-compose.yml** file. This file will contain information about what image we want to install and some important configuration information, such as the username for the database, password, timezone and database name. The same goes for the WordPress container: it will contain the password and username and we will also enter the database hostname and which container will be used as the database. We recommend that you change the default passwords to more secure ones by replacing the default ones that are stated in the file below. ### The Complete Docker-compose.yml File -In this section you can find the complete **docker-compose.yml** file that we will be using for this tutorial. +In this section, you can find the complete **docker-compose.yml** file that we will be using for this tutorial. ``` version: "3.9" @@ -84,19 +84,19 @@ Now let's create a directory on our X8 and put this **docker-compose.yml** file ### Installing The Containers -First we create a directory where we want to add our **docker-compose.yml** file. Using the `mkdir` command we will create a directory named "wordpress-test". Navigate into this directory with a simple `cd` command. Either copy the docker-compose.yml file into this directory or create it directly here. To create the file, we can use `cat > docker-compose.yml`, this will create the file, so you can copy contents of the file from above and paste it. Push enter once to go to a new line and press `ctrl C` to exit the file editor. To copy the file from your computer onto the device use: `adb push /home/fio/wordpress-test`. +First, we create a directory where we want to add our **docker-compose.yml** file. Using the `mkdir` command we will create a directory named "wordpress-test". Navigate into this directory with a simple `cd` command. Either copy the docker-compose.yml file into this directory or create it directly here. To create the file, we can use `cat > docker-compose.yml`, this will create the file, so you can copy the content of the file from above and paste it. Push enter once to go to a new line and press `ctrl C` to exit the file editor. To copy the file from your computer onto the device use: `adb push /home/fio/wordpress-test`. ![cd into correct directory](assets/webserver-mkdir.png) -Before installing the containers, make sure that no other container is running on the ports that the Wordpress container will use. You can check what containers are running and what port they are using by running the `docker ps -a` command. This will show a list of the currently installed and running containers on the Portenta X8. To remove a container first stop it with `docker stop `, then you can run `docker rm ` to remove it. If you want more information about handling containers on your Portenta X8, take a look at our [managing containers with docker tutorial](https://docs.arduino.cc/tutorials/portenta-x8/docker-container). +Before installing the containers, make sure that no other container is running on the ports that the WordPress container will use. You can check what containers are running and what port they are using by running the `docker ps -a` command. This will show a list of the currently installed and running containers on the Portenta X8. To remove a container first stop it with `docker stop `, then you can run `docker rm ` to remove it. If you want more information about handling containers on your Portenta X8, take a look at our [managing containers with docker tutorial](https://docs.arduino.cc/tutorials/portenta-x8/docker-container). -When you are in the correct directory and no other container is running on the ports that Wordpress will use, you can now run `docker compose up -d`. Using the `-d` tag in the command will allow running these containers in the background. If you run the command without the `-d` tag, the application will exit when you close the terminal. When the command is executed it will start installing the **Wordpress** and **mariadb** containers. This can take a while. To get the output from the containers use: `docker-compose logs -f`. Once it is done you can connect to the device and site. +When you are in the correct directory and no other container is running on the ports that WordPress will use, you can now run `docker compose up -d`. Using the `-d` tag in the command will allow running these containers in the background. If you run the command without the `-d` tag, the application will exit when you close the terminal. When the command is executed it will start installing the **WordPress** and **MariaDB** containers. This can take a while. To get the output from the containers use: `docker-compose logs -f`. Once it is done you can connect to the device and site. ![Containers install progress in the terminal](assets/webserver-container-install.png) -### Connecting to the Wordpress Site +### Connecting to the WordPress Site -To connect to the Wordpress setup site, you simply need to access it with your Portenta X8s unique id and port. So for example: `http://portenta-x8-.local:`, where you would substitute the `` with your Portenta X8's unique id and the port chosen for the Wordpress container with ``. The `` can be found on the setup page that is showed in the [Getting started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box), but you can also see it in the terminal when running `adb` or you can go to `http://192.168.7.1:8000` if you use Windows and Linux, on MacOS use `http://192.168.8.1:8000`. +To connect to the WordPress setup site, you simply need to access it with your Portenta X8s unique id and port. So for example: `http://portenta-x8-.local:`, where you would substitute the `` with your Portenta X8's unique id and the port chosen for the WordPress container with ``. The `` can be found on the setup page that is shown in the [Getting started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box), but you can also see it in the terminal when running `adb` or you can go to `http://192.168.7.1:8000` if you use Windows and Linux, on MacOS use `http://192.168.8.1:8000`. When you connect, you should get some feedback in the terminal. Text will begin printing in the terminal, showing you information about the connection that has just been established as shown in the image below. @@ -106,15 +106,15 @@ Now you should see a webpage, like the following image, in your browser. ![Wordpress setup site](assets/webserver-wordpress-site.png) -You are now free to go through the Wordpress set up process and configure it however you like. +You are now free to go through the WordPress setup process and configure it however you like. ## Conclusion -In this tutorial we went through how to install and run a Wordpress and database container on the Portenta X8. We then accessed the Wordpress site on our X8 through our web browser. So now you can setup your own Wordpress site on your X8 device and access it from another device. +In this tutorial, we went through how to install and run a WordPress and database container on the Portenta X8. We then accessed the WordPress site on our X8 through our web browser. So now you can set up your own WordPress site on your X8 device and access it from another device. ## Troubleshooting -- If the containers are not installing or running correctly, check if there are any other containers currently running on the same ports as the ones used by the Wordpress container. You can check this with ``docker ps -a``. +- If the containers are not installing or running correctly, check if there are any other containers currently running on the same ports as the ones used by the WordPress container. You can check this with ``docker ps -a``. - If there is any issue running docker commands, make sure you are using ``sudo`` before the commands. -- If you cannot connect to the site when everything is running, you can double check the X8s IP address. Run the command `ip s a` in the **adb shell**. This will display the X8's IP address via USB and WiFi. Try connecting via those IP addresses if all the rest fails. +- If you cannot connect to the site when everything is running, you can double-check the X8s IP address. Run the command `ip s a` in the **adb shell**. This will display the X8's IP address via USB and WiFi. Try connecting via those IP addresses if all the rest fails. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/content.md deleted file mode 100644 index 34662e7aab..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/custom-container/content.md +++ /dev/null @@ -1,197 +0,0 @@ ---- -title: Create and Upload a Custom Container to the Portenta X8 -difficulty: intermediate -tags: [Linux, Python®, Containers, ADB] -description: This tutorial will show you how to create and upload your custom container to your Portenta X8 -author: Benjamin Dannegård -hardware: - - hardware/04.pro/boards/portenta-x8 -software: - - adb ---- - -## Overview - -In this tutorial we will create a simple container that we can then upload to the Arduino Portenta X8. A container consists of an image file and all it's dependencies if there are any. This tutorial will go through the different files needed to create a container and their functions. Building this container locally and then uploading it to a Portenta X8. Using docker with ADB to build, run and attach our container to the Portenta X8. - -## Goals - -- Learn how to create a container for use with the Portenta X8 -- Learn how to upload a container to the Portenta X8 - -### Required Hardware and Software - -- [Portenta X8](https://store.arduino.cc/portenta-x8) -- ADB -- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) -- Arduino Pro Cloud Subscription. [Learn more about the Pro Cloud](https://www.arduino.cc/pro/hardware/product/portenta-x8#pro-cloud). - - -## Instructions - -When running a container, it uses an isolated filesystem. This custom filesystem is provided by a container image. Since the image contains the container’s filesystem, it must contain everything needed to run an application - all dependencies, configuration, scripts, binaries, etc. The image also contains other configuration for the container, such as environment variables, a default command to run, and other metadata. - -## Container File Structure - -To create our container we need to collect our necessary files. Creating a folder called **x8-custom-test**, the following files needs to be in the folder: -- docker-build.conf -- docker-compose.yml -- Dockerfile -- requirements.txt -- src folder -- main.py (This file should be inside the src folder) - -The complete folder will look like this: - -![Folder structure for container](assets/custom-container-folder.png) - -Lets go through what these files contain and do. - -### Docker-build.conf -A file containing the minimal "unit test" command to be executed on the container to prove it's working. Our file will make our containers minimal unit test a test of Python3 help command. - -```python -TEST_CMD="python3 --help" -``` - -### Docker-compose.yml -This file defines the app name through the Factory, permissions and settings for the involved containers. The argument in the image tag will make it so our image file builds locally. - -```python -version: '3.6' - -services: - x8-custom-test: - image: blob-opera:latest - restart: always - tty: true - read_only: true - user: "63" - tmpfs: - - /run - - /var/lock - - /var/log - - /tmp -``` - -### Dockerfile -This is used to build the container. - -```python -FROM python:3-alpine3.15 - -# Set our working directory -WORKDIR /usr/src/app - -# Copy requirements.txt first for better cache on later pushes -COPY requirements.txt requirements.txt - -# pip install python deps from requirements.txt on the resin.io build server -RUN pip install -r requirements.txt - -# This will copy all files in our root to the working directory in the container -COPY ./src/main.py ./ - -# Enable udevd so that plugged dynamic hardware devices show up in our container. -ENV UDEV=1 - -# main.py will run when container starts up on the device -CMD ["python","-u","main.py"] -``` - -### Requirements.txt - -```python -Flask==0.12.3 -``` - -### Source -Here we will keep source code of the app you want to run in the container or a startup script. We will create a file and name it **main.py** in this folder. This script will print "Hello World!" in the CLI window. - -```python -from flask import Flask -app = Flask(__name__) - -@app.route('/') -def hello_world(): - return 'Hello World!' - -if __name__ == '__main__': - app.run(host='0.0.0.0', port=80) -``` - -## Uploading the Container Folder - -First, you have to have set up your board to a Factory, as shown in the [Portenta X8 Out of the Box tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box). - -Once this is done, we will push our folder to a repository within the Factory. Lets place our folder "x8-custom-test" inside the "containers.git" repository. You can find this repository inside your Factory page, if you click on "Source". And then on "container.git", the url of this page will be used in the next command. - -![Source on Foundries.io Factory page](assets/custom-factory-page.png) - -![Where to find container.git](assets/custom-factory-git.png) - -![Container.git page](assets/custom-git.png) - -In order to pull or push repositories you have to generate an API key. This can be done by going to the user settings on the Factory page. First click on the user drop-down menu, then go into the tokens page and follow the steps of creating a new API key. When creating the API key make sure you select the "Use for source code access" option and the correct factory that you want to use the key for. This token will be used as the password for all git operations while the username can be anything, except an empty string. - -![User settings on your Factory page](assets/factory-user-settings.png) - -![Token creation section in Foundries.io](assets/token-creation-page.png) - -Use the following command in git on your machine. To get the repository on your machine, replace "YOUR_FACTORY" with the name of your Factory. The "-b" parameter specifies a branch to checkout after cloning the repository. Running this command will get the container repository, where we will put our folder. - -``` -git clone https://source.foundries.io/factories/YOUR_FACTORY/containers.git -b devel -``` - -Put the "x8-custom-test" folder in the repository and push it with git. When you have put the folder into the git folder, use `git status` to see the changed files in the folder, it will show the unadded changes in red, then use `git add` to add the changes you want to your git commit. Then use `git commit` and `git push` to finally push the changes to the repo. If you push the commit to "containers.git" a new target will automatically build on your FoundriesFactory, you can inspect it in the "Targets" page. - -### Building and Running the Container - -After the build is finished, it can take up to 10 minutes for your device to OTA update to this new version. You can inspect it via the "Devices" tab of your FoundriesFactory. After your device takes the update, navigate into the "x8-custom-test" folder, that should be located on your board now. This allows us to build our container with a simple command. Using ```docker build``` with a ```--tag``` will let us give the container a tag so we can easily keep track of what version of the build this is. - -```python -docker build --tag "x8-custom-test:latest" . -``` - -Now that it is built we can run it with ```docker run```, finding it with the tag that we chose to give to the build we want to run. Here we will have to enter the user information into the --user tag. This information is found inside the "docker-compose.yml" file. - -```python -docker run -it --rm --user "63" x8-custom-test:latest -``` - -### Using Docker-Compose - -A option for testing an app or container is to use "docker-compose". This is helpful when we have a lot of settings in our "docker-compose.yml" file, since we don't have to use those settings in the run argument with this method. First navigate into the container folder. - -```python -cd /home/fio/x8-custom-test -``` - -This docker-compose command will start your application and register it as a systemd service that will persist even when a reboot occurs. So at the next boot your docker-compose app will run automatically. - -```python -docker-compose up --detach -``` - -To stop the docker-compose app from running, use the following command: - -```python -docker-compose stop -``` - -## Conclusion - -This tutorial went through what goes into a container, how the folder should be built and what files it should contain. It then explained what each files purpose is and what they should contain for this example. Then we went through how this relates back to the Factory, and how Foundries.io makes the whole process easier for us. We then showed how to build the container and run it on the Portenta X8. Lastly, we showed a useful testing feature with docker-compose. Which lets us test our container with a faster process. - -### Next Steps - -To get a better understanding of how to manage containers with Docker, take a look at our [Managing Containers with Docker on Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/docker-container). This tutorial will show some useful commands to use with the docker service and ADB or SSH. - - -## Troubleshooting - -Here are some errors that might occur in the process of this tutorial: - -- Make sure you have followed our other tutorials that shows how to set up the [Portenta X8 out of the box](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box) -- If you are having issues with the adb shell, don't forget to try and use `sudo` and `su` diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/content.md deleted file mode 100644 index f26c98600f..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/display-output-webgl/content.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: 'Output WebGL Content on a Screen' -description: 'This tutorial shows how to install and modify a container that outputs web browser and webGL content' -difficulty: beginner -tags: - - containers - - Docker - - WebGL - - Vim -author: 'Pablo Marquínez' -software: - - Terminal - - Docker -hardware: - - hardware/04.pro/boards/portenta-x8 ---- - -## Overview - -The Arduino Portenta X8's processor **NXP® i.MX 8M Mini Processor** can be used for 3D rendering, this will allow us to display 3D content on a screen or video output, the device is using OpenGL to process the 3D related calculations. In this tutorial we will render web content from the internet using WebGL and display it on a screen, using an USB Hub. We will go through the steps of how to setup, install and modify the video output. - -## Goals - -- Setup the Video Output -- Get the required container -- Run the container -- Change the video output - -### Required Hardware and Software - -- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) -- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) -- USB-C® hub with HDMI -- External monitor -- HDMI cable - -## Instructions - -### Install The Container - -There are two ways to get the container, either through `foundriesFactories` or downloading the container from [portenta-containers repository](https://github.com/arduino/portenta-containers) - -**With Foundries.io:** - -If you use [Foundries.io](https://www.foundries.io) you can switch the current `target` of your device to `x-kiosk-imx8-webgl` by switching the app from a terminal on your computer: - -``` -//Change the app to an existing one -fioctl devices config updates --apps "x-kiosk-imx8-webgl" -f - -//Make a clean installation with no containers -fioctl devices config updates --apps "," -f - -//If you are getting issues to do so, make sure you are logged correctly with your token -//You can logout: -fioctl logout - -//Then login again and follow the instructions -fioctl login -``` - -You will now see the home-screen for some seconds and then it will fade-out and open the Aquarium 3D from [WebGL samples - Aquarium](https://webglsamples.org/aquarium/aquarium.html). - -**With downloaded repository:** In case you downloaded the [portenta-containers repository](https://github.com/arduino/portenta-containers) you will need to connect your board directly to your computer and run the `adb shell`, then push the container to your Portenta X8. - -### Connect to a Wi-Fi - -Check the available Wi-Fi access points -``` -nmcli de wifi - -//Output -IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY - AA:BB:CC:DD:EE:FF Infra X 130 Mbit/s -- * WPA2 -``` - -You can save your Wi-Fi details with these commands: -``` -nmcli c add type wifi con-name ifname wlan0 ssid -nmcli con modify wifi-sec.key-mgmt wpa-psk -nmcli con modify wifi-sec.psk -nmcli con up - -//To disconnect from a custom connection -nmcli con down - -//To delete a saved connection -nmcli c delete -``` - -If the LED is on and green then we know that has been correctly connected. If you want to check it in your terminal, you can type: -``` -nmcli de - -//Output -DEVICE TYPE STATE CONNECTION -usb0 ethernet connected usbrndis -usb1 ethernet connected usbecm -wlan0 wifi connected -docker0 bridge connected (externally) docker0 -``` - -### Get Your Board's IP -``` -ifconfig wlan0 - -//Output -wlan0: flags=4163 mtu 1500 - inet netmask 255.255.255.0 broadcast -``` - -Test your IP connection by exiting the `adb shell`, you can use **CTRL+Z** or typing `exit`, then try to connect through **ssh** with: -``` -ssh fio@ -``` -***To connect through ssh it will request the user's password, which is "fio".*** -***If you have troubles connecting with the ssh, please check the troubleshooting section at the end of this tutorial*** - -### Copy/push the Container -You can push the container from your computer, first open a terminal on the container's directory, then you can use this command to send the container to the Portenta X8: -``` -scp fio@: -``` - -### Video Output Setup - -Now we need a USB Hub that has a video output connector, like for an HDMI cable. Connect the Portenta X8 to the USB Hub as a Host, the video connector to a display, the power supply USB to your computer. We could also connect a USB mouse to the hub, this step is optional. - -The setup should look like this: - -![X8 usb hub setup](assets/portentaX8_hub_screen.svg) - -By default if you connect the board to a display you will see the "home-screen" with the `Arduino PRO` background wallpaper, and a bottom bar with the real time. - -***You can interact with the interface by plugging USB devices to your hub, like a mouse or a keyboard.*** - -![X8 home-screen](assets/portentaX8-home-screen.png) - -### Running The Container -If you got the container from **Foundries.io** it will run automatically after few seconds. - -In case you copied from the repository, you will need to initialize it with **docker** by accessing your Portenta X8 through ssh, going to the directory where you copied it and run it from there: - -``` -//Connect to your device -ssh fio@ - -//Change directory -cd - -//Compose with docker -docker-compose up --detach - -//Stop the docker-compose -docker-compose stop -``` - -### Edit The Output -You can change the URL of the web output, by going to the container's directory and editing the `docker-compose.yml` file: -``` -//Connect to your device -ssh fio@ - -//Change directory -cd - -//Edit the file with VIM -vim docker-compose.yml -``` - -Once you are inside the **VIM** editor, to edit the file you will need to press **insert** and replace the url as shown in the screenshot. - -![VIM editing docker-compose.yml](assets/vim-edit-dockerCompose.png) - -To save the changes press the **ESC** key and type `:wq` this will write and quit the **VIM** editor. After editing it you will need to compose the container again. - -## Conclusion - -In this tutorial we went through how to connect the board and display something on a screen. Using a container from FoundriesFactories or by downloading it and uploading it to your Portenta X8. Lastly, we showed how to edit the video output by editing the container. - -### Next Steps - -- Make your own HTML content, push it to your device and output that content. -- You could make an app that shows information about the weather in a web and having that on a display. - -## Troubleshooting -- If you tried to connect with `ssh` and you get a **fingerprint** issue you will need to remove the IP and fingerprint on your `.ssh` file, on windows the file is at `C:\Users\\.ssh\known_hosts` and try again the **ssh** connection. - -Example: -``` -// -192.168.50.8 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAasdaddgre -``` - -In this case we run `docker ps -a` and copy the `CONTAINER_ID` which in this case is `c44ba77b65cb`. - -***`CONTAINER_ID` changes its value every time you re-install them*** - -![Docker CLI container uninstall](assets/docker-container-rm.png) - -If you run `docker images` again you will see that the container is not showing up anymore. - -## Conclusion - -In this tutorial you learned how to install a container onto your device, run it and manage it. - -### Next Steps - -- Now that you have the base of the workflow to use [Docker](https://docker.com), go to its docs page and make sure you understand all the features. -- Look for a container from [Docker hub](http://hub.docker.com), install it and make your own application out of it. -- Create a container to run your custom made application. \ No newline at end of file diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/content.md deleted file mode 100644 index 5cfc552ae8..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-building/content.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -beta: true -title: 'How To Build a Custom Image for Your Portenta X8' -description: 'This tutorial teaches you how to compile a custom image for your Portenta X8' -difficulty: advanced -tags: - - Embedded Linux - - Building - - Yocto-project -author: 'Pablo Marquínez' -hardware: - - hardware/04.pro/boards/portenta-x8 ---- - -## Overview - -In this tutorial you will learn how to build an image for the Portenta X8 with the source code provided at our [GitHub repository for lmp-manifest](https://github.com/arduino/lmp-manifest). -Building your image locally can help debug certain aspects of the system, such as the bootloader or kernel support. - -***Keep in mind that images built locally cannot register with FoundriesFactory and will not be OTA compatible, but this is a good alternative for those who do not have a FoundriesFactory subscription. -This tutorial targets customers that are not FoundriesFactory subscribers, but still want to extend the functionality of the Arduino pre-built sources by building their own images. For FoundriesFactory subscribers, we strongly suggest making use of your Factory's continuous integration system for creating images.*** - -## Goals - -- Build a "builder" Docker image -- Get the required files -- Configure the build settings -- Build the image -- Save the needed files for flashing - -### Required Hardware and Software - -- [Docker Engine](https://docs.docker.com/engine/install/) -- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) -- ~60GB available space on your machine's drive - -## Instructions - -### Docker - -#### Build the Docker Image - -You will create a Docker image that has the dependencies needed to build your device image. - -To do so you will need to clone our [lmp-manifest repository](https://github.com/arduino/lmp-manifest), follow these steps to do so: - -First, clone the lmp-manifest repository with this command: - ``` - git clone https://github.com/arduino/lmp-manifest.git - ``` - ![Cloning lmp-manifest repository](assets/git_clone_lmp-manifest.png) - -Then build the Docker Image using: - ``` - cd lmp-manifest - docker build -t yocto-build ./lmp-manifest - ``` - ![Building a Docker Image](assets/docker_build.png) - -#### Run The Docker Image (Builder) - -Run the image with the `-v` argument to mount a volume. This allows you to use a host directory inside the Docker image, so you can store all the data and build artifacts safely. - -***If you do not use a volume while running the image, you will lose the data when the image stops*** - -Run the `yocto-build` builder image with: -``` -docker run -v :/dockerVolume -it yocto-build bash -``` - -Switch to the `builder` user with the following command, the password is **builder**: -``` -su builder -``` - -### Setup and Build - -***You can download a [bash script](assets/portenta-x8_build.sh) that wraps all the upcoming steps.*** - -#### Setup the Environment - -Now that you are running inside the Docker Image, you can use tools like **git-repo**, which is already installed. - -First configure git with your credentials. They don't need to be the real ones, but are required by `git-repo` to pull. -Copy and paste the following: -``` -git config --global user.email "you@example.com" -git config --global user.name "Your Name" -``` -![Adding credentials to git config](assets/git_config.png) - -Change to the home directory, and initialize the repository using **repo**: -``` -cd ~ -repo init -u https://github.com/arduino/lmp-manifest.git -m arduino.xml -b release -``` -![Git-repo initialization](assets/repo_init.png) - -Then pull the needed files with: -``` -repo sync -``` -![Git-repo pulling all the repositories](assets/repo_sync.png) - -After completion it should look like the following image: - -![Git-repo finished sync](assets/repo_sync_finished.png) - -***NOTE: If you are a FoundriesFactory subscriber and want to build your Factory sources locally, please use the manifest link for your Factory as below. This is not recommended as images built locally cannot register to the Factory and receive OTAs.*** - -#### Set Up The Portenta X8 Distribution - -You can set `DISTRO` to: -- `lmp-base`: insecure image without ostree, developer friendly, not OTA compatible -- `lmp`: secure image without xwayland -- `lmp-xwayland`: secure image with xwayland support - -***`lmp-partner-arduino-image` will be better supported in the near future.*** - -```bash -DISTRO=lmp-xwayland MACHINE=portenta-x8 . setup-environment -``` - -It will then switch automatically to a new folder. Now to accept the EULA with: - -```bash -echo "ACCEPT_FSL_EULA = \"1\"" >> conf/local.conf -``` - -![Setup Portenta X8 DISTRO](assets/x8_distro_setup.png) - -#### Build Image With Bitbake - -To start building the image, run: - -``` -bitbake lmp-partner-arduino-image -``` -***This process takes ~7h depending on the build host*** - -![Compile Portenta X8 image](assets/x8_build.png) - -In case you want to use your computer while it builds, (which is going to take time and resources) you should lower the threads used. -Do so by opening `conf/local.conf` and lower the values of the following variables: - -- `BB_NUMBER_PARSE_THREADS = "4"` -- `BB_NUMBER_THREADS = "4"` - -And add: - -- `PARALLEL_MAKE = "-j 4"` - -Once it finishes you will see something similar to: -![Portenta X8 Image finished compilation](assets/x8_build_finished.png) - -#### Setup Manufacturing Tools - -To flash your board you will need to compile **lmp-mfgtool distro** to get additional tools. First go into your home folder and change `DISTRO`: -``` -cd .. -DISTRO=lmp-mfgtool MACHINE=portenta-x8 . setup-environment -echo "ACCEPT_FSL_EULA = \"1\"" >> conf/local.conf -echo "MFGTOOL_FLASH_IMAGE = \"lmp-partner-arduino-image\"" >> conf/local.conf -``` -![Flashing tools DISTRO setup](assets/tools_distro_setup.png) - -#### Build Manufacturing Tools: Flash The Board - -To compile and get the tools you will need to type: -``` -bitbake mfgtool-files -``` -![Compiling flashing tools](assets/tools_build.png) - -After completion: -![Tools compilation finished](assets/tools_finished.png) - -***This process takes ~2h depending on your build host*** - -#### Save Your Image For Flashing - -After a successful build, save the needed files to the host volume you mounted with `docker run`. Use the following commands to copy the files to your storage unit: - -``` -cd .. -mkdir ../../dockerVolume/flashing -DEPLOY_FOLDER=../../dockerVolume/flashing - -cp -L build-lmp-mfgtool/deploy/images/portenta-x8/mfgtool-files-portenta-x8.tar.gz $DEPLOY_FOLDER -cp -L build-lmp-xwayland/deploy/images/portenta-x8/imx-boot-portenta-x8 $DEPLOY_FOLDER -cp -L build-lmp-xwayland/deploy/images/portenta-x8/u-boot-portenta-x8.itb $DEPLOY_FOLDER -cp -L build-lmp-xwayland/deploy/images/portenta-x8/sit-portenta-x8.bin $DEPLOY_FOLDER -cp -L build-lmp-xwayland/deploy/images/portenta-x8/lmp-partner-arduino-image-portenta-x8.wic $DEPLOY_FOLDER - -cd $DEPLOY_FOLDER -tar xvf mfgtool-files-portenta-x8.tar.gz -``` - -![Copying compiled files](assets/copy_files.png) - -You will be able to see the copied files in your OS file explorer. -![Checking copied files with file explorer](assets/docker_volume_explorer.png) - - -## Conclusion - -Now you have all the required files to flash the image you built onto the device. - -Please follow the [Flashing tutorial](image-flashing) to flash your device with your custom image. -Keep in mind you will need to use the files provided from this build, not the ones mentioned in the Flashing tutorial. - -## Troubleshooting - -- If you are having `do_fetch` issues, try to check your system's and virtual machine's DNS settings. \ No newline at end of file diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/content.md deleted file mode 100644 index 042932a884..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/image-flashing/content.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -beta: true -title: 'How To Flash Your Portenta X8' -description: 'This tutorial teaches you how to flash your Portenta X8 through USB' -difficulty: intermediate -tags: - - Embedded Linux - - Flashing -author: 'Pablo Marquínez' -hardware: - - hardware/04.pro/boards/portenta-x8 ---- - -## Overview - -In this tutorial you will see how to manually flash your Portenta X8 with the image that is provided by Arduino. You will flash your board through USB using the Terminal. -The instructions below are meant to be used with a Windows Operating System. - -***Attention: We encourage you to check every now and then if the device image version is up-to-date in order to have the latest bootloader. Please check the release section of the [lmp-manifest repository](https://github.com/arduino/lmp-manifest/releases) and compare the target version number*** - -## Goals - -- Get the required files -- Set up the correct structure of the files -- Set up the board -- Flash the device - -### Required Hardware and Software - -- USB-A to USB-C® cable -- Portenta X8 -- Portenta Breakout Board or Portenta Max Carrier - -## Instructions - -### Get the Required Files - -#### Arduino's GitHub Repository - -Go to the `lmp-manifest` [GitHub repository](https://github.com/arduino/lmp-manifest) and open the [releases](https://github.com/arduino/lmp-manifest/releases) section, there you will find a compressed `.tar.gz` with all the required files. - -While we were writing this tutorial the available version was `456`, but you will probably find a more recent version in the future. - -Click on the file `456.tar.gz` (or newer) and download it to your computer. - -![lpm-manifest repository overview](assets/lpm-manifest-overview.png) - -Then After downloading it, unzip it, you will get a structure like the following: - -``` -Unzipped folder -├── imx-boot-portenta-x8 -├── lmp-partner-arduino-image-portenta-x8.wic.gz **(Compressed)** -├── mfgtool-files-portenta-x8.tar.gz **(Compressed)** -├── sit-portenta-x8.bin -└── u-boot-portenta-x8.itb -``` - -Then unzip `mfgtool-files-portenta-x8.tar.gz` and `lmp-partner-arduino-image-portenta-x8.wic.gz` make sure the .wic is on the unzipped folder in the main directory. - -It needs to be like: -``` -Unzipped folder -├── mfgtool-files-portenta-x8/ -├── imx-boot-portenta-x8 -├── lmp-partner-arduino-image-portenta-x8.wic -├── lmp-partner-arduino-image-portenta-x8.wic.gz **(Compressed)** -├── mfgtool-files-portenta-x8.tar.gz **(Compressed)** -├── sit-portenta-x8.bin -└── u-boot-portenta-x8.itb -``` - -### Set the Portenta X8 to Flashing Mode - -Plug your Portenta X8 into your carrier (e.g. Portenta Breakout carrier or Portenta Max Carrier). - -Place both DIP switches to the ON position. - -On the Portenta Max Carrier the DIP switches are identified by a label `BOOT SEL` and `BOOT` as shown in figure. - -![Max Carrier DIP switches](assets/max-carrier-dip-switches.png) - -On the Portenta Breakout the DIP switches are identified by a label `BT_SEL` and `BOOT` as shown in figure. - -![Breakout DIP switches](assets/breakout-dip-switches.png) - -Plug one USB-C® end into the Portenta X8 and the other end (USB-C® or USB-A) to your computer. - -You will see a new connected device called `SE Blank M845S`. - -### Flash the Device - -Open a terminal and change the directory (`cd`) to the folder where `mfgtool-files-portenta-x8` file is located. - -Use the `uuu full_image.uuu` command. - -Wait until it gets flashed. - -![uuu tool flashing success output](assets/uuu-flashing-success.png) - -At this point, set back the DIP switches to OFF position. - -Unplug and then plug-in again the Portenta X8 to your computer. - -***After booting you will need to wait 10 secs until the Portenta X8 blue LED starts blinking. This means the boot was successful.*** - -Now you can start using your Portenta X8 with the latest updates. - -## Troubleshooting - -- If you get an error while it is flashing, make sure your USB is correctly plugged in. Re-plug your board and try to flash it again. You may need few trials before the flashing is successful. -- If you get an error related to permissions, try to launch the `uuu` command as Super User (`sudo`). diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/Multi_Protocol_Gateway_X8.zip b/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/Multi_Protocol_Gateway_X8.zip deleted file mode 100644 index 38fa514b1a..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/Multi_Protocol_Gateway_X8.zip and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-arch-general.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-arch-general.png deleted file mode 100644 index f640189892..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-arch-general.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-arch.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-arch.png deleted file mode 100644 index fbdd83d772..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-arch.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-hardware.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-hardware.png deleted file mode 100644 index 2e5d462e25..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/assets/multi-protocol-hardware.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/content.md deleted file mode 100644 index bc6b956b93..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/multi-protocol-gateway/content.md +++ /dev/null @@ -1,532 +0,0 @@ ---- -title: 'Multi-Protocol Gateway With Portenta X8 & Max Carrier' -description: 'This tutorial shows how to setup a multi-protocol gateway environment on Portenta X8 using Max Carrier' -tags: - - Containers - - Docker - - LoRa® - - Wi-Fi - - Sensor - - RPC -author: 'Taddy Ho Chung, José Bagur' -software: - - Terminal - - Docker -hardware: - - hardware/04.pro/boards/portenta-x8 ---- - -## Overview - -Portenta X8 has the NXP® i.MX 8M Mini MPU (Linux) and STM32H747XI dual Cortex®-M7+M4 32bit low power ARM® MCU (Arduino) stacked together and can be used to design different work loads for these two different microprocessors. We will use the Portenta Max Carriers onboard CMWX1ZZABZ-078 LoRaWAN® module from Murata® and the Wi-Fi connectivity from Portenta X8 to build a Multi-Protocol Gateway. - -In this tutorial we will go through the steps on how to setup both the Linux and Arduino side. A device collecting sensor data will transfer the data via Wi-Fi, receive the data and exchange them between the Arduino and Linux layers, for finally using LoRaWAN® to send the information to The Things Network. We will also configure and expose a local communication lane to further expand its capability if a local sensor is desired. - -## Goals - -- Build an Arduino layer script using RPC to handle sensor readings or data traffic on Portenta X8. -- Build a multi-protocol script to manage MQTT protocol and LoRa® connectivity to handle data traffic on the Linux layer of Portenta X8. -- Assemble both layer scripts to build an operational multi-protocol gateway using Portenta X8 and Max Carrier. - -### Required Hardware and Software - -- [Arduino Portenta X8](https://store.arduino.cc/products/portenta-x8) -- [Arduino Portenta Max Carrier](https://store.arduino.cc/products/portenta-max-carrier) -- USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®) -- Wi-Fi Access Point with Internet Access -- 868-915 MHz antenna with SMA connector -- ADB or SSH. [Check how to connect to your Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box#controlling-portenta-x8-through-the-terminal) - -## Multi-Protocol Gateway 101 - -A gateway is a network node and a key-point for data exchange between different networks under certain given specifications. Simply referred to as hardware that communicates between two networks. On the other hand, a **multi-protocol gateway** goes one step further by implementing variety of protocols in a single gateway. - -The idea of **Multi-Protocol Gateway** is to build a device that will establish a information relay, that handles incoming and outgoing traffic of data using different connectivity protocols. - -This means that the gateway can receive the data transmitted in certain protocol type and relay the data in a different protocol for a remote server. Such feature provides the ability to develop distinctive types of protocols and relay the data with less complexity. - -The Portenta X8 paired with the Portenta Max Carrier has the potential to create synergy, and you will have following connectivity tools at your disposal: - -- Wi-Fi (MQTT Protocol) -- Bluetooth® Low Energy -- LoRaWAN® (The Things Network) -- NB-IoT & Cat-M1 - -The following image illustrates how a overall multi-protocol gateway works with Portenta X8 and Max Carrier as the gateway system. - -![Multi-Protocol Gateway General Architecture Overview](assets/multi-protocol-arch-general.png) - -Bear in mind, that this tutorial focuses on developing a multi-protocol gateway using some connectivity modules. Yet, this Portenta combination still has much to offer. To get the most out of it, we will go step by step on how to establish the multi-protocol gateway and add scalability to expand its capability. - -Foremost, you will get to know how the multi-protocol gateway will be implemented with Portenta X8 paired with Max Carrier. Some other tutorials will be referenced to guide you through the present tutorial, as it involves mechanisms that are extensive to cover. - -### Arduino Layer - -The Arduino layer is extended within the M4 Core and it is the layer dedicated to the development of real time operations. Thus, you can use the Arduino layer to perform PID tasks and make the RPC calls to exchange data with the Linux layer. - -***To learn about how to exchange data using RPC between Arduino and Linux layer, please read ["Data Exchange Between Python® on Linux and an Arduino Sketch"](https://docs.arduino.cc/tutorials/portenta-x8/python-arduino-data-exchange)*** - -We will go through how to use RPC to expose data received from the Arduino layer to the Linux layer, if further development requires you to feed data to devices interfaced communicating with the M4 core. We will leave the tasks running and open to be interfaced with for expanding the capability of the Portenta X8 and Max Carrier. It will let you develop a gateway system where: - -1. The Arduino layer will be the terminal to expose the received sensor data to control a local end-device. -2. A local end-device transferring data to the Linux layer for further networking process. - -Hence the multi-protocol architecture will process and manage the data traffic with the desired protocol. - -### Linux Layer - -It is important to understand that **all networking processes are made within the Linux layer**. All network processes that are Wi-Fi, Bluetooth® Low Energy, LoRa®, NB-IoT and Cat. M1. We will focus on using Wi-Fi with MQTT protocol and LoRa® connectivities to establish a multiple protocol gateway. - -The Portenta X8 provides Wi-Fi connectivity and the Portenta Max Carrier provides a LoRaWAN® module that can help us communicate with The Things Network. We will use the MQTT protocol to receive sensor data transmitted by an end device. - -We will use a Python® script that will configure and handle the connectivity modules and its sensor data. The RPC calls will be used to expose the received sensor data to the Arduino layer, setting up data exchange configuration to further expand the capability of the Portenta X8 and Max Carrier. The process can also be done vice-versa and makes use of the Arduino layer to transmit the data to the Linux layer from the local end-device. - -Now that we know the roles of Arduino and Linux layer, we will need a clear picture on how the multi-protocol gateway should look. The next diagram illustrates the in-depth multi-protocol gateway architecture, showing how each layer and module will cooperate. - -![Multi-Protocol Gateway In-Depth Architecture](assets/multi-protocol-arch.png) - -## Instructions - -To showcase the ability of the Linux layer and Arduino layer extended by M4 Core, we will build a multi-protocol gateway that will receive MQTT protocol packages using EMQX as the broker, retrieve the data from a local sensor attached to Portenta via RPC mechanism, wrap the data together and send to The Things Netowork using LoRa® connectivity within Cayenne Low Power Payload Encoder. - -This will help you get a better understanding on how the Portenta X8 and the Portenta Max Carrier can help you develop a multi-protocol gateway. - -### Hardware Setup - -First things first, you will need to configure the hardware to be able to develop and work on the Multi-Protocol gateway. We will attach the Portenta X8 to the Portenta Max Carrier with High-Density Connectors and you will have to make sure to attach an antenna for LoRa® connectvity. The Portenta X8 also needs to have the Wi-Fi antenna attached to it. - -![Multi-Protocol Gateway Hardware Setup](assets/multi-protocol-hardware.png) - -***If you have not set up your Portenta X8, please have a look at [Portenta X8 Getting Started](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box) tutorial.*** - -### Setting Up The Portenta X8 - -Before you begin diving deep into creating Multi-protocol gateway, and having understood that you will frequently communicate between Arduino and Linux layers, you will have to understand how to debug and observe the way these 2 layers interact. - -The `m4-proxy` is a service that manages data exchange between these layers. You can use the following command in the terminal to observe if the service is running correctly. - -``` -sudo journalctl -fu m4-proxy -``` - -Now you are going to implement RPC (Remote Procedure Call) to establish communication between the Arduino and Linux layers. This is a communication mechanism developed to exchange data between these two layers. - -A very important note to take into account: **you will not be able to check messages via `Serial.println()` statements** to check if the Arduino sketch is running in a desired manner. You will have to use **`py-serialrpc`**, which is a service that will assist you in listening to those messages, printing them on a console. To have the service active, please download [this compressed file](assets/py-serialrpc.zip) to build and run the container on the Linux side of Portenta X8. Please execute following commands in order to have the service running. - -``` -// Copy the decompressed files in ../adb/32.0.0 -adb push py-serialrpc /home/fio -adb shell - -sudo su - - -// Head to directory and mount the container -cd /home/fio/py-serialrpc -#py-serialrpc sudo docker build . -t py-serialrpc -#py-serialrpc sudo docker-compose up -d -``` - -To access the logs of `py-serialrpc` service, while maintaining the same directory, execute the following command. - -``` -sudo docker-compose logs -f --tail 20 -``` - -***For more details about how data exchange between Arduino and Linux layer works and to understand how to debug, please read [Data Exchange Between Python® on Linux and an Arduino Sketch](https://docs.arduino.cc/tutorials/portenta-x8/python-arduino-data-exchange)*** - -In case you have not configured internal Wi-Fi connectivity within the system, please use following command line. - -``` -nmcli device wifi connect "SSID" password "PASSWORD" -``` - -### Setting Up The Things Network - -You now have the pre-requisites for the Portenta X8 ready, but, since you are using the LoRa® connectivity, you will need a platform that has the capability to receive data transmitted from the Portenta X8 and Max Carrier. **The Things Network** will be the platform you are going to use communicate using LoRaWAN®. On the platform, you will need to create an application to add the Portenta Max Carrier as an End-Device. - -When adding the End-Device, at the moment you will have to use the **Manual** option. The Portenta Max Carrier will be added under Arduino SA in the near future to be included in the LoRaWAN® Device Repository. The LoRaWAN® version and parameters compatible with the Portenta Max Carrier are as follows. The frequency plan will depend on the region in which you are going install the device. - -![General End-Device Configuration](assets/ttn-end-device.png) - -***To learn more about LoRa® and LoRaWAN®, please have a look at our [Arduino Guide to LoRa® and LoRaWAN®](https://docs.arduino.cc/learn/communication/lorawan-101). Additionally, if you wish to learn on how to properly setup the End-Device in The Things Network, please read [this tutorial](https://docs.arduino.cc/tutorials/mkr-wan-1310/the-things-network) reference*** - -Let's now dive into developing a multi-protocol gateway using Portenta X8 and Max Carrier! - -### Building the Multi-Protocol Gateway - -It is important to put all the requirements into an operational task that will orchestrate every protocol you are going to use. You will have to create the following files and the required codes for your multi-protocol gateway. - -You will need the Docker files that will configure and let you build a working container. - -***If you are unfamiliar handling with Docker and containers, please read the tutorial on how to [Create and Upload a Custom Container to the Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/custom-container)*** - -You can access the files [here](assets/Multi_Protocol_Gateway_X8.zip). Meanwhile, let's take a look at some of the important details of the included files. - -### Docker Compose - -Beginning with the `docker-compose.yml` file, which is where you define permissions and settings for the involved container. - -``` -... -extra_hosts: - - 'm4-proxy:host-gateway' -devices: - - '/dev/ttymxc3' - - '/dev/gpiochip5' -tty: true -user: "0" -``` - -### Requirements - -Here you will define which additional components are required to be able to run the script built inside the container. If you decide to further develop with different protocol, you will have to add the package in order to be able to use them for development. - -``` -msgpack-rpc-python -pyserial==3.4 -python-periphery==2.3.0 -python-dotenv -pycayennelpp -paho-mqtt -``` - -### Multi-Protocol Python® Application - -This is the main Python® script that will handle overall networking process. We will highlight important fragments of the code to help you understand how these codes pieces work together to build a gateway based on multiple protocols. For full Python® script please refer to the files [here](assets/Multi_Protocol_Gateway_X8.zip). - -First up, the configuration for the M4 Proxy Server, which are the parameters that handles communication with the M4 core that extends the Arduino layer. The `m4_proxy_port` is configured to `5001`, as it is the port used by clients to send the data to the M4. - -```python -#M4 Proxy Server Configuration -# Fixed configuration parameters -port = 8884 -publish_interval = 5 - -# The M4 Proxy address needs to be mapped via Docker's extra hosts -m4_proxy_address = 'm4-proxy' -m4_proxy_port = 5001 -``` - -The next function is dedicated to retrieve data from the M4 (Arduino layer). It will help you set the variables, such as sensor data, to then be pulled and be exposed to the Linux layer. With this, you will have the information available to be used within the Python® script. - -```python -def get_data_from_m4(): - - rpc_address = RpcAddress(m4_proxy_address, m4_proxy_port) - - data = () - - try: - rpc_client = RpcClient(rpc_address) - rpc_data0 = rpc_client.call('Data_0') - - rpc_client = RpcClient(rpc_address) - rpc_data1 = rpc_client.call('Data_1') - - data = rpc_data0, rpc_data1 - - except RpcError.TimeoutError: - print("Unable to retrieve data from the M4.") - - return data -``` - -For MQTT configuration, you will need to set the desired parameters. Below you can find the parameters we use for MQTT in this tutorial. - -```python -mqtt_broker = 'broker.emqx.io' -mqtt_port = 1883 -mqtt_topic = "multiPrGw/mqtt1" -# generate client ID with pub prefix randomly -mqtt_client_id = f'python-mqtt-{random.randint(0, 100)}' -mqtt_username = 'emqx' -mqtt_password = 'public' -``` - -These 2 parameters are required to establish a connection with The Things Network. The `APP_EUI` and `APP_KEY` are required to be configured, as they are provided from The Things Network or from the LoRaWAN® platform that you may try extablishing connection to. Additionally, the `DEV_EUI` will be predefined as the device will request and apply the EUI. However, if it requires to use different `DEV_EUI`, you can make the change in this section. - -```python -# Obtained during first registration of the device -SECRET_APP_EUI = 'XXXXXXXXXXXXXXXX' -SECRET_APP_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -``` - -With these parameters configured, you have secured the connection between your device and The Things Network. The Things Network would be your end-point where the sensor data is going to be sent over. And to send data, you need to begin by gathering this data, which can be from sensors or modules with status feedback. A sensor can be attached directly communicating via Arduino layer to receive the data, wrap it and send it to The Things Network. Meanwhile, you will also need to have a mechanism that will be able to intercept data sent over Wi-Fi connectivity using a MQTT protocol. - -Following tasks are the main processes that will be used to handle MQTT protocol. This will allow to decode incoming packets from the subscribed device and buffer the data if timeout has occurred while waiting on the MQTT packet. In this way you will be able to receive sensor data from any external device, for example using Arduino MKR Wi-Fi 1010 with a sensor attached, using MQTT protocol. - -```python -# MQTT protocol handler -... -def connect_mqtt() -> mqtt_client: - def on_connect(client, userdata, flags, rc): - if rc == 0: - logging.debug("Connected to MQTT Broker!") - else: - logging.debug("Failed to connect, return code %d\n", rc) - - client = mqtt_client.Client(mqtt_client_id) - client.username_pw_set(mqtt_username, mqtt_password) - client.on_connect = on_connect - client.connect(mqtt_broker, mqtt_port) - - # Thread in the background calling loop() in an automatic manner - client.loop_start() - return client - -def on_message(client, userdata, msg): - logging.debug(f"MQTT Client: `{msg.payload.decode()}` from `{msg.topic}` topic") - - decoded_mqtt_payload = json.dumps(EncodeFloat(msg.payload.decode("utf-8"))) - print("MQTT Payload Data=%.15g" % (float(decoded_mqtt_payload))) - - # `mqtt_data` is the payload decoded within receiving MQTT packet from a remote device - mqtt_data.append(float(decoded_mqtt_payload)) - client.loop_stop() - - return mqtt_data - -def subscribe(client: mqtt_client): - global mqtt_data - mqtt_timeout = time.time() + 60 - - client.subscribe(mqtt_topic) - client.on_message = on_message - - while len(mqtt_data) <= 0: - print(f"Awaiting MQTT packet before proceeding") - time.sleep(publish_interval) - if time.time() > mqtt_timeout: - print(f"No MQTT packet is received - Defaulting Data") - mqtt_data = [0.0] - break - else: - print(f"MQTT packet received") - - print(f"MQTT packet: ", mqtt_data[0]) -... -``` - -For LoRa® connectivity, to establish communication with The Things Network, we are going to use the Cayenne Low Power Payload Encoder as part of the process in this build. - -```python -... -frame = LppFrame() -frame.add_temperature(0, rpc_data[0]) -frame.add_humidity(1, rpc_data[1]) - -# MQTT payload as Generic 4-Byte Unsigned Integer -frame.add_generic(2, mqtt_data[0]) - -# Encoding packet for transmission -payload = bytes(frame) -lora_module.sendBytes(payload, len(payload), False) -... -``` - -### Multi-Protocol Arduino (M4) Application - -For the full Arduino scripts please refer to the files found inside [this compressed file](assets/Multi_Protocol_Gateway_X8.zip). - -The following sketch is for the Arduino layer that will help us retrieve the data in between Arduino and Linux layer. - -```arduino -# Arduino side sketch -#include -#include - -const long interval = 1000; -unsigned long previousMillis = 0; - -void setup(){ - pinMode(PA_12, INPUT); - //RPC.begin(); - - Serial.begin(115200); - while (!Serial) {} - - Serial.println("M4 Layer - Multi Protocol Gateway"); - - RPC.bind("Data_0", []{ return analogRead(A0); }); - RPC.bind("Data_1", []{ return analogRead(A1); }); - - Serial.println("Service Begin"); -} - -void loop(){ - unsigned long currentMillis = millis(); - - if (currentMillis - previousMillis >= interval) { - previousMillis = currentMillis; - - //record random value from A0 and A1 - Serial.println(analogRead(A0)); - Serial.println(analogRead(A1)); - - } -} -``` - -The sketch above will help to expose and transfer the data that is processed within the Linux side. Transferring data to Linux side can be seen as a direct communication, as the sensor connected and monitored via Arduino side will send this data over LoRa® connectivity. For this build, we are going to use Analog readings to emulate the functionality. - -Additionally by exposing, it means you will bring forth the data received within the Linux side to the Arduino side to feed the local-device as a control input. It can be used to display the data if you wish to for instance. This can be implemented in this script if you wish to further develop your desired multi-protocol gateway. - -For MQTT publishing, we have also included a sketch that can be used with Arduino MKR Wi-Fi 1010 to test the gateway build. Of course, the code can be extended and be modified according the requirements of the device that will collect data from a certain sensor to send over MQTT protocol. - -```arduino -#include -#include -#include "arduino_secrets.h" - -///////please enter your sensitive data in the Secret tab/arduino_secrets.h -char ssid[] = SECRET_SSID; // your network SSID (name) -char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) - -WiFiClient wifiClient; -MqttClient mqttClient(wifiClient); - -const char broker[] = "broker.emqx.io"; -int port = 1883; -const char topic[] = "multiPrGw/mqtt1"; - -//set interval for sending messages (milliseconds) -const long interval = 50000; -unsigned long previousMillis = 0; - -int count = 0; - -void setup() { - //Initialize serial and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } - - // attempt to connect to Wi-Fi network: - Serial.print("Attempting to connect to WPA SSID: "); - Serial.println(ssid); - while (WiFi.begin(ssid, pass) != WL_CONNECTED) { - // failed, retry - Serial.print("."); - delay(5000); - } - - Serial.println("You're connected to the network"); - Serial.println(); - - Serial.print("Attempting to connect to the MQTT broker: "); - Serial.println(broker); - - if (!mqttClient.connect(broker, port)) { - Serial.print("MQTT connection failed! Error code = "); - Serial.println(mqttClient.connectError()); - - while (1); - } - - Serial.println("You're connected to the MQTT broker!"); - Serial.println(); -} - -void loop() { - // call poll() regularly to allow the library to send MQTT keep alive which - // avoids being disconnected by the broker - mqttClient.poll(); - - unsigned long currentMillis = millis(); - - if (currentMillis - previousMillis >= interval) { - // save the last time a message was sent - previousMillis = currentMillis; - - //record random value from A0, A1 and A2 - float Rvalue = analogRead(A0); - - Serial.print("Sending message to topic: "); - Serial.println(topic); - Serial.println(Rvalue/10); - - // send message, the Print interface can be used to set the message contents - mqttClient.beginMessage(topic); - mqttClient.print(Rvalue/10); - mqttClient.endMessage(); - - Serial.println(); - } -} -``` - -## Mounting the Multi-Protocol Gateway - -It is now time to make the multi-protocol gateway to run and for this you will need to build the Docker container that will help you operate in the background on the Linux layer. Using the terminal, you can use the following commands to get the multi-protocol gateway container up and running. - -You will need to have the files ready in a folder inside the `adb` directory within Arduino root. - -``` -C:\Users\#USERNAME#\AppData\Local\Arduino15\packages\arduino\tools\adb\32.0.0 -``` - -Having the files ready at that directory, you can use the following commands to push the files to the `fio` directory inside the Portenta X8. The second command will let you navigate inside the Portenta X8. - -``` -adb push multi-protocol-gateway /home/fio -adb shell -``` - -You will now build the container using the following commands. The following command will tag the container with `Multi_Protocol_Gateway_X8` as its name. - -``` -cd ../home/fio/Multi_Protocol_Gateway_X8 -#Multi_Protocol_Gateway_X8 sudo docker build . -t multi_gateway -``` - -You will be able to see following results when the image is built successfully. - -![Multi-Protocol Gateway Docker Build Terminal Log](assets/docker-build.png) - -***If you have created the Docker container previously and want to re-create it with new changes made outside the shell, please check that the container and its build directory is stopped and removed. This is for the convenience of having a clean working environment*** - -After a successful container build, you will have to make the image run. To do that, you can use the following command. This command will immediately give an output in your terminal, telling you how the Python® script is running. If you wish to have it running in the background, please add `-d` flag at the end of the command. - -``` -#Multi_Protocol_Gateway_X8 sudo docker-compose up -``` - -Finally, you will have the multi-protocol gateway running, in which it uses Wi-Fi and LoRa® connectivity. And also RPC for exchanging data between its layers. However, there are cases where you wish to make changes by adding more functionalities, such as including Cat. M1 or NB-IoT to expand its communication spectrum and for this you will need to stop the image. To stop the image from running, you can use following command. - -``` -#Multi_Protocol_Gateway_X8 sudo docker-compose down -``` - -Getting to know status of the image is also crucial as it is the indicator of state of operation. The following command brings up **active** images and shows the status if the image restarted or stopped due to certain reasons. The second command lists built images and it will show you the components that goes with the main image that you're building. - -``` -docker ps -a -docker images -``` - -![Multi-Protocol Gateway Active Docker Image](assets/docker-state.png) - -With all this, you have built a running multi-protocol gateway based on Portenta X8 and Max Carrier. You will be able to observe the data sent by the gateway with The Things Network platform End-Device section under Applications. - -If you are curious about what to expect from the build you have made in this tutorial, the following image shows you the terminal of the running multi-protocol gateway. - -![Multi-Protocol Gateway Run Log](assets/multi-protocol-gateway-example-run.png) - -## Conclusion - -In this tutorial you have learned how to set up a Multi-Protocol Gateway composed of MQTT protocol, RPC and LoRaWAN®, by using the Portenta X8 and the Portenta Max Carrier. You have built the gateway that will connect to The Things Network to send the desired data. Also, the gateway is capable of exchanging data between Arduino and Linux layer using RPC, in which you have exposed the ports to be able to receive data from the local sensor to be sent directly to The Things Network. - -### Next Steps -- Now that you have developed a multi-protocol gateway, using Wi-Fi and LoRaWAN® connectivity, expand the gateway's capability by adding other connectivity types such as Cat. M1 and NB-IoT -- Expand functionalities for data processing using RPC while using multi-protocol architecture. - -## Troubleshooting - -You might encounter some errors or misbehaviors while working on the code, preventing you from progressing on the development. You can try the following troubleshooting tips to solve the commonly known issues: - -* If the sketch upload process fails, check if your Portenta X8 is in bootloader mode. To put the Portenta X8 into Bootloader mode, double-press its RESET button and verify that the green LED is blinking. After this, you can try re-uploading the sketch for the Arduino layer. -* Check the position of the BOOT DIP switch of the Portenta Max Carrier. If the Portenta X8 gets into bootloader mode immediately after powering-on, including when connected via USB-C®, change the position of the BOOT DIP switch to OFF. This case applies to the Arduino layer. -* If you encounter an issue regarding terminal input inconvenience, please enter `export TERM=xterm` as the command in the terminal to get readable inputs. -* In case internal Wi-Fi connection cannot be established through the command input due to "unavailable" SSID, although it is in range. Please try using different SSID if available or hotspot from a different device to host network connectivity. -* If you encounter docker image conflict when running after building, please make sure you have used name tag that matches the one from the `docker-compose.yml` file. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/adb-connection.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/adb-connection.png deleted file mode 100644 index 7dfb9345b7..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/adb-connection.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/cloud-main.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/cloud-main.png deleted file mode 100644 index e9980a2748..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/cloud-main.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/command-journalctl.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/command-journalctl.png deleted file mode 100644 index e256cf9268..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/command-journalctl.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-device-page.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-device-page.png deleted file mode 100644 index c7f5f9eb69..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-device-page.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-prompt.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-prompt.png deleted file mode 100644 index c4a596114b..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-prompt.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-success.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-success.png deleted file mode 100644 index 4f12c185d1..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-success.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-token.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-token.png deleted file mode 100644 index 24921c3bc3..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-activation-token.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-create-factory.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-create-factory.png deleted file mode 100644 index cbe25d16ff..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-create-factory.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factories.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factories.png deleted file mode 100644 index bf63d97701..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factories.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factory-dashboard.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factory-dashboard.png deleted file mode 100644 index 3a68352d0d..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factory-dashboard.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factory-devices.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factory-devices.png deleted file mode 100644 index 38e92b4f07..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/foundries-factory-devices.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/ssh-connection-admin.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/ssh-connection-admin.png deleted file mode 100644 index 842e74986e..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/ssh-connection-admin.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/ssh-connection.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/ssh-connection.png deleted file mode 100644 index 28da9376e3..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/ssh-connection.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-name.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-name.png deleted file mode 100644 index 79d6416b14..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-name.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-register.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-register.png deleted file mode 100644 index e1aebda952..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-register.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-success.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-success.png deleted file mode 100644 index 53f785cdb7..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-factory-success.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main-factory.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main-factory.png deleted file mode 100644 index cc6909c764..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main-factory.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main-wifi.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main-wifi.png deleted file mode 100644 index 904d8b675b..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main-wifi.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main.png deleted file mode 100644 index bfa60466d8..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-main.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-pass.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-pass.png deleted file mode 100644 index 246107dcbb..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-pass.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-ssid.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-ssid.png deleted file mode 100644 index bc87fca757..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-ssid.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-sucess.png b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-sucess.png deleted file mode 100644 index 6a9a146bbf..0000000000 Binary files a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/assets/x8-oob-wifi-sucess.png and /dev/null differ diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/content.md deleted file mode 100644 index a64e2573c9..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/out-of-the-box/content.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -beta: true -title: 'Portenta X8 Getting Started' -description: 'Learn how to set up the Portenta X8' -difficulty: intermediate -tags: - - Beta - - Installation - - OTA - - Embedded Linux - - Arduino Pro Cloud -author: 'Pablo Marquínez' -hardware: - - hardware/04.pro/boards/portenta-x8 -software: - - ide-v1 - - ide-v2 - - web-editor - - iot-cloud ---- - - -## Required Hardware and Software - -* [Portenta X8](https://store.arduino.cc/products/portenta-x8) board. -* Wi-Fi AP with Internet access. - -***Attention: We encourage you to check every now and then if the device image version is up to date in order to have the latest bootloader, please check the tutorial [How to flash your Portenta X8](https://docs.arduino.cc/tutorials/portenta-x8/image-flashing) for instructions.*** - -## Connecting to the Board - -Once the Portenta X8 is plugged in via USB, you can open your browser and go to http://192.168.7.1 if you use Windows and Linux or http://192.168.8.1 on MacOS. It can take up to 15 seconds for the board to boot up and make the page available. This web page is hosted on the Portenta X8, from this dashboard you will be able to: - -![Board set up page](assets/x8-oob-main.png) - -* [Configure Wi-Fi](#connecting-to-your-wi-fi) -* [Add your device to FoundriesFactory (OTA)](#add-a-new-device-to-your-factory) -* Board details -* Shell (alpine Python®) - -## Connecting to Your Wi-Fi - -Click the Wi-Fi button to start configuring your network connection. - -![Select Wi-Fi on set up page](assets/x8-oob-main-wifi.png) - -Select your Wi-Fi SSID. - -![Wi-Fi ssid set up](assets/x8-oob-wifi-ssid.png) - -Type the password. - -![Wi-Fi password set up](assets/x8-oob-wifi-pass.png) - -Once it is connected, you should see the Wi-Fi status bullet in the bottom left turning green. - -![Wi-Fi connection done](assets/x8-oob-wifi-sucess.png) - -***You can change your network by clicking on the button again and repeat the above steps*** - -## Connect to FoundriesFactory - -### Register a FoundriesFactory on Foundries.io - -***The integration with Foundries.io requires the Arduino Pro Cloud Subscription, subscribe at [Arduino PRO Cloud for Business](https://cloud.arduino.cc/plans), or learn more on the [Arduino Pro Page](https://www.arduino.cc/pro/hardware/product/portenta-x8#pro-cloud)*** - -Go to [https://create.arduino.cc](https://create.arduino.cc) and click on Portenta X8 Board Manager, you will get prompted to set a new `Factory` name if you did not have one before. You will not be able to be change the name later, so use one that you can remember and write easily. - -![Arduino Cloud integration](assets/cloud-main.png) - -It will redirect you to FoundriesFactory registration page. - -![Foundries Factory creation](assets/foundries-create-factory.png) - -Then you can go to [https://app.foundries.io/factories](https://app.foundries.io/factories) and it will show the Factory you just created. - -![Foundries Factories](assets/foundries-factories.png) - -After you have created your FoundriesFactory you need to go back to the Portenta-X8 web dashboard to add a new device into your new Factory. - -### Add A New Device To Your Factory - -Click the "Register Factory name" button. - -![Register Factory button](assets/x8-oob-main-factory.png) - -![Factory connection](assets/x8-oob-factory-name.png) - -The next panel gives you a code that you need to copy. - -![Device Factory token](assets/x8-oob-factory-register.png) - -Click on the "Complete registration" button on the Portenta X8 dashboard - -The button will open the Foundries.io activation page. Paste your token in the text box and press continue. - -![Foundries device link](assets/foundries-activation-token.png) - -Confirm the addition of the new device by pressing "Connect" - -![Foundries device confirmation](assets/foundries-activation-prompt.png) - -Finally you will see a confirmation which means that your device now is attached to the new Factory. - -![Dashboard with a Factory attached](assets/foundries-activation-success.png) - -Once it is completed, the Factory button on the Portenta X8 dashboard will turn green. - -![Successful connection](assets/x8-oob-factory-success.png) - -#### Check Your FoundriesFactory - -Have a look to your factories by going to [Foundries.io factories page](https://app.foundries.io/factories) - -![Foundries.io factories page](assets/foundries-factories.png) - -Select the Factory that you want to check and it will open its dashboard. - -![Foundries.io Factory dashboard](assets/foundries-factory-dashboard.png) - -#### Check Your Device - -You can check if your device is fully connected to your Factory by going to the "devices" tab. - -![Foundries.io Factory devices page](assets/foundries-factory-devices.png) - -Then choose the device you want to check by clicking on its box and it will open its page. - -![Foundries new device activation page](assets/foundries-activation-device-page.png) - -## Controlling Portenta X8 Through the Terminal - -You have plenty of ways to communicate with your board, be it wirelessly or with a cable. Next we are going to show how to use adb and ssh. - -### ADB - -First of all make sure you have the latest **Mbed OS Portenta Core**, which contains the adb program. - -You can go to its directory inside the **Arduino15/packages/arduino/tools/adb/32.0.0**. To check the tool you can use your terminal and type `adb`, you should get feedback from the tool when typing this. - -To know the list of devices that can be accessed type `adb devices`. - -If you only see one device you can try and type `adb shell`, you are now communicating with your Portenta X8. - -![Terminal using ADB](assets/adb-connection.png) - -### SSH - -SSH is commonly used for remote control on different kinds of devices running different set ups through TCP-IP. - -To communicate with your board, you will need to know the IP of it, and just type `ssh fio@`, then the terminal workaround should be the same as ADB. The password is `fio`. - -![SSH connection](assets/ssh-connection.png) - -As it is a linux device, you can do normal stuff like creating files, changing directory, etc. - -To gain admin (root) access, type `sudo su -` and the password is `fio` after that the terminal prefix should turn red. - -![CLI configured](assets/ssh-connection-admin.png) - -### CLI Commands - -### Connect to a Wi-Fi Access Point - -Using the network manager tool `nmcli`: - -`nmcli device wifi connect password ` - -To check your manager connection status, use this command: - -`nmcli de` - -### Register Device to the FoundriesFactory - -***The integration with Foundries.io requires the Arduino Pro Cloud Subscription, subscribe at [Arduino PRO Cloud for Business](https://cloud.arduino.cc/plans), or learn more on the [Arduino Pro Page](https://www.arduino.cc/pro/hardware/product/portenta-x8#pro-cloud)*** - -Make sure the name is not already being used in your Factory. - -`lmp-device-register -n ` - -**Not recommended:** In case you cannot register the new device, you can erase the current device info by stopping the OTA services and removing `/var/sota/sql.db`. After these commands, you can register the device again. - -`sudo systemctl stop aktualizr-lite` -`sudo systemctl stop fioconfig.path` -`sudo systemctl stop fioconfig.service` -`sudo rm /var/sota/sql.db` - -### Inspecting Real Time Tasks - -Run: `journalctl -f` to see what's going on on the device - -![Real time tasks on CLI](assets/command-journalctl.png) diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/content.md deleted file mode 100644 index e4e7d43134..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/python-arduino-data-exchange/content.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 'Data Exchange Between Python® on Linux and an Arduino Sketch' -description: 'This tutorial will show you how to run a Python® application that exchanges data with an Arduino Sketch.' -tags: - - RPC - - Python® -author: 'Sebastian Romero' -hardware: - - hardware/04.pro/boards/portenta-x8 ---- - -## Overview - -The container infrastructure provided by Arduino contains a pre-built Python® image that you can use to run Python® applications on the Portenta X8. In this tutorial we're going to build a container based on a provided one. While all the peripherals can be accessed from the iMX8 processor running the Linux environment, it can be useful to let the onboard microcontroller take care of certain peripheral handling and just exchange the required data between the microcontroller and the Python® application. In this tutorial you will learn how to do that. If you haven't done so, read through the [foundations article](/tutorials/portenta-x8/x8-fundamentals) to understand the fundamental concepts of the X8 and the provided infrastructure. - -## Goals - -- Learn how the RPC mechanism on the X8 works -- Learn how to exchange sensor data between Linux and an Arduino sketch -- Learn how to modify a container and run it -- Learn how to use commands to debug the container and service infrastructure - -## Required Hardware and Software - -- [Portenta X8](https://store.arduino.cc/products/portenta-x8) board -- [Portenta breakout](https://docs.arduino.cc/hardware/portenta-breakout) board -- Any sensor (in this example we'll use an [BME680](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors/bme680/) I2C module) - -## Python® on the X8 - -Python® is a modern and powerful scripting language that can be used for all sorts of use cases. In this tutorial we only read sensor data from an Arduino sketch without doing anything interesting with it, but you could extend the example and process the data further. - -### Communication Between Linux and Arduino Sketches - -The Python® script will run on the Linux side and therefore on the iMX8 processor. The Arduino sketch on the other hand will run on the STM32H747 microcontroller. That allows for real-time processing on the Arduino side while running a fully fledged operating system on iMX8. However the two processors need a communication mechanism to exchange data with one another. The communication mechanism that is being used is referred to as RPC (Remote Procedure Call). To facilitate the communication the M7 core on the STM32H747 microcontroller is used which hands over any data / request to the M4 core. That means your Arduino sketch will solely run on the M4 core. Dual core processing on the Arduino side is currently not supported. - -On the Linux side there is a service that takes care of sending data between the two worlds. It's called `m4-proxy`. You can check if the service is running by logging into the X8 via `adb shell` and then executing `sudo journalctl -fu m4-proxy`. If, for whatever reason, the service has stopped, you can restart it with `sudo systemctl restart m4-proxy` - -## The Arduino Sketch - -The Arduino sketch to read sensor data doesn't look much different from an ordinary sketch. The only thing that differs is that we expose the sensor data via RPC. - -```arduino -RPC.bind("temperature", []{ return bme.temperature; }); -RPC.bind("humidity", []{ return bme.humidity; }); -RPC.bind("pressure", []{ return bme.pressure / 100.0F; }); -RPC.bind("gas", []{ return bme.gas_resistance / 1000.0; }); -RPC.bind("altitude", []{ return bme.readAltitude(SEALEVELPRESSURE_HPA); }); -``` - -Two additional header files need to be included: - -```arduino -#include -#include -``` - -The bind function makes the data available via the specified name e.g. "temperature". In our example an anonymous function is created that returns the corresponding sensor property whenever requested. Alternatively you could bind the name to an existing, named function instead. The data can then easily be requested using that name (e.g. "humidity") by querying the `m4-proxy` service. Once data is being requested it is packaged as a message and sent over SPI to the iMX8. - -![The iMX8 and the STM32H747 processor communicate via SPI](assets/component-placement.svg) - -You can find the sketch in the software package [here](assets/python-sensor-rpc.zip). You may need to change the sketch depending on what sensor you would like to read from. If you're using an I2C sensor, you can connect SCL to **PWM6** and SDA to **PWM8** on the Portenta breakout. That's because the labeled I2C pins on the Portenta Breakout are only available on the Linux side. If you're using an analog sensor you can connect it to any analog pin. Please refer to the pinout diagram on the Portenta Breakout [documentation page](/hardware/portenta-breakout). - -![Wiring diagram of an I2C sensor attached to the X8 via Portenta Breakout](assets/sensor-wiring-breakout.svg) - -Make sure you've installed the "Arduino Mbed OS Portenta Boards" core and upload the sketch to the X8 in the Arduino IDE or via Arduino CLI. - -### Debugging the Arduino Sketch - -To check if the Arduino sketch is working correctly you may want to read the messages from the `Serial.println` statements. You can't currently read them directly in the serial monitor of the Arduino IDE. Instead, you can use a simple service called `py-serialrpc` which listens for those messages and prints them to the console. This service needs to run on the Linux side of the X8. You can get the files [here](assets/py-serialrpc.zip). From the command prompt of your local machine, navigate to the adb tool folder and upload the files to the X8 with `adb push /py-serialrpc /home/fio`. - -Log into the X8 shell with `adb shell` and navigate into the `serialrpc` folder. Build the container using `sudo docker build . -t py-serialrpc`. The `-t` flag assigns a tag to the container. Then run the container by executing `cd..` and then `sudo docker-compose up -d`. The `-d` flag detaches the container so it runs in the background. Note that this will run the docker container persistently across reboots by registering it as a systemd service. To stop the container, run `sudo docker-compose stop`. - -Check if the container is running by executing `sudo docker ps`. You can then access the log of this service at any time by executing `sudo docker-compose logs -f --tail 20` from the **same directory**. If you don't run the container in the background (skip the `-d` flag), you will get the console output directly in the executing shell. Once the container is running you will see the messages that are being sent from the M4. - -## The Python® Application - -The Python® application requests the sensor data from the M4 over RPC and unpacks the message. Data can be requested by calling the function exposed over RPC on the M4 e.g.: - -```python -m4_proxy_address = 'm4-proxy' -m4_proxy_port = 5001 -rpc_address = RpcAddress(m4_proxy_address, m4_proxy_port) -rpc_client = RpcClient(rpc_address) -temperature = rpc_client.call('temperature') -``` - -The files for the complete Python® application can be found in the same package as the Arduino sketch (see above). Like in the previous step, upload the `python-sensor-rpc` folder to the X8 via `adb push /python-sensor-rpc /home/fio`. Log into the X8 via `adb shell`. Then navigate into the `python-sensor-rpc` folder and execute `sudo docker build . -t python-sensor-rpc`. When it's done you can run the container with `sudo docker-compose up`. After a few seconds you should see the output from the Python application featuring the sensor readings on the M4 that were piped through the RPC mechanism. The output should look similar to the following: - -``` -python-sensor-rpc_1 | ============================================ -python-sensor-rpc_1 | == Portenta X8 Sensor reading == -python-sensor-rpc_1 | ============================================ -python-sensor-rpc_1 | -python-sensor-rpc_1 | Temperature: 25.904266357421875 -python-sensor-rpc_1 | Humidity: 25.564695358276367 -python-sensor-rpc_1 | Pressure: 976.4400024414062 -python-sensor-rpc_1 | Gas: 136.496 -python-sensor-rpc_1 | Altitude: 311.0769348144531 -``` - - Keep in mind that, whenever you change anything in the Python® script on your computer you will have to sync it back to the X8 and re-build the container: - -``` -# On your computer -adb push python-sensor-rpc /home/fio - -# On X8 -sudo docker-compose down -sudo docker build . -t python-sensor-rpc -sudo docker-compose up -``` - -Alternatively you could modify the files directly on the X8 using an editor such as VIM so you don't need to upload the files all the time. Re-building the container will be necessary in any case though. In case you wonder how to specify the Python® script that is executed when running a container, have a look at the `Dockerfile` file. There you'll find the `ENTRYPOINT` command that takes multiple arguments. In our example: `ENTRYPOINT [ "python3", "m4_to_python.py"]` - -## Conclusion - -In this tutorial you learned how to use the docker infrastructure to build a container that runs a Python® application. You have also learned how to use the RPC mechanism to exchange data between the microcontroller and the iMX8 which runs the Linux operating system. - -### Next Steps - -- You may now further process the data that you receive from the Arduino sketch and e.g. upload it to a cloud service or similar. -- Familiarize yourself with Docker commands to adjust the docker configuration to your needs. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/content.md deleted file mode 100644 index d609aca96e..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/uploading-sketches-m4/content.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: 'Uploading Sketches to the M4 Core on Arduino Portenta X8' -description: 'This tutorial explains how to upload Arduino sketches to the M4 core.' -difficulty: intermediate -tags: - - firmware - - M4 -author: 'Pablo Marquínez' -hardware: - - hardware/04.pro/boards/portenta-x8 -software: - - ide-v1 - - ide-v2 - - cli ---- - -## Overview -In this tutorial we will go through the process of uploading sketches to the M4 core on the STM32H747XI MCU. For the user the process is the same as usual but it differs quite a bit in regards to what happens behind the scenes compared to other Arduino boards. - -## Goals -- Learn how to use the Arduino IDE to compile and upload a sketch. -- Learn how to compile the sketch binaries with the Arduino IDE and upload it manually via ADB. - -### Required Hardware and Software -- [Portenta X8](https://store.arduino.cc/products/portenta-x8) -- USB-C® cable (either USB-A to USB-C® or USB-C® to USB-C®) -- Arduino IDE 1.8.10+ or Arduino-cli -- Latest "Arduino Mbed OS Portenta Boards" Core > 3.0.1 - -## Instructions - -### Standard Arduino IDE Upload -Open the Arduino IDE, make sure you have selected the Portenta X8 in the boards selector. - -![IDE board selector](assets/x8-board-manager.png) - -Create a custom sketch or open one of the example sketches e.g. the blink sketch: -```arduino -void setup(){ - pinMode(LED_BUILTIN ,OUTPUT); -} - -void loop(){ - digitalWrite(LED_BUILTIN , HIGH); - delay(1000); - digitalWrite(LED_BUILTIN , LOW); - delay(1000); -} -``` - -- Select the port of your device in the port selector menu. -- Press the Compile and Upload button. - -Behind the curtains, the sketch gets compiled into a binary. That binary file is then uploaded to the Linux side of the Portenta X8 via an `adb` SSH connection. The flashing itself is done on the board itself by a service running on Linux. When the sketch has bee uploaded successfully, check if the onboard LED is blinking at an interval of one second. - -### Upload Manually Using ADB - -To upload a firmware manually, you first need to compile the sketch. In the Arduino IDE select "Export compiled binary" from the Sketch menu. It will compile the sketch and save the binary file in the sketch folder. Alternatively you can use the [Arduino CLI](https://arduino.github.io/arduino-cli/) to create an elf file. - -To upload the firmware you can use the ADB tool that has been installed as part of the Portenta X8 core. It can be found at `Arduino15\packages\arduino\tools\adb\32.0.0`. - -From that directory you can use the `adb` tool. To upload your compiled sketch you just need to type: -``` -adb push /tmp/arduino/m4-user-sketch.elf -``` - -![ADB upload with a terminal](assets/x8-terminal-ADB-push.png) - -## How It Works? -The Portenta X8 has a service that waits for a sketch to be uploaded to a folder. If it detects changes the device will flash the M4 with the uploaded firmware. - -This work thanks to the following services: -* **monitor-m4-elf-file.service**: this service monitors the directory `/tmp/arduino/m4-user-sketch.elf` and each time it detects a new file it will proceed to flash the M4 using `openOCD` with the sketch that has been pushed. - -## Conclusion -In this tutorial you have learned how to upload a sketch to the M4 core. Now for example you are able to connect an I2C sensor and interact with it. - -## Troubleshooting - -- If you cannot use the `ADB` tool and the folder `Arduino15\packages\arduino\tools\adb\32.0.0` is empty Remove the Mbed Portenta Core and install it again. \ No newline at end of file diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/content.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/content.md deleted file mode 100644 index f1c1cb869d..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/waves-fleet-managment/content.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 'Using FoundriesFactory Waves Fleet Management' -description: 'Learn how to manage multiple Portenta X8 devices using FoundriesFactory fleet management tool, Waves' -difficulty: intermediate -tags: - - Embedded Linux - - Flashing - - Foundries.io -author: 'Benjamin Dannegård' -hardware: - - hardware/04.pro/boards/portenta-x8 ---- - -## Overview - -In a production environment it is convenient to plan updates and have control over when and which devices are updated. FoundriesFactory® Waves is the feature for this. It allows you to easily define a group of Portenta X8s and then push updates to that specific group. The difference between standard updates and using Waves to update is that the Wave update will promote targets to production by double signing them, which makes the updates more manageable and controllable. This tutorial will show you how to define that group and how to construct a Wave that can then be pushed to a group. - -## Goals - -- Learn how to use Waves fleet manager -- Learn how to assign a target to a Wave -- Learn how to push a Wave to a group of devices - -### Required Hardware and Software - -- USB-C® to USB-A or USB-C® to USB-C® -- Portenta X8 -- Arduino Create account -- Arduino Cloud for business subscription with Portenta X8 Manager add-on. [Learn more about it](https://cloud.arduino.cc/plans#business). -- Foundries.io™ account (linked with the Arduino Cloud for business subscription) -- FoundriesFactory® and devices already attached to your Factory. ([Check the Getting Started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box)) - -## Instructions - -### Setting Up the Terminal - -Waves fleet management requires us to have the X8 setup with FoundriesFactory. If you have not done so, please follow our [Getting Started tutorial](https://docs.arduino.cc/tutorials/portenta-x8/out-of-the-box), as it will walk you through setting up the X8 with your Factory. To use Waves, you need to have fioctl installed and configured. Follow this [guide](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) to do so.Creating Waves and device groups will be done via the host, which is your factory. As such, the following commands will be entered in a terminal using fioctl to connect to your Factory. - -### Rotating Our Keys - -For security purposes, we recommend that you rotate your FoundriesFactory keys. Rotation of the key will convert the root role's online-key, which was generated during the bootstrap of your Factory, to an [offline key](https://docs.foundries.io/latest/reference-manual/security/offline-keys.html). - -First we will rotate the root keys. These are the most important keys, as they can be used to create new target keys. Rotate them with the command: -``` -fioctl keys rotate-root --initial /absolute/path/to/root.keys.tgz -``` - -Now we can rotate the target only keys with: -``` -fioctl keys rotate-targets /absolute/path/to/root.keys.tgz -``` - -And finally, for security reasons, we separate the target keys from root using: -``` -fioctl keys copy-targets /absolute/path/to/root.keys.tgz /path/to/target.only.key.tgz -``` - -Now we can move on creating our Wave. - -### Creating a Dummy Wave for Production Targets - -Before a Factory can start doing production OTAs, an initial production Targets file must be created. More information can be found [here](https://docs.foundries.io/latest/reference-manual/ota/production-targets.html). This can be done by creating a dummy wave with the command: -``` -fioctl wave init -k /absolute/path/to/targets.only.key.tgz populate-targets -``` - -Then complete the Wave with: -``` -fioctl wave complete populate-targets -``` -This creates a new targets.json file for production devices, subscribing to the production tag. It will include a single Target from CI build. - -### Creating a Wave - -Now we can start creating our Wave. The command below will create a Wave that can then be pushed to our devices. To create a Wave, we will sign it with a key, here we will use the targets only key. Then we give the Wave a name, target number, and tag. The `target number` needs to correspond to the target that we want the Wave to contain for our devices. The `tag` can be set as production or development. -``` -fioctl wave init -k /absolute/path/to/targets.only.key.tgz -``` - -And then we can complete the Wave by passing the name to the "complete" function: -``` -fioctl wave complete -``` - -Or we can cancel it with: -``` -fioctl waves cancel -``` - -After creating the Wave, you should see it on your Factory page. It should also be marked as complete after you call the Wave complete command. - -![The wave page on your FoundriesFactory](assets/foundriesfactory-waves-page.png) - -### Create the Device Group - -With this command, we create our group, giving it a name and a short description: -``` -fioctl config device-group create "" -``` - -Now to assign a device to our group we use: -``` -fioctl device config group -``` - -On your FoundriesFactory device page you can sort and view devices by group. - -![Device group sorting on the FoundriesFactory page](assets/foundriesfactory-device-group.png) - -To rollout our Wave to our device group, use: -``` -fioctl waves rollout -``` - -Every device in the device group should now have the target specified in the Wave creation. - -### Conclusion - -In this tutorial we first looked at what is required to use the Wave tool. We then went through the process of creating a Wave and device group. Then we pushed a target to the device group using the Wave tool. - -## Troubleshooting - -- If you are having trouble with any fioctl commands you can use `fioctl wave --help` or `fioctl wave rollout --help` depending on the context. diff --git a/content/hardware/04.pro/boards/portenta-x8/tutorials/x8-fundamentals/portenta-x8-fundamentals.md b/content/hardware/04.pro/boards/portenta-x8/tutorials/x8-fundamentals/portenta-x8-fundamentals.md deleted file mode 100644 index 21db7347c0..0000000000 --- a/content/hardware/04.pro/boards/portenta-x8/tutorials/x8-fundamentals/portenta-x8-fundamentals.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Portenta X8 Fundamentals -difficulty: beginner -tags: [Linux, containers, factories, foundries] -description: This article contains information about the fundamental concepts of the Portenta X8 -author: Benjamin Dannegård -hardware: - - hardware/04.pro/board/portenta-x8 -software: - - fioctl - ---- - -## Overview - -The Portenta X8 is one of the more advanced boards available from Arduino. And with that comes some new concepts that are not standard for Arduino boards. In this article we will go through some of the foundations of the Portenta X8 and help you understand how the board works and how you can benefit from the advanced features of this board. You will learn about FoundriesFactory® and how containers on the Portenta X8 work. - -## Goals - -- Get in-depth information about how the Portenta X8 works -- Learn how containers work - -### Required Hardware and Software - -- [Portenta X8](https://store.arduino.cc/portenta-x8) -- [fioctl](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) - -## Instructions - -If you need help with setting up your board then please have a look at the "Getting Started" tutorial. That tutorial will show you how to set up your board with FoundriesFactory and install containers on it. - -## Embedded Linux - -To work in an embedded Linux environment there a few things to consider. When approaching linux-based embedded devices software solutions, you need to provide a base distribution, a mechanism to update it and some applications that can run on the board. The X8 uses a Linux distribution built with the Yocto Project® as the base platform, with applications that are installed and packaged as confined containers. - -A ready-made Linux distribution that packages everything seems most attractive for end users but you need to find a distribution that implements the function that you need. If you need to tweak them you may end up in a mess of patches on the top of someone else's build system. On the other hand, a generic distribution has some problems since installing software over it may pollute the original system and cause issues when updating the base platform. For example you install a new application and the older one no longer works. In addition to that you have to implement a lot of things like cybersecurity functions and system updates. Finally, your solution may rely on a too "generic" distribution, with tons of software you don't need. So you may end up removing a lot of software on the target and also turning features on and off. Until you mess up things or you need to update the system and you restart with a new fresh image and restart everything from the beginning. - -### Benefits of Foundries.io - -Foundries.io™ basically created their generic-but-not-too-generic distribution based on Yocto with minimal software installed, by default implementing top level cybersecurity features like OP-TEE and OSTREE that makes their solution ideal for professional applications. A custom OTA system update mechanism which is based on a client running on target and a robust cloud server. And they married Docker-compose as a way to deploy a software solution to a target. This is like having an app store for a particular device with the difference that we're not installing an app but a container which may contain a whole distribution or a minimal distribution running only our app or our set of apps. - -In addition to that they developed the cloud side as well. In a nutshell you can use what's called FoundriesFactory, a cloud DevSecOps subscription service to build, test, deploy, and maintain secure, updatable IoT and Edge products. It provides a unique id and automatic builds of the base system and containers for this system in one place. Let's now take a look at the Foundries.io Factory page. - -### Foundries.io Factory - -With the help of the Arduino Cloud integration with Foundries.io, you can easily create your Factory right from the Arduino Cloud page. You can set your Factory's platform and name. The platform here will be the Portenta X8. - -![Factory page](assets/factory-page.png) - -Your Factory page allows you to add members, so that you can easily keep track of the members of your team that should have access to the Portenta X8's that are linked to your Factory. You can also set up teams for better management. On the page you can also find a list of all devices linked to the Factory, along with their name and version of container that is currently uploaded to the board. On the containers page you can find all the different versions of containers uploaded to the Factory. - -On the "source" page of your Factory, you can find the four repositories that are used to customize the images. These are: - -- **ci-scripts.git**: Scripts that define the platform and container build jobs to the FoundriesFactory continuous integration system. -- **lmp-manifest.git**: The repo manifest for the platform build. It defines which layer versions are included in the platform image. This includes **meta-partner-arduino**, the layer containing Arduino specific customizations (machine definition, device drivers, etc). -- **meta-subscriber-overrides.git**: OE layer that defines what is included into your Factory image. You can add board specific customizations and overrides, add and remove packages provided in the default Linux microPlatform base. -- **containers.git**: This is where containers and docker-compose apps are defined. It allows you to define what containers to build, and how to orchestrate them on the platform. - -While the "targets" page contains the images built by the Continuous integration system each time something is committed in the repositories. Committing to **lmp-manifest.git** or **meta-subscriber-overrides.git** repositories will create a platform target, while committing to **containers.git** will create a container target. These targets will generate the artifacts for the platforms as specified in the **ci-scripts.git**, including all the required files to program the target in case of platform builds. You can inspect your FoundriesFactory targets in the "targets" page. - -## Containers - -Containers allow for easy deployment of Linux based processes, uploaded through git, which can then be tracked on your Factory page. A Linux container are processes that are isolated from the rest of the system. A container is an image file that contains all the files that are necessary to run it. This makes the Linux containers portable and consistent throughout development, testing and production. Making them much quicker to use than development pipelines that rely on replicating traditional testing environments. - -Foundries.io provides a service that builds images using the Yocto Project and specifically built around the Linux microPlatform (LmP) distribution they maintain. LmP contains an extensive set of software components needed for IoT applications. - -Using [fioctl](https://docs.foundries.io/latest/getting-started/install-fioctl/index.html) allows you to manage your boards through CLI. This will make it possible for you to easily upload containers to a board that is linked to your Factory. When the board is online and connected to the Factory you can easily push new apps to the board. Using fioctl command lines you only need to state the Factory, board and app. - -### Benefits of Containers - -For example if you are developing an application on a laptop and your environment has a specific configuration. Other developers may have slightly different configurations. The application will rely on your configuration and is dependent on specific files, libraries and dependencies. While your business has development and production environments with their own configurations and supporting files. You would want to emulate that environment as much as possible locally. - -With containers you can make your app work across environments, pass quality assurance and get it deployed as fast and easy as possible. - -The contents of a container image can be compared to a an installation of a Linux distribution complete with RPM packages, configuration files, etc. However, a container image distribution is easier to install rather than a new copy of the operating system. - -A Linux container is a good solution for solutions that require portability, configurability and isolation. The idea behind Linux containers is to be able to develop solutions faster to meet business needs as they arise. In certain scenarios, like when real-time data streaming is implemented, containers are the only way to provide the scalability that the application needs. Regardless of the infrastructure on site, in the cloud, or a mix of both. - -## Conclusion - -Now you should have a better understanding of how the Portenta X8 works with factories and containers. This article also gives a better picture of how to utilize the Portenta X8 to its full potential. Be sure to check out our other tutorials with the Portenta X8 to see how to practically use factories and containers.