diff --git a/sw/example/demo_freeRTOS_xirq/FreeRTOSConfig.h b/sw/example/demo_freeRTOS_xirq/FreeRTOSConfig.h
new file mode 100644
index 000000000..5526b9fe6
--- /dev/null
+++ b/sw/example/demo_freeRTOS_xirq/FreeRTOSConfig.h
@@ -0,0 +1,157 @@
+/*
+ FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
+
+ ***************************************************************************
+ >>! NOTE: The modification to the GPL is included to allow you to !<<
+ >>! distribute a combined work that includes FreeRTOS without being !<<
+ >>! obliged to provide the source code for proprietary components !<<
+ >>! outside of the FreeRTOS kernel. !<<
+ ***************************************************************************
+
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following
+ link: http://www.freertos.org/a00114.html
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
+ * *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial middleware.
+
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+ engineered and independently SIL3 certified version for use in safety and
+ mission critical applications that require provable dependability.
+
+ 1 tab == 4 spaces!
+*/
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+//#include "clock_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 http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+/* See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
+
+
+/******************************************************************************
+ * Modified for the NEORV32 processor by Stephan Nolting.
+ ******************************************************************************/
+#define configMTIME_BASE_ADDRESS ( 0xFFFFFF90UL )
+#define configMTIMECMP_BASE_ADDRESS ( 0xFFFFFF98UL )
+
+#define configISR_STACK_SIZE_WORDS ( 128 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_IDLE_HOOK 1
+#define configUSE_TICK_HOOK 1
+#define configCPU_CLOCK_HZ 100000000
+#define configTICK_RATE_HZ ( ( TickType_t ) 100 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) /* Can be as low as 60 but some of the demo tasks that use this constant require it to be higher. */
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 7 * 1024 ) )
+#define configMAX_TASK_NAME_LEN ( 16 )
+#define configUSE_TRACE_FACILITY 1
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 0
+#define configUSE_MUTEXES 1
+#define configQUEUE_REGISTRY_SIZE 8
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_MALLOC_FAILED_HOOK 1
+#define configUSE_APPLICATION_TASK_TAG 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configGENERATE_RUN_TIME_STATS 0
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES 4
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH 4
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
+
+/* Task priorities. Allow these to be overridden. */
+#ifndef uartPRIMARY_PRIORITY
+ #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
+#endif
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_eTaskGetState 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 1
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xSemaphoreGetMutexHolder 1
+
+/* Normal assert() semantics without relying on the provision of an assert.h
+header file. */
+#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); }
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/sw/example/demo_freeRTOS_xirq/README.md b/sw/example/demo_freeRTOS_xirq/README.md
new file mode 100644
index 000000000..8b3d3a3cb
--- /dev/null
+++ b/sw/example/demo_freeRTOS_xirq/README.md
@@ -0,0 +1,106 @@
+ # FreeRTOS Demo for the NEORV32 Processor
+
+This example shows how to run [FreeRTOS](https://www.freertos.org/) on the NEORV32 processor while using xirq's. See the comments in `main.c` and the according
+source files for more information.
+
+The chip-specific extensions folder (`chip_specific_extensions/neorv32`) should be in `$(FREERTOS_HOME)/Source/portable/GCC/RISC-V/chip_specific_extensions`,
+but is placed in this source directory for simplicity.
+
+**:information_source: Tested with FreeRTOS version V10.4.4+**
+
+
+## Requirements
+
+* Hardware
+ * DMEM/IMEM requirements depend on the actual application (for example: 16kB DMEM and 16kB IMEM for "blinky_demo")
+ * peripherals: MTIME (machine timer), UART0, GPIO
+
+* Software
+ * NEORV32 software framework
+ * RISC-V gcc
+ * FreeRTOS
+ * application-specific configuration of `FreeRTOSConfig.h` (especially `configCPU_CLOCK_HZ`)
+ * application-specific configuration of the NEORV32 linker script when using non-default IMEM or DMEM configurations (size!)
+
+
+## Instructions
+
+Download FreeRTOS from the [official GitHub repository](https://github.com/FreeRTOS/FreeRTOS) or from the its official homepage.
+
+ $ git clone https://github.com/FreeRTOS/FreeRTOS.git
+
+Open the makefile from this example folder and configure the `FREERTOS_HOME` variable to point to your FreeRTOS home folder.
+
+ FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOS
+
+Compile the NEORV32 executable. Do not forget the `RUN_FREERTOS_DEMO` switch.
+
+ $ make USER_FLAGS+=-DRUN_FREERTOS_DEMO clean_all exe
+
+Note: The *.c sources and the FreeRTOS-specific part of the makefile have (include) guards that test if `RUN_FREERTOS_DEMO` is defined.
+This has no practical usage for the user - it is just a work-around for the NEORV32 CI environment.
+
+Upload the executable (`neorv32_exe.bin`) to the processor via the bootloader and execute it.
+
+```
+CMD:> u
+Awaiting neorv32_exe.bin... OK
+CMD:> e
+Booting...
+
+FreeRTOS V10.4.4+ on NEORV32 Demo
+
+Hello
+ mcause = 0x80000018, Channel = 0
+Hello
+ mcause = 0x80000018, Channel = 1
+ mcause = 0x80000018, Channel = 2
+ mcause = 0x80000018, Channel = 2
+Hello
+Hello
+```
+
+## NEORV32-Specific Interrupts and Exceptions
+
+The `main.c` file provides two "trampolines" for NEORV32-specific interrupts/exceptions:
+
+```c
+/* Handle NEORV32-specific interrupts */
+void freertos_risc_v_application_interrupt_handler(void) {
+
+ // acknowledge XIRQ (FRIST!)
+ NEORV32_XIRQ->EIP = 0; // clear pending interrupt
+ uint32_t irq_channel = NEORV32_XIRQ->ESC; // store the channel before clearing it.
+ NEORV32_XIRQ->ESC = 0; // acknowledge XIRQ interrupt
+
+ // acknowledge/clear ALL pending interrupt sources here - adapt this for your setup
+ neorv32_cpu_csr_write(CSR_MIP, 0);
+
+ // debug output - Use the value from the mcause CSR to call interrupt-specific handlers
+ neorv32_uart0_printf("\n mcause = 0x%x, Channel = %d \n", neorv32_cpu_csr_read(CSR_MCAUSE), irq_channel);
+}
+
+/* Handle NEORV32-specific exceptions */
+void freertos_risc_v_application_exception_handler(void) {
+
+ // debug output
+ neorv32_uart0_printf("\n mcause = 0x%x \n", neorv32_cpu_csr_read(CSR_MCAUSE));
+}
+```
+
+This functions can be used to call specific handlers based on the value from the `mcause` CSR, which indicates
+the actual cause of the interrupt or exception (for example FIRQ channel or illegal instruction).
+
+
+## Notes
+
+The onfiguration of the FreeRTOS home folder (via `FREERTOS_HOME`) is corrupted if the compiler shows the following error:
+
+```
+main.c:36:10: fatal error: FreeRTOS.h: No such file or directory
+ 36 | #include
+ | ^~~~~~~~~~~~
+compilation terminated.
+make: *** [makefile:203: main.c.o] Error 1
+```
+
diff --git a/sw/example/demo_freeRTOS_xirq/chip_specific_extensions/neorv32/freertos_risc_v_chip_specific_extensions.h b/sw/example/demo_freeRTOS_xirq/chip_specific_extensions/neorv32/freertos_risc_v_chip_specific_extensions.h
new file mode 100644
index 000000000..c10f8484b
--- /dev/null
+++ b/sw/example/demo_freeRTOS_xirq/chip_specific_extensions/neorv32/freertos_risc_v_chip_specific_extensions.h
@@ -0,0 +1,72 @@
+/*
+ * FreeRTOS Kernel V10.3.1
+ * 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+/*
+ * The FreeRTOS kernel's RISC-V port is split between the the code that is
+ * common across all currently supported RISC-V chips (implementations of the
+ * RISC-V ISA), and code that tailors the port to a specific RISC-V chip:
+ *
+ * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that
+ * is common to all currently supported RISC-V chips. There is only one
+ * portASM.S file because the same file is built for all RISC-V target chips.
+ *
+ * + Header files called freertos_risc_v_chip_specific_extensions.h contain the
+ * code that tailors the FreeRTOS kernel's RISC-V port to a specific RISC-V
+ * chip. There are multiple freertos_risc_v_chip_specific_extensions.h files
+ * as there are multiple RISC-V chip implementations.
+ *
+ * !!!NOTE!!!
+ * TAKE CARE TO INCLUDE THE CORRECT freertos_risc_v_chip_specific_extensions.h
+ * HEADER FILE FOR THE CHIP IN USE. This is done using the assembler's (not the
+ * compiler's!) include path. For example, if the chip in use includes a core
+ * local interrupter (CLINT) and does not include any chip specific register
+ * extensions then add the path below to the assembler's include path:
+ * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions
+ *
+ */
+
+/*
+ * NEORV32 chip specific extensions
+ */
+
+
+#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__
+#define __FREERTOS_RISC_V_EXTENSIONS_H__
+
+#define portasmHAS_SIFIVE_CLINT 0
+#define portasmHAS_MTIME 1
+#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
+
+.macro portasmSAVE_ADDITIONAL_REGISTERS
+ /* No additional registers to save, so this macro does nothing. */
+ .endm
+
+.macro portasmRESTORE_ADDITIONAL_REGISTERS
+ /* No additional registers to restore, so this macro does nothing. */
+ .endm
+
+#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
diff --git a/sw/example/demo_freeRTOS_xirq/demo/main_demo.c b/sw/example/demo_freeRTOS_xirq/demo/main_demo.c
new file mode 100644
index 000000000..3cc9b0d26
--- /dev/null
+++ b/sw/example/demo_freeRTOS_xirq/demo/main_demo.c
@@ -0,0 +1,163 @@
+/*
+ * FreeRTOS Kernel V10.3.0
+ * 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+/* Standard includes. */
+#include
+#include
+#include
+
+/* Kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Priorities used by the tasks. */
+#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+
+/* The rate at which data is sent to the queue. The 200ms value is converted
+to ticks using the pdMS_TO_TICKS() macro. */
+#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 )
+
+/* The maximum number items the queue can hold. The priority of the receiving
+task is above the priority of the sending task, so the receiving task will
+preempt the sending task and remove the queue items each time the sending task
+writes to the queue. Therefore the queue will never have more than one item in
+it at any time, and even with a queue length of 1, the sending task will never
+find the queue full. */
+#define mainQUEUE_LENGTH ( 1 )
+
+/*-----------------------------------------------------------*/
+
+void main_demo( void );
+
+/*
+ * The tasks as described in the comments at the top of this file.
+ */
+static void prvQueueReceiveTask( void *pvParameters );
+static void prvQueueSendTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used by both tasks. */
+static QueueHandle_t xQueue = NULL;
+
+/*-----------------------------------------------------------*/
+
+void main_demo( void )
+{
+ /* Create the queue. */
+ xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
+
+ if( xQueue != NULL )
+ {
+ /* Start the two tasks as described in the comments at the top of this
+ file. */
+ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
+ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
+ configMINIMAL_STACK_SIZE * 2U, /* The size of the stack to allocate to the task. */
+ NULL, /* The parameter passed to the task - not used in this case. */
+ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
+ NULL ); /* The task handle is not required, so NULL is passed. */
+
+ xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE * 2U, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
+
+ /* Start the tasks and timer running. */
+ vTaskStartScheduler();
+ }
+
+ /* If all is well, the scheduler will now be running, and the following
+ line will never be reached. If the following line does execute, then
+ there was insufficient FreeRTOS heap memory available for the Idle and/or
+ timer tasks to be created. See the memory management section on the
+ FreeRTOS web site for more details on the FreeRTOS heap
+ http://www.freertos.org/a00111.html. */
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueSendTask( void *pvParameters )
+{
+TickType_t xNextWakeTime;
+const unsigned long ulValueToSend = 100UL;
+BaseType_t xReturned;
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ /* Initialise xNextWakeTime - this only needs to be done once. */
+ xNextWakeTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ /* Place this task in the blocked state until it is time to run again. */
+ vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
+
+ /* Send to the queue - causing the queue receive task to unblock and
+ toggle the LED. 0 is used as the block time so the sending operation
+ will not block - it shouldn't need to block as the queue should always
+ be empty at this point in the code. */
+ xReturned = xQueueSend( xQueue, &ulValueToSend, 0U );
+ configASSERT( xReturned == pdPASS );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueReceiveTask( void *pvParameters )
+{
+unsigned long ulReceivedValue;
+const unsigned long ulExpectedValue = 100UL;
+const char * const pcPassMessage = "Hello\r\n";
+const char * const pcFailMessage = "Unexpected value received\r\n";
+extern void vSendString( const char * const pcString );
+extern void vToggleLED( void );
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ for( ;; )
+ {
+ /* Wait until something arrives in the queue - this task will block
+ indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
+ FreeRTOSConfig.h. */
+ xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
+
+ /* To get here something must have been received from the queue, but
+ is it the expected value? If it is, toggle the LED. */
+ if( ulReceivedValue == ulExpectedValue )
+ {
+ vSendString( pcPassMessage );
+ vToggleLED();
+ ulReceivedValue = 0U;
+ }
+ else
+ {
+ vSendString( pcFailMessage );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/sw/example/demo_freeRTOS_xirq/main.c b/sw/example/demo_freeRTOS_xirq/main.c
new file mode 100644
index 000000000..263beeaaf
--- /dev/null
+++ b/sw/example/demo_freeRTOS_xirq/main.c
@@ -0,0 +1,271 @@
+/******************************************************************************
+ * FreeRTOS Kernel V10.4.4
+ * Copyright (C) 2022 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ ******************************************************************************/
+
+
+/******************************************************************************
+ * This project provides two demo applications. A simple blinky style project,
+ * and a more comprehensive test and demo application. The
+ * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
+ * select between the two. The simply blinky demo is implemented and described
+ * in main_blinky.c. The more comprehensive test and demo application is
+ * implemented and described in main_full.c.
+ *
+ * This file implements the code that is not demo specific, including the
+ * hardware setup and standard FreeRTOS hook functions.
+ *
+ * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
+ * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
+ * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ * Modified for the NEORV32 processor by Stephan Nolting.
+ ******************************************************************************/
+
+/* UART hardware constants. */
+#define BAUD_RATE 19200
+
+#ifdef RUN_FREERTOS_DEMO
+
+#include
+
+/* FreeRTOS kernel includes. */
+#include
+#include
+#include
+#include
+
+/* NEORV32 includes. */
+#include
+
+/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
+or 0 to run the more comprehensive test and demo application. */
+#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
+
+/*-----------------------------------------------------------*/
+
+extern void main_demo( void );
+
+extern void freertos_risc_v_trap_handler( void );
+
+/*
+ * Prototypes for the standard FreeRTOS callback/hook functions implemented
+ * within this file. See https://www.freertos.org/a00016.html
+ */
+void vApplicationMallocFailedHook( void );
+void vApplicationIdleHook( void );
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
+void vApplicationTickHook( void );
+
+/* Prepare hardware to run the demo. */
+static void prvSetupHardware( void );
+
+/* System */
+void vToggleLED( void );
+void vSendString( const char * pcString );
+
+/*-----------------------------------------------------------*/
+
+int main( void )
+{
+ prvSetupHardware();
+
+ /* say hi */
+ neorv32_uart0_printf("FreeRTOS %s with XIRQ on NEORV32 Demo\n\n", tskKERNEL_VERSION_NUMBER);
+
+ main_demo();
+
+}
+
+/*-----------------------------------------------------------*/
+
+/* Handle NEORV32-specific interrupts */
+void freertos_risc_v_application_interrupt_handler(void) {
+
+
+ // acknowledge XIRQ (FRIST!)
+ NEORV32_XIRQ->EIP = 0; // clear pending interrupt
+ uint32_t irq_channel = NEORV32_XIRQ->ESC; // store the channel before clearing it.
+ NEORV32_XIRQ->ESC = 0; // acknowledge XIRQ interrupt
+
+ // acknowledge/clear ALL pending interrupt sources here - adapt this for your setup
+ neorv32_cpu_csr_write(CSR_MIP, 0);
+
+ // debug output - Use the value from the mcause CSR to call interrupt-specific handlers
+ neorv32_uart0_printf("\n mcause = 0x%x, Channel = %d \n", neorv32_cpu_csr_read(CSR_MCAUSE), irq_channel);
+}
+
+/* Handle NEORV32-specific exceptions */
+void freertos_risc_v_application_exception_handler(void) {
+
+ // debug output - Use the value from the mcause CSR to call exception-specific handlers
+ neorv32_uart0_printf("\n mcause = 0x%x \n", neorv32_cpu_csr_read(CSR_MCAUSE));
+}
+
+/*-----------------------------------------------------------*/
+
+static void prvSetupHardware( void )
+{
+ // install the freeRTOS trap handler
+ neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&freertos_risc_v_trap_handler);
+
+ // enable XIRQ channels 0, 1 and 2
+ NEORV32_XIRQ->EIP = 0; // clear all pending IRQs
+ NEORV32_XIRQ->ESC = 0; // acknowledge (clear) XIRQ interrupt
+ NEORV32_XIRQ->EIE = 0x00000007UL; // enable channels 0, 1 and 2
+
+ // Enable the FIRQ interrupt in the MSTATUS CSR
+ neorv32_cpu_csr_set(CSR_MSTATUS, 1 << XIRQ_FIRQ_ENABLE);
+
+ // clear GPIO.out port
+ neorv32_gpio_port_set(0);
+
+ // enable xirq interrupts globally.
+ neorv32_xirq_global_enable();
+
+ // setup UART at default baud rate, no interrupts (yet)
+ neorv32_uart0_setup(BAUD_RATE, 0);
+
+ // check clock tick configuration
+ if (NEORV32_SYSINFO->CLK != (uint32_t)configCPU_CLOCK_HZ) {
+ neorv32_uart0_printf("Warning! Incorrect 'configCPU_CLOCK_HZ' configuration!\n"
+ "Is %u Hz but should be %u Hz.\n\n", (uint32_t)configCPU_CLOCK_HZ, NEORV32_SYSINFO->CLK);
+ }
+
+ // check available hardware ISA extensions and compare with compiler flags
+ neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
+
+
+ // enable and configure further NEORV32-specific modules if required
+ // ...
+
+ // enable NEORV32-specific interrupts if required
+ // ...
+}
+
+/*-----------------------------------------------------------*/
+
+void vToggleLED( void )
+{
+ neorv32_gpio_pin_toggle(0);
+}
+
+/*-----------------------------------------------------------*/
+
+void vSendString( const char * pcString )
+{
+ neorv32_uart0_puts( ( const char * ) pcString );
+}
+
+/*-----------------------------------------------------------*/
+
+void vApplicationMallocFailedHook( void )
+{
+ /* vApplicationMallocFailedHook() will only be called if
+ configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
+ function that will get called if a call to pvPortMalloc() fails.
+ pvPortMalloc() is called internally by the kernel whenever a task, queue,
+ timer or semaphore is created. It is also called by various parts of the
+ demo application. If heap_1.c or heap_2.c are used, then the size of the
+ heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
+ FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
+ to query the size of free heap space that remains (although it does not
+ provide information on how the remaining heap might be fragmented). */
+ taskDISABLE_INTERRUPTS();
+ neorv32_uart0_puts("FreeRTOS_FAULT: vApplicationMallocFailedHook (solution: increase 'configTOTAL_HEAP_SIZE' in FreeRTOSConfig.h)\n");
+ __asm volatile( "ebreak" );
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationIdleHook( void )
+{
+ /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
+ to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
+ task. It is essential that code added to this hook function never attempts
+ to block in any way (for example, call xQueueReceive() with a block time
+ specified, or call vTaskDelay()). If the application makes use of the
+ vTaskDelete() API function (as this demo application does) then it is also
+ important that vApplicationIdleHook() is permitted to return to its calling
+ function, because it is the responsibility of the idle task to clean up
+ memory allocated by the kernel to any task that has since been deleted. */
+ neorv32_cpu_sleep();
+}
+
+/*-----------------------------------------------------------*/
+
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
+{
+ ( void ) pcTaskName;
+ ( void ) pxTask;
+
+ /* Run time stack overflow checking is performed if
+ configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
+ function is called if a stack overflow is detected. */
+ taskDISABLE_INTERRUPTS();
+ neorv32_uart0_puts("FreeRTOS_FAULT: vApplicationStackOverflowHook\n");
+ __asm volatile( "ebreak" );
+ for( ;; );
+}
+
+/*-----------------------------------------------------------*/
+
+void vApplicationTickHook( void )
+{
+ /* The tests in the full demo expect some interaction with interrupts. */
+#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
+ {
+ extern void vFullDemoTickHook( void );
+ vFullDemoTickHook();
+ }
+#endif
+}
+
+/*-----------------------------------------------------------*/
+
+/* This handler is responsible for handling all interrupts. Only the machine timer interrupt is handled by the kernel. */
+void SystemIrqHandler( uint32_t mcause )
+{
+ neorv32_uart0_printf("freeRTOS: Unknown interrupt (0x%x)\n", mcause);
+}
+
+
+// ---------- Primitive main in case this demo is not enabled (i.e. RUN_FREERTOS_DEMO is not defined) ----------
+#else
+ #warning FREERTOS DEMO HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_FREERTOS_DEMO clean_all exe<< to compile it.
+
+#include
+int main() {
+
+ // setup UART at default baud rate, no interrupts
+ neorv32_uart0_setup(BAUD_RATE, 0);
+ neorv32_uart0_puts("ERROR! FreeRTOS has not been compiled. Use >>make USER_FLAGS+=-DRUN_FREERTOS_DEMO clean_all exe<< to compile it.\n");
+ return 1;
+}
+#endif
diff --git a/sw/example/demo_freeRTOS_xirq/makefile b/sw/example/demo_freeRTOS_xirq/makefile
new file mode 100644
index 000000000..e747dc500
--- /dev/null
+++ b/sw/example/demo_freeRTOS_xirq/makefile
@@ -0,0 +1,71 @@
+# *****************************************************************************
+# USER CONFIGURATION
+# *****************************************************************************
+# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
+APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
+
+# User's application include folders (don't forget the '-I' before each entry)
+APP_INC ?= -I .
+# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
+ASM_INC ?= -I .
+
+# Optimization
+EFFORT ?= -Os
+
+# CPU architecture and ABI
+MARCH ?= rv32i
+MABI ?= ilp32
+
+# User flags for additional configuration (will be added to compiler flags)
+USER_FLAGS ?=
+# *****************************************************************************
+
+
+# -----------------------------------------------------------------------------
+# FreeRTOS
+# -----------------------------------------------------------------------------
+ifneq (,$(findstring RUN_FREERTOS_DEMO,$(USER_FLAGS)))
+# FreeRTOS home folder (adapt this!)
+FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOS
+
+# FreeRTOS RISC-V specific
+APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V/*.c)
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S
+
+APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V
+
+# FreeRTOS core
+APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/*.c)
+APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/portable/MemMang/heap_4.c)
+
+APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Source/include
+
+# FreeRTOS sources for the full_demo
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/blocktim.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/dynamic.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/GenQTest.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/recmutex.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TaskNotify.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c
+APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TimerDemo.c
+
+APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Demo/Common/include
+
+# NEORV32 specific
+ASM_INC += -DportasmHANDLE_INTERRUPT=SystemIrqHandler
+
+APP_INC += -I chip_specific_extensions/neorv32
+
+ASM_INC += -I chip_specific_extensions/neorv32
+
+# Demo application
+APP_SRC += demo/main_demo.c
+endif
+
+
+
+# Modify this variable to fit your NEORV32 setup (neorv32 home folder)
+NEORV32_HOME ?= ../../..
+
+include $(NEORV32_HOME)/sw/common/common.mk