diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/FreeRTOSConfig.h new file mode 100644 index 0000000000..a3ff1bfd87 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/FreeRTOSConfig.h @@ -0,0 +1,104 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "riscv-virt.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 */ +#define configMTIME_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIME ) +#define configMTIMECMP_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIMECMP ) + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( 1000000 ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 7 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 512 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) 64500 ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#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 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 6 +#define configTIMER_TASK_STACK_DEPTH ( 110 ) + +/* RISC-V definitions. */ +#define configISR_STACK_SIZE_WORDS 2048 + +/* 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 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Makefile b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Makefile new file mode 100644 index 0000000000..4d806bf498 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Makefile @@ -0,0 +1,70 @@ +CROSS = riscv64-unknown-elf- +CC = $(CROSS)gcc +OBJCOPY = $(CROSS)objcopy +ARCH = $(CROSS)ar + +BUILD_DIR = build +RTOS_SOURCE_DIR = $(abspath ../../Source) +DEMO_SOURCE_DIR = $(abspath ../Common/Minimal) + +CPPFLAGS = \ + -D__riscv_float_abi_soft \ + -DportasmHANDLE_INTERRUPT=handle_trap \ + -I . -I ../Common/include \ + -I $(RTOS_SOURCE_DIR)/include \ + -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V \ + -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions +CFLAGS = -march=rv32ima -mabi=ilp32 -mcmodel=medany \ + -Wall \ + -fmessage-length=0 \ + -ffunction-sections \ + -fdata-sections \ + -fno-builtin-printf +ASFLAGS = -march=rv32ima -mabi=ilp32 -mcmodel=medany +LDFLAGS = -nostartfiles -Tfake_rom.lds \ + -Xlinker --gc-sections \ + -Xlinker --defsym=__stack_size=300 + +ifeq ($(DEBUG), 1) + CFLAGS += -Og -ggdb3 +else + CFLAGS += -O2 +endif + +SRCS = main.c main_blinky.c riscv-virt.c ns16550.c \ + $(DEMO_SOURCE_DIR)/EventGroupsDemo.c \ + $(DEMO_SOURCE_DIR)/TaskNotify.c \ + $(DEMO_SOURCE_DIR)/TimerDemo.c \ + $(DEMO_SOURCE_DIR)/blocktim.c \ + $(DEMO_SOURCE_DIR)/dynamic.c \ + $(DEMO_SOURCE_DIR)/recmutex.c \ + $(RTOS_SOURCE_DIR)/event_groups.c \ + $(RTOS_SOURCE_DIR)/list.c \ + $(RTOS_SOURCE_DIR)/queue.c \ + $(RTOS_SOURCE_DIR)/stream_buffer.c \ + $(RTOS_SOURCE_DIR)/tasks.c \ + $(RTOS_SOURCE_DIR)/timers.c \ + $(RTOS_SOURCE_DIR)/portable/MemMang/heap_4.c \ + $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/port.c + +ASMS = start.S \ + $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/portASM.S + +OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o) $(ASMS:%.S=$(BUILD_DIR)/%.o) +DEPS = $(SRCS:%.c=$(BUILD_DIR)/%.d) $(ASMS:%.S=$(BUILD_DIR)/%.d) + +$(BUILD_DIR)/RTOSDemo.axf: $(OBJS) fake_rom.lds Makefile + $(CC) $(LDFLAGS) $(OBJS) -o $@ + +$(BUILD_DIR)/%.o: %.c Makefile + @mkdir -p $(@D) + $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ + +$(BUILD_DIR)/%.o: %.S Makefile + @mkdir -p $(@D) + $(CC) $(CPPFLAGS) $(ASFLAGS) -MMD -MP -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) + +-include $(DEPS) diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Readme.md b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Readme.md new file mode 100644 index 0000000000..86282ea67b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Readme.md @@ -0,0 +1,104 @@ +# Emulating generic RISC-V 32bit machine on QEMU + +## Requirements + +1. GNU RISC-V toolchains (tested on Crosstool-NG) +1. qemu-riscv32-system (tested on Debian 10 package) +1. Linux OS (tested on Debian 10) + + +## How to build toolchain + +Clone the Crosstool-NG and build. + +``` +$ git clone https://github.com/crosstool-ng/crosstool-ng +$ ./configure --enable-local +$ make + +$ ./ct-ng menuconfig +``` + +Change the following configs: + +``` +CT_EXPERIMENTAL=y +CT_ARCH_RISCV=y +CT_ARCH_64=y +CT_ARCH_ARCH=rv32ima +CT_ARCH_ABI=ilp32 +CT_MULTILIB=y +CT_DEBUG_GDB=y +``` + +Build the GNU toolchain for RISC-V. + +``` +$ ./ct-ng build +``` + +A toolchain is installed at ~/x-tools/riscv64-unknown-elf directory. + + +## How to build + +Add path of toolchain that is described above section. + +``` +$ export PATH=~/x-tools/riscv64-unknown-elf:$PATH +``` + +For release build: + +``` +$ make +``` + +For debug build: + +``` +$ make DEBUG=1 +``` + +If success to build, executable file RTOSDemo.axf in ./build directory. + + +## How to run + +``` +$ qemu-system-riscv32 -nographic -machine virt -net none \ + -chardev stdio,id=con,mux=on -serial chardev:con \ + -mon chardev=con,mode=readline -bios none \ + -smp 4 -kernel ./build/RTOSDemo.axf +``` + + +## How to debug with gdb + +Append -s and -S options to the previous qemu command. + +- -s: enable to attach gdb to QEMU at port 1234 +- -S: start and halted CPU (wait for attach from gdb) + +This is just recommend to use 'debug build' for more efficient debugging. +Run these commands after starting the QEMU with above options: + +``` +$ riscv64-unknown-elf-gdb build/RTOSDemo.axf + +(gdb) target remote localhost:1234 +(gdb) break main +Breakpoint 1 at 0x80000110 + +(gdb) c +Continuing. + +Breakpoint 1, 0x80000110 in main () +``` + + +## Description + +This demo just prints Tx/Rx message of queue to serial port, use no +other hardware and use only primary core (currently hart 0). +Other cores are simply going to wfi state and execute nothing else. diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/fake_rom.lds b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/fake_rom.lds new file mode 100644 index 0000000000..b63fad8f05 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/fake_rom.lds @@ -0,0 +1,117 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY( _start ) + +MEMORY +{ + /* Fake ROM area */ + rom (rxa) : ORIGIN = 0x80000000, LENGTH = 512K + ram (wxa) : ORIGIN = 0x80080000, LENGTH = 512K +} + +SECTIONS +{ + .init : + { + _text = .; + KEEP (*(SORT_NONE(.init))) + } >rom AT>rom + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom AT>rom + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + _etext = .; + } >rom AT>rom + + .rodata.align : + { + . = ALIGN(4); + _rodata = .; + } >rom AT>rom + + .rodata.start : + { + _rodata_lma = LOADADDR(.rodata.start); + } >rom AT>rom + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + + . = ALIGN(4); + _erodata = .; + } >rom AT>rom + + .data.align : + { + . = ALIGN(4); + _data = .; + } >ram AT>rom + + .data.start : + { + _data_lma = LOADADDR(.data.start); + } >ram AT>rom + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2 .sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + + . = ALIGN(4); + _edata = .; + } >ram AT>rom + + .bss.align : + { + . = ALIGN(4); + _bss = .; + } >ram AT>rom + + .bss.start : + { + _bss_lma = LOADADDR(.bss.start); + } >ram AT>rom + + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; + } >ram AT>rom + + . = ALIGN(8); + _end = .; + + .stack : + { + . = ALIGN(16); + . += __stack_size; + _stack_top = .; + } >ram AT>ram +} diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main.c b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main.c new file mode 100644 index 0000000000..ee50cb4b43 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main.c @@ -0,0 +1,117 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +/* FreeRTOS kernel includes. */ +#include +#include + +/* Run a simple demo just prints 'Blink' */ +#define DEMO_BLINKY 1 + +void vApplicationMallocFailedHook( void ); +void vApplicationIdleHook( void ); +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); +void vApplicationTickHook( void ); + +int main_blinky( void ); + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + int ret; + +#if defined(DEMO_BLINKY) + ret = main_blinky(); +#else +#error "Please add or select demo." +#endif + + return ret; +} + +/*-----------------------------------------------------------*/ + +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(); + 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. */ +} +/*-----------------------------------------------------------*/ + +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(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ +} +/*-----------------------------------------------------------*/ + +void vAssertCalled( void ) +{ +volatile uint32_t ulSetTo1ToExitFunction = 0; + + taskDISABLE_INTERRUPTS(); + while( ulSetTo1ToExitFunction != 1 ) + { + __asm volatile( "NOP" ); + } +} diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main_blinky.c b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main_blinky.c new file mode 100644 index 0000000000..e3d9f32422 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main_blinky.c @@ -0,0 +1,160 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +/* FreeRTOS kernel includes. */ +#include +#include +#include + +#include + +#include "riscv-virt.h" +#include "ns16550.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 ) + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static QueueHandle_t xQueue = NULL; + +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +TickType_t xNextWakeTime; +const unsigned long ulValueToSend = 100UL; +const char * const pcMessage1 = "Transfer1"; +const char * const pcMessage2 = "Transfer2"; +int f = 1; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + char buf[40]; + + sprintf( buf, "%d: %s: %s", xGetCoreID(), + pcTaskGetName( xTaskGetCurrentTaskHandle() ), + ( f ) ? pcMessage1 : pcMessage2 ); + vSendString( buf ); + f = !f; + + /* 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. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); + } +} + +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; +const unsigned long ulExpectedValue = 100UL; +const char * const pcMessage1 = "Blink1"; +const char * const pcMessage2 = "Blink2"; +const char * const pcFailMessage = "Unexpected value received\r\n"; +int f = 1; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + for( ;; ) + { + char buf[40]; + + /* 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 ) + { + sprintf( buf, "%d: %s: %s", xGetCoreID(), + pcTaskGetName( xTaskGetCurrentTaskHandle() ), + ( f ) ? pcMessage1 : pcMessage2 ); + vSendString( buf ); + f = !f; + + ulReceivedValue = 0U; + } + else + { + vSendString( pcFailMessage ); + } + } +} + +/*-----------------------------------------------------------*/ + +int main_blinky( void ) +{ + vSendString( "Hello FreeRTOS!" ); + + /* 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, "Rx", configMINIMAL_STACK_SIZE * 2U, NULL, + mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); + xTaskCreate( prvQueueSendTask, "Tx", configMINIMAL_STACK_SIZE * 2U, NULL, + mainQUEUE_SEND_TASK_PRIORITY, NULL ); + } + + vTaskStartScheduler(); + + return 0; +} diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/ns16550.c b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/ns16550.c new file mode 100644 index 0000000000..d195caba29 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/ns16550.c @@ -0,0 +1,75 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#include + +#include "ns16550.h" + +/* register definitions */ +#define REG_RBR 0x00 /* Receiver buffer reg. */ +#define REG_THR 0x00 /* Transmitter holding reg. */ +#define REG_IER 0x01 /* Interrupt enable reg. */ +#define REG_IIR 0x02 /* Interrupt ID reg. */ +#define REG_FCR 0x02 /* FIFO control reg. */ +#define REG_LCR 0x03 /* Line control reg. */ +#define REG_MCR 0x04 /* Modem control reg. */ +#define REG_LSR 0x05 /* Line status reg. */ +#define REG_MSR 0x06 /* Modem status reg. */ +#define REG_SCR 0x07 /* Scratch reg. */ +#define REG_BRDL 0x00 /* Divisor latch (LSB) */ +#define REG_BRDH 0x01 /* Divisor latch (MSB) */ + +/* Line status */ +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun error */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break interrupt */ +#define LSR_THRE 0x20 /* Transmitter holding register empty */ +#define LSR_TEMT 0x40 /* Transmitter empty */ +#define LSR_EIRF 0x80 /* Error in RCVR FIFO */ + +static uint8_t readb( uintptr_t addr ) +{ + return *( (uint8_t *) addr ); +} + +static void writeb( uint8_t b, uintptr_t addr ) +{ + *( (uint8_t *) addr ) = b; +} + +void vOutNS16550( struct device *dev, unsigned char c ) +{ + uintptr_t addr = dev->addr; + + while ( (readb( addr + REG_LSR ) & LSR_THRE) == 0 ) { + /* busy wait */ + } + + writeb( c, addr + REG_THR ); +} diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/ns16550.h b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/ns16550.h new file mode 100644 index 0000000000..8830de2225 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/ns16550.h @@ -0,0 +1,39 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#ifndef NS16550_H_ +#define NS16550_H_ + +#include + +struct device { + uintptr_t addr; +}; + +void vOutNS16550( struct device *dev, unsigned char c ); + +#endif /* NS16550_H_ */ diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-reg.h b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-reg.h new file mode 100644 index 0000000000..c77a9cb9bf --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-reg.h @@ -0,0 +1,43 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#ifndef RISCV_REG_H_ +#define RISCV_REG_H_ + +#if __riscv_xlen == 32 +#define REGSIZE 4 +#define REGSHIFT 2 +#define LOAD lw +#define STOR sw +#elif __riscv_xlen == 64 +#define REGSIZE 8 +#define REGSHIFT 3 +#define LOAD ld +#define STOR sd +#endif /* __riscv_xlen */ + +#endif /* RISCV_REG_H_ */ diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-virt.c b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-virt.c new file mode 100644 index 0000000000..e1f933f9f4 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-virt.c @@ -0,0 +1,65 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#include + +#include + +#include "riscv-virt.h" +#include "ns16550.h" + +int xGetCoreID( void ) +{ +int id; + + __asm ("csrr %0, mhartid" : "=r" ( id ) ); + + return id; +} + +void vSendString( const char *s ) +{ +struct device dev; +size_t i; + + dev.addr = NS16550_ADDR; + + portENTER_CRITICAL(); + + for (i = 0; i < strlen(s); i++) { + vOutNS16550( &dev, s[i] ); + } + vOutNS16550( &dev, '\n' ); + + portEXIT_CRITICAL(); +} + +void handle_trap(void) +{ + while (1) + ; +} diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-virt.h b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-virt.h new file mode 100644 index 0000000000..e52bde7375 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/riscv-virt.h @@ -0,0 +1,55 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#ifndef RISCV_VIRT_H_ +#define RISCV_VIRT_H_ + +#include "riscv-reg.h" + +#ifdef __ASSEMBLER__ +#define CONS(NUM, TYPE)NUM +#else +#define CONS(NUM, TYPE)NUM##TYPE +#endif /* __ASSEMBLER__ */ + +#define PRIM_HART 0 + +#define CLINT_ADDR CONS(0x02000000, UL) +#define CLINT_MSIP CONS(0x0000, UL) +#define CLINT_MTIMECMP CONS(0x4000, UL) +#define CLINT_MTIME CONS(0xbff8, UL) + +#define NS16550_ADDR CONS(0x10000000, UL) + +#ifndef __ASSEMBLER__ + +int xGetCoreID( void ); +void vSendString( const char * s ); + +#endif /* __ASSEMBLER__ */ + +#endif /* RISCV_VIRT_H_ */ diff --git a/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/start.S b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/start.S new file mode 100644 index 0000000000..466933cbcc --- /dev/null +++ b/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/start.S @@ -0,0 +1,85 @@ +/* + * FreeRTOS Kernel V10.4.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. + * + * https://www.FreeRTOS.org + * https://www.github.com/FreeRTOS + * + * 1 tab == 4 spaces! + */ + +#include "riscv-virt.h" + + .section .init + .globl _start + .type _start,@function +_start: + .cfi_startproc + .cfi_undefined ra +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + // Continue primary hart + csrr a0, mhartid + li a1, PRIM_HART + bne a0, a1, secondary + + // Primary hart + la sp, _stack_top + + // Load data section + la a0, _data_lma + la a1, _data + la a2, _edata + bgeu a1, a2, 2f +1: + LOAD t0, (a0) + STOR t0, (a1) + addi a0, a0, REGSIZE + addi a1, a1, REGSIZE + bltu a1, a2, 1b +2: + + // Clear bss section + la a0, _bss + la a1, _ebss + bgeu a0, a1, 2f +1: + STOR zero, (a0) + addi a0, a0, REGSIZE + bltu a0, a1, 1b +2: + + // argc, argv, envp is 0 + li a0, 0 + li a1, 0 + li a2, 0 + jal main +1: + wfi + j 1b + +secondary: + // TODO: Multicore is not supported + wfi + j secondary + .cfi_endproc