RTOS Demo for RISC-V QEMU sifive_e Model
[RTOS Ports]
This page documents a pre-configured SiFive Freedom Studio project that builds and runs a FreeRTOS RISC-V demo in the sifive_e QEMU
model using GCC and GDB.
IMPORTANT! Notes on using the SiFive RISC-V port
Please read all the following points before using this RTOS port.
- Instructions on using FreeRTOS on RISC-V cores
- Source code organisation
- The demo application functionality
- Building the RTOS demo application
- Running/debugging the RTOS demo in the QEMU emulator
- RTOS configuration and usage details
Also see the FAQ
My application does not run, what could be wrong?.
Instructions on using FreeRTOS on RISC-V cores
If you want to go beyond just running the demo described on this page, or if you want to create your own RISC-V FreeRTOS project,
then please also read the documentation page that provides generic information
on running the FreeRTOS kernel on RISC-V cores.
The FreeRTOS zip file download contains the source code for all the FreeRTOS ports, and every demo application. That means it
contains many more files than are required to use the FreeRTOS sifive_e QEMU RISC-V demo. See the
Source Code Organization page for information on the zip file's directory structure. The sifive_e
RISC-V QEMU Freedom Studio project is located in the /Demo/RISC-V-Qemu-sifive_e-FreedomStudio directory. More information
is provided in the build instructions section below.
On RISC-V architectures the additional
freertos_risc_v_chip_specific_extensions.h header file is used to extend the base RISC-V RTOS port to any chip specific
extensions the target RISC-V chip may implement. The QEMU sive5_e model does not implement any registers over and above those defined
by the base RISC-V architecture, and does emulate a CLINT. Therefore this project uses the freertos_risc_v_chip_specific_extensions.h
header file from the /FreeRTOS/Source/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions directory.
The sifive_e QEMU RISC-V Demo Application
Functionality
The constant mainCREATE_SIMPLE_BLINKY_DEMO_ONLY, which is defined at the top of main.c, is used to switch between
a simple 'blinky' style getting started project and a more comprehensive test and demo application.
When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1
When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 main() calls main_blinky().
main_blinky() creates a basic example that uses two tasks and one queue.
The Queue Send Task:
The queue send task is implemented by the prvQueueSendTask() function. It sits in a loop, sending the value 100
to the queue every 1000 emulated milliseconds (1 emulated second).
The Queue Receive Task:
The queue receive task is implemented by the prvQueueReceiveTask() function. It sits in a loop that blocks on attempts to
read from the queue (no CPU cycles are consumed while the task is blocked). It writes 'blink' to the QEMU console each time
the value 100 is received from the queue send task.
Since the queue send task writes to the queue every 1000 emulated milliseconds, the queue receive task unblocks and writes to
the QEMU console every 1000 emulated milliseconds.
When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0
When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0, main() calls main_full(). main_full() implements
a comprehensive test and demo application that demonstrates and/or tests (among other things):
The created tasks are from the set of standard demo tasks. Standard demo tasks are used by all FreeRTOS
port demo applications. They have no specific functionality, and are created just to demonstrate how to use the FreeRTOS API, and
test the RTOS port.
A 'check' task is created that periodically inspects the standard demo tasks (which contain self monitoring code) to ensure all the
tasks are functioning as expected. The check task outputs a '.' character or error message to the QEMU console each time it executes.
This gives visual feedback of the system health. If the '.' appears on the console every 3 emulated seconds (which may be different
than real seconds), then the check task has not discovered any problems. If the console displays an error message, then the check task
has discovered a problem in one or more tasks.
Building the RTOS demo application
Important note: The project will not build if the directory structure is different to the directory structure used in official
FreeRTOS zip file releases. Ensure the 'copy projects into workspace' check box is not checked when importing
the project into the Eclipse workspace.
To open and build the Freedom Studio RISC-V project:
-
Download and install the Freedom Studio development tools (scroll down to see software downloads).
-
Start Freedom Studio and either select an existing or create a new workspace
when prompted.
-
Select "Import..." from the Freedom Studio 'File' menu. The Import dialog box
will open.
-
In the Import dialog box, select "General->Existing Project into Workspace".
The Import Projects dialog box will open.
Importing an existing project into the workspace
-
In the Import Projects dialog box, navigate to and select the
FreeRTOS/Demo/RISC-V-Qemu-siFive_e-FreedomStudio
directory, and ensure the 'copy projects into workspace'
check box is not checked.
Selecting the directory and project in the Import Projects
dialog box. Click to enlarge.
-
In the 'Projects' window of the Import Projects dialog box, select the RTOSDemo project, and click finish.
-
Set the Cross Compiler toolchain path in the project properties to the location of riscv64-unknown-elf binaries in your installation:
Setting the Cross Compiler toolchain path in the Settings dialog box. Click to enlarge.
-
Select "Build all" from the Freedom Studio 'Project' menu. The project should build
without any errors or warnings, and create a file called RTOSDemo.elf.
-
Download QEMU.
The project was created and tested using the
pre-built Windows binaries.
-
Use the command line below to start QEMU, replacing "path/to"
with the real path to the RTOSDemo.elf output by the following the build
instructions above:
qemu-system-riscv32 -kernel path/to/RTOSDemo.elf -S -s -machine sifive_e
-
Finally, right click the "Hardware_QEMU.launch"
file in the Eclipse project explorer, then select "Debug As->Hardware_QEMU"
from the pop up menu. The debugger should start and connect to QEMU
(assuming the previous step left QEMU running).
Creating a debug launch configuration. Click
to enlarge.
RTOS port specific configuration
This section relates to the information provided on the
Running FreeRTOS on RISC-V Cores
documentation page:
-
Configuration items specific to this demo are contained in FreeRTOS/Demo/RISC-V-Qemu-sifive_e-FreedomStudio/FreeRTOSConfig.h. The
constants defined in that file
can be edited to suit your application. In particular, as the emulated SiFive core includes a machine timer (MTIMER)configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are defined to ( CLINT_CTRL_ADDR ) + 0xBFF8 and ( CLINT_CTRL_ADDR ) + 0x4000 respectively.
-
The emulated SiFive core does not include any registers over and above those defined
by the base RISC-V architecture. The project therefore uses the
freertos_risc_v_chip_specific_extensions.h
header file located in the /FreeRTOS/Source/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions directory,
so that directory is in the assembler's include path.
-
The interrupt handler provided in the SiFive software development kit (SDK)
is called trap_handler, so the assembler's command line options include
-DportasmHANDLE_INTERRUPT=handle_trap.
-
The file flash.lds is a version of the linker
script provided with the development tools, edited to add the __freertos_irq_stack_top
linker variable necessary to ensure the stack that was used by main before
the scheduler starts is reused as the interrupt stack after the scheduler starts.
Other notes:
-
vPortEndScheduler() has not been implemented.
-
Source/Portable/MemMang/heap_4.c is included in the RISC-V project to provide the memory
allocation required by the RTOS kernel.
Please refer to the Memory Management section of the API documentation for
full information.
-
At the time of writing, the demo does not support interrupt nesting.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.