diff --git a/.gitmodules b/.gitmodules index 387e13a..93113c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,9 @@ [submodule "trycatch"] path = modules/trycatch/lib_trycatch url = git@github.com:xmos/lib_trycatch.git +[submodule "modules/multitile_support/tests/tile_map_defines/modules/fwk_rtos"] + path = modules/multitile_support/tests/tile_map_defines/modules/fwk_rtos + url = git@github.com:xmos/fwk_rtos.git +[submodule "modules/multitile_support/tests/tile_map_defines/modules/xmos_cmake_toolchain"] + path = modules/multitile_support/tests/tile_map_defines/modules/xmos_cmake_toolchain + url = git@github.com:xmos/xmos_cmake_toolchain.git diff --git a/modules/multitile_support/README.md b/modules/multitile_support/README.md new file mode 100644 index 0000000..d03ca4b --- /dev/null +++ b/modules/multitile_support/README.md @@ -0,0 +1,87 @@ +# Multi-Tile Support + +This module provides support for starting an application on multiple tiles +and communicating between those tiles. Support is provided for applications +using 2 or 4 tile XCore devices. + +## Starting a multi-tile application + +Starting a multi-tile application on an XCore device requires that an +entry point be defined for each tile. These entry points replace the +C standard main() entry point and are defined in tile_map.xc. In order +to make communication possible between the tiles of an XCore device, +the multi-tile entry points provide an XCore channel between each pair +of tiles used. + +A set of weak implementations is provided for inclusion in your +project by adding tile_map_defaults.c to your build sources. This allows +the application code for on tile to be compiled and tested without +adding code for other tiles. + +### Standard two tile configuration (e.g. XCore.ai) + +Most applications will use a single XCore device with two tiles. In this +case, the application the C code needs two entry points, and the +prototypes (for tiles 0 and 1 respectively) will be: + + void main_tile0(chanend_t c); + void main_tile1(chanend_t c); + +The *chanend_t c* can be used on each tile to communicate with the other +tile by making use of the functions defined in ****. Note +that any channel communication operation (e.g. *chan_out_word(c, 100);* ) +on one tile must be matched by the opposite channel operation on the +other tile (e.g. *int a = chan_in_word(c);* ) + +To achieve this configuration, the required preprocessor defines are: + + PLATFORM_SUPPORTS_TILE_0 = 1 + PLATFORM_SUPPORTS_TILE_1 = 1 + PLATFORM_USES_TILE_0 = 1 + PLATFORM_USES_TILE_1 = 1 + MINIMISE_MAIN_TILE_ARGS + +### Alternate configurations + +In general, the code entry point prototype for each tile *X* which has both +**PLATFORM_SUPPORTS_TILE_*X* = 1** and **PLATFORM_USES_TILE_*X* = 1** +will be: + + void main_tile*X* (*ARGS*); + +If **MINIMISE_MAIN_TILE_ARGS** is not defined, each tile has an entry point of +the form: + + void main_tile*X*(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3); + +where *X* is the tile number. The four arguments are channel ends that +connect to each of the other tiles. In the above protoype, c*Y* indicates a +channel to tile *Y*. Where a tile *Y* is not both supported and used, or the +channel indicates a loopback (i.e. *X* == *Y*), that channel end argument is +not a valid channel end, and must not be used. + +If **MINIMISE_MAIN_TILE_ARGS** is defined, the entry point prototype for +tiles defined as both supported and used will be as described above except +that invalid channel ends are removed. For example, if tiles 0, 2 and 3 are +available and used and MINIMISE_MAIN_TILE_ARGS is defined, the entry point +prototypes would be: + + void main_tile0(chanend c2, chanend c3); + void main_tile2(chanend c0, chanend c3); + void main_tile3(chanend c0, chanend c2); + +When setting preprocessor defines, using the **MINIMISE_MAIN_TILE_ARGS** define +also means that **PLATFORM_SUPPORTS_TILE_*X*** and **PLATFORM_USES_TILE_*X*** +that are undefined are considered to be the equivalent to being set to 0. + + + +## Inter-tile communication + +The entry point prototypes provide a single channel for communication between +each tile pair by passing a dedicated channel end (*chanend_t*) to those two +tiles. In general, a chanend can only be used by a single thread running on a +core of the tile to which the channel end was provided. To establish +additional channels between tiles, this module provides an api which makes use +of the single channel passed to the code entry point to establish additional +channels. \ No newline at end of file diff --git a/modules/multitile_support/api/main_tile.h b/modules/multitile_support/api/main_tile.h new file mode 100644 index 0000000..bc93edc --- /dev/null +++ b/modules/multitile_support/api/main_tile.h @@ -0,0 +1,238 @@ +// Copyright 2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* +main_tile.h + +This file provides prototypes for the entry point for each tile on an XCore +device. Including this file with your application will allow entry point +errors to be picked up at compile time rather than at the link stage. + +Please see the multi-tile support module README for further details. +*/ +#include + +#include + +extern "C" +{ + +#ifndef MINIMISE_MAIN_TILE_ARGS + +void main_tile0(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3); +void main_tile1(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3); +void main_tile2(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3); +void main_tile3(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3); + +#else // MINIMISE_MAIN_TILE_ARGS + +// ---------------- Minimised Argument Prototypes --------------------- +// Common to all +#define MAIN_TAIL ); + +// -------------------- Tile 0 prototype ------------------------------ +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + +#define MAIN0_HEAD void main_tile0( + +// c0 +// channel c0 is loopback so it is never in the minimised argument set +#define MAIN0_ARG0 + +// c1 +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) + #define MAIN0_ARG1 chanend_t c_0to1 + #define ARGS_STARTED +#else + #define MAIN0_ARG1 +#endif + + +// c2 +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) + + #ifdef ARGS_STARTED + #define MAIN0_ARG2 , chanend_t c_0to2 + #else + #define MAIN0_ARG2 chanend_t c_0to2 + #endif + + #define ARGS_STARTED + +#else + #define MAIN0_ARG2 +#endif + + +// c3 +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) + + #ifdef ARGS_STARTED + #define MAIN0_ARG3 , chanend_t c_0to3 + #else + #define MAIN0_ARG3 chanend_t c_0to3 + #endif + +#else + #define MAIN0_ARG3 +#endif + + +MAIN0_HEAD MAIN0_ARG0 MAIN0_ARG1 MAIN0_ARG2 MAIN0_ARG3 MAIN_TAIL +#endif // ----------------- End tile 0 prototype -------------------------- + + + +// -------------------- Tile 1 prototype ------------------------------ +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) + +#define MAIN1_HEAD void main_tile1( + + +// c0 +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + #define MAIN1_ARG0 chanend_t c_1to0 + #define ARGS_STARTED +#else + #define MAIN1_ARG0 +#endif + +// c1 +// channel c1 is loopback so it is never in the minimised argument set +#define MAIN1_ARG1 + + +// c2 +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) + #ifdef ARGS_STARTED + #define MAIN1_ARG2 , chanend_t c_1to2 + #else + #define MAIN1_ARG2 chanend_t c_1to2 + #endif + + #define ARGS_STARTED + +#else + #define MAIN1_ARG2 +#endif + + +// c3 +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) + + #ifdef ARGS_STARTED + #define MAIN1_ARG3 , chanend_t c_1to3 + #else + #define MAIN1_ARG3 chanend_t c_1to3 + #endif + +#else + #define MAIN1_ARG3 +#endif + + +MAIN1_HEAD MAIN1_ARG0 MAIN1_ARG1 MAIN1_ARG2 MAIN1_ARG3 MAIN_TAIL +#endif // ----------------- End tile 1 prototype -------------------------- + + + +// -------------------- Tile 2 prototype ------------------------------ +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) +#define MAIN2_HEAD void main_tile2( + +// c0 +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + #define MAIN2_ARG0 chanend_t c_2to0 + #define ARGS_STARTED +#else + #define MAIN2_ARG0 +#endif + +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) + #ifdef ARGS_STARTED + #define MAIN2_ARG1 , chanend_t c_2to1 + #else + #define MAIN2_ARG1 chanend_t c_2to1 + #endif + + #define ARGS_STARTED + +#else + #define MAIN3_ARG1 +#endif + +// c2 +// channel c2 is loopback so it is never in the minimised argument set +#define MAIN2_ARG2 + + +// c3 +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) + + #ifdef ARGS_STARTED + #define MAIN2_ARG3 , chanend_t c_2to3 + #else + #define MAIN2_ARG3 chanend_t c_2to3 + #endif + +#else + #define MAIN2_ARG3 +#endif + + +MAIN2_HEAD MAIN2_ARG0 MAIN2_ARG1 MAIN2_ARG2 MAIN2_ARG3 MAIN_TAIL +#endif // ----------------- End tile 2 prototype -------------------------- + + + +// -------------------- Tile 3 prototype ------------------------------ +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) +#define MAIN3_HEAD void main_tile3( + +// c0 +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + #define MAIN3_ARG0 chanend_t c_3to0 + #define ARGS_STARTED +#else + #define MAIN3_ARG0 +#endif + +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) + #ifdef ARGS_STARTED + #define MAIN3_ARG1 , chanend_t c_3to1 + #else + #define MAIN3_ARG1 chanend_t c_3to1 + #endif + + #define ARGS_STARTED + +#else + #define MAIN3_ARG1 +#endif + + +// c2 +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) + #ifdef ARGS_STARTED + #define MAIN3_ARG2 , chanend_t c_3to2 + #else + #define MAIN3_ARG2 chanend_t c_3to2 + #endif + + #define ARGS_STARTED + +#else + #define MAIN3_ARG2 +#endif + +// c3 +// channel c3 is loopback so it is never in the minimised argument set +#define MAIN3_ARG3 + + +MAIN3_HEAD MAIN3_ARG0 MAIN3_ARG1 MAIN3_ARG2 MAIN3_ARG3 MAIN_TAIL +#endif // ----------------- End tile 3 prototype -------------------------- + +#endif // MINIMISE_MAIN_TILE_ARGS +} + diff --git a/modules/multitile_support/src/tile_map.xc b/modules/multitile_support/src/tile_map.xc index af7de3f..0936792 100644 --- a/modules/multitile_support/src/tile_map.xc +++ b/modules/multitile_support/src/tile_map.xc @@ -1,13 +1,36 @@ +// Copyright 2021-2023 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. -// XMOS Public License: Version 1 + + +/* +tile_map.xc + +This file defines entry points and initial communication channels between +tiles on an XCore device. For a two tile application on an XCore +the C code entry point prototypes for tiles 0 and 1 respectively will be: + +void main_tile0(chanend_t c); +void main_tile1(chanend_t c); + +The chanend_t c can be used on each tile to communicate with the other +tile by making use of the functions defined in . To +achieve this configuration, the required preprocessor defines are: + +PLATFORM_SUPPORTS_TILE_0 = 1 +PLATFORM_SUPPORTS_TILE_1 = 1 +PLATFORM_USES_TILE_0 = 1 +PLATFORM_USES_TILE_1 = 1 +MINIMISE_MAIN_TILE_ARGS + +Please the multi-tile support module README for further details. +*/ #include "platform.h" extern "C" { -void main_tile0(chanend c0, chanend c1, chanend c2, chanend c3); -void main_tile1(chanend c0, chanend c1, chanend c2, chanend c3); -void main_tile2(chanend c0, chanend c1, chanend c2, chanend c3); -void main_tile3(chanend c0, chanend c1, chanend c2, chanend c3); + +#include "main_tile.h + #if (XSCOPE_HOST_IO_ENABLED == 1) #ifndef XSCOPE_HOST_IO_TILE #define XSCOPE_HOST_IO_TILE 0 @@ -50,89 +73,277 @@ int main(void) { xscope_host_data(c_xscope_host); on tile[XSCOPE_HOST_IO_TILE] : init_xscope_host_data_user_cb(c_xscope_host); #endif + + + +// -------------------- Tile 0 usage ------------------------------- #if (PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1) +#undef ARGS_STARTED on tile[0] : main_tile0( + +// Tile 0 loopback argument +#ifndef MINIMISE_MAIN_TILE_ARGS null, +#endif + + +// Tile 0 channel to tile 1 #if (PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1) - c_t0_t1, +#ifdef ARGS_STARTED + , +#endif + c_t0_t1 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED +#else + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + +// Tile 0 channel to tile 2 #if (PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1) - c_t0_t2, +#ifdef ARGS_STARTED + , +#endif + c_t0_t2 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED #else + , +#endif +#else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + +// Tile 0 channel to tile 3 #if (PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1) +#ifdef ARGS_STARTED + , +#endif c_t0_t3 +#ifndef MINIMISE_MAIN_TILE_ARGS + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null #endif - ); #endif + + ); +#endif // ----------------- End tile 0 usage ----------------------- + + + + +// -------------------- Tile 1 usage ------------------------------- #if (PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1) +#undef ARGS_STARTED on tile[1] : main_tile1( + + +// Tile 1 channel to tile 0 #if (PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1) - c_t0_t1, +#ifdef ARGS_STARTED + , +#endif + c_t0_t1 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED +#else + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + +// Tile 1 loopback argument +#ifndef MINIMISE_MAIN_TILE_ARGS null, +#endif + + +// Tile 1 channel to tile 2 #if (PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1) - c_t1_t2, +#ifdef ARGS_STARTED + , +#endif + c_t1_t2 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED +#else + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + + +// Tile 1 channel to tile 3 #if (PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1) +#ifdef ARGS_STARTED + , +#endif c_t1_t3 +#ifndef MINIMISE_MAIN_TILE_ARGS + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null #endif - ); #endif + + ); +#endif // -------------------- End tile 1 usage ----------------------- + + + +// -------------------- Tile 2 usage ------------------------------- #if (PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1) +#undef ARGS_STARTED on tile[2] : main_tile2( + + +// Tile 2 channel to tile 0 #if (PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1) - c_t0_t2, +#ifdef ARGS_STARTED + , +#endif + c_t0_t2 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED +#else + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + + +// Tile 2 channel to tile 1 #if (PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1) - c_t1_t2, +#ifdef ARGS_STARTED + , +#endif + c_t1_t2 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED +#else + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + + +// Tile 2 loopback argument +#ifndef MINIMISE_MAIN_TILE_ARGS null, +#endif + + +// Tile 2 channel to tile 3 #if (PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1) +#ifdef ARGS_STARTED + , +#endif c_t2_t3 +#ifndef MINIMISE_MAIN_TILE_ARGS + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null #endif - ); #endif + + ); +#endif // -------------------- End tile 2 usage ----------------------- + + + +// -------------------- Tile 3 usage ------------------------------- #if (PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1) +#undef ARGS_STARTED on tile[3] : main_tile3( + + +// Tile 3 channel to tile 0 #if (PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1) - c_t0_t3, +#ifdef ARGS_STARTED + , +#endif + c_t0_t3 +#ifdef MINIMISE_MAIN_TILE_ARGS +#define ARGS_STARTED #else + , +#endif +#else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + +// Tile 3 channel to tile 1 #if (PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1) - c_t1_t3, +#ifdef ARGS_STARTED + , +#endif + c_t1_t3 +#ifndef MINIMISE_MAIN_TILE_ARGS + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif +#endif + + +// Tile 2 channel to tile 0 #if (PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1) - c_t2_t3, +#ifdef ARGS_STARTED + , +#endif + c_t2_t3 +#ifndef MINIMISE_MAIN_TILE_ARGS + , +#endif #else +#ifndef MINIMISE_MAIN_TILE_ARGS null, #endif - null); #endif + +// Tile 3 loopback argument +#ifndef MINIMISE_MAIN_TILE_ARGS + null +#endif + + + ); +#endif // -------------------- End tile 3 usage ----------------------- } return 0; } + diff --git a/modules/multitile_support/src/tile_map_defaults.c b/modules/multitile_support/src/tile_map_defaults.c index e63eef2..0fef068 100644 --- a/modules/multitile_support/src/tile_map_defaults.c +++ b/modules/multitile_support/src/tile_map_defaults.c @@ -1,10 +1,22 @@ -// Copyright 2021 XMOS LIMITED. +// Copyright 2021-23 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. +/* +tile_map_defaults.c + +This file defines weak C entry point implementations for each tile on an XCore +device. Configuration matches the protoype given in tile_map.xc + +Please the multi-tile support module README for further details. +*/ #include #include +#include "main_tile.h" + +#ifndef MINIMISE_MAIN_TILE_ARGS + __attribute__((weak)) void main_tile0(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3) { @@ -28,3 +40,169 @@ void main_tile3(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3) { return; } + +else // MINIMISE_MAIN_TILE_ARGS defined + + +// -------------------- Tile 0 weak implementation ------------------------------ +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) +__attribute__((weak)) void main0( + +// c0 +// channel c0 is loopback so it is never in the minimised argument set + + +// c1 +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) + chanend_t c1 +#define ARGS_STARTED +#endif + + +// c2 +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c2 +#define ARGS_STARTED +#endif + + +// c3 +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c3 +#endif + ) +{ + return; +} +#endif // -------- End tile 0 weak implementation --------------------- + + + +// ------------------- Tile 1 weak implementation --------------------- +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) +__attribute__((weak)) void main1( + +// c0 +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + chanend_t c0 +#define ARGS_STARTED +#endif + +// c1 +// channel c1 is loopback so it is never in the minimised argument set + + +// c2 +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c2 +#define ARGS_STARTED +#endif + + +// c3 +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c3 +#endif + + ) +{ + return; +} + +#endif // ---------- End tile 1 weak implementation ------------------ + + + +// -------------------- Tile 2 weak implementation ------------------- +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) +__attribute__((weak)) void main2( + +// c0 +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + chanend_t c0 +#define ARGS_STARTED +#endif + +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c1 +#define ARGS_STARTED +#endif + +// c2 +// channel c2 is loopback so it is never in the minimised argument set + + +// c3 +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c3 +#endif + + ) +{ + return; +} + +#endif // ----------- End tile 2 weak implementation ---------------- + + + +// -------------------- Tile 3 weak implementation ------------------- +#if ((PLATFORM_SUPPORTS_TILE_3 == 1) && (PLATFORM_USES_TILE_3 == 1)) +__attribute__((weak)) void main3( + +// c0 +#if ((PLATFORM_SUPPORTS_TILE_0 == 1) && (PLATFORM_USES_TILE_0 == 1)) + chanend_t c0 +#define ARGS_STARTED +#endif + +#if ((PLATFORM_SUPPORTS_TILE_1 == 1) && (PLATFORM_USES_TILE_1 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c1 +#define ARGS_STARTED +#endif + + +// c2 +#if ((PLATFORM_SUPPORTS_TILE_2 == 1) && (PLATFORM_USES_TILE_2 == 1)) +#ifdef ARGS_STARTED + , +#endif + chanend_t c2 +#endif + + +// c3 +// channel c3 is loopback so it is never in the minimised argument set + ) +{ + return; +} + + +#endif // ---------- End tile 3 weak implementation ------------------ + + +#endif // MINIMISE_MAIN_TILE_ARGS + +