Extend qemu virt riscv demo (#774)
* Simple blinky demo working. Not tried full demo yet. * Get the full demo running. * Add Eclipse project to build the RISC-V_RV32_QEMU_VIRT_GCC gcc makefile. * Add regtest tasks to the RISC-V_RV32_QEMU_VIRT_GCC demo. * Update priority of the timer task. * Adjust timer frequency and optimisation level before committing prior to rearranging the Eclipse project. * Reorganise Eclipse project slightly. * Add note to the RISC-V-Qemu-virt_GCC readme file about the updated version in RISC-V_RV32_QEMU_VIRT_GCC. * Update headers in newly added source files so they pass the automated header check. * Update lexicon to pass automated spell check. Co-authored-by: none <>pull/779/head
parent
0744c28749
commit
4629138a42
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
|
||||
#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 configISR_STACK_SIZE_WORDS ( 300 )
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 25000000 )
|
||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 80 * 1024 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 0
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
|
||||
#define configMAX_PRIORITIES ( 9UL )
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
|
||||
/* Timer related defines. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 3 )
|
||||
#define configTIMER_QUEUE_LENGTH 20
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
|
||||
|
||||
/* 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 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
|
||||
/* This demo makes 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 1
|
||||
|
||||
/* The QEMU target is capable of running all the tests tasks at the same
|
||||
* time. */
|
||||
#define configRUN_ADDITIONAL_TESTS 1
|
||||
|
||||
void vAssertCalled( const char *pcFileName, uint32_t ulLine );
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ );
|
||||
|
||||
/* The test that checks the trigger level on stream buffers requires an
|
||||
allowable margin of error on slower processors (slower than the Win32
|
||||
machine on which the test is developed). */
|
||||
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 2
|
||||
|
||||
#define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 5 )
|
||||
#define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 4 )
|
||||
#define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 5 )
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="0.208514950">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.208514950" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration buildProperties="" description="" id="0.208514950" name="Default" optionalBuildProperties="" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.208514950." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1104818234" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1104818234.1571743114" name=""/>
|
||||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1258987068" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1255019096" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.2025884899" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.876141242" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.2088826057" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.707688561" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1095452603" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1783280172" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="RTOSDemo.null.342773888" name="RTOSDemo"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="0.208514950">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Default">
|
||||
<resource resourceType="PROJECT" workspacePath="/RTOSDemo"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
</cproject>
|
@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>RTOSDemo</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>FreeRTOS_kernel</name>
|
||||
<type>2</type>
|
||||
<locationURI>FREERTOS_ROOT/Source</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source</name>
|
||||
<type>2</type>
|
||||
<locationURI>virtual:/virtual</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Blinky_Demo</name>
|
||||
<type>2</type>
|
||||
<locationURI>virtual:/virtual</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/FreeRTOSConfig.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/FreeRTOSConfig.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Full_Demo</name>
|
||||
<type>2</type>
|
||||
<locationURI>virtual:/virtual</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Makefile</name>
|
||||
<type>1</type>
|
||||
<locationURI>PROJECT_LOC/Makefile</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/fake_rom.ld</name>
|
||||
<type>1</type>
|
||||
<locationURI>PROJECT_LOC/fake_rom.ld</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/main.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/main.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/ns16550.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/ns16550.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/ns16550.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/ns16550.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/printf-stdarg.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PROJECT_LOC/printf-stdarg.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/riscv-reg.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/riscv-reg.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/riscv-virt.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/riscv-virt.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/riscv-virt.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/riscv-virt.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/start.S</name>
|
||||
<type>1</type>
|
||||
<locationURI>PROJECT_LOC/start.S</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/startfiles</name>
|
||||
<type>1</type>
|
||||
<locationURI>PROJECT_LOC/startfiles</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Blinky_Demo/main_blinky.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/main_blinky.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Full_Demo/CommonDemoSource</name>
|
||||
<type>2</type>
|
||||
<locationURI>FREERTOS_ROOT/Demo/Common/Minimal</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Full_Demo/RegTest.S</name>
|
||||
<type>1</type>
|
||||
<locationURI>PROJECT_LOC/RegTest.S</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Full_Demo/main_full.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/main_full.c</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1640399877287</id>
|
||||
<name></name>
|
||||
<type>6</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-*</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1640399593493</id>
|
||||
<name>FreeRTOS_kernel/portable</name>
|
||||
<type>9</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-GCC</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1640399593501</id>
|
||||
<name>FreeRTOS_kernel/portable</name>
|
||||
<type>9</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-MemMang</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1640399614171</id>
|
||||
<name>FreeRTOS_kernel/portable/GCC</name>
|
||||
<type>9</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-RISC-V</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
<filter>
|
||||
<id>1640399630077</id>
|
||||
<name>FreeRTOS_kernel/portable/MemMang</name>
|
||||
<type>5</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
<variableList>
|
||||
<variable>
|
||||
<name>FREERTOS_ROOT</name>
|
||||
<value>$%7BPARENT-4-PROJECT_LOC%7D</value>
|
||||
</variable>
|
||||
</variableList>
|
||||
</projectDescription>
|
@ -0,0 +1,140 @@
|
||||
OUTPUT_DIR := ./output
|
||||
IMAGE := RTOSDemo.elf
|
||||
|
||||
# The directory that contains the /source and /demo sub directories.
|
||||
FREERTOS_ROOT = ./../../../..
|
||||
|
||||
CC = riscv64-unknown-elf-gcc
|
||||
LD = riscv64-unknown-elf-gcc
|
||||
SIZE = riscv64-unknown-elf-size
|
||||
MAKE = make
|
||||
|
||||
CFLAGS += $(INCLUDE_DIRS) -DportasmHANDLE_INTERRUPT=handle_trap -fmessage-length=0 \
|
||||
-march=rv32imac -mabi=ilp32 -mcmodel=medlow -ffunction-sections -fdata-sections \
|
||||
--specs=nano.specs -fno-builtin-printf -Wno-unused-parameter -nostartfiles -g3 -Os
|
||||
|
||||
LDFLAGS += -nostartfiles -Xlinker --gc-sections -Wl,-Map,$(OUTPUT_DIR)/RTOSDemo.map \
|
||||
-T./fake_rom.ld -march=rv32imac -mabi=ilp32 -mcmodel=medlow -Xlinker \
|
||||
--defsym=__stack_size=350 -Wl,--start-group -Wl,--end-group -Wl,--wrap=malloc \
|
||||
-Wl,--wrap=free -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=read -Wl,--wrap=write \
|
||||
-Wl,--wrap=fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=link -Wl,--wrap=unlink \
|
||||
-Wl,--wrap=execve -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait \
|
||||
-Wl,--wrap=isatty -Wl,--wrap=times -Wl,--wrap=sbrk -Wl,--wrap=puts -Wl,--wrap=_malloc \
|
||||
-Wl,--wrap=_free -Wl,--wrap=_open -Wl,--wrap=_lseek -Wl,--wrap=_read -Wl,--wrap=_write \
|
||||
-Wl,--wrap=_fstat -Wl,--wrap=_stat -Wl,--wrap=_close -Wl,--wrap=_link -Wl,--wrap=_unlink \
|
||||
-Wl,--wrap=_execve -Wl,--wrap=_fork -Wl,--wrap=_getpid -Wl,--wrap=_kill -Wl,--wrap=_wait \
|
||||
-Wl,--wrap=_isatty -Wl,--wrap=_times -Wl,--wrap=_sbrk -Wl,--wrap=__exit -Wl,--wrap=_puts
|
||||
|
||||
# -Wl,--wrap=_exit
|
||||
#
|
||||
# Kernel build.
|
||||
#
|
||||
KERNEL_DIR = $(FREERTOS_ROOT)/Source
|
||||
KERNEL_PORT_DIR += $(KERNEL_DIR)/portable/GCC/RISC-V
|
||||
INCLUDE_DIRS += -I$(KERNEL_DIR)/include \
|
||||
-I$(KERNEL_PORT_DIR) \
|
||||
-I$(KERNEL_PORT_DIR)/chip_specific_extensions/RV32I_CLINT_no_extensions
|
||||
VPATH += $(KERNEL_DIR) $(KERNEL_PORT_DIR) $(KERNEL_DIR)/portable/MemMang
|
||||
SOURCE_FILES += $(KERNEL_DIR)/tasks.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/list.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/queue.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/timers.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/event_groups.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/stream_buffer.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/portable/MemMang/heap_4.c
|
||||
SOURCE_FILES += $(KERNEL_DIR)/portable/GCC/RISC-V/port.c
|
||||
ASM_SOURCE_FILES += $(KERNEL_DIR)/portable/GCC/RISC-V/portASM.S
|
||||
|
||||
#
|
||||
# Common demo files for the "full" build, as opposed to the "blinky" build -
|
||||
# these files are build by all the FreeRTOS kernel demos.
|
||||
#
|
||||
DEMO_ROOT = $(FREERTOS_ROOT)/Demo
|
||||
COMMON_DEMO_FILES = $(DEMO_ROOT)/Common/Minimal
|
||||
INCLUDE_DIRS += -I$(DEMO_ROOT)/Common/include
|
||||
VPATH += $(COMMON_DEMO_FILES)
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/AbortDelay.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/BlockQ.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/blocktim.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/countsem.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/death.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/dynamic.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/EventGroupsDemo.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/GenQTest.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/integer.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/IntSemTest.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/MessageBufferAMP.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/MessageBufferDemo.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/PollQ.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/QPeek.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/QueueOverwrite.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/QueueSet.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/QueueSetPolling.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/recmutex.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/semtest.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/StaticAllocation.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/StreamBufferDemo.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/StreamBufferInterrupt.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/TaskNotify.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/TaskNotifyArray.c
|
||||
SOURCE_FILES += (COMMON_DEMO_FILES)/TimerDemo.c
|
||||
|
||||
#
|
||||
# Application entry point. main_blinky is self contained. main_full builds
|
||||
# the above common demo (and test) files too.
|
||||
#
|
||||
DEMO_PROJECT = $(DEMO_ROOT)/RISC-V_RV32_QEMU_VIRT_GCC
|
||||
VPATH += $(DEMO_PROJECT)
|
||||
INCLUDE_DIRS += -I$(DEMO_PROJECT)
|
||||
SOURCE_FILES += (DEMO_PROJECT)/main.c
|
||||
SOURCE_FILES += (DEMO_PROJECT)/main_blinky.c
|
||||
SOURCE_FILES += (DEMO_PROJECT)/main_full.c
|
||||
SOURCE_FILES += (DEMO_PROJECT)/ns16550.c
|
||||
SOURCE_FILES += (DEMO_PROJECT)/riscv-virt.c
|
||||
# Lightweight print formatting to use in place of the heavier GCC equivalent.
|
||||
SOURCE_FILES += ./printf-stdarg.c
|
||||
ASM_SOURCE_FILES += ./start.S
|
||||
ASM_SOURCE_FILES += ./RegTest.S
|
||||
|
||||
|
||||
#Create a list of object files with the desired output directory path.
|
||||
OBJS = $(SOURCE_FILES:%.c=%.o) $(ASM_SOURCE_FILES:%.S=%.o)
|
||||
OBJS_NO_PATH = $(notdir $(OBJS))
|
||||
OBJS_OUTPUT = $(OBJS_NO_PATH:%.o=$(OUTPUT_DIR)/%.o)
|
||||
|
||||
#Create a list of dependency files with the desired output directory path.
|
||||
DEP_FILES := $(SOURCE_FILES:%.c=$(OUTPUT_DIR)/%.d) $(ASM_SOURCE_FILES:%.S=$(OUTPUT_DIR)/%.d)
|
||||
DEP_FILES_NO_PATH = $(notdir $(DEP_FILES))
|
||||
DEP_OUTPUT = $(DEP_FILES_NO_PATH:%.d=$(OUTPUT_DIR)/%.d)
|
||||
|
||||
all: $(OUTPUT_DIR)/$(IMAGE)
|
||||
|
||||
%.o : %.c
|
||||
$(OUTPUT_DIR)/%.o : %.c $(OUTPUT_DIR)/%.d Makefile
|
||||
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
|
||||
|
||||
%.o : %.S
|
||||
$(OUTPUT_DIR)/%.o: %.S $(OUTPUT_DIR)/%.d Makefile
|
||||
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
|
||||
|
||||
$(OUTPUT_DIR)/$(IMAGE): $(OBJS_OUTPUT) Makefile
|
||||
@echo ""
|
||||
@echo ""
|
||||
@echo "--- Final linking ---"
|
||||
@echo ""
|
||||
$(LD) $(OBJS_OUTPUT) $(LDFLAGS) -o $(OUTPUT_DIR)/$(IMAGE)
|
||||
$(SIZE) $(OUTPUT_DIR)/$(IMAGE)
|
||||
|
||||
$(DEP_OUTPUT):
|
||||
include $(wildcard $(DEP_OUTPUT))
|
||||
|
||||
clean:
|
||||
rm -f $(OUTPUT_DIR)/$(IMAGE) $(OUTPUT_DIR)/*.o $(OUTPUT_DIR)/*.d $(OUTPUT_DIR)/*.map
|
||||
|
||||
#use "make print-[VARIABLE_NAME] to print the value of a variable generated by
|
||||
#this makefile.
|
||||
print-% : ; @echo $* = $($*)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.connection" value="gdb:localhost:1234#"/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="0"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDeviceId" value="org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.genericDevice"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="riscv64-unknown-elf-gdb"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_VALUE" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./output/RTOSDemo.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RTOSDemo"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/RTOSDemo"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/>
|
||||
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="AbsolutePath" typeId="org.eclipse.cdt.debug.core.containerType.absolutePath"/> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><memoryBlockExpressionList context="reserved-for-future-use"/>"/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
.extern ulRegTest1LoopCounter
|
||||
.extern ulRegTest2LoopCounter
|
||||
|
||||
.global vRegTest1Implementation
|
||||
.global vRegTest2Implementation
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The register check tasks are described in the comments at the top of
|
||||
* main_full.c.
|
||||
*/
|
||||
|
||||
.align( 4 )
|
||||
vRegTest1Implementation:
|
||||
|
||||
/* Fill the core registers with known values. */
|
||||
li x5, 0x5
|
||||
li x6, 0x6
|
||||
li x7, 0x7
|
||||
li x8, 0x8
|
||||
li x9, 0x9
|
||||
li x10, 0xa
|
||||
li x11, 0xb
|
||||
li x12, 0xc
|
||||
li x13, 0xd
|
||||
li x14, 0xe
|
||||
li x15, 0xf
|
||||
li x16, 0x10
|
||||
li x17, 0x11
|
||||
li x18, 0x12
|
||||
li x19, 0x13
|
||||
li x20, 0x14
|
||||
li x21, 0x15
|
||||
li x22, 0x16
|
||||
li x23, 0x17
|
||||
li x24, 0x18
|
||||
li x25, 0x19
|
||||
li x26, 0x1a
|
||||
li x27, 0x1b
|
||||
li x28, 0x1c
|
||||
li x29, 0x1d
|
||||
li x30, 0x1e
|
||||
|
||||
reg1_loop:
|
||||
|
||||
/* Check each register still contains the expected known value.
|
||||
vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation
|
||||
uses x5 as the temporary. */
|
||||
li x31, 0x5
|
||||
bne x31, x5, reg1_error_loop
|
||||
li x31, 0x6
|
||||
bne x31, x6, reg1_error_loop
|
||||
li x31, 0x7
|
||||
bne x31, x7, reg1_error_loop
|
||||
li x31, 0x8
|
||||
bne x31, x8, reg1_error_loop
|
||||
li x31, 0x9
|
||||
bne x31, x9, reg1_error_loop
|
||||
li x31, 0xa
|
||||
bne x31, x10, reg1_error_loop
|
||||
li x31, 0xb
|
||||
bne x31, x11, reg1_error_loop
|
||||
li x31, 0xc
|
||||
bne x31, x12, reg1_error_loop
|
||||
li x31, 0xd
|
||||
bne x31, x13, reg1_error_loop
|
||||
li x31, 0xe
|
||||
bne x31, x14, reg1_error_loop
|
||||
li x31, 0xf
|
||||
bne x31, x15, reg1_error_loop
|
||||
li x31, 0x10
|
||||
bne x31, x16, reg1_error_loop
|
||||
li x31, 0x11
|
||||
bne x31, x17, reg1_error_loop
|
||||
li x31, 0x12
|
||||
bne x31, x18, reg1_error_loop
|
||||
li x31, 0x13
|
||||
bne x31, x19, reg1_error_loop
|
||||
li x31, 0x14
|
||||
bne x31, x20, reg1_error_loop
|
||||
li x31, 0x15
|
||||
bne x31, x21, reg1_error_loop
|
||||
li x31, 0x16
|
||||
bne x31, x22, reg1_error_loop
|
||||
li x31, 0x17
|
||||
bne x31, x23, reg1_error_loop
|
||||
li x31, 0x18
|
||||
bne x31, x24, reg1_error_loop
|
||||
li x31, 0x19
|
||||
bne x31, x25, reg1_error_loop
|
||||
li x31, 0x1a
|
||||
bne x31, x26, reg1_error_loop
|
||||
li x31, 0x1b
|
||||
bne x31, x27, reg1_error_loop
|
||||
li x31, 0x1c
|
||||
bne x31, x28, reg1_error_loop
|
||||
li x31, 0x1d
|
||||
bne x31, x29, reg1_error_loop
|
||||
li x31, 0x1e
|
||||
bne x31, x30, reg1_error_loop
|
||||
|
||||
/* Everything passed, increment the loop counter. */
|
||||
lw x31, ulRegTest1LoopCounterConst
|
||||
lw x30, 0(x31)
|
||||
addi x30, x30, 1
|
||||
sw x30, 0(x31)
|
||||
|
||||
/* Restore clobbered register reading for next loop. */
|
||||
li x30, 0x1e
|
||||
|
||||
/* Yield to increase code coverage. */
|
||||
ecall
|
||||
|
||||
/* Start again. */
|
||||
jal reg1_loop
|
||||
|
||||
reg1_error_loop:
|
||||
/* Jump here if a register contains an uxpected value. This stops the loop
|
||||
counter being incremented so the check task knows an error was found. */
|
||||
ebreak
|
||||
jal reg1_error_loop
|
||||
|
||||
.align( 4 )
|
||||
ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align( 4 )
|
||||
vRegTest2Implementation:
|
||||
|
||||
/* Fill the core registers with known values. */
|
||||
li x6, 0x61
|
||||
li x7, 0x71
|
||||
li x8, 0x81
|
||||
li x9, 0x91
|
||||
li x10, 0xa1
|
||||
li x11, 0xb1
|
||||
li x12, 0xc1
|
||||
li x13, 0xd1
|
||||
li x14, 0xe1
|
||||
li x15, 0xf1
|
||||
li x16, 0x20
|
||||
li x17, 0x21
|
||||
li x18, 0x22
|
||||
li x19, 0x23
|
||||
li x20, 0x24
|
||||
li x21, 0x25
|
||||
li x22, 0x26
|
||||
li x23, 0x27
|
||||
li x24, 0x28
|
||||
li x25, 0x29
|
||||
li x26, 0x2a
|
||||
li x27, 0x2b
|
||||
li x28, 0x2c
|
||||
li x29, 0x2d
|
||||
li x30, 0x2e
|
||||
li x31, 0x2f
|
||||
|
||||
Reg2_loop:
|
||||
|
||||
/* Check each register still contains the expected known value.
|
||||
vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation
|
||||
uses x31 as the temporary. */
|
||||
li x5, 0x61
|
||||
bne x5, x6, reg2_error_loop
|
||||
li x5, 0x71
|
||||
bne x5, x7, reg2_error_loop
|
||||
li x5, 0x81
|
||||
bne x5, x8, reg2_error_loop
|
||||
li x5, 0x91
|
||||
bne x5, x9, reg2_error_loop
|
||||
li x5, 0xa1
|
||||
bne x5, x10, reg2_error_loop
|
||||
li x5, 0xb1
|
||||
bne x5, x11, reg2_error_loop
|
||||
li x5, 0xc1
|
||||
bne x5, x12, reg2_error_loop
|
||||
li x5, 0xd1
|
||||
bne x5, x13, reg2_error_loop
|
||||
li x5, 0xe1
|
||||
bne x5, x14, reg2_error_loop
|
||||
li x5, 0xf1
|
||||
bne x5, x15, reg2_error_loop
|
||||
li x5, 0x20
|
||||
bne x5, x16, reg2_error_loop
|
||||
li x5, 0x21
|
||||
bne x5, x17, reg2_error_loop
|
||||
li x5, 0x22
|
||||
bne x5, x18, reg2_error_loop
|
||||
li x5, 0x23
|
||||
bne x5, x19, reg2_error_loop
|
||||
li x5, 0x24
|
||||
bne x5, x20, reg2_error_loop
|
||||
li x5, 0x25
|
||||
bne x5, x21, reg2_error_loop
|
||||
li x5, 0x26
|
||||
bne x5, x22, reg2_error_loop
|
||||
li x5, 0x27
|
||||
bne x5, x23, reg2_error_loop
|
||||
li x5, 0x28
|
||||
bne x5, x24, reg2_error_loop
|
||||
li x5, 0x29
|
||||
bne x5, x25, reg2_error_loop
|
||||
li x5, 0x2a
|
||||
bne x5, x26, reg2_error_loop
|
||||
li x5, 0x2b
|
||||
bne x5, x27, reg2_error_loop
|
||||
li x5, 0x2c
|
||||
bne x5, x28, reg2_error_loop
|
||||
li x5, 0x2d
|
||||
bne x5, x29, reg2_error_loop
|
||||
li x5, 0x2e
|
||||
bne x5, x30, reg2_error_loop
|
||||
li x5, 0x2f
|
||||
bne x5, x31, reg2_error_loop
|
||||
|
||||
/* Everything passed, increment the loop counter. */
|
||||
lw x5, ulRegTest2LoopCounterConst
|
||||
lw x6, 0(x5)
|
||||
addi x6, x6, 1
|
||||
sw x6, 0(x5)
|
||||
|
||||
/* Restore clobbered register reading for next loop. */
|
||||
li x6, 0x61
|
||||
|
||||
/* Start again. */
|
||||
jal Reg2_loop
|
||||
|
||||
reg2_error_loop:
|
||||
/* Jump here if a register contains an uxpected value. This stops the loop
|
||||
counter being incremented so the check task knows an error was found. */
|
||||
ebreak
|
||||
jal reg2_error_loop
|
||||
|
||||
.align( 4 )
|
||||
ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
File included to ensure the "output" directory is not empty, and can therefore
|
||||
be checked into Git. This prevents the necessity to have a cross platform
|
||||
method of creating the directory from within the makefile.
|
@ -0,0 +1,314 @@
|
||||
/*
|
||||
Copyright 2001, 2002 Georges Menie (www.menie.org)
|
||||
stdarg version contributed by Christian Ettinger
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
putchar is the only external dependency for this file,
|
||||
if you have a working putchar, leave it commented out.
|
||||
If not, uncomment the define below and
|
||||
replace outbyte(c) by your own function call.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "ns16550.h"
|
||||
#include "riscv-virt.h"
|
||||
|
||||
#define putchar(c) vOutNS16550( &dev, c )
|
||||
|
||||
static int tiny_print( char **out, const char *format, va_list args, unsigned int buflen );
|
||||
|
||||
static struct device dev = { NS16550_ADDR };
|
||||
|
||||
static void printchar(char **str, int c, char *buflimit)
|
||||
{
|
||||
if (str) {
|
||||
if( buflimit == ( char * ) 0 ) {
|
||||
/* Limit of buffer not known, write charater to buffer. */
|
||||
**str = (char)c;
|
||||
++(*str);
|
||||
}
|
||||
else if( ( ( unsigned long ) *str ) < ( ( unsigned long ) buflimit ) ) {
|
||||
/* Within known limit of buffer, write character. */
|
||||
**str = (char)c;
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
#define PAD_RIGHT 1
|
||||
#define PAD_ZERO 2
|
||||
|
||||
static int prints(char **out, const char *string, int width, int pad, char *buflimit)
|
||||
{
|
||||
register int pc = 0, padchar = ' ';
|
||||
|
||||
if (width > 0) {
|
||||
register int len = 0;
|
||||
register const char *ptr;
|
||||
for (ptr = string; *ptr; ++ptr) ++len;
|
||||
if (len >= width) width = 0;
|
||||
else width -= len;
|
||||
if (pad & PAD_ZERO) padchar = '0';
|
||||
}
|
||||
if (!(pad & PAD_RIGHT)) {
|
||||
for ( ; width > 0; --width) {
|
||||
printchar (out, padchar, buflimit);
|
||||
++pc;
|
||||
}
|
||||
}
|
||||
for ( ; *string ; ++string) {
|
||||
printchar (out, *string, buflimit);
|
||||
++pc;
|
||||
}
|
||||
for ( ; width > 0; --width) {
|
||||
printchar (out, padchar, buflimit);
|
||||
++pc;
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* the following should be enough for 32 bit int */
|
||||
#define PRINT_BUF_LEN 12
|
||||
|
||||
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase, char *buflimit)
|
||||
{
|
||||
char print_buf[PRINT_BUF_LEN];
|
||||
register char *s;
|
||||
register int t, neg = 0, pc = 0;
|
||||
register unsigned int u = (unsigned int)i;
|
||||
|
||||
if (i == 0) {
|
||||
print_buf[0] = '0';
|
||||
print_buf[1] = '\0';
|
||||
return prints (out, print_buf, width, pad, buflimit);
|
||||
}
|
||||
|
||||
if (sg && b == 10 && i < 0) {
|
||||
neg = 1;
|
||||
u = (unsigned int)-i;
|
||||
}
|
||||
|
||||
s = print_buf + PRINT_BUF_LEN-1;
|
||||
*s = '\0';
|
||||
|
||||
while (u) {
|
||||
t = (unsigned int)u % b;
|
||||
if( t >= 10 )
|
||||
t += letbase - '0' - 10;
|
||||
*--s = (char)(t + '0');
|
||||
u /= b;
|
||||
}
|
||||
|
||||
if (neg) {
|
||||
if( width && (pad & PAD_ZERO) ) {
|
||||
printchar (out, '-', buflimit);
|
||||
++pc;
|
||||
--width;
|
||||
}
|
||||
else {
|
||||
*--s = '-';
|
||||
}
|
||||
}
|
||||
|
||||
return pc + prints (out, s, width, pad, buflimit);
|
||||
}
|
||||
|
||||
static int tiny_print( char **out, const char *format, va_list args, unsigned int buflen )
|
||||
{
|
||||
register int width, pad;
|
||||
register int pc = 0;
|
||||
char scr[2], *buflimit;
|
||||
|
||||
if( buflen == 0 ){
|
||||
buflimit = ( char * ) 0;
|
||||
}
|
||||
else {
|
||||
/* Calculate the last valid buffer space, leaving space for the NULL
|
||||
terminator. */
|
||||
buflimit = ( *out ) + ( buflen - 1 );
|
||||
}
|
||||
|
||||
for (; *format != 0; ++format) {
|
||||
if (*format == '%') {
|
||||
++format;
|
||||
width = pad = 0;
|
||||
if (*format == '\0') break;
|
||||
if (*format == '%') goto out;
|
||||
if (*format == '-') {
|
||||
++format;
|
||||
pad = PAD_RIGHT;
|
||||
}
|
||||
while (*format == '0') {
|
||||
++format;
|
||||
pad |= PAD_ZERO;
|
||||
}
|
||||
for ( ; *format >= '0' && *format <= '9'; ++format) {
|
||||
width *= 10;
|
||||
width += *format - '0';
|
||||
}
|
||||
if( *format == 's' ) {
|
||||
register char *s = (char *)va_arg( args, int );
|
||||
pc += prints (out, s?s:"(null)", width, pad, buflimit);
|
||||
continue;
|
||||
}
|
||||
if( *format == 'd' ) {
|
||||
pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a', buflimit);
|
||||
continue;
|
||||
}
|
||||
if( *format == 'x' ) {
|
||||
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a', buflimit);
|
||||
continue;
|
||||
}
|
||||
if( *format == 'X' ) {
|
||||
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A', buflimit);
|
||||
continue;
|
||||
}
|
||||
if( *format == 'u' ) {
|
||||
pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a', buflimit);
|
||||
continue;
|
||||
}
|
||||
if( *format == 'c' ) {
|
||||
/* char are converted to int then pushed on the stack */
|
||||
scr[0] = (char)va_arg( args, int );
|
||||
scr[1] = '\0';
|
||||
pc += prints (out, scr, width, pad, buflimit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
out:
|
||||
printchar (out, *format, buflimit);
|
||||
++pc;
|
||||
}
|
||||
}
|
||||
if (out) **out = '\0';
|
||||
va_end( args );
|
||||
return pc;
|
||||
}
|
||||
|
||||
int printf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, format );
|
||||
return tiny_print( 0, format, args, 0 );
|
||||
}
|
||||
|
||||
int sprintf(char *out, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, format );
|
||||
return tiny_print( &out, format, args, 0 );
|
||||
}
|
||||
|
||||
|
||||
int snprintf( char *buf, unsigned int count, const char *format, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
( void ) count;
|
||||
|
||||
va_start( args, format );
|
||||
return tiny_print( &buf, format, args, count );
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PRINTF
|
||||
int main(void)
|
||||
{
|
||||
char *ptr = "Hello world!";
|
||||
char *np = 0;
|
||||
int i = 5;
|
||||
unsigned int bs = sizeof(int)*8;
|
||||
int mi;
|
||||
char buf[80];
|
||||
|
||||
mi = (1 << (bs-1)) + 1;
|
||||
printf("%s\n", ptr);
|
||||
printf("printf test\n");
|
||||
printf("%s is null pointer\n", np);
|
||||
printf("%d = 5\n", i);
|
||||
printf("%d = - max int\n", mi);
|
||||
printf("char %c = 'a'\n", 'a');
|
||||
printf("hex %x = ff\n", 0xff);
|
||||
printf("hex %02x = 00\n", 0);
|
||||
printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
|
||||
printf("%d %s(s)%", 0, "message");
|
||||
printf("\n");
|
||||
printf("%d %s(s) with %%\n", 0, "message");
|
||||
sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
|
||||
sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
|
||||
sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
|
||||
sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
|
||||
sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
|
||||
sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
|
||||
sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
|
||||
sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if you compile this file with
|
||||
* gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
|
||||
* you will get a normal warning:
|
||||
* printf.c:214: warning: spurious trailing `%' in format
|
||||
* this line is testing an invalid % at the end of the format string.
|
||||
*
|
||||
* this should display (on 32bit int machine) :
|
||||
*
|
||||
* Hello world!
|
||||
* printf test
|
||||
* (null) is null pointer
|
||||
* 5 = 5
|
||||
* -2147483647 = - max int
|
||||
* char a = 'a'
|
||||
* hex ff = ff
|
||||
* hex 00 = 00
|
||||
* signed -3 = unsigned 4294967293 = hex fffffffd
|
||||
* 0 message(s)
|
||||
* 0 message(s) with %
|
||||
* justif: "left "
|
||||
* justif: " right"
|
||||
* 3: 0003 zero padded
|
||||
* 3: 3 left justif.
|
||||
* 3: 3 right justif.
|
||||
* -3: -003 zero padded
|
||||
* -3: -3 left justif.
|
||||
* -3: -3 right justif.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* To keep linker happy. */
|
||||
int write( int i, char* c, int n)
|
||||
{
|
||||
(void)i;
|
||||
(void)n;
|
||||
(void)c;
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "riscv-virt.h"
|
||||
|
||||
.extern main
|
||||
.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
|
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* See https://www.freertos.org/freertos-on-qemu-mps2-an385-model.html for
|
||||
* instructions.
|
||||
*
|
||||
* 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 constant, 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 FreeRTOS hook functions.
|
||||
*
|
||||
* Running in QEMU:
|
||||
* Use the following commands to start the application running in a way that
|
||||
* enables the debugger to connect, omit the "-s -S" to run the project without
|
||||
* the debugger:
|
||||
*
|
||||
* qemu-system-riscv32 -machine virt -smp 1 -nographic -bios none -serial stdio -kernel [path-to]/RTOSDemo.elf -s -S
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* This project provides two demo applications. A simple blinky style demo
|
||||
application, and a more comprehensive test and demo application. The
|
||||
mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.
|
||||
|
||||
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is 1 then the blinky demo will be built.
|
||||
The blinky demo is implemented and described in main_blinky.c.
|
||||
|
||||
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and
|
||||
demo application will be built. The comprehensive test and demo application is
|
||||
implemented and described in main_full.c. */
|
||||
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
|
||||
|
||||
/* printf() output uses the UART. These constants define the addresses of the
|
||||
required UART registers. */
|
||||
#define UART0_ADDRESS ( 0x40004000UL )
|
||||
#define UART0_DATA ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 0UL ) ) ) )
|
||||
#define UART0_STATE ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 4UL ) ) ) )
|
||||
#define UART0_CTRL ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 8UL ) ) ) )
|
||||
#define UART0_BAUDDIV ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 16UL ) ) ) )
|
||||
#define TX_BUFFER_MASK ( 1UL )
|
||||
|
||||
/* Registers used to initialise the PLIC. */
|
||||
#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) )
|
||||
#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) )
|
||||
#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) )
|
||||
#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) )
|
||||
|
||||
/*
|
||||
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
|
||||
*/
|
||||
extern void main_blinky( void );
|
||||
extern void main_full( void );
|
||||
|
||||
/*
|
||||
* Only the comprehensive demo uses application hook (callback) functions. See
|
||||
* https://www.FreeRTOS.org/a00016.html for more information.
|
||||
*/
|
||||
void vFullDemoTickHookFunction( void );
|
||||
void vFullDemoIdleFunction( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main( void )
|
||||
{
|
||||
/* See https://www.freertos.org/freertos-on-qemu-mps2-an385-model.html for
|
||||
instructions. */
|
||||
|
||||
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
|
||||
of this file. */
|
||||
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
|
||||
{
|
||||
main_blinky();
|
||||
}
|
||||
#else
|
||||
{
|
||||
main_full();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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 using the dynamic allocation (as opposed to
|
||||
static allocation) option. It is also called by various parts of the
|
||||
demo application. If heap_1.c, heap_2.c or heap_4.c is being 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). See http://www.freertos.org/a00111.html for more
|
||||
information. */
|
||||
printf( "\r\n\r\nMalloc failed\r\n" );
|
||||
portDISABLE_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 application tasks make use of the
|
||||
vTaskDelete() API function to delete themselves 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 deleted itself. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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. */
|
||||
printf( "\r\n\r\nStack overflow in %s\r\n", pcTaskName );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationTickHook( void )
|
||||
{
|
||||
/* This function will be called by each tick interrupt if
|
||||
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
|
||||
added here, but the tick hook is called from an interrupt context, so
|
||||
code must not attempt to block, and only the interrupt safe FreeRTOS API
|
||||
functions can be used (those that end in FromISR()). */
|
||||
|
||||
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
|
||||
{
|
||||
extern void vFullDemoTickHookFunction( void );
|
||||
|
||||
vFullDemoTickHookFunction();
|
||||
}
|
||||
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationDaemonTaskStartupHook( void )
|
||||
{
|
||||
/* This function will be called once only, when the daemon task starts to
|
||||
execute (sometimes called the timer task). This is useful if the
|
||||
application includes initialisation code that would benefit from executing
|
||||
after the scheduler has been started. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vAssertCalled( const char *pcFileName, uint32_t ulLine )
|
||||
{
|
||||
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
|
||||
|
||||
/* Called if an assertion passed to configASSERT() fails. See
|
||||
http://www.freertos.org/a00110.html#configASSERT for more information. */
|
||||
|
||||
printf( "ASSERT! Line %d, file %s\r\n", ( int ) ulLine, pcFileName );
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* You can step out of this function to debug the assertion by using
|
||||
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
|
||||
value. */
|
||||
while( ulSetToNonZeroInDebuggerToContinue == 0 )
|
||||
{
|
||||
__asm volatile( "NOP" );
|
||||
__asm volatile( "NOP" );
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
|
||||
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
||||
used by the Idle task. */
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
|
||||
{
|
||||
/* If the buffers to be provided to the Idle task are declared inside this
|
||||
function then they must be declared static - otherwise they will be allocated on
|
||||
the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
||||
state will be stored. */
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Idle task's stack. */
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||
Note that, as the array is necessarily of type StackType_t,
|
||||
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||
application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||
to provide the memory that is used by the Timer service task. */
|
||||
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
|
||||
{
|
||||
/* If the buffers to be provided to the Timer task are declared inside this
|
||||
function then they must be declared static - otherwise they will be allocated on
|
||||
the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xTimerTaskTCB;
|
||||
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
||||
task's state will be stored. */
|
||||
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Timer task's stack. */
|
||||
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
||||
Note that, as the array is necessarily of type StackType_t,
|
||||
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int __write( int iFile, char *pcString, int iStringLength )
|
||||
{
|
||||
int iNextChar;
|
||||
|
||||
/* Avoid compiler warnings about unused parameters. */
|
||||
( void ) iFile;
|
||||
|
||||
/* Output the formatted string to the UART. */
|
||||
for( iNextChar = 0; iNextChar < iStringLength; iNextChar++ )
|
||||
{
|
||||
while( ( UART0_STATE & TX_BUFFER_MASK ) != 0 );
|
||||
UART0_DATA = *pcString;
|
||||
pcString++;
|
||||
}
|
||||
|
||||
return iStringLength;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void *malloc( size_t size )
|
||||
{
|
||||
( void ) size;
|
||||
|
||||
/* This project uses heap_4 so doesn't set up a heap for use by the C
|
||||
library - but something is calling the C library malloc(). See
|
||||
https://freertos.org/a00111.html for more information. */
|
||||
printf( "\r\n\r\nUnexpected call to malloc() - should be usine pvPortMalloc()\r\n" );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* 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 in main.c is used to select
|
||||
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||
* in main.c. This file implements the simply blinky version.
|
||||
*
|
||||
* This file only contains the source code that is specific to the basic demo.
|
||||
* Generic functions, such FreeRTOS hook functions, are defined in main.c.
|
||||
******************************************************************************
|
||||
*
|
||||
* main_blinky() creates one queue, one software timer, and two tasks. It then
|
||||
* starts the scheduler.
|
||||
*
|
||||
* The Queue Send Task:
|
||||
* The queue send task is implemented by the prvQueueSendTask() function in
|
||||
* this file. It uses vTaskDelayUntil() to create a periodic task that sends
|
||||
* the value 100 to the queue every 200 (simulated) milliseconds.
|
||||
*
|
||||
* The Queue Send Software Timer:
|
||||
* The timer is an auto-reload timer with a period of two (simulated) seconds.
|
||||
* Its callback function writes the value 200 to the queue. The callback
|
||||
* function is implemented by prvQueueSendTimerCallback() within this file.
|
||||
*
|
||||
* The Queue Receive Task:
|
||||
* The queue receive task is implemented by the prvQueueReceiveTask() function
|
||||
* in this file. prvQueueReceiveTask() waits for data to arrive on the queue.
|
||||
* When data is received, the task checks the value of the data, then outputs a
|
||||
* message to indicate if the data came from the queue send task or the queue
|
||||
* send software timer.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* Priorities at which the tasks are created. */
|
||||
#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 times are converted from
|
||||
milliseconds to ticks using the pdMS_TO_TICKS() macro. */
|
||||
#define mainTASK_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200UL )
|
||||
#define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL )
|
||||
|
||||
/* The number of items the queue can hold at once. */
|
||||
#define mainQUEUE_LENGTH ( 2 )
|
||||
|
||||
/* The values sent to the queue receive task from the queue send task and the
|
||||
queue send software timer respectively. */
|
||||
#define mainVALUE_SENT_FROM_TASK ( 100UL )
|
||||
#define mainVALUE_SENT_FROM_TIMER ( 200UL )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The tasks as described in the comments at the top of this file.
|
||||
*/
|
||||
static void prvQueueReceiveTask( void *pvParameters );
|
||||
static void prvQueueSendTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* The callback function executed when the software timer expires.
|
||||
*/
|
||||
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The queue used by both tasks. */
|
||||
static QueueHandle_t xQueue = NULL;
|
||||
|
||||
/* A software timer that is started from the tick hook. */
|
||||
static TimerHandle_t xTimer = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/
|
||||
void main_blinky( void )
|
||||
{
|
||||
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
|
||||
|
||||
/* 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, /* The size of the stack to allocate to the task. */
|
||||
NULL, /* The parameter passed to the task - not used in this simple 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, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||
|
||||
/* Create the software timer, but don't start it yet. */
|
||||
xTimer = xTimerCreate( "Timer", /* The text name assigned to the software timer - for debug only as it is not used by the kernel. */
|
||||
xTimerPeriod, /* The period of the software timer in ticks. */
|
||||
pdTRUE, /* xAutoReload is set to pdTRUE, so this is an auto-reload timer. */
|
||||
NULL, /* The timer's ID is not used. */
|
||||
prvQueueSendTimerCallback );/* The function executed when the timer expires. */
|
||||
|
||||
xTimerStart( xTimer, 0 ); /* The scheduler has not started so use a block time of 0. */
|
||||
|
||||
/* 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. NOTE: This demo uses static allocation
|
||||
for the idle and timer tasks so this line should never execute. */
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueSendTask( void *pvParameters )
|
||||
{
|
||||
TickType_t xNextWakeTime;
|
||||
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
|
||||
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
|
||||
|
||||
/* Prevent the compiler warning about the 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.
|
||||
The block time is specified in ticks, pdMS_TO_TICKS() was used to
|
||||
convert a time specified in milliseconds into a time specified in ticks.
|
||||
While in the Blocked state this task will not consume any CPU time. */
|
||||
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
|
||||
|
||||
/* Send to the queue - causing the queue receive task to unblock and
|
||||
write to the console. 0 is used as the block time so the send operation
|
||||
will not block - it shouldn't need to block as the queue should always
|
||||
have at least one space at this point in the code. */
|
||||
xQueueSend( xQueue, &ulValueToSend, 0U );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )
|
||||
{
|
||||
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;
|
||||
|
||||
/* This is the software timer callback function. The software timer has a
|
||||
period of two seconds and is reset each time a key is pressed. This
|
||||
callback function will execute if the timer expires, which will only happen
|
||||
if a key is not pressed for two seconds. */
|
||||
|
||||
/* Avoid compiler warnings resulting from the unused parameter. */
|
||||
( void ) xTimerHandle;
|
||||
|
||||
/* Send to the queue - causing the queue receive task to unblock and
|
||||
write out a message. This function is called from the timer/daemon task, so
|
||||
must not block. Hence the block time is set to 0. */
|
||||
xQueueSend( xQueue, &ulValueToSend, 0U );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueReceiveTask( void *pvParameters )
|
||||
{
|
||||
uint32_t ulReceivedValue;
|
||||
|
||||
/* Prevent the compiler warning about the 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. It will not use any CPU time while it is in the
|
||||
Blocked state. */
|
||||
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||
|
||||
/* To get here something must have been received from the queue, but
|
||||
is it an expected value? */
|
||||
if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )
|
||||
{
|
||||
/* It is normally not good to call printf() from an embedded system,
|
||||
although it is ok in this simulated case. */
|
||||
printf( "Message received from task\r\n" );
|
||||
}
|
||||
else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
|
||||
{
|
||||
printf( "Message received from software timer\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Unexpected message\r\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -0,0 +1,398 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* 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 in main.c is used to select
|
||||
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||
* in main.c. This file implements the comprehensive test and demo version.
|
||||
*
|
||||
* This file only contains the source code that is specific to the full demo.
|
||||
* Generic functions, such FreeRTOS hook functions, are defined in main.c.
|
||||
*******************************************************************************
|
||||
*
|
||||
* main() creates all the demo application tasks, then starts the scheduler.
|
||||
* The web documentation provides more details of the standard demo application
|
||||
* tasks, which provide no particular functionality but do provide a good
|
||||
* example of how to use the FreeRTOS API.
|
||||
*
|
||||
* In addition to the standard demo tasks, the following tasks and tests are
|
||||
* defined and/or created within this file:
|
||||
*
|
||||
* "Check" task - This only executes every five (simulated) seconds. Its main
|
||||
* function is to check the tests running in the standard demo tasks have never
|
||||
* failed and that all the tasks are still running. If that is the case the
|
||||
* check task prints "PASS : nnnn (x)", where nnnn is the current tick count and
|
||||
* x is the number of times the interrupt nesting test executed while interrupts
|
||||
* were nested. If the check task discovers a failed test or a stalled task
|
||||
* it prints a message that indicates which task reported the error or stalled.
|
||||
* Normally the check task would have the highest priority to keep its timing
|
||||
* jitter to a minimum. In this case the check task is run at the idle priority
|
||||
* to ensure other tasks are not stalled by it writing to a slow UART using a
|
||||
* polling driver.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Demo app includes. */
|
||||
#include "death.h"
|
||||
#include "blocktim.h"
|
||||
#include "semtest.h"
|
||||
#include "PollQ.h"
|
||||
#include "GenQTest.h"
|
||||
#include "QPeek.h"
|
||||
#include "recmutex.h"
|
||||
#include "QueueSet.h"
|
||||
#include "EventGroupsDemo.h"
|
||||
#include "MessageBufferDemo.h"
|
||||
#include "StreamBufferDemo.h"
|
||||
#include "AbortDelay.h"
|
||||
#include "countsem.h"
|
||||
#include "dynamic.h"
|
||||
#include "MessageBufferAMP.h"
|
||||
#include "QueueOverwrite.h"
|
||||
#include "QueueSetPolling.h"
|
||||
#include "StaticAllocation.h"
|
||||
#include "TaskNotify.h"
|
||||
#include "TaskNotifyArray.h"
|
||||
#include "TimerDemo.h"
|
||||
#include "StreamBufferInterrupt.h"
|
||||
#include "IntSemTest.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task priorities. */
|
||||
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
|
||||
/* Stack sizes are defined relative to configMINIMAL_STACK_SIZE so they scale
|
||||
across projects that have that constant set differently - in this case the
|
||||
constant is different depending on the compiler in use. */
|
||||
#define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
|
||||
#define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
|
||||
#define mainREG_TEST_STACK_SIZE_WORDS 90
|
||||
|
||||
/* Parameters that are passed into the register check tasks solely for the
|
||||
purpose of ensuring parameters are passed into tasks correctly. */
|
||||
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
|
||||
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Register check tasks as described at the top of this file. The nature of
|
||||
* these files necessitates that they are written in an assembly file, but the
|
||||
* entry points are kept in the C file for the convenience of checking the task
|
||||
* parameter.
|
||||
*/
|
||||
static void prvRegTestTaskEntry1( void *pvParameters );
|
||||
extern void vRegTest1Implementation( void );
|
||||
static void prvRegTestTaskEntry2( void *pvParameters );
|
||||
extern void vRegTest2Implementation( void );
|
||||
|
||||
/* The task that checks the operation of all the other standard demo tasks, as
|
||||
* described at the top of this file. */
|
||||
static void prvCheckTask( void *pvParameters );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The following two variables are used to communicate the status of the
|
||||
register check tasks to the check task. If the variables keep incrementing,
|
||||
then the register check tasks have not discovered any errors. If a variable
|
||||
stops incrementing, then an error has been found. */
|
||||
uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
|
||||
volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter;
|
||||
volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main_full( void )
|
||||
{
|
||||
/* Start the standard demo tasks. */
|
||||
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
|
||||
vStartRecursiveMutexTasks();
|
||||
vCreateBlockTimeTasks();
|
||||
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
||||
vStartQueuePeekTasks();
|
||||
vStartQueueSetTasks();
|
||||
vStartEventGroupTasks();
|
||||
vStartMessageBufferTasks( mainMESSAGE_BUFFER_STACK_SIZE );
|
||||
vStartStreamBufferTasks();
|
||||
vCreateAbortDelayTasks();
|
||||
vStartCountingSemaphoreTasks();
|
||||
vStartDynamicPriorityTasks();
|
||||
vStartMessageBufferAMPTasks( configMINIMAL_STACK_SIZE );
|
||||
vStartQueueOverwriteTask( tskIDLE_PRIORITY );
|
||||
vStartQueueSetPollingTask();
|
||||
vStartStaticallyAllocatedTasks();
|
||||
vStartTaskNotifyTask();
|
||||
vStartTaskNotifyArrayTask();
|
||||
vStartTimerDemoTask( 50 );
|
||||
vStartStreamBufferInterruptDemo();
|
||||
vStartInterruptSemaphoreTasks();
|
||||
|
||||
/* Create the register check tasks, as described at the top of this file.
|
||||
Use xTaskCreateStatic() to create a task using only statically allocated
|
||||
memory. */
|
||||
xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */
|
||||
"Reg1", /* The name of the task. */
|
||||
mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */
|
||||
mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */
|
||||
tskIDLE_PRIORITY, /* Priority of the task. */
|
||||
NULL ); /* Can be used to pass out a handle to the created task. */
|
||||
xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
|
||||
|
||||
/* The suicide tasks must be created last as they need to know how many
|
||||
tasks were running prior to their creation in order to ascertain whether
|
||||
or not the correct/expected number of tasks are running at any given time. */
|
||||
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
|
||||
|
||||
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
|
||||
/* Start the scheduler. */
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If configSUPPORT_STATIC_ALLOCATION was false then execution would only
|
||||
get here if there was insufficient heap memory to create either the idle or
|
||||
timer tasks. As static allocation is used execution should never be able
|
||||
to reach here. */
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvRegTestTaskEntry1( void *pvParameters )
|
||||
{
|
||||
/* Although the regtest task is written in assembler, its entry point is
|
||||
written in C for convenience of checking the task parameter is being passed
|
||||
in correctly. */
|
||||
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
|
||||
{
|
||||
/* Start the part of the test that is written in assembler. */
|
||||
vRegTest1Implementation();
|
||||
}
|
||||
|
||||
/* The following line will only execute if the task parameter is found to
|
||||
be incorrect. The check task will detect that the regtest loop counter is
|
||||
not being incremented and flag an error. */
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvRegTestTaskEntry2( void *pvParameters )
|
||||
{
|
||||
/* Although the regtest task is written in assembler, its entry point is
|
||||
written in C for convenience of checking the task parameter is being passed
|
||||
in correctly. */
|
||||
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
|
||||
{
|
||||
/* Start the part of the test that is written in assembler. */
|
||||
vRegTest2Implementation();
|
||||
}
|
||||
|
||||
/* The following line will only execute if the task parameter is found to
|
||||
be incorrect. The check task will detect that the regtest loop counter is
|
||||
not being incremented and flag an error. */
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* See the comments at the top of this file. */
|
||||
static void prvCheckTask( void *pvParameters )
|
||||
{
|
||||
static const char * pcMessage = "PASS";
|
||||
const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL );
|
||||
TickType_t xPreviousWakeTime;
|
||||
uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
|
||||
|
||||
/* Avoid warning about unused parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
xPreviousWakeTime = xTaskGetTickCount();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
vTaskDelayUntil( &xPreviousWakeTime, xTaskPeriod );
|
||||
|
||||
/* Has an error been found in any task? */
|
||||
if( xAreStreamBufferTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreStreamBufferTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreMessageBufferTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreMessageBufferTasksStillRunning() returned false";
|
||||
}
|
||||
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreGenericQueueTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xIsCreateTaskStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xIsCreateTaskStillRunning() returned false";
|
||||
}
|
||||
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreBlockTimeTestTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreSemaphoreTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xArePollingQueuesStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xArePollingQueuesStillRunning() returned false";
|
||||
}
|
||||
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreQueuePeekTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreRecursiveMutexTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreQueueSetTasksStillRunning() != pdPASS )
|
||||
{
|
||||
pcMessage = "xAreQueueSetTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreEventGroupTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreAbortDelayTestTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreAbortDelayTestTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreCountingSemaphoreTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreDynamicPriorityTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreMessageBufferAMPTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreMessageBufferAMPTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xIsQueueOverwriteTaskStillRunning() returned false";
|
||||
}
|
||||
else if( xAreQueueSetPollTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreQueueSetPollTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreStaticAllocationTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreStaticAllocationTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreTaskNotificationTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreTaskNotificationArrayTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreTaskNotificationArrayTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xAreTimerDemoTasksStillRunning( xTaskPeriod ) != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreTimerDemoTasksStillRunning() returned false";
|
||||
}
|
||||
else if( xIsInterruptStreamBufferDemoStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xIsInterruptStreamBufferDemoStillRunning() returned false";
|
||||
}
|
||||
else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
pcMessage = "xAreInterruptSemaphoreTasksStillRunning() returned false";
|
||||
}
|
||||
else if( ulLastRegTest1Value == ulRegTest1LoopCounter ) /* Check that the register test 1 task is still running. */
|
||||
{
|
||||
pcMessage = "FreeRTOS Demo ERROR: Register test 1.\r\n";
|
||||
}
|
||||
else if( ulLastRegTest2Value == ulRegTest2LoopCounter ) /* Check that the register test 2 task is still running. */
|
||||
{
|
||||
pcMessage = "FreeRTOS Demo ERROR: Register test 2.\r\n";
|
||||
}
|
||||
|
||||
ulLastRegTest1Value = ulRegTest1LoopCounter;
|
||||
ulLastRegTest2Value = ulRegTest2LoopCounter;
|
||||
|
||||
/* It is normally not good to call printf() from an embedded system,
|
||||
although it is ok in this simulated case. */
|
||||
printf( "%s : %d\r\n", pcMessage, (int) xTaskGetTickCount() );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vFullDemoTickHookFunction( void )
|
||||
{
|
||||
/* Write to a queue that is in use as part of the queue set demo to
|
||||
demonstrate using queue sets from an ISR. */
|
||||
vQueueSetAccessQueueSetFromISR();
|
||||
|
||||
/* Call the event group ISR tests. */
|
||||
vPeriodicEventGroupsProcessing();
|
||||
|
||||
/* Exercise stream buffers from interrupts. */
|
||||
vPeriodicStreamBufferProcessing();
|
||||
|
||||
/* Exercise using queue overwrites from interrupts. */
|
||||
vQueueOverwritePeriodicISRDemo();
|
||||
|
||||
/* Exercise using Queue Sets from interrupts. */
|
||||
vQueueSetPollingInterruptAccess();
|
||||
|
||||
/* Exercise using task notifications from interrupts. */
|
||||
xNotifyTaskFromISR();
|
||||
xNotifyArrayTaskFromISR();
|
||||
|
||||
/* Exercise software timers from interrupts. */
|
||||
vTimerPeriodicISRTests();
|
||||
|
||||
/* Exercise stream buffers from interrupts. */
|
||||
vBasicStreamBufferSendFromISR();
|
||||
|
||||
/* Exercise semaphores from interrupts. */
|
||||
vInterruptSemaphorePeriodicTest();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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 );
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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 NS16550_H_
|
||||
#define NS16550_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct device {
|
||||
uintptr_t addr;
|
||||
};
|
||||
|
||||
void vOutNS16550( struct device *dev, unsigned char c );
|
||||
|
||||
#endif /* NS16550_H_ */
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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 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_ */
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
;
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* FreeRTOS V202112.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 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_ */
|
Loading…
Reference in New Issue