diff --git a/doc/tutorials/freertos/examples/dfu.rst b/doc/tutorials/freertos/examples/dfu.rst
new file mode 100644
index 000000000..1535f3263
--- /dev/null
+++ b/doc/tutorials/freertos/examples/dfu.rst
@@ -0,0 +1 @@
+.. include:: ../../../../examples/freertos/dfu/README.rst
diff --git a/examples/examples.cmake b/examples/examples.cmake
index e509e1478..3bf4baa86 100644
--- a/examples/examples.cmake
+++ b/examples/examples.cmake
@@ -4,6 +4,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL XCORE_XS3A)
include(${CMAKE_CURRENT_LIST_DIR}/bare-metal/explorer_board/explorer_board.cmake)
## FreeRTOS examples
+ include(${CMAKE_CURRENT_LIST_DIR}/freertos/dfu/dfu.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/freertos/device_control/device_control.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/freertos/dispatcher/dispatcher.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/freertos/explorer_board/explorer_board.cmake)
diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst
new file mode 100644
index 000000000..a498269c0
--- /dev/null
+++ b/examples/freertos/dfu/README.rst
@@ -0,0 +1,249 @@
+##############
+DFU
+##############
+
+This example application demonstrates a method to add DFU to a FreeRTOS application on XCORE.
+
+**********************
+Preparing the host
+**********************
+
+This application supports any host host application that is capable of USB DFU Class V1.1.
+
+The application was verified using dfu-util.
+
+Installation instructions for respective operating system can be found `here `__
+
+If on Linux the user may need to add the USB device to their udev rules. This example defaults to Vendor ID 0xCAFE with Product ID 0x4000.
+
+If on Windows the user may need to use a tool such as Zadig to install USB drivers.
+
+*********************
+Building the firmware
+*********************
+
+Run the following commands in the xcore_sdk root folder to build the firmware:
+
+.. tab:: Linux and Mac
+
+ .. code-block:: console
+
+ cmake -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake
+ cd build
+ make example_freertos_dfu_v1
+ make example_freertos_dfu_v2
+
+.. tab:: Windows
+
+ .. code-block:: console
+
+ cmake -G "NMake Makefiles" -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake
+ cd build
+ nmake example_freertos_dfu_v1
+ nmake example_freertos_dfu_v2
+
+**********************
+Preparing the hardware
+**********************
+
+It is recommended to begin from an erased flash. To erase flash run:
+
+.. tab:: Linux and Mac
+
+ .. code-block:: console
+
+ make erase_all_example_freertos_dfu_v1
+
+.. tab:: Windows
+
+ .. code-block:: console
+
+ nmake erase_all_example_freertos_dfu_v1
+
+This target will use `xflash` to erase the flash of the device specified by the provided target XN file.
+
+After building the firmware and erasing the flash, the factory image must be flashed. From the xcore_sdk build folder run:
+
+.. tab:: Linux and Mac
+
+ .. code-block:: console
+
+ make flash_app_example_freertos_dfu_v1
+
+.. tab:: Windows
+
+ .. code-block:: console
+
+ nmake flash_app_example_freertos_dfu_v1
+
+This target will use `xflash` to flash the application as a factory image with a boot partition size specified in dfu.cmake.
+
+The board may then be power cycled and will boot up the application.
+
+.. tab:: Linux and Mac
+
+ .. code-block:: console
+
+ make create_upgrade_img_example_freertos_dfu_v2
+
+.. tab:: Windows
+
+ .. code-block:: console
+
+ nmake create_upgrade_img_example_freertos_dfu_v2
+
+This target will use `xflash` to create an upgrade image for the specified target.
+
+********************
+Running the firmware
+********************
+
+After flashed, the factory image will run by default. The user may opt to manually run via xrun to see debug messages.
+
+From the xcore_sdk build folder run:
+
+.. tab:: Linux and Mac
+
+ .. code-block:: console
+
+ make run_example_freertos_dfu_v1
+
+.. tab:: Windows
+
+ .. code-block:: console
+
+ nmake run_example_freertos_dfu_v1
+
+********************
+Upgrading the firmware via DFU
+********************
+
+Once the application is running, a USB DFU v1.1 tool can be used to perform various actions. This example will demonstrate with dfu-util commands.
+
+MacOS users may need to sudo the following commands.
+
+To verify the device is running run:
+
+.. code-block:: console
+
+ dfu-util -l
+
+The output of this command will very based on which image is running.
+For example_freertos_dfu_v1, the output should contain:
+
+.. code-block:: console
+
+ Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU dev DATAPARTITION v1", serial="123456"
+ Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU dev UPGRADE v1", serial="123456"
+ Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU dev FACTORY v1", serial="123456"
+
+For example_freertos_dfu_v2, the output should contain:
+
+.. code-block:: console
+
+ Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU dev DATAPARTITION v2", serial="123456"
+ Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU dev UPGRADE v2", serial="123456"
+ Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU dev FACTORY v2", serial="123456"
+
+The factory image can be read back by running:
+
+.. code-block:: console
+
+ dfu-util -e -d 4000 -a 0 -U readback_factory_img.bin
+
+From the xcore_sdk build folder, the upgrade image can be written by running:
+
+.. code-block:: console
+
+ dfu-util -e -d 4000 -a 1 -D example_freertos_dfu_v2_upgrade.bin
+
+After updating the upgrade image it may be necessary to unplug the USB device to initiate a host re-enumeration.
+
+The upgrade image can be read back by running:
+
+.. code-block:: console
+
+ dfu-util -e -d 4000 -a 1 -U readback_upgrade_img.bin
+
+The data partition image can be read back by running:
+
+.. code-block:: console
+
+ dfu-util -e -d 4000 -a 2 -U readback_data_partition_img.bin
+
+The data partition image can be written by running:
+
+.. code-block:: console
+
+ dfu-util -e -d 4000 -a 2 -D readback_data_partition_img.bin
+
+If running the application with the run_example_freertos_dfu_v1 target, information is printed to verify behavior.
+
+Initially, the debug prints will contain:
+
+.. code-block:: console
+
+ DFU Image Info
+ Factory:
+ Addr:0x1C70
+ Size:103108
+ Version:0
+ Upgrade:
+ Addr:0x1B000
+ Size:0
+ Version:0
+ Data Partition
+ Addr:0x100000
+ First word at data partition start is: 0xFFFFFFFF
+
+After writing an upgrade image the debug prints will contain:
+
+.. code-block:: console
+
+ DFU Image Info
+ Factory:
+ Addr:0x1C70
+ Size:103108
+ Version:0
+ Upgrade:
+ Addr:0x1B000
+ Size:103108
+ Version:0
+ Data Partition
+ Addr:0x100000
+ First word at data partition start is: 0xFFFFFFFF
+
+The debug prints include the value of the first word at the start of the data partition. Writing a text file containing "XMOS" will result in:
+
+.. code-block:: console
+
+ DFU Image Info
+ Factory:
+ Addr:0x1C70
+ Size:103108
+ Version:0
+ Upgrade:
+ Addr:0x1B000
+ Size:103108
+ Version:0
+ Data Partition
+ Addr:0x100000
+ First word at data partition start is: 0x534F4D58
+
+********************************
+Debugging the firmware with xgdb
+********************************
+
+From the xcore_sdk build folder run:
+
+.. tab:: Linux and Mac
+
+ .. code-block:: console
+
+ make debug_example_freertos_dfu_v1
+
+.. tab:: Windows
+
+ .. code-block:: console
+
+ nmake debug_example_freertos_dfu_v1
diff --git a/examples/freertos/dfu/XCORE-AI-EXPLORER.xn b/examples/freertos/dfu/XCORE-AI-EXPLORER.xn
new file mode 100644
index 000000000..4dde19f84
--- /dev/null
+++ b/examples/freertos/dfu/XCORE-AI-EXPLORER.xn
@@ -0,0 +1,109 @@
+
+
+ Board
+ xcore.ai Explorer Kit
+
+
+ tileref tile[2]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/freertos/dfu/bsp_config/CMakeLists.txt b/examples/freertos/dfu/bsp_config/CMakeLists.txt
new file mode 100644
index 000000000..e7321512e
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/CMakeLists.txt
@@ -0,0 +1,35 @@
+## Create Explorer Board 2V0 target
+add_library(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 INTERFACE)
+target_sources(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0
+ INTERFACE
+ XCORE-AI-EXPLORER_2V0/platform/driver_instances.c
+ XCORE-AI-EXPLORER_2V0/platform/platform_init.c
+ XCORE-AI-EXPLORER_2V0/platform/platform_start.c
+)
+target_include_directories(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0
+ INTERFACE
+ XCORE-AI-EXPLORER_2V0
+)
+target_link_libraries(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0
+ INTERFACE
+ core::general
+ rtos::freertos
+ rtos::drivers::general
+ rtos::drivers::usb
+ rtos::drivers::dfu_image
+ rtos::sw_services::usb
+
+)
+target_compile_definitions(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0
+ INTERFACE
+ XCOREAI_EXPLORER=1
+ PLATFORM_SUPPORTS_TILE_0=1
+ PLATFORM_SUPPORTS_TILE_1=1
+ PLATFORM_SUPPORTS_TILE_2=0
+ PLATFORM_SUPPORTS_TILE_3=0
+ USB_TILE_NO=0
+ USB_TILE=tile[USB_TILE_NO]
+)
+
+## Create an alias
+add_library(example::freertos::dfu::bsp_config::xcore_ai_explorer ALIAS example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0)
diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c
new file mode 100644
index 000000000..d5344d6e2
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c
@@ -0,0 +1,34 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#include "platform/driver_instances.h"
+
+static rtos_intertile_t intertile_ctx_s;
+rtos_intertile_t *intertile_ctx = &intertile_ctx_s;
+
+static rtos_qspi_flash_t qspi_flash_ctx_s;
+rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s;
+
+static rtos_spi_master_t spi_master_ctx_s;
+rtos_spi_master_t *spi_master_ctx = &spi_master_ctx_s;
+
+static rtos_spi_master_device_t wifi_device_ctx_s;
+rtos_spi_master_device_t *wifi_device_ctx = &wifi_device_ctx_s;
+
+static rtos_gpio_t gpio_ctx_t0_s;
+rtos_gpio_t *gpio_ctx_t0 = &gpio_ctx_t0_s;
+
+static rtos_gpio_t gpio_ctx_t1_s;
+rtos_gpio_t *gpio_ctx_t1 = &gpio_ctx_t1_s;
+
+static rtos_i2c_master_t i2c_master_ctx_s;
+rtos_i2c_master_t *i2c_master_ctx = &i2c_master_ctx_s;
+
+static rtos_uart_tx_t uart_tx_ctx_s;
+rtos_uart_tx_t *uart_tx_ctx = &uart_tx_ctx_s;
+
+static rtos_uart_rx_t uart_rx_ctx_s;
+rtos_uart_rx_t *uart_rx_ctx = &uart_rx_ctx_s;
+
+static rtos_dfu_image_t dfu_image_ctx_s;
+rtos_dfu_image_t *dfu_image_ctx = &dfu_image_ctx_s;
diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h
new file mode 100644
index 000000000..ee4a4d65a
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#ifndef DRIVER_INSTANCES_H_
+#define DRIVER_INSTANCES_H_
+
+#include "rtos_intertile.h"
+#include "rtos_i2c_master.h"
+#include "rtos_spi_master.h"
+#include "rtos_qspi_flash.h"
+#include "rtos_dfu_image.h"
+#include "rtos_gpio.h"
+#include "rtos_uart_tx.h"
+#include "rtos_uart_rx.h"
+#include "usb_support.h"
+
+#define FLASH_TILE_NO 0
+#define I2C_TILE_NO 0
+#define UART_TILE_NO 1
+
+/** TILE 0 Clock Blocks */
+#define FLASH_CLKBLK XS1_CLKBLK_1
+// #define UNUSED_CLKBLK XS1_CLKBLK_2
+#define SPI_CLKBLK XS1_CLKBLK_3
+#define XUD_CLKBLK_1 XS1_CLKBLK_4 /* Reserved for lib_xud */
+#define XUD_CLKBLK_2 XS1_CLKBLK_5 /* Reserved for lib_xud */
+
+/** TILE 1 Clock Blocks */
+// #define UNUSED_CLKBLK XS1_CLKBLK_1
+// #define UNUSED_CLKBLK XS1_CLKBLK_2
+// #define UNUSED_CLKBLK XS1_CLKBLK_3
+// #define UNUSED_CLKBLK XS1_CLKBLK_4
+// #define UNUSED_CLKBLK XS1_CLKBLK_5
+
+extern rtos_intertile_t *intertile_ctx;
+extern rtos_qspi_flash_t *qspi_flash_ctx;
+extern rtos_spi_master_t *spi_master_ctx;
+extern rtos_spi_master_device_t *wifi_device_ctx;
+extern rtos_gpio_t *gpio_ctx_t0;
+extern rtos_gpio_t *gpio_ctx_t1;
+extern rtos_i2c_master_t *i2c_master_ctx;
+extern rtos_uart_tx_t *uart_tx_ctx;
+extern rtos_uart_rx_t *uart_rx_ctx;
+extern rtos_dfu_image_t *dfu_image_ctx;
+
+#endif /* DRIVER_INSTANCES_H_ */
diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h
new file mode 100644
index 000000000..80d2d56aa
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h
@@ -0,0 +1,135 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#ifndef PLATFORM_CONF_H_
+#define PLATFORM_CONF_H_
+
+/*
+ * This file contains defaults to build a basic project targetting the
+ * XCORE-AI-EXPLORER board. Users may create their own app_conf.h to override
+ * any default settings.
+ *
+ * For a different soft tapeout design, it is recommended to create an entirely
+ * different board support package.
+ */
+
+#if __has_include("app_conf.h")
+#include "app_conf.h"
+#endif /* __has_include("app_conf.h") */
+
+/*****************************************/
+/* Intertile Communication Configuration */
+/*****************************************/
+#ifndef appconfI2C_MASTER_RPC_PORT
+#define appconfI2C_MASTER_RPC_PORT 10
+#endif /* appconfI2C_MASTER_RPC_PORT */
+
+#ifndef appconfI2C_MASTER_RPC_PRIORITY
+#define appconfI2C_MASTER_RPC_PRIORITY (configMAX_PRIORITIES/2)
+#endif /* appconfI2C_MASTER_RPC_PRIORITY */
+
+#ifndef appconfGPIO_T0_RPC_PORT
+#define appconfGPIO_T0_RPC_PORT 11
+#endif /* appconfGPIO_T0_RPC_PORT */
+
+#ifndef appconfGPIO_T1_RPC_PORT
+#define appconfGPIO_T1_RPC_PORT 12
+#endif /* appconfGPIO_T1_RPC_PORT */
+
+#ifndef appconfGPIO_RPC_PRIORITY
+#define appconfGPIO_RPC_PRIORITY (configMAX_PRIORITIES/2)
+#endif /* appconfGPIO_RPC_PRIORITY */
+
+/*****************************************/
+/* I/O and interrupt cores for Tile 0 */
+/*****************************************/
+#ifndef appconfI2C_IO_CORE
+#define appconfI2C_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */
+#endif /* appconfI2C_IO_CORE */
+
+#ifndef appconfI2C_INTERRUPT_CORE
+#define appconfI2C_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */
+#endif /* appconfI2C_INTERRUPT_CORE */
+
+/*****************************************/
+/* I/O and interrupt cores for Tile 1 */
+/*****************************************/
+#ifndef appconfUART_RX_IO_CORE
+#define appconfUART_RX_IO_CORE 3 /* Must be kept off core 0 with the RTOS tick ISR */
+#endif /* appconfUART_RX_IO_CORE */
+
+#ifndef appconfUART_RX_INTERRUPT_CORE
+#define appconfUART_RX_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */
+#endif /* appconfUART_RX_INTERRUPT_CORE */
+
+/*****************************************/
+/* I/O Settings */
+/*****************************************/
+#ifndef appconfUART_BAUD_RATE
+#define appconfUART_BAUD_RATE 115200
+#endif /* appconfUART_BAUD_RATE */
+
+/*****************************************/
+/* I/O Task Priorities */
+/*****************************************/
+#ifndef appconfSPI_MASTER_TASK_PRIORITY
+#define appconfSPI_MASTER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#endif /* appconfSPI_MASTER_TASK_PRIORITY */
+
+#ifndef appconfQSPI_FLASH_TASK_PRIORITY
+#define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#endif /* appconfQSPI_FLASH_TASK_PRIORITY */
+
+/*****************************************/
+/* DFU Settings */
+/*****************************************/
+#define FL_QUADDEVICE_AT25FF321A \
+{ \
+ 0, /* UNKNOWN */ \
+ 256, /* page size */ \
+ 16384, /* num pages */ \
+ 3, /* address size */ \
+ 3, /* log2 clock divider */ \
+ 0x9F, /* QSPI_RDID */ \
+ 0, /* id dummy bytes */ \
+ 3, /* id size in bytes */ \
+ 0x1F4708, /* device id */ \
+ 0x20, /* QSPI_SE */ \
+ 4096, /* Sector erase is always 4KB */ \
+ 0x06, /* QSPI_WREN */ \
+ 0x04, /* QSPI_WRDI */ \
+ PROT_TYPE_SR, /* Protection via SR */ \
+ {{0x3C,0x00},{0,0}}, /* QSPI_SP, QSPI_SU */ \
+ 0x02, /* QSPI_PP */ \
+ 0xEB, /* QSPI_READ_FAST */ \
+ 1, /* 1 read dummy byte */ \
+ SECTOR_LAYOUT_REGULAR, /* mad sectors */ \
+ {4096,{0,{0}}}, /* regular sector sizes */ \
+ 0x05, /* QSPI_RDSR */ \
+ 0x01, /* QSPI_WRSR */ \
+ 0x01, /* QSPI_WIP_BIT_MASK */ \
+}
+
+#ifndef BOARD_QSPI_SPEC
+/* Set up a default SPI spec if the app has not provided
+ * one explicitly.
+ * Note: The version checks only work in XTC Tools >15.3.0
+ * By default FL_QUADDEVICE_AT25FF321A is used
+ */
+#ifdef __XMOS_XTC_VERSION_MAJOR__
+#if (__XMOS_XTC_VERSION_MAJOR__ == 15) \
+ && (__XMOS_XTC_VERSION_MINOR__ >= 2) \
+ && (__XMOS_XTC_VERSION_PATCH__ >= 0)
+/* In XTC >15.2.0 some SFDP support enables a generic
+ * default spec
+ */
+#define BOARD_QSPI_SPEC FL_QUADDEVICE_DEFAULT
+#else
+#define BOARD_QSPI_SPEC FL_QUADDEVICE_AT25FF321A
+#endif
+#else
+#define BOARD_QSPI_SPEC FL_QUADDEVICE_AT25FF321A
+#endif /* __XMOS_XTC_VERSION_MAJOR__ */
+#endif /* BOARD_QSPI_SPEC */
+
+#endif /* PLATFORM_CONF_H_ */
diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c
new file mode 100644
index 000000000..b9e722960
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c
@@ -0,0 +1,213 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#include
+#include
+
+#include "platform_conf.h"
+#include "platform/driver_instances.h"
+#include
+#include
+
+static void flash_init(void)
+{
+#if ON_TILE(FLASH_TILE_NO)
+ fl_QuadDeviceSpec qspi_spec = BOARD_QSPI_SPEC;
+ fl_QSPIPorts qspi_ports = {
+ .qspiCS = PORT_SQI_CS,
+ .qspiSCLK = PORT_SQI_SCLK,
+ .qspiSIO = PORT_SQI_SIO,
+ .qspiClkblk = FLASH_CLKBLK,
+ };
+
+ rtos_dfu_image_init(
+ dfu_image_ctx,
+ &qspi_ports,
+ &qspi_spec,
+ 1);
+
+ qspi_flash_ctx->ctx.sfdp_skip = true;
+ qspi_flash_ctx->ctx.sfdp_supported = false;
+ qspi_flash_ctx->ctx.page_size_bytes = 256;
+ qspi_flash_ctx->ctx.page_count = 16384;
+ qspi_flash_ctx->ctx.flash_size_kbytes = 4096;
+ qspi_flash_ctx->ctx.address_bytes = 3;
+ qspi_flash_ctx->ctx.erase_info[0].size_log2 = 12;
+ qspi_flash_ctx->ctx.erase_info[0].cmd = 0xEEFEEEEE;
+ qspi_flash_ctx->ctx.erase_info[1].size_log2 = 15;
+ qspi_flash_ctx->ctx.erase_info[1].cmd = 0xEFEFEEFE;
+ qspi_flash_ctx->ctx.erase_info[2].size_log2 = 16;
+ qspi_flash_ctx->ctx.erase_info[2].cmd = 0xFFEFFEEE;
+ qspi_flash_ctx->ctx.erase_info[3].size_log2 = 0;
+ qspi_flash_ctx->ctx.erase_info[3].cmd = 0;
+ qspi_flash_ctx->ctx.busy_poll_cmd = 0xEEEEEFEF;
+ qspi_flash_ctx->ctx.busy_poll_bit = 0;
+ qspi_flash_ctx->ctx.busy_poll_ready_value = 0;
+ qspi_flash_ctx->ctx.qe_reg = 2;
+ qspi_flash_ctx->ctx.qe_bit = 1;
+ qspi_flash_ctx->ctx.sr2_read_cmd = 0xEEFFEFEF;
+ qspi_flash_ctx->ctx.sr2_write_cmd = 0xEEEEEEEE;
+
+ rtos_qspi_flash_init(
+ qspi_flash_ctx,
+ FLASH_CLKBLK,
+ PORT_SQI_CS,
+ PORT_SQI_SCLK,
+ PORT_SQI_SIO,
+
+ /** Derive QSPI clock from the 600 MHz xcore clock **/
+ qspi_io_source_clock_xcore,
+
+ /** Full speed clock configuration **/
+ 5, // 600 MHz / (2*5) -> 60 MHz,
+ 1,
+ qspi_io_sample_edge_rising,
+ 0,
+
+ /** SPI read clock configuration **/
+ 12, // 600 MHz / (2*12) -> 25 MHz
+ 0,
+ qspi_io_sample_edge_falling,
+ 0,
+
+ qspi_flash_page_program_1_1_4);
+#endif
+}
+
+static void gpio_init(void)
+{
+ static rtos_driver_rpc_t gpio_rpc_config_t0;
+ static rtos_driver_rpc_t gpio_rpc_config_t1;
+ rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx};
+
+#if ON_TILE(0)
+ rtos_gpio_init(gpio_ctx_t0);
+
+ rtos_gpio_rpc_host_init(
+ gpio_ctx_t0,
+ &gpio_rpc_config_t0,
+ client_intertile_ctx,
+ 1);
+
+ rtos_gpio_rpc_client_init(
+ gpio_ctx_t1,
+ &gpio_rpc_config_t1,
+ intertile_ctx);
+#endif
+
+#if ON_TILE(1)
+ rtos_gpio_init(gpio_ctx_t1);
+
+ rtos_gpio_rpc_client_init(
+ gpio_ctx_t0,
+ &gpio_rpc_config_t0,
+ intertile_ctx);
+
+ rtos_gpio_rpc_host_init(
+ gpio_ctx_t1,
+ &gpio_rpc_config_t1,
+ client_intertile_ctx,
+ 1);
+#endif
+}
+
+static void i2c_init(void)
+{
+ static rtos_driver_rpc_t i2c_rpc_config;
+
+#if ON_TILE(I2C_TILE_NO)
+ rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx};
+ rtos_i2c_master_init(
+ i2c_master_ctx,
+ PORT_I2C_SCL, 0, 0,
+ PORT_I2C_SDA, 0, 0,
+ 0,
+ 100);
+
+ rtos_i2c_master_rpc_host_init(
+ i2c_master_ctx,
+ &i2c_rpc_config,
+ client_intertile_ctx,
+ 1);
+#else
+ rtos_i2c_master_rpc_client_init(
+ i2c_master_ctx,
+ &i2c_rpc_config,
+ intertile_ctx);
+#endif
+}
+
+static void spi_init(void)
+{
+#if ON_TILE(0)
+ rtos_spi_master_init(
+ spi_master_ctx,
+ SPI_CLKBLK,
+ WIFI_CS_N,
+ WIFI_CLK,
+ WIFI_MOSI,
+ WIFI_MISO);
+
+ rtos_spi_master_device_init(
+ wifi_device_ctx,
+ spi_master_ctx,
+ 1, /* WiFi CS pin is on bit 1 of the CS port */
+ SPI_MODE_0,
+ spi_master_source_clock_ref,
+ 0, /* 50 MHz */
+ spi_master_sample_delay_2, /* what should this be? 2? 3? 4? */
+ 0, /* should this be > 0 if the above is 3-4 ? */
+ 1,
+ 0,
+ 0);
+#endif
+}
+
+
+static void uart_init(void)
+{
+#if ON_TILE(UART_TILE_NO)
+ hwtimer_t tmr_rx = hwtimer_alloc();
+
+ rtos_uart_rx_init(
+ uart_rx_ctx,
+ (1 << appconfUART_RX_IO_CORE),
+ XS1_PORT_1M, //X1D36
+ appconfUART_BAUD_RATE,
+ 8,
+ UART_PARITY_NONE,
+ 1,
+ tmr_rx);
+
+
+ hwtimer_t tmr_tx = hwtimer_alloc();
+
+ rtos_uart_tx_init(
+ uart_tx_ctx,
+ XS1_PORT_1P, //X1D39
+ appconfUART_BAUD_RATE,
+ 8,
+ UART_PARITY_NONE,
+ 1,
+ tmr_tx);
+#endif
+}
+
+void usb_init(void)
+{
+#if ON_TILE(USB_TILE_NO)
+ usb_manager_init();
+#endif
+}
+
+void platform_init(chanend_t other_tile_c)
+{
+ rtos_intertile_init(intertile_ctx, other_tile_c);
+
+ flash_init();
+ gpio_init();
+ spi_init();
+ i2c_init();
+ uart_init();
+ usb_init();
+}
diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h
new file mode 100644
index 000000000..bae19eb7a
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#ifndef PLATFORM_INIT_H_
+#define PLATFORM_INIT_H_
+
+#include
+
+void platform_init(chanend_t other_tile_c);
+void platform_start(void);
+
+#endif /* PLATFORM_INIT_H_ */
diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c
new file mode 100644
index 000000000..caa1e6613
--- /dev/null
+++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c
@@ -0,0 +1,60 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#include
+
+#include "platform_conf.h"
+#include "platform/driver_instances.h"
+
+static void gpio_start(void)
+{
+ rtos_gpio_rpc_config(gpio_ctx_t0, appconfGPIO_T0_RPC_PORT, appconfGPIO_RPC_PRIORITY);
+ rtos_gpio_rpc_config(gpio_ctx_t1, appconfGPIO_T1_RPC_PORT, appconfGPIO_RPC_PRIORITY);
+
+#if ON_TILE(0)
+ rtos_gpio_start(gpio_ctx_t0);
+#endif
+#if ON_TILE(1)
+ rtos_gpio_start(gpio_ctx_t1);
+#endif
+}
+
+static void spi_start(void)
+{
+#if ON_TILE(0)
+ rtos_spi_master_start(spi_master_ctx, appconfSPI_MASTER_TASK_PRIORITY);
+#endif
+}
+
+static void i2c_start(void)
+{
+ rtos_i2c_master_rpc_config(i2c_master_ctx, appconfI2C_MASTER_RPC_PORT, appconfI2C_MASTER_RPC_PRIORITY);
+#if ON_TILE(I2C_TILE_NO)
+ rtos_i2c_master_start(i2c_master_ctx);
+#endif
+}
+
+static void flash_start(void)
+{
+#if ON_TILE(0)
+ rtos_qspi_flash_start(qspi_flash_ctx, appconfQSPI_FLASH_TASK_PRIORITY);
+#endif
+}
+
+static void usb_start(void)
+{
+#if ON_TILE(USB_TILE_NO)
+ usb_manager_start(appconfUSB_MANAGER_TASK_PRIORITY);
+#endif
+}
+
+void platform_start(void)
+{
+ rtos_intertile_start(intertile_ctx);
+
+ gpio_start();
+ spi_start();
+ flash_start();
+ i2c_start();
+ usb_start();
+}
diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake
new file mode 100644
index 000000000..d63611f4b
--- /dev/null
+++ b/examples/freertos/dfu/dfu.cmake
@@ -0,0 +1,119 @@
+#**********************
+# Gather Sources
+#**********************
+file(GLOB_RECURSE APP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.c)
+set(APP_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/src)
+
+#**********************
+# Import example specific bsp_config
+#**********************
+add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/bsp_config)
+
+#**********************
+# Flags
+#**********************
+set(APP_COMPILER_FLAGS
+ -Os
+ -g
+ -report
+ -fxscope
+ -mcmodel=large
+ -Wno-xcore-fptrgroup
+ ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope
+ ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn
+)
+set(APP_COMPILE_DEFINITIONS
+ DEBUG_PRINT_ENABLE=1
+ PLATFORM_USES_TILE_0=1
+ PLATFORM_USES_TILE_1=1
+
+ XUD_CORE_CLOCK=600
+)
+
+set(APP_LINK_OPTIONS
+ -fxscope
+ -report
+ ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn
+ ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope
+)
+
+set(APP_LINK_LIBRARIES
+ example::freertos::dfu::bsp_config::xcore_ai_explorer
+)
+
+#**********************
+# Tile Targets
+#**********************
+set(TARGET_NAME tile0_example_freertos_dfu_v1)
+add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
+target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES})
+target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES})
+target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0 VERSION=1)
+target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
+target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
+target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
+unset(TARGET_NAME)
+
+set(TARGET_NAME tile1_example_freertos_dfu_v1)
+add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
+target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES})
+target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES})
+target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1 VERSION=1)
+target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
+target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
+target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
+unset(TARGET_NAME)
+
+set(TARGET_NAME tile0_example_freertos_dfu_v2)
+add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
+target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES})
+target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES})
+target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0 VERSION=2)
+target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
+target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
+target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
+unset(TARGET_NAME)
+
+set(TARGET_NAME tile1_example_freertos_dfu_v2)
+add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
+target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES})
+target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES})
+target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1 VERSION=2)
+target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
+target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
+target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
+unset(TARGET_NAME)
+
+#**********************
+# Merge binaries
+#**********************
+merge_binaries(example_freertos_dfu_v1 tile0_example_freertos_dfu_v1 tile1_example_freertos_dfu_v1 1)
+merge_binaries(example_freertos_dfu_v2 tile0_example_freertos_dfu_v2 tile1_example_freertos_dfu_v2 1)
+
+#**********************
+# Create run and debug targets
+#**********************
+create_run_target(example_freertos_dfu_v1)
+create_debug_target(example_freertos_dfu_v1)
+create_flash_app_target(
+ #[[ Target ]] example_freertos_dfu_v1
+ #[[ Boot Partition Size ]] 0x100000
+ #[[ Data Parition Contents ]]
+ #[[ Dependencies ]]
+)
+query_tools_version()
+create_upgrade_img_target(example_freertos_dfu_v1 ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR})
+create_install_target(example_freertos_dfu_v1)
+create_erase_all_target(example_freertos_dfu_v1 ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn)
+
+create_run_target(example_freertos_dfu_v2)
+create_debug_target(example_freertos_dfu_v2)
+create_flash_app_target(
+ #[[ Target ]] example_freertos_dfu_v2
+ #[[ Boot Partition Size ]] 0x100000
+ #[[ Data Parition Contents ]]
+ #[[ Dependencies ]]
+)
+create_upgrade_img_target(example_freertos_dfu_v2 ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR})
+create_install_target(example_freertos_dfu_v2)
+create_erase_all_target(example_freertos_dfu_v2 ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn)
diff --git a/examples/freertos/dfu/src/FreeRTOSConfig.h b/examples/freertos/dfu/src/FreeRTOSConfig.h
new file mode 100644
index 000000000..e45891dac
--- /dev/null
+++ b/examples/freertos/dfu/src/FreeRTOSConfig.h
@@ -0,0 +1,113 @@
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/* Here is a good place to include header files that are required across
+your application. */
+#include "platform.h"
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configUSE_TICKLESS_IDLE 0
+#define configCPU_CLOCK_HZ 100000000
+#define configNUM_CORES 5
+#define configTICK_RATE_HZ 1000
+#define configMAX_PRIORITIES 32
+#define configRUN_MULTIPLE_PRIORITIES 1
+#define configUSE_TASK_PREEMPTION_DISABLE 1
+#define configUSE_CORE_AFFINITY 1
+#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 1256
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_TASK_NOTIFICATIONS 1
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES 2
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
+#define configQUEUE_REGISTRY_SIZE 10
+#define configUSE_QUEUE_SETS 1
+#define configUSE_TIME_SLICING 1
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1 /* Required for FreeRTOS_TCP_WIN.c TODO: active closed bug, may have been fixed upstream */
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
+#define configSTACK_DEPTH_TYPE uint32_t
+#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
+
+
+/* Memory allocation related definitions. */
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#define configTOTAL_HEAP_SIZE 256*1024
+#define configAPPLICATION_ALLOCATED_HEAP 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_MINIMAL_IDLE_HOOK 1
+#define configUSE_TICK_HOOK 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
+#define configUSE_CORE_INIT_HOOK 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_STATS_FORMATTING_FUNCTIONS 2 /* Setting to 2 does not include in tasks.c */
+
+/* Co-routine related definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 1
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH 10
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE << 2 )
+
+/* Define to trap errors during development. */
+#define configASSERT(x) xassert(x)
+
+/* Define to enable debug_printf() */
+#define configENABLE_DEBUG_PRINTF 1
+
+/* Define to map sprintf and snprintf to the
+ * lite versions in lib_rtos_support */
+ #include
+#define configUSE_DEBUG_SPRINTF 1
+
+/* Define to enable debug prints from tasks.c */
+#if ON_TILE(0)
+#define configTASKS_DEBUG 0
+#endif
+#if ON_TILE(1)
+#define configTASKS_DEBUG 0
+#endif
+
+/* FreeRTOS MPU specific definitions. */
+#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_xResumeFromISR 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_xTaskGetIdleTaskHandle 1
+#define INCLUDE_eTaskGetState 1
+#define INCLUDE_xEventGroupSetBitFromISR 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 1
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xTaskResumeFromISR 1
+#define INCLUDE_xQueueGetMutexHolder 1
+
+/* A header file that defines trace macro can be included here. */
+// #include "xcore_trace.h"
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/examples/freertos/dfu/src/app_conf.h b/examples/freertos/dfu/src/app_conf.h
new file mode 100644
index 000000000..9d3762515
--- /dev/null
+++ b/examples/freertos/dfu/src/app_conf.h
@@ -0,0 +1,38 @@
+// Copyright 2022 XMOS LIMITED.
+// This Software is subject to the terms of the XMOS Public Licence: Version 1.
+
+#ifndef APP_CONF_H_
+#define APP_CONF_H_
+
+/* Intertile Communication Configuration */
+#define appconfI2C_MASTER_RPC_PORT 10
+#define appconfI2C_MASTER_RPC_PRIORITY (configMAX_PRIORITIES/2)
+
+#define appconfGPIO_T0_RPC_PORT 11
+#define appconfGPIO_T1_RPC_PORT 12
+#define appconfGPIO_RPC_PRIORITY (configMAX_PRIORITIES/2)
+
+/* I/O and interrupt cores for Tile 0 */
+#define appconfI2C_IO_CORE 4 /* Must be kept off core 0 with the RTOS tick ISR */
+#define appconfI2C_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */
+#define appconfXUD_IO_CORE 1 /* Must be kept off core 0 with the RTOS tick ISR */
+#define appconfUSB_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */
+#define appconfUSB_SOF_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off cores with other ISRs. */
+#define appconfSPI_IO_CORE 4 /* Must be kept off core 0 with the RTOS tick ISR */
+#define appconfSPI_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */
+
+/* I/O and interrupt cores for Tile 1 */
+#define appconfUART_RX_IO_CORE 3 /* Must be kept off core 0 with the RTOS tick ISR */
+#define appconfUART_RX_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */
+
+/* UART Configuration */
+#define appconfUART_BAUD_RATE 806400
+
+/* Task Priorities */
+#define appconfSTARTUP_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define appconfSPI_MASTER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define appconfUART_RX_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define appconfUSB_MANAGER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+
+#endif /* APP_CONF_H_ */
diff --git a/examples/freertos/dfu/src/config.xscope b/examples/freertos/dfu/src/config.xscope
new file mode 100644
index 000000000..bb71bfe23
--- /dev/null
+++ b/examples/freertos/dfu/src/config.xscope
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c
new file mode 100644
index 000000000..e440adfe3
--- /dev/null
+++ b/examples/freertos/dfu/src/main.c
@@ -0,0 +1,118 @@
+// Copyright 2022 XMOS LIMITED.
+// This Software is subject to the terms of the XMOS Public Licence: Version 1.
+
+/* System headers */
+#include
+#include
+
+/* FreeRTOS headers */
+#include "FreeRTOS.h"
+#include "queue.h"
+
+/* Library headers */
+
+/* App headers */
+#include "app_conf.h"
+#include "usb_support.h"
+#include "xcore/channel_streaming.h"
+#include "platform/platform_init.h"
+#include "platform/driver_instances.h"
+
+void vApplicationMallocFailedHook( void )
+{
+ rtos_printf("Malloc Failed on tile %d!\n", THIS_XCORE_TILE);
+ for(;;);
+}
+
+void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) {
+ rtos_printf("\nStack Overflow!!! %d %s!\n", THIS_XCORE_TILE, pcTaskName);
+ configASSERT(0);
+}
+
+void blinky_task(void *arg) {
+ uint32_t gpio_port = rtos_gpio_port(PORT_LEDS);
+ uint32_t led_val = 0;
+
+ rtos_gpio_port_enable(gpio_ctx_t0, gpio_port);
+
+ for (;;) {
+ rtos_gpio_port_out(gpio_ctx_t0, gpio_port, led_val);
+ led_val ^= VERSION;
+ vTaskDelay(pdMS_TO_TICKS(1000));
+ }
+}
+
+void startup_task(void *arg)
+{
+ rtos_printf("Startup task running from tile %d on core %d\n", THIS_XCORE_TILE, portGET_CORE_ID());
+
+ platform_start();
+
+#if ON_TILE(0)
+ rtos_dfu_image_print_debug(dfu_image_ctx);
+
+ uint32_t data;
+ rtos_qspi_flash_read(
+ qspi_flash_ctx,
+ (uint8_t*)&data,
+ rtos_dfu_image_get_data_partition_addr(dfu_image_ctx),
+ sizeof(int32_t));
+ rtos_printf("First word at data partition start is: 0x%x\n", data);
+#endif
+
+ for (;;) {
+ rtos_printf("Tile[%d]:\n\tMinimum heap free: %d\n\tCurrent heap free: %d\n", THIS_XCORE_TILE, xPortGetMinimumEverFreeHeapSize(), xPortGetFreeHeapSize());
+ vTaskDelay(pdMS_TO_TICKS(5000));
+ }
+}
+
+void vApplicationMinimalIdleHook(void)
+{
+ rtos_printf("idle hook on tile %d core %d\n", THIS_XCORE_TILE, rtos_core_id_get());
+ asm volatile("waiteu");
+}
+
+void tile_common_init(chanend_t c)
+{
+ platform_init(c);
+ chanend_free(c);
+
+ xTaskCreate((TaskFunction_t) startup_task,
+ "startup_task",
+ RTOS_THREAD_STACK_SIZE(startup_task),
+ NULL,
+ appconfSTARTUP_TASK_PRIORITY,
+ NULL);
+
+#if ON_TILE(0)
+ xTaskCreate((TaskFunction_t) blinky_task,
+ "blinky_task",
+ RTOS_THREAD_STACK_SIZE(blinky_task),
+ NULL,
+ appconfSTARTUP_TASK_PRIORITY / 2,
+ NULL);
+#endif
+
+ rtos_printf("start scheduler on tile %d\n", THIS_XCORE_TILE);
+ vTaskStartScheduler();
+}
+
+#if ON_TILE(0)
+void main_tile0(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3) {
+ (void)c0;
+ (void)c2;
+ (void)c3;
+
+ tile_common_init(c1);
+}
+#endif
+
+#if ON_TILE(1)
+void main_tile1(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3) {
+ (void)c1;
+ (void)c2;
+ (void)c3;
+
+ tile_common_init(c0);
+}
+#endif
diff --git a/examples/freertos/dfu/src/tusb_config.h b/examples/freertos/dfu/src/tusb_config.h
new file mode 100644
index 000000000..21fe4c315
--- /dev/null
+++ b/examples/freertos/dfu/src/tusb_config.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the
+// XMOS Public License: Version 1
+
+#ifndef TUSB_CONFIG_H_
+#define TUSB_CONFIG_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "app_conf.h"
+
+//--------------------------------------------------------------------
+// COMMON CONFIGURATION
+//--------------------------------------------------------------------
+
+#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
+#define CFG_TUSB_OS OPT_OS_CUSTOM
+
+#ifndef CFG_TUSB_DEBUG
+#define CFG_TUSB_DEBUG 0
+#endif
+
+#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(8)))
+
+#define CFG_TUSB_DEBUG_PRINTF rtos_printf
+
+//--------------------------------------------------------------------
+// DEVICE CONFIGURATION
+//--------------------------------------------------------------------
+
+#define CFG_TUD_EP_MAX 12
+#define CFG_TUD_TASK_QUEUE_SZ 8
+#define CFG_TUD_ENDPOINT0_SIZE 64
+
+#define CFG_TUD_XCORE_INTERRUPT_CORE appconfUSB_INTERRUPT_CORE
+#define CFG_TUD_XCORE_SOF_INTERRUPT_CORE appconfUSB_SOF_INTERRUPT_CORE
+#define CFG_TUD_XCORE_IO_CORE_MASK (1 << appconfXUD_IO_CORE)
+
+//------------- CLASS -------------//
+#define CFG_TUD_DFU 1
+
+// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR
+#define CFG_TUD_DFU_XFER_BUFSIZE 4096
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* TUSB_CONFIG_H_ */
diff --git a/examples/freertos/dfu/src/usb/app_dfu.c b/examples/freertos/dfu/src/usb/app_dfu.c
new file mode 100644
index 000000000..316f72c8c
--- /dev/null
+++ b/examples/freertos/dfu/src/usb/app_dfu.c
@@ -0,0 +1,264 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include
+#include
+#include
+#include
+
+#include "FreeRTOS.h"
+#include "timers.h"
+#include "platform/driver_instances.h"
+#include "tusb.h"
+
+/*
+ * After device is enumerated in dfu mode run the following commands
+ *
+ * To transfer firmware from host to device
+ *
+ * $ dfu-util -d cafe -a 0 -D [filename]
+ * $ dfu-util -d cafe -a 1 -D [filename]
+ *
+ * To transfer firmware from device to host:
+ *
+ * $ dfu-util -d cafe -a 0 -U [filename]
+ * $ dfu-util -d cafe -a 1 -U [filename]
+ *
+ */
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF PROTYPES
+//--------------------------------------------------------------------+
+static void reboot(void);
+
+//--------------------------------------------------------------------+
+// Device callbacks
+//--------------------------------------------------------------------+
+
+// Invoked when device is mounted
+void tud_mount_cb(void)
+{
+ rtos_printf("mounted\n");
+}
+
+// Invoked when device is unmounted
+void tud_umount_cb(void)
+{
+ rtos_printf("unmounted\n");
+}
+
+// Invoked when usb bus is suspended
+// remote_wakeup_en : if host allow us to perform remote wakeup
+// Within 7ms, device must draw an average of current less than 2.5 mA from bus
+void tud_suspend_cb(bool remote_wakeup_en)
+{
+ (void) remote_wakeup_en;
+ rtos_printf("suspended\n");
+}
+
+// Invoked when usb bus is resumed
+void tud_resume_cb(void)
+{
+ rtos_printf("resumed\n");
+}
+
+//--------------------------------------------------------------------+
+// DFU callbacks
+// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc.
+//--------------------------------------------------------------------+
+
+static size_t total_len = 0;
+static size_t bytes_avail = 0;
+static uint32_t dn_base_addr = 0;
+
+// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST)
+// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation.
+// During this period, USB host won't try to communicate with us.
+uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state)
+{
+ if ( state == DFU_DNBUSY ) {
+ return 10; // 10 ms
+ } else if (state == DFU_MANIFEST) {
+ // since we don't buffer entire image and do any flashing in manifest stage
+ return 0;
+ }
+
+ return 0;
+}
+
+// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests
+// This callback could be returned before flashing op is complete (async).
+// Once finished flashing, application must call tud_dfu_finish_flashing()
+void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, uint16_t length)
+{
+ rtos_printf("Received Alt %d BlockNum %d of length %d\n", alt, block_num, length);
+
+ unsigned data_partition_base_addr = rtos_dfu_image_get_data_partition_addr(dfu_image_ctx);
+ switch(alt) {
+ default:
+ case 0:
+ tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE);
+ break;
+ case 1:
+ if (dn_base_addr == 0) {
+ total_len = 0;
+ dn_base_addr = rtos_dfu_image_get_upgrade_addr(dfu_image_ctx);
+ bytes_avail = data_partition_base_addr - dn_base_addr;
+ }
+ /* fallthrough */
+ case 2:
+ if (dn_base_addr == 0) {
+ total_len = 0;
+ dn_base_addr = data_partition_base_addr;
+ bytes_avail = rtos_qspi_flash_size_get(qspi_flash_ctx) - dn_base_addr;
+ }
+ rtos_printf("Using addr 0x%x\nsize %u\n", dn_base_addr, bytes_avail);
+ if(length > 0) {
+ unsigned cur_addr = dn_base_addr + (block_num * CFG_TUD_DFU_XFER_BUFSIZE);
+ if((bytes_avail - total_len) >= length) {
+ rtos_printf("write %d at 0x%x\n", length, cur_addr);
+
+ size_t sector_size = rtos_qspi_flash_sector_size_get(qspi_flash_ctx);
+ xassert(CFG_TUD_DFU_XFER_BUFSIZE == sector_size);
+
+ uint8_t *tmp_buf = rtos_osal_malloc( sizeof(uint8_t) * sector_size);
+ rtos_qspi_flash_lock(qspi_flash_ctx);
+ {
+ rtos_qspi_flash_read(
+ qspi_flash_ctx,
+ tmp_buf,
+ cur_addr,
+ sector_size);
+ memcpy(tmp_buf, data, length);
+ rtos_qspi_flash_erase(
+ qspi_flash_ctx,
+ cur_addr,
+ sector_size);
+ rtos_qspi_flash_write(
+ qspi_flash_ctx,
+ (uint8_t *) tmp_buf,
+ cur_addr,
+ sector_size);
+ }
+ rtos_qspi_flash_unlock(qspi_flash_ctx);
+ rtos_osal_free(tmp_buf);
+ total_len += length;
+ } else {
+ rtos_printf("Insufficient space\n");
+ tud_dfu_finish_flashing(DFU_STATUS_ERR_ADDRESS);
+ }
+ }
+
+ tud_dfu_finish_flashing(DFU_STATUS_OK);
+ break;
+ }
+}
+
+// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest)
+// Application can do checksum, or actual flashing if buffered entire image previously.
+// Once finished flashing, application must call tud_dfu_finish_flashing()
+void tud_dfu_manifest_cb(uint8_t alt)
+{
+ (void) alt;
+ rtos_printf("Download completed, enter manifestation\n");
+
+ /* Perform a read to ensure all writes have been flushed */
+ uint32_t dummy = 0;
+ rtos_qspi_flash_read(
+ qspi_flash_ctx,
+ (uint8_t *)&dummy,
+ 0,
+ sizeof(dummy));
+
+ /* Reset download */
+ dn_base_addr = 0;
+
+ // flashing op for manifest is complete without error
+ // Application can perform checksum, should it fail, use appropriate status such as errVERIFY.
+ tud_dfu_finish_flashing(DFU_STATUS_OK);
+}
+
+// Invoked when received DFU_UPLOAD request
+// Application must populate data with up to length bytes and
+// Return the number of written bytes
+uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length)
+{
+ uint32_t endaddr = 0;
+ uint16_t retval = 0;
+ uint32_t addr = block_num * CFG_TUD_DFU_XFER_BUFSIZE;
+
+ rtos_printf("Upload Alt %d BlockNum %d of length %d\n", alt, block_num, length);
+
+ switch(alt) {
+ default:
+ break;
+ case 0:
+ if (rtos_dfu_image_get_factory_size(dfu_image_ctx) > 0) {
+ addr += rtos_dfu_image_get_factory_addr(dfu_image_ctx);
+ endaddr = rtos_dfu_image_get_factory_addr(dfu_image_ctx) + rtos_dfu_image_get_factory_size(dfu_image_ctx);
+ }
+ break;
+ case 1:
+ if (rtos_dfu_image_get_upgrade_size(dfu_image_ctx) > 0) {
+ addr += rtos_dfu_image_get_upgrade_addr(dfu_image_ctx);
+ endaddr = rtos_dfu_image_get_upgrade_addr(dfu_image_ctx) + rtos_dfu_image_get_upgrade_size(dfu_image_ctx);
+ }
+ break;
+ case 2:
+ if ((rtos_qspi_flash_size_get(qspi_flash_ctx) - rtos_dfu_image_get_data_partition_addr(dfu_image_ctx)) > 0) {
+ addr += rtos_dfu_image_get_data_partition_addr(dfu_image_ctx);
+ endaddr = rtos_qspi_flash_size_get(qspi_flash_ctx); /* End of flash */
+ }
+ break;
+ }
+
+ if (addr < endaddr) {
+ rtos_qspi_flash_read(qspi_flash_ctx, data, addr, length);
+ retval = length;
+ }
+ return retval;
+}
+
+// Invoked when the Host has terminated a download or upload transfer
+void tud_dfu_abort_cb(uint8_t alt)
+{
+ (void) alt;
+ rtos_printf("Host aborted transfer\n");
+}
+
+// Invoked when a DFU_DETACH request is received
+void tud_dfu_detach_cb(void)
+{
+ rtos_printf("Host detach, we should probably reboot\n");
+ reboot();
+}
+
+static void reboot(void)
+{
+ rtos_printf("Reboot initiated by tile:0x%x\n", get_local_tile_id());
+ write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_COUNT_NUM, 0x10000);
+ write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_CFG_NUM, (1 << XS1_WATCHDOG_COUNT_ENABLE_SHIFT) | (1 << XS1_WATCHDOG_TRIGGER_ENABLE_SHIFT) );
+ while(1) {;}
+}
diff --git a/examples/freertos/dfu/src/usb/usb_descriptors.c b/examples/freertos/dfu/src/usb/usb_descriptors.c
new file mode 100644
index 000000000..503e0cc1c
--- /dev/null
+++ b/examples/freertos/dfu/src/usb/usb_descriptors.c
@@ -0,0 +1,173 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "tusb.h"
+#include "class/dfu/dfu_device.h"
+
+/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
+ * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
+ *
+ * Auto ProductID layout's Bitmap:
+ * [MSB] HID | MSC | CDC [LSB]
+ */
+#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
+#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
+ _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
+
+//--------------------------------------------------------------------+
+// Device Descriptors
+//--------------------------------------------------------------------+
+tusb_desc_device_t const desc_device =
+{
+ .bLength = sizeof(tusb_desc_device_t),
+ .bDescriptorType = TUSB_DESC_DEVICE,
+ .bcdUSB = 0x0200,
+
+ #if CFG_TUD_CDC
+ // Use Interface Association Descriptor (IAD) for CDC
+ // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
+ .bDeviceClass = TUSB_CLASS_MISC,
+ .bDeviceSubClass = MISC_SUBCLASS_COMMON,
+ .bDeviceProtocol = MISC_PROTOCOL_IAD,
+ #else
+ .bDeviceClass = 0x00,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ #endif
+
+ .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
+
+ .idVendor = 0xCafe,
+ .idProduct = USB_PID,
+ .bcdDevice = 0x0100,
+
+ .iManufacturer = 0x01,
+ .iProduct = 0x02,
+ .iSerialNumber = 0x03,
+
+ .bNumConfigurations = 0x01
+};
+
+// Invoked when received GET DEVICE DESCRIPTOR
+// Application return pointer to descriptor
+uint8_t const * tud_descriptor_device_cb(void)
+{
+ return (uint8_t const *) &desc_device;
+}
+
+//--------------------------------------------------------------------+
+// Configuration Descriptor
+//--------------------------------------------------------------------+
+
+// Number of Alternate Interface (each for 1 flash partition)
+#define ALT_COUNT 3
+
+enum
+{
+ ITF_NUM_DFU_MODE,
+ ITF_NUM_TOTAL
+};
+
+#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT))
+
+#define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_WILL_DETACH | DFU_ATTR_MANIFESTATION_TOLERANT)
+
+uint8_t const desc_configuration[] =
+{
+ // Config number, interface count, string index, total length, attribute, power in mA
+ TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
+
+ // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size
+ TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE),
+};
+
+
+// Invoked when received GET CONFIGURATION DESCRIPTOR
+// Application return pointer to descriptor
+// Descriptor contents must exist long enough for transfer to complete
+uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
+{
+ (void) index; // for multiple configurations
+ return desc_configuration;
+}
+
+//--------------------------------------------------------------------+
+// String Descriptors
+//--------------------------------------------------------------------+
+
+// array of pointer to string descriptors
+char const* string_desc_arr [] =
+{
+ (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
+ "TinyUSB", // 1: Manufacturer
+ "TinyUSB Device", // 2: Product
+ "123456", // 3: Serials, should use chip ID
+ "DFU dev FACTORY v" XCORE_UTILS_STRINGIFY(VERSION), // 4: DFU device
+ "DFU dev UPGRADE v" XCORE_UTILS_STRINGIFY(VERSION), // 5: DFU device
+ "DFU dev DATAPARTITION v" XCORE_UTILS_STRINGIFY(VERSION), // 6: DFU device
+};
+
+static uint16_t _desc_str[32];
+
+// Invoked when received GET STRING DESCRIPTOR request
+// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
+uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
+{
+ (void) langid;
+
+ size_t chr_count;
+
+ if ( index == 0)
+ {
+ memcpy(&_desc_str[1], string_desc_arr[0], 2);
+ chr_count = 1;
+ }
+ else
+ {
+ // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
+ // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
+
+ if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
+
+ const char* str = string_desc_arr[index];
+
+ // Cap at max char
+ chr_count = strlen(str);
+ if ( chr_count > 31 ) {
+ chr_count = 31;
+ }
+
+ // Convert ASCII string into UTF-16
+ for(uint8_t i=0; iapp_data, 0, &dummy, 1); // dummy read to ensure flash writes have completed
- reboot();
- return true;
+ if ( state == DFU_DNBUSY )
+ {
+ return 10; /* 10 ms */
+ }
+ else if (state == DFU_MANIFEST)
+ {
+ // since we don't buffer entire image and do any flashing in manifest stage
+ return 0;
+ }
+
+ return 0;
}
-void tud_dfu_req_dnload_data_cb(uint16_t wBlockNum, uint8_t* data, uint16_t length)
+// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests
+// This callback could be returned before flashing op is complete (async).
+// Once finished flashing, application must call tud_dfu_finish_flashing()
+void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, uint16_t length)
{
- // rtos_printf("Block[%u] Len[%u] Buffer\n", wBlockNum, length);
-
- if (dn_base_addr == 0)
- {
- uint32_t addr = 0;
- total_len = 0;
- int tmp = boot_image_locate_available_spot(bim_ctx_ptr, &addr, &bytes_avail);
- if(tmp == -1)
- {
- boot_image_t* imgptr = NULL;
- imgptr = boot_image_get_last_image(bim_ctx_ptr);
- addr = imgptr->startAddress;
- bytes_avail = bim_ctx_ptr->boot_partition_size - addr;
- }
- rtos_printf("Using addr 0x%x\nsize %u\n", addr, bytes_avail);
- dn_base_addr = addr;
- }
-
- if(length > 0)
- {
- unsigned cur_addr = dn_base_addr + (wBlockNum * bim_ctx_ptr->page_size);
- if((bytes_avail - total_len) >= length)
+ (void) alt;
+ rtos_printf("Block[%u] Len[%u] Buffer\n", block_num, length);
+ if (dn_base_addr == 0)
{
- // rtos_printf("write %d at 0x%x\n", length, cur_addr);
- boot_image_write(bim_ctx_ptr->app_data, cur_addr, data, length);
- total_len += length;
+ uint32_t addr = 0;
+ total_len = 0;
+ int tmp = boot_image_locate_available_spot(bim_ctx_ptr, &addr, &bytes_avail);
+ if(tmp == -1)
+ {
+ boot_image_t* imgptr = NULL;
+ imgptr = boot_image_get_last_image(bim_ctx_ptr);
+ addr = imgptr->startAddress;
+ bytes_avail = bim_ctx_ptr->boot_partition_size - addr;
+ }
+ rtos_printf("Using addr 0x%x\nsize %u\n", addr, bytes_avail);
+ dn_base_addr = addr;
+ }
- tud_dfu_dnload_complete();
- } else {
- rtos_printf("Insufficient space\n");
+ if(length > 0)
+ {
+ unsigned cur_addr = dn_base_addr + (block_num * bim_ctx_ptr->page_size);
+ if((bytes_avail - total_len) >= length)
+ {
+ // rtos_printf("write %d at 0x%x\n", length, cur_addr);
+ boot_image_write(bim_ctx_ptr->app_data, cur_addr, data, length);
+ total_len += length;
+ } else {
+ rtos_printf("Insufficient space\n");
+ }
}
- }
}
-bool tud_dfu_device_data_done_check_cb()
+// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest)
+// Application can do checksum, or actual flashing if buffered entire image previously.
+// Once finished flashing, application must call tud_dfu_finish_flashing()
+void tud_dfu_manifest_cb(uint8_t alt)
{
- rtos_printf("Dummy device data done check... Returning true\n");
- return true;
-}
+ (void) alt;
+ rtos_printf("Download completed, enter manifestation\n");
+ uint8_t dummy;
-void tud_dfu_abort_cb()
-{
- rtos_printf("Host Aborted transfer\n");
+ rtos_printf("Pass firmware validity check addr 0x%x size %u\n", dn_base_addr, total_len);
+ set_rt_mode();
+ boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, 1); // dummy read to ensure flash writes have completed
+ reboot();
+
+ /* TODO actually verify */
+ // tud_dfu_finish_flashing(DFU_STATUS_ERR_VERIFY);
+ // flashing op for manifest is complete without error
+ // Application can perform checksum, should it fail, use appropriate status such as errVERIFY.
+ tud_dfu_finish_flashing(DFU_STATUS_OK);
}
-uint16_t tud_dfu_req_upload_data_cb(uint16_t block_num, uint8_t* data, uint16_t length)
+// Invoked when received DFU_UPLOAD request
+// Application must populate data with up to length bytes and
+// Return the number of written bytes
+uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length)
{
- memset(data, 0x00, length);
- uint32_t addr = block_num * FLASH_PAGE_SIZE;
- uint32_t endaddr;
+ (void) alt;
+
+ memset(data, 0x00, length);
+ uint32_t addr = block_num * FLASH_PAGE_SIZE;
+ uint32_t endaddr;
#if 0
- // Test code which will just read out all of flash rather than a specific image
- endaddr = 0x800000;
+ // Test code which will just read out all of flash rather than a specific image
+ endaddr = 0x800000;
#else
- boot_image_t* imgptr = NULL;
- imgptr = boot_image_get_last_image(bim_ctx_ptr);
- addr += imgptr->startAddress;
- endaddr = imgptr->startAddress + imgptr->size;
+ boot_image_t* imgptr = NULL;
+ imgptr = boot_image_get_last_image(bim_ctx_ptr);
+ addr += imgptr->startAddress;
+ endaddr = imgptr->startAddress + imgptr->size;
#endif
- return (addr >= endaddr) ? 0 : (uint16_t)boot_image_read(bim_ctx_ptr->app_data, addr, data, length);
+ return (addr >= endaddr) ? 0 : (uint16_t)boot_image_read(bim_ctx_ptr->app_data, addr, data, length);
}
-static void reboot(void)
+// Invoked when the Host has terminated a download or upload transfer
+void tud_dfu_abort_cb(uint8_t alt)
{
- rtos_printf("Reboot initiated by tile:0x%x\n", get_local_tile_id());
- write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_COUNT_NUM, 0x10000);
- write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_CFG_NUM, (1 << XS1_WATCHDOG_COUNT_ENABLE_SHIFT) | (1 << XS1_WATCHDOG_TRIGGER_ENABLE_SHIFT) );
- while(1) {;}
+ (void) alt;
+ uint8_t dummy;
+ rtos_printf("Host Aborted transfer. Reboot to RT\n");
+ set_rt_mode();
+ boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, 1); // dummy read to ensure flash writes have completed
+ reboot();
+}
+
+// Invoked when a DFU_DETACH request is received
+void tud_dfu_detach_cb(void)
+{
+ rtos_printf("Host detach, reboot\n");
+ set_rt_mode();
+ reboot();
}
void tud_dfu_runtime_reboot_to_dfu_cb(void)
{
+ rtos_printf("Host detach, reboot\n");
set_dfu_mode();
reboot();
}
+static void reboot(void)
+{
+ rtos_printf("Reboot initiated by tile:0x%x\n", get_local_tile_id());
+ write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_COUNT_NUM, 0x10000);
+ write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_CFG_NUM, (1 << XS1_WATCHDOG_COUNT_ENABLE_SHIFT) | (1 << XS1_WATCHDOG_TRIGGER_ENABLE_SHIFT) );
+ while(1) {;}
+}
+
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
diff --git a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h
index 92648f3a4..319b2072b 100644
--- a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h
+++ b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h
@@ -76,12 +76,14 @@
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
-#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096
+// #define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096
+#define CFG_TUD_DFU_XFER_BUFSIZE ( OPT_MODE_HIGH_SPEED ? 512 : 64 )
//------------- CLASS -------------//
-#define CFG_TUD_DFU_RUNTIME 1
-#define CFG_TUD_DFU_MODE 1
+// #define CFG_TUD_DFU_RUNTIME 1
+// #define CFG_TUD_DFU_MODE 1
+#define CFG_TUD_DFU 1
#ifdef __cplusplus
}
diff --git a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c
index 6e0f0e31d..2e153bbab 100644
--- a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c
+++ b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c
@@ -119,11 +119,9 @@ enum
ITF1_NUM_TOTAL
};
-#define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_MODE_DESC_LEN )
+#define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(1) )
-#define FUNC_ATTRS (DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK | DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK)
-// #define FUNC_ATTRS (DFU_FUNC_ATTR_WILL_DETACH_BITMASK | DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK | DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK)
-// #define FUNC_ATTRS 0x0d // original
+#define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_MANIFESTATION_TOLERANT)
uint8_t const desc_configuration_rt[] =
{
@@ -131,7 +129,7 @@ uint8_t const desc_configuration_rt[] =
TUD_CONFIG_DESCRIPTOR(1, ITF0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, attributes, detach timeout, transfer size */
- TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE),
+ TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE),
};
uint8_t const desc_configuration_mode[] =
@@ -140,7 +138,7 @@ uint8_t const desc_configuration_mode[] =
TUD_CONFIG_DESCRIPTOR(1, ITF1_NUM_TOTAL, 0, CONFIG_1_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, attributes, detach timeout, transfer size */
- TUD_DFU_MODE_DESCRIPTOR(ITF1_NUM_DFU_MODE, 0, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE),
+ TUD_DFU_DESCRIPTOR(ITF1_NUM_DFU_MODE, 1, 5, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE),
};
// Invoked when received GET CONFIGURATION DESCRIPTOR
@@ -149,7 +147,9 @@ uint8_t const desc_configuration_mode[] =
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
{
(void) index; // for multiple configurations
- return check_dfu_mode() ? desc_configuration_rt : desc_configuration_mode;
+ return desc_configuration_mode;
+ /* TODO tmp always mode for now*/
+ // return check_dfu_mode() ? desc_configuration_rt : desc_configuration_mode;
}
//--------------------------------------------------------------------+
@@ -164,6 +164,7 @@ char const* string_desc_arr [] =
"TinyUSB Device", // 2: Product
"123456", // 3: Serials, should use chip ID
"TinyUSB DFU runtime", // 4: DFU runtime
+ "TinyUSB DFU FLASH", // 5: DFU device
};
static uint16_t _desc_str[32];
diff --git a/examples/freertos/usb/usb.cmake b/examples/freertos/usb/usb.cmake
index b6fbd19e5..15d124543 100644
--- a/examples/freertos/usb/usb.cmake
+++ b/examples/freertos/usb/usb.cmake
@@ -211,48 +211,47 @@ create_run_target(example_freertos_usb_tusb_demo_dfu)
create_debug_target(example_freertos_usb_tusb_demo_dfu)
-# Incomplete pending xcore tools updates
#**********************
# DFU Runtime Tile Targets
#**********************
-# file(GLOB_RECURSE DEMO_SOURCES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/*.c )
-# set(DEMO_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/)
-# set(DEMO_COMPILE_DEFINITIONS BOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED
-# DFU_DEMO=1
-# )
-# set(TARGET_NAME tile0_example_freertos_usb_tusb_demo_dfu_runtime)
-# add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
-# target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES})
-# target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES})
-# target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0)
-# target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
-# target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
-# target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
-# unset(TARGET_NAME)
-#
-# set(TARGET_NAME tile1_example_freertos_usb_tusb_demo_dfu_runtime)
-# add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
-# target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES})
-# target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES})
-# target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1)
-# target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
-# target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
-# target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
-# unset(TARGET_NAME)
-# unset(DEMO_SOURCES)
-# unset(DEMO_INCLUDES)
-# unset(DEMO_COMPILE_DEFINITIONS)
-#
-# #**********************
-# # Merge binaries
-# #**********************
-# merge_binaries(example_freertos_usb_tusb_demo_dfu_runtime tile0_example_freertos_usb_tusb_demo_dfu_runtime tile1_example_freertos_usb_tusb_demo_dfu_runtime 1)
-#
-# #**********************
-# # Create run and debug targets
-# #**********************
-# create_run_target(example_freertos_usb_tusb_demo_dfu_runtime)
-# create_debug_target(example_freertos_usb_tusb_demo_dfu_runtime)
+file(GLOB_RECURSE DEMO_SOURCES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/*.c )
+set(DEMO_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/)
+set(DEMO_COMPILE_DEFINITIONS BOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED
+ DFU_DEMO=1
+)
+set(TARGET_NAME tile0_example_freertos_usb_tusb_demo_dfu_runtime)
+add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
+target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES})
+target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES})
+target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0)
+target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
+target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
+target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
+unset(TARGET_NAME)
+
+set(TARGET_NAME tile1_example_freertos_usb_tusb_demo_dfu_runtime)
+add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL)
+target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES})
+target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES})
+target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1)
+target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS})
+target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES})
+target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS})
+unset(TARGET_NAME)
+unset(DEMO_SOURCES)
+unset(DEMO_INCLUDES)
+unset(DEMO_COMPILE_DEFINITIONS)
+
+#**********************
+# Merge binaries
+#**********************
+merge_binaries(example_freertos_usb_tusb_demo_dfu_runtime tile0_example_freertos_usb_tusb_demo_dfu_runtime tile1_example_freertos_usb_tusb_demo_dfu_runtime 1)
+
+#**********************
+# Create run and debug targets
+#**********************
+create_run_target(example_freertos_usb_tusb_demo_dfu_runtime)
+create_debug_target(example_freertos_usb_tusb_demo_dfu_runtime)
#**********************
diff --git a/modules/rtos b/modules/rtos
index ad077ebba..5c1e94444 160000
--- a/modules/rtos
+++ b/modules/rtos
@@ -1 +1 @@
-Subproject commit ad077ebbad55ccc640711a5255e8fd09206a4de5
+Subproject commit 5c1e94444b023f07232b55a9b9971fb2f9271053
diff --git a/tools/ci/build_rtos_core_examples.sh b/tools/ci/build_rtos_core_examples.sh
index e1874eedb..3dcad32e0 100755
--- a/tools/ci/build_rtos_core_examples.sh
+++ b/tools/ci/build_rtos_core_examples.sh
@@ -16,17 +16,21 @@ if [ -d "${DIST_HOST_DIR}" ]; then
find ${DIST_HOST_DIR} -type f -exec chmod a+x {} +
fi
-# row format is: "target min_tools_version run_fs_target run_swmem_target board toolchain"
+# row format is: "target min_tools_version run_fs_target run_swmem_target run_upgrade_img_target board toolchain"
applications=(
- "example_freertos_device_control 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_dispatcher 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_explorer_board 15.1.0 Yes No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_getting_started 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_l2_cache 15.1.0 No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_tracealyzer 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_xlink_0 15.2.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_xlink_1 15.2.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
- "example_freertos_xscope_fileio 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_device_control 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_dfu_v1 15.1.3 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_dfu_v2 15.1.3 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_dfu_v1 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_dfu_v2 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_dispatcher 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_explorer_board 15.1.0 Yes No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_getting_started 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_l2_cache 15.1.0 No Yes No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_tracealyzer 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_xlink_0 15.2.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_xlink_1 15.2.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
+ "example_freertos_xscope_fileio 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake"
)
# perform builds
@@ -36,8 +40,9 @@ for ((i = 0; i < ${#applications[@]}; i += 1)); do
min_tools_version="${FIELDS[1]}"
run_fs_target="${FIELDS[2]}"
run_swmem_target="${FIELDS[3]}"
- board="${FIELDS[4]}"
- toolchain_file="${XCORE_SDK_ROOT}/${FIELDS[5]}"
+ run_upgrade_img_target="${FIELDS[4]}"
+ board="${FIELDS[5]}"
+ toolchain_file="${XCORE_SDK_ROOT}/${FIELDS[6]}"
path="${XCORE_SDK_ROOT}"
if check_tools_version ${min_tools_version}
@@ -63,5 +68,12 @@ for ((i = 0; i < ${#applications[@]}; i += 1)); do
(cd ${path}/build_${board}; log_errors make make_swmem_${app_target} -j)
(cd ${path}/build_${board}; cp ${app_target}.swmem ${DIST_DIR})
fi
+ if [ "$run_upgrade_img_target" = "Yes" ]; then
+ echo '======================================================'
+ echo '= Making upgrade image for' ${app_target}
+ echo '======================================================'
+ (cd ${path}/build_${board}; log_errors make create_upgrade_img_${app_target} -j)
+ (cd ${path}/build_${board}; cp ${app_target}_upgrade.bin ${DIST_DIR})
+ fi
fi
done