diff --git a/.bazelrc b/.bazelrc
new file mode 100644
index 000000000..e0c5c47b8
--- /dev/null
+++ b/.bazelrc
@@ -0,0 +1,3 @@
+# For CI testing only
+build --//:freertos_config=:posix
+build --platforms=:example_platform
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..0d4fed27c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+bazel-*
+MODULE.bazel.lock
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 000000000..73587ac4b
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,376 @@
+"""This is a BUILD.bazel file for FreeRTOS."""
+
+load("@local_config_platform//:constraints.bzl", "HOST_CONSTRAINTS")
+
+package(default_visibility = ["//visibility:public"])
+
+# Label flag that points to the cc_library target providing freertos_config.h.
+label_flag(
+    name = "freertos_config",
+    build_setting_default = ":default_freertos_config",
+)
+
+cc_library(name = "empty_cc_library")
+
+cc_library(
+    name = "default_freertos_config",
+    # The "default" config is not compatible with any configuration: you can't
+    # build FreeRTOS without choosing a config.
+    target_compatible_with = ["@platforms//:incompatible"],
+)
+
+# Constraint setting used to select the FreeRTOSConfig version.
+constraint_setting(
+    name = "freertos_config_setting",
+)
+
+constraint_setting(
+    name = "port",
+)
+
+# Cortex-M33 with No TrustZone
+constraint_value(
+    name = "port_ARM_CM33_NTZ",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_ARM_CM4F",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_ARM_CM0",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_ARM_CM3",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_ARM_CM7",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_Xtensa",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_Posix",
+    constraint_setting = ":port",
+)
+
+constraint_value(
+    name = "port_RP2040",
+    constraint_setting = ":port",
+)
+
+cc_library(
+    name = "rp2040_sdk_deps",
+    deps = [
+        "@pico-sdk//src/rp2_common/hardware_clocks",
+        "@pico-sdk//src/rp2_common/hardware_exception",
+        "@pico-sdk//src/rp2_common/pico_multicore",
+    ],
+)
+
+cc_library(
+    name = "freertos",
+    srcs = [
+        "croutine.c",
+        "event_groups.c",
+        "list.c",
+        "queue.c",
+        "stream_buffer.c",
+        "timers.c",
+    ] + select({
+        ":port_ARM_CM0": ["portable/GCC/ARM_CM0/port.c"],
+        ":port_ARM_CM3": ["portable/GCC/ARM_CM3/port.c"],
+        ":port_ARM_CM33_NTZ": [
+            "portable/GCC/ARM_CM33_NTZ/non_secure/port.c",
+            "portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c",
+        ],
+        ":port_ARM_CM4F": ["portable/GCC/ARM_CM4F/port.c"],
+        ":port_ARM_CM7": ["portable/GCC/ARM_CM7/r0p1/port.c"],
+        ":port_Xtensa": [
+            "portable/ThirdParty/XCC/Xtensa/mpu.S",
+            "portable/ThirdParty/XCC/Xtensa/port.c",
+            "portable/ThirdParty/XCC/Xtensa/portasm.S",
+            "portable/ThirdParty/XCC/Xtensa/portclib.c",
+            "portable/ThirdParty/XCC/Xtensa/portmpu.c",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_context.S",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_coproc_handler.S",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_intr.c",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_intr_asm.S",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_intr_wrapper.c",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_vectors.S",
+        ],
+        ":port_Posix": [
+            "portable/ThirdParty/GCC/Posix/port.c",
+            "portable/ThirdParty/GCC/Posix/utils/wait_for_event.c",
+            "portable/ThirdParty/GCC/Posix/utils/wait_for_event.h",
+        ],
+        ":port_RP2040": [
+            "portable/ThirdParty/GCC/RP2040/port.c",
+        ],
+        "//conditions:default": [],
+    }),
+    includes = ["include/"],
+    textual_hdrs = [
+        "include/FreeRTOS.h",
+        "include/StackMacros.h",
+        "include/croutine.h",
+        "include/deprecated_definitions.h",
+        "include/event_groups.h",
+        "include/list.h",
+        "include/message_buffer.h",
+        "include/mpu_wrappers.h",
+        "include/portable.h",
+        "include/projdefs.h",
+        "include/queue.h",
+        "include/semphr.h",
+        "include/stack_macros.h",
+        "include/stream_buffer.h",
+        "include/task.h",
+        "include/timers.h",
+    ],
+    deps = [
+        ":freertos_config",
+        ":freertos_port_headers",
+        ":heap",
+        ":tasks_c",
+    ] + select({
+        ":port_RP2040": [":rp2040_sdk_deps"],
+        "//conditions:default": [],
+    }),
+    # Required because breaking out tasks_c results in the dependencies between
+    # the libraries not being quite correct: to link tasks_c you actually need
+    # a bunch of the source files from here (e.g., list.c).
+    alwayslink = 1,
+)
+
+cc_library(
+    name = "freertos_port_headers",
+    hdrs = select({
+        ":port_ARM_CM0": ["portable/GCC/ARM_CM0/portmacro.h"],
+        ":port_ARM_CM3": ["portable/GCC/ARM_CM3/portmacro.h"],
+        ":port_ARM_CM33_NTZ": glob(["portable/GCC/ARM_CM33_NTZ/non_secure/*.h"]),
+        ":port_ARM_CM4F": ["portable/GCC/ARM_CM4F/portmacro.h"],
+        ":port_ARM_CM7": ["portable/GCC/ARM_CM7/r0p1/portmacro.h"],
+        ":port_Posix": [
+            "portable/ThirdParty/GCC/Posix/portmacro.h",
+        ],
+        ":port_Xtensa": [
+            "portable/ThirdParty/XCC/Xtensa/portbenchmark.h",
+            "portable/ThirdParty/XCC/Xtensa/portmacro.h",
+            "portable/ThirdParty/XCC/Xtensa/porttrace.h",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_api.h",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_config.h",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_context.h",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h",
+            "portable/ThirdParty/XCC/Xtensa/xtensa_timer.h",
+        ],
+        ":port_RP2040": [
+            "portable/ThirdParty/GCC/RP2040/include/freertos_sdk_config.h",
+            "portable/ThirdParty/GCC/RP2040/include/portmacro.h",
+            "portable/ThirdParty/GCC/RP2040/include/rp2040_config.h",
+        ],
+        "//conditions:default": [],
+    }),
+    defines = select({
+        ":port_RP2040": ["PICO_CONFIG_RTOS_ADAPTER_HEADER=\"freertos_sdk_config.h\""],
+        "//conditions:default": [],
+    }),
+    includes = select({
+        ":port_ARM_CM0": ["portable/GCC/ARM_CM0/"],
+        ":port_ARM_CM3": ["portable/GCC/ARM_CM3/"],
+        ":port_ARM_CM33_NTZ": ["portable/GCC/ARM_CM33_NTZ/non_secure"],
+        ":port_ARM_CM4F": ["portable/GCC/ARM_CM4F/"],
+        ":port_ARM_CM7": ["portable/GCC/ARM_CM7/r0p1/"],
+        ":port_Posix": ["portable/ThirdParty/GCC/Posix/"],
+        ":port_Xtensa": ["portable/ThirdParty/XCC/Xtensa"],
+        ":port_RP2040": ["portable/ThirdParty/GCC/RP2040/include"],
+        "//conditions:default": [],
+    }),
+)
+
+# Headers transitively included by using "FreeRTOS.h"
+cc_library(
+    name = "freertos_headers",
+    hdrs = [
+        "include/FreeRTOS.h",
+        "include/deprecated_definitions.h",
+        "include/list.h",
+        "include/mpu_wrappers.h",
+        "include/portable.h",
+        "include/projdefs.h",
+        "include/stack_macros.h",
+        "include/task.h",
+        "include/timers.h",
+    ],
+    includes = [
+        "include/",
+    ],
+    deps = [
+        ":freertos_config",
+        ":freertos_port_headers",
+    ],
+)
+
+# Constraint setting used to determine if task statics should be disabled.
+constraint_setting(
+    name = "disable_tasks_statics_setting",
+    default_constraint_value = ":no_disable_task_statics",
+)
+
+constraint_value(
+    name = "disable_task_statics",
+    constraint_setting = ":disable_tasks_statics_setting",
+)
+
+constraint_value(
+    name = "no_disable_task_statics",
+    constraint_setting = ":disable_tasks_statics_setting",
+)
+
+cc_library(
+    name = "tasks_c",
+    srcs = ["tasks.c"],
+    copts = [
+        "-Wno-cast-qual",
+    ],
+    local_defines = select({
+        ":disable_task_statics": [
+            "static=",
+        ],
+        "//conditions:default": [],
+    }) + select({
+        ":port_RP2040": ["PICO_CONFIG_RTOS_ADAPTER_HEADER=\"freertos_sdk_config.h\""],
+        "//conditions:default": [],
+    }),
+    deps = [":freertos_headers"] + select({
+        ":port_RP2040": [":rp2040_sdk_deps"],
+        "//conditions:default": [],
+    }),
+)
+
+# Constraint setting for malloc implementation.
+#
+# Note that while a platform may set this via its constraint_values, the top-
+# level "freertos" target depends on "heap". This defaults to using this
+# constraint_setting via "freertos_malloc". The label flag may be configured to
+# be different, e.g. if you want to wrap the heap API.
+constraint_setting(
+    name = "malloc",
+    default_constraint_value = ":no_malloc",
+)
+
+constraint_value(
+    name = "no_malloc",
+    constraint_setting = ":malloc",
+)
+
+constraint_value(
+    name = "malloc_heap_1",
+    constraint_setting = ":malloc",
+)
+
+constraint_value(
+    name = "malloc_heap_2",
+    constraint_setting = ":malloc",
+)
+
+constraint_value(
+    name = "malloc_heap_3",
+    constraint_setting = ":malloc",
+)
+
+constraint_value(
+    name = "malloc_heap_4",
+    constraint_setting = ":malloc",
+)
+
+constraint_value(
+    name = "malloc_heap_5",
+    constraint_setting = ":malloc",
+)
+
+cc_library(
+    name = "freertos_malloc",
+    deps = select({
+        ":malloc_heap_1": [":heap_1"],
+        ":malloc_heap_2": [":heap_2"],
+        ":malloc_heap_3": [":heap_3"],
+        ":malloc_heap_4": [":heap_4"],
+        ":malloc_heap_5": [":heap_5"],
+        ":no_malloc": [],
+    }),
+)
+
+cc_library(
+    name = "heap_1",
+    srcs = ["portable/MemMang/heap_1.c"],
+    deps = [":freertos_headers"],
+)
+
+cc_library(
+    name = "heap_2",
+    srcs = ["portable/MemMang/heap_2.c"],
+    deps = [":freertos_headers"],
+)
+
+cc_library(
+    name = "heap_3",
+    srcs = ["portable/MemMang/heap_3.c"],
+    deps = [":freertos_headers"],
+)
+
+cc_library(
+    name = "heap_4",
+    srcs = ["portable/MemMang/heap_4.c"],
+    deps = [":freertos_headers"],
+)
+
+cc_library(
+    name = "heap_5",
+    srcs = ["portable/MemMang/heap_5.c"],
+    deps = [":freertos_headers"],
+)
+
+# Build target that provide a heap implementation.
+#
+# See also the note on the "malloc" constraint setting.
+label_flag(
+    name = "heap",
+    build_setting_default = ":freertos_malloc",
+)
+
+# Exported for users who need to extract the tskTCB struct. See
+# e.g. https://pigweed.dev/third_party/freertos/.
+exports_files(
+    ["tasks.c"],
+)
+
+cc_library(
+    name = "posix",
+    hdrs = ["host_include/FreeRTOSConfig.h"],
+    defines = [
+        "projENABLE_TRACING=0",
+        "projCOVERAGE_TEST=0",
+    ],
+    includes = ["host_include"],
+    # For CI testing the build only, not part of the API.
+    visibility = ["//visibility:private"],
+)
+
+platform(
+    name = "example_platform",
+    constraint_values = [":port_Posix"] + HOST_CONSTRAINTS,
+    # For CI testing the build only, not part of the API.
+    visibility = ["//visibility:private"],
+)
diff --git a/FreeRTOSConfig.h b/FreeRTOSConfig.h
new file mode 100644
index 000000000..96aa2c1eb
--- /dev/null
+++ b/FreeRTOSConfig.h
@@ -0,0 +1,206 @@
+/* FreeRTOS V202212.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * 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.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+* Application specific definitions.
+*
+* These definitions should be adjusted for your particular hardware and
+* application requirements.
+*
+* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.  See
+* https://www.FreeRTOS.org/a00110.html
+*----------------------------------------------------------*/
+
+#define configUSE_PREEMPTION                       1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION    0
+#define configUSE_IDLE_HOOK                        1
+#define configUSE_TICK_HOOK                        1
+#define configUSE_DAEMON_TASK_STARTUP_HOOK         1
+#define configTICK_RATE_HZ                         ( 1000 )                  /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
+#define configMINIMAL_STACK_SIZE                   ( ( unsigned short ) PTHREAD_STACK_MIN ) /* The stack size being passed is equal to the minimum stack size needed by pthread_create(). */
+#define configTOTAL_HEAP_SIZE                      ( ( size_t ) ( 65 * 1024 ) )
+#define configMAX_TASK_NAME_LEN                    ( 12 )
+#define configUSE_TRACE_FACILITY                   1
+#define configUSE_16_BIT_TICKS                     0
+#define configIDLE_SHOULD_YIELD                    1
+#define configUSE_MUTEXES                          1
+#define configCHECK_FOR_STACK_OVERFLOW             0
+#define configUSE_RECURSIVE_MUTEXES                1
+#define configQUEUE_REGISTRY_SIZE                  20
+#define configUSE_APPLICATION_TASK_TAG             1
+#define configUSE_COUNTING_SEMAPHORES              1
+#define configUSE_ALTERNATIVE_API                  0
+#define configUSE_QUEUE_SETS                       1
+#define configUSE_TASK_NOTIFICATIONS               1
+
+/* The following 2  memory allocation schemes are possible for this demo:
+ *
+ * 1. Dynamic Only.
+ *    #define configSUPPORT_STATIC_ALLOCATION  0
+ *    #define configSUPPORT_DYNAMIC_ALLOCATION 1
+ *
+ * 2. Static and Dynamic.
+ *    #define configSUPPORT_STATIC_ALLOCATION  1
+ *    #define configSUPPORT_DYNAMIC_ALLOCATION 1
+ *
+ * Static only configuration is not possible for this demo as it utilizes
+ * dynamic allocation.
+ */
+#define configSUPPORT_STATIC_ALLOCATION            1
+#define configSUPPORT_DYNAMIC_ALLOCATION           1
+
+#define configRECORD_STACK_HIGH_ADDRESS            1
+
+/* Software timer related configuration options.  The maximum possible task
+ * priority is configMAX_PRIORITIES - 1.  The priority of the timer task is
+ * deliberately set higher to ensure it is correctly capped back to
+ * configMAX_PRIORITIES - 1. */
+#define configUSE_TIMERS                           1
+#define configTIMER_TASK_PRIORITY                  ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH                   20
+#define configTIMER_TASK_STACK_DEPTH               ( configMINIMAL_STACK_SIZE * 2 )
+
+#define configMAX_PRIORITIES                       ( 7 )
+
+/* Run time stats gathering configuration options. */
+unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
+void vConfigureTimerForRunTimeStats( void );    /* Prototype of function that initialises the run time counter. */
+#define configGENERATE_RUN_TIME_STATS             1
+
+/* Co-routine related configuration options. */
+#define configUSE_CO_ROUTINES                     0
+#define configMAX_CO_ROUTINE_PRIORITIES           ( 2 )
+
+/* This demo can use of one or more example stats formatting functions.  These
+ * format the raw data provided by the uxTaskGetSystemState() function in to human
+ * readable ASCII form.  See the notes in the implementation of vTaskList() within
+ * FreeRTOS/Source/tasks.c for limitations. */
+#define configUSE_STATS_FORMATTING_FUNCTIONS      0
+
+/* Enables the test whereby a stack larger than the total heap size is
+ * requested. */
+#define configSTACK_DEPTH_TYPE                    uint32_t
+
+/* Set the following definitions to 1 to include the API function, or zero
+ * to exclude the API function.  In most cases the linker will remove unused
+ * functions anyway. */
+#define INCLUDE_vTaskPrioritySet                  1
+#define INCLUDE_uxTaskPriorityGet                 1
+#define INCLUDE_vTaskDelete                       1
+#define INCLUDE_vTaskCleanUpResources             0
+#define INCLUDE_vTaskSuspend                      1
+#define INCLUDE_vTaskDelayUntil                   1
+#define INCLUDE_vTaskDelay                        1
+#define INCLUDE_uxTaskGetStackHighWaterMark       1
+#define INCLUDE_uxTaskGetStackHighWaterMark2      1
+#define INCLUDE_xTaskGetSchedulerState            1
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle    1
+#define INCLUDE_xTaskGetIdleTaskHandle            1
+#define INCLUDE_xTaskGetHandle                    1
+#define INCLUDE_eTaskGetState                     1
+#define INCLUDE_xSemaphoreGetMutexHolder          1
+#define INCLUDE_xTimerPendFunctionCall            1
+#define INCLUDE_xTaskAbortDelay                   1
+
+#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO     0
+#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
+    extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
+    #define sbSEND_COMPLETED( pxStreamBuffer )    vGenerateCoreBInterrupt( pxStreamBuffer )
+#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
+
+extern void vAssertCalled( const char * const pcFileName,
+                           unsigned long ulLine );
+
+/* projCOVERAGE_TEST should be defined on the command line so this file can be
+ * used with multiple project configurations.  If it is
+ */
+#ifndef projCOVERAGE_TEST
+    #error projCOVERAGE_TEST should be defined to 1 or 0 on the command line.
+#endif
+
+#ifndef projENABLE_TRACING
+    #error projENABLE_TRACING should be defined to 1 or 0 on the command line.
+#endif
+
+#if ( projCOVERAGE_TEST == 1 )
+
+/* Insert NOPs in empty decision paths to ensure both true and false paths
+ * are being tested. */
+    #define mtCOVERAGE_TEST_MARKER()    __asm volatile ( "NOP" )
+
+/* Ensure the tick count overflows during the coverage test. */
+    #define configINITIAL_TICK_COUNT        0xffffd800UL
+
+/* Allows tests of trying to allocate more than the heap has free. */
+    #define configUSE_MALLOC_FAILED_HOOK    0
+
+/* To test builds that remove the static qualifier for debug builds. */
+    #define portREMOVE_STATIC_QUALIFIER
+#else /* if ( projCOVERAGE_TEST == 1 ) */
+
+/* It is a good idea to define configASSERT() while developing.  configASSERT()
+ * uses the same semantics as the standard C assert() macro.  Don't define
+ * configASSERT() when performing code coverage tests though, as it is not
+ * intended to asserts() to fail, some some code is intended not to run if no
+ * errors are present. */
+    #define configASSERT( x )    if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
+
+    #define configUSE_MALLOC_FAILED_HOOK    1
+
+/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
+    #if( projENABLE_TRACING == 1 )
+        #include "trcRecorder.h"
+    #endif /* if ( projENABLE_TRACING == 1 ) */
+#endif /* if ( projCOVERAGE_TEST == 1 ) */
+
+/* networking definitions */
+#define configMAC_ISR_SIMULATOR_PRIORITY    ( configMAX_PRIORITIES - 1 )
+
+/* Prototype for the function used to print out.  In this case it prints to the
+ * console before the network is connected then a UDP port after the network has
+ * connected. */
+extern void vLoggingPrintf( const char * pcFormatString,
+                            ... );
+
+/* Set to 1 to print out debug messages.  If ipconfigHAS_DEBUG_PRINTF is set to
+ * 1 then FreeRTOS_debug_printf should be defined to the function used to print
+ * out the debugging messages. */
+#define ipconfigHAS_DEBUG_PRINTF    1
+#if ( ipconfigHAS_DEBUG_PRINTF == 1 )
+    #define FreeRTOS_debug_printf( X )    vLoggingPrintf X
+#endif
+
+/* Set to 1 to print out non debugging messages, for example the output of the
+ * FreeRTOS_netstat() command, and ping replies.  If ipconfigHAS_PRINTF is set to 1
+ * then FreeRTOS_printf should be set to the function used to print out the
+ * messages. */
+#define ipconfigHAS_PRINTF    0
+#if ( ipconfigHAS_PRINTF == 1 )
+    #define FreeRTOS_printf( X )    vLoggingPrintf X
+#endif
+#endif /* FREERTOS_CONFIG_H */
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 000000000..6e13256f0
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,8 @@
+module(
+    name = "freertos",
+    version = "11.1.0.bcr.1",
+    compatibility_level = 0,
+)
+
+bazel_dep(name = "platforms", version = "0.0.9")
+bazel_dep(name = "pico-sdk", version = "2.0.0")
diff --git a/host_include/FreeRTOSConfig.h b/host_include/FreeRTOSConfig.h
new file mode 100644
index 000000000..96aa2c1eb
--- /dev/null
+++ b/host_include/FreeRTOSConfig.h
@@ -0,0 +1,206 @@
+/* FreeRTOS V202212.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * 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.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+* Application specific definitions.
+*
+* These definitions should be adjusted for your particular hardware and
+* application requirements.
+*
+* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.  See
+* https://www.FreeRTOS.org/a00110.html
+*----------------------------------------------------------*/
+
+#define configUSE_PREEMPTION                       1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION    0
+#define configUSE_IDLE_HOOK                        1
+#define configUSE_TICK_HOOK                        1
+#define configUSE_DAEMON_TASK_STARTUP_HOOK         1
+#define configTICK_RATE_HZ                         ( 1000 )                  /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
+#define configMINIMAL_STACK_SIZE                   ( ( unsigned short ) PTHREAD_STACK_MIN ) /* The stack size being passed is equal to the minimum stack size needed by pthread_create(). */
+#define configTOTAL_HEAP_SIZE                      ( ( size_t ) ( 65 * 1024 ) )
+#define configMAX_TASK_NAME_LEN                    ( 12 )
+#define configUSE_TRACE_FACILITY                   1
+#define configUSE_16_BIT_TICKS                     0
+#define configIDLE_SHOULD_YIELD                    1
+#define configUSE_MUTEXES                          1
+#define configCHECK_FOR_STACK_OVERFLOW             0
+#define configUSE_RECURSIVE_MUTEXES                1
+#define configQUEUE_REGISTRY_SIZE                  20
+#define configUSE_APPLICATION_TASK_TAG             1
+#define configUSE_COUNTING_SEMAPHORES              1
+#define configUSE_ALTERNATIVE_API                  0
+#define configUSE_QUEUE_SETS                       1
+#define configUSE_TASK_NOTIFICATIONS               1
+
+/* The following 2  memory allocation schemes are possible for this demo:
+ *
+ * 1. Dynamic Only.
+ *    #define configSUPPORT_STATIC_ALLOCATION  0
+ *    #define configSUPPORT_DYNAMIC_ALLOCATION 1
+ *
+ * 2. Static and Dynamic.
+ *    #define configSUPPORT_STATIC_ALLOCATION  1
+ *    #define configSUPPORT_DYNAMIC_ALLOCATION 1
+ *
+ * Static only configuration is not possible for this demo as it utilizes
+ * dynamic allocation.
+ */
+#define configSUPPORT_STATIC_ALLOCATION            1
+#define configSUPPORT_DYNAMIC_ALLOCATION           1
+
+#define configRECORD_STACK_HIGH_ADDRESS            1
+
+/* Software timer related configuration options.  The maximum possible task
+ * priority is configMAX_PRIORITIES - 1.  The priority of the timer task is
+ * deliberately set higher to ensure it is correctly capped back to
+ * configMAX_PRIORITIES - 1. */
+#define configUSE_TIMERS                           1
+#define configTIMER_TASK_PRIORITY                  ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH                   20
+#define configTIMER_TASK_STACK_DEPTH               ( configMINIMAL_STACK_SIZE * 2 )
+
+#define configMAX_PRIORITIES                       ( 7 )
+
+/* Run time stats gathering configuration options. */
+unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
+void vConfigureTimerForRunTimeStats( void );    /* Prototype of function that initialises the run time counter. */
+#define configGENERATE_RUN_TIME_STATS             1
+
+/* Co-routine related configuration options. */
+#define configUSE_CO_ROUTINES                     0
+#define configMAX_CO_ROUTINE_PRIORITIES           ( 2 )
+
+/* This demo can use of one or more example stats formatting functions.  These
+ * format the raw data provided by the uxTaskGetSystemState() function in to human
+ * readable ASCII form.  See the notes in the implementation of vTaskList() within
+ * FreeRTOS/Source/tasks.c for limitations. */
+#define configUSE_STATS_FORMATTING_FUNCTIONS      0
+
+/* Enables the test whereby a stack larger than the total heap size is
+ * requested. */
+#define configSTACK_DEPTH_TYPE                    uint32_t
+
+/* Set the following definitions to 1 to include the API function, or zero
+ * to exclude the API function.  In most cases the linker will remove unused
+ * functions anyway. */
+#define INCLUDE_vTaskPrioritySet                  1
+#define INCLUDE_uxTaskPriorityGet                 1
+#define INCLUDE_vTaskDelete                       1
+#define INCLUDE_vTaskCleanUpResources             0
+#define INCLUDE_vTaskSuspend                      1
+#define INCLUDE_vTaskDelayUntil                   1
+#define INCLUDE_vTaskDelay                        1
+#define INCLUDE_uxTaskGetStackHighWaterMark       1
+#define INCLUDE_uxTaskGetStackHighWaterMark2      1
+#define INCLUDE_xTaskGetSchedulerState            1
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle    1
+#define INCLUDE_xTaskGetIdleTaskHandle            1
+#define INCLUDE_xTaskGetHandle                    1
+#define INCLUDE_eTaskGetState                     1
+#define INCLUDE_xSemaphoreGetMutexHolder          1
+#define INCLUDE_xTimerPendFunctionCall            1
+#define INCLUDE_xTaskAbortDelay                   1
+
+#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO     0
+#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
+    extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
+    #define sbSEND_COMPLETED( pxStreamBuffer )    vGenerateCoreBInterrupt( pxStreamBuffer )
+#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
+
+extern void vAssertCalled( const char * const pcFileName,
+                           unsigned long ulLine );
+
+/* projCOVERAGE_TEST should be defined on the command line so this file can be
+ * used with multiple project configurations.  If it is
+ */
+#ifndef projCOVERAGE_TEST
+    #error projCOVERAGE_TEST should be defined to 1 or 0 on the command line.
+#endif
+
+#ifndef projENABLE_TRACING
+    #error projENABLE_TRACING should be defined to 1 or 0 on the command line.
+#endif
+
+#if ( projCOVERAGE_TEST == 1 )
+
+/* Insert NOPs in empty decision paths to ensure both true and false paths
+ * are being tested. */
+    #define mtCOVERAGE_TEST_MARKER()    __asm volatile ( "NOP" )
+
+/* Ensure the tick count overflows during the coverage test. */
+    #define configINITIAL_TICK_COUNT        0xffffd800UL
+
+/* Allows tests of trying to allocate more than the heap has free. */
+    #define configUSE_MALLOC_FAILED_HOOK    0
+
+/* To test builds that remove the static qualifier for debug builds. */
+    #define portREMOVE_STATIC_QUALIFIER
+#else /* if ( projCOVERAGE_TEST == 1 ) */
+
+/* It is a good idea to define configASSERT() while developing.  configASSERT()
+ * uses the same semantics as the standard C assert() macro.  Don't define
+ * configASSERT() when performing code coverage tests though, as it is not
+ * intended to asserts() to fail, some some code is intended not to run if no
+ * errors are present. */
+    #define configASSERT( x )    if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
+
+    #define configUSE_MALLOC_FAILED_HOOK    1
+
+/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
+    #if( projENABLE_TRACING == 1 )
+        #include "trcRecorder.h"
+    #endif /* if ( projENABLE_TRACING == 1 ) */
+#endif /* if ( projCOVERAGE_TEST == 1 ) */
+
+/* networking definitions */
+#define configMAC_ISR_SIMULATOR_PRIORITY    ( configMAX_PRIORITIES - 1 )
+
+/* Prototype for the function used to print out.  In this case it prints to the
+ * console before the network is connected then a UDP port after the network has
+ * connected. */
+extern void vLoggingPrintf( const char * pcFormatString,
+                            ... );
+
+/* Set to 1 to print out debug messages.  If ipconfigHAS_DEBUG_PRINTF is set to
+ * 1 then FreeRTOS_debug_printf should be defined to the function used to print
+ * out the debugging messages. */
+#define ipconfigHAS_DEBUG_PRINTF    1
+#if ( ipconfigHAS_DEBUG_PRINTF == 1 )
+    #define FreeRTOS_debug_printf( X )    vLoggingPrintf X
+#endif
+
+/* Set to 1 to print out non debugging messages, for example the output of the
+ * FreeRTOS_netstat() command, and ping replies.  If ipconfigHAS_PRINTF is set to 1
+ * then FreeRTOS_printf should be set to the function used to print out the
+ * messages. */
+#define ipconfigHAS_PRINTF    0
+#if ( ipconfigHAS_PRINTF == 1 )
+    #define FreeRTOS_printf( X )    vLoggingPrintf X
+#endif
+#endif /* FREERTOS_CONFIG_H */
diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h
index 79b34f969..980d0fc65 100644
--- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h
+++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h
@@ -203,13 +203,18 @@ extern void vPortEnableInterrupts();
 
 #define portRTOS_SPINLOCK_COUNT    2
 
-/* Note this is a single method with uxAcquire parameter since we have
- * static vars, the method is always called with a compile time constant for
- * uxAcquire, and the compiler should dothe right thing! */
+// In BUILD.bazel, we define a library that disables all the
+// static declarations in tasks.c by defining static as nothing.
+// However, here, we need static to be something, because otherwise
+// this is just inline void vPortRecursiveLock, and that will not link.
+#ifdef static
+#define STATIC_DEFINED
+#undef static
+#endif
+
 static inline void vPortRecursiveLock( uint32_t ulLockNum,
                                        spin_lock_t * pxSpinLock,
-                                       BaseType_t uxAcquire )
-{
+                                       BaseType_t uxAcquire ) {
     static uint8_t ucOwnedByCore[ portMAX_CORE_COUNT ];
     static uint8_t ucRecursionCountByLock[ portRTOS_SPINLOCK_COUNT ];
 
@@ -253,6 +258,10 @@ static inline void vPortRecursiveLock( uint32_t ulLockNum,
     }
 }
 
+#ifdef STATIC_DEFINED
+#define static
+#endif
+
 #if ( configNUMBER_OF_CORES == 1 )
     #define portGET_ISR_LOCK()
     #define portRELEASE_ISR_LOCK()
