OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/sw/example/demo_freeRTOS
    from Rev 34 to Rev 36
    Reverse comparison

Rev 34 → Rev 36

/full_demo/RegTest.s
0,0 → 1,266
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
 
.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
 
 
/full_demo/main_full.c
0,0 → 1,328
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
 
/******************************************************************************
* NOTE 1: 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.
*
* NOTE 2: This file only contains the source code that is specific to the
* full demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware, are defined in main.c.
*
******************************************************************************
*
* main_full() creates all the demo application tasks and software timers, 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:
*
* "Reg test" tasks - These fill both the core registers with known values, then
* check that each register maintains its expected value for the lifetime of the
* task. Each task uses a different set of values. The reg test tasks execute
* with a very low priority, so get preempted very frequently. A register
* containing an unexpected value is indicative of an error in the context
* switching mechanism.
*
* "Check" task - The check executes every three seconds. It checks that all
* the standard demo tasks, and the register check tasks, are not only still
* executing, but are executing without reporting any errors. The check task
* toggles the LED every three seconds if all the standard demo tasks are
* executing as expected, or every 500ms if a potential error is discovered in
* any task.
*/
 
/* Standard includes. */
#include <string.h>
#include <unistd.h>
 
/* NEORV32*/
#include <neorv32.h>
 
/* Kernel includes. */
#include <FreeRTOS.h>
#include <task.h>
#include <timers.h>
#include <semphr.h>
 
/* Standard demo application includes. */
#include <dynamic.h>
#include <blocktim.h>
#include <GenQTest.h>
#include <TimerDemo.h>
#include <TaskNotify.h>
 
/* Priorities for the demo application tasks. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
 
/* The period of the check task, in ms, converted to ticks using the
pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have
been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 2000UL )
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 100UL )
 
/* 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 )
 
/* The base period used by the timer test tasks. */
#define mainTIMER_TEST_PERIOD ( 50 )
 
/* The size of the stack allocated to the check task (as described in the
comments at the top of this file. */
#define mainCHECK_TASK_STACK_SIZE_WORDS 160
 
/* Size of the stacks to allocated for the register check tasks. */
#define mainREG_TEST_STACK_SIZE_WORDS 90
 
/*-----------------------------------------------------------*/
 
/*
* Called by main() to run the full demo (as opposed to the blinky demo) when
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/
void main_full( void );
 
/*
* The check task, as described at the top of this file.
*/
static void prvCheckTask( void *pvParameters );
 
/*
* 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 );
 
/*
* IO
*/
extern void vSendString( const char * pcString );
extern void vToggleLED( void );
 
/*
* Tick hook used by the full demo, which includes code that interacts with
* some of the tests.
*/
void vFullDemoTickHook( void );
 
/*-----------------------------------------------------------*/
 
/* 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 )
{
 
vSendString("FreeRTOS: Creating tasks...\n");
 
/* Start all the other standard demo/test tasks. They have no particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
 
vSendString("FreeRTOS: Starting <vStartDynamicPriorityTasks>...\n");
vStartDynamicPriorityTasks();
 
vSendString("FreeRTOS: Starting <vStartGenericQueueTasks>...\n");
vStartGenericQueueTasks( tskIDLE_PRIORITY );
 
vSendString("FreeRTOS: Starting <vStartTimerDemoTask>...\n");
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
 
vSendString("FreeRTOS: Starting <vStartTaskNotifyTask>...\n");
vStartTaskNotifyTask();
 
 
/* Create the register check tasks, as described at the top of this file.
Use xTaskCreateStatic() to create a task using only statically allocated
memory. */
vSendString("FreeRTOS: Creating tasks <prvRegTestTaskEntry1>...\n");
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. */
vSendString("FreeRTOS: Creating tasks <prvRegTestTaskEntry2>...\n");
xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
 
/* Create the task that performs the 'check' functionality, as described at
the top of this file. */
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL );
 
 
/* Start the scheduler. */
vSendString("\nFreeRTOS: Starting scheduler...\n\n");
vTaskStartScheduler();
 
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the Idle and/or
timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details on the FreeRTOS heap
http://www.freertos.org/a00111.html. */
for( ;; );
}
/*-----------------------------------------------------------*/
 
static void prvCheckTask( void *pvParameters )
{
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime;
uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
char * const pcPassMessage = ".";
char * pcStatusMessage = pcPassMessage;
 
/* Just to stop compiler warnings. */
( void ) pvParameters;
 
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
xLastExecutionTime = xTaskGetTickCount();
 
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration.
If an error is detected then the delay period is decreased from
mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
effect of increasing the rate at which the onboard LED toggles, and in so
doing gives visual feedback of the system status. */
for( ;; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
 
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Dynamic priority demo/tests.\n";
}
 
if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE )
{
pcStatusMessage = "ERROR: Timer demo/tests.\n";
}
 
if( xAreGenericQueueTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Generic queue demo/tests.\n";
}
 
if( xAreTaskNotificationTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Task notification demo/tests.\n";
}
 
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
pcStatusMessage = "ERROR: Register test 1.\n";
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
 
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
pcStatusMessage = "ERROR: Register test 2.\n";
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
 
/* Write the status message to the UART. */
vSendString( pcStatusMessage );
 
/* Toggle the LED to show the system status */
vToggleLED();
 
/* If an error has been found then increase the LED toggle rate by
increasing the cycle frequency. */
if( pcStatusMessage != pcPassMessage )
{
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
}
}
}
/*-----------------------------------------------------------*/
 
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 );
}
/*-----------------------------------------------------------*/
 
void vFullDemoTickHook( void )
{
/* Called from vApplicationTickHook() when the project is configured to
build the full test/demo applications. */
 
/* Use task notifications from an interrupt. */
xNotifyTaskFromISR();
}
/FreeRTOSConfig.h
97,10 → 97,11
#define configCPU_CLOCK_HZ 100000000
#define configTICK_RATE_HZ ( ( TickType_t ) 100 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 200 ) /* Can be as low as 60 but some of the demo tasks that use this constant require it to be higher. */
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) /* Can be as low as 60 but some of the demo tasks that use this constant require it to be higher. */
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 7 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_MUTEXES 1
111,6 → 112,8
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 4
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
 
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
142,15 → 145,8
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
 
// get runtime stats
#define configGENERATE_RUN_TIME_STATS 0
 
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); }
 
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configKERNEL_INTERRUPT_PRIORITY 7
 
 
#endif /* FREERTOS_CONFIG_H */
/README.md
1,7 → 1,8
# FreeRTOS Demo for the NEORV32 Processor
# FreeRTOS Demo for the NEORV32 Processor
 
This is simple example shows the usage of [FreeRTOS](https://www.freertos.org/) on the NEORV32 processor. It uses the default *blink*
demo application (`blinky_demo/main_blinky.c`). See the comments in that source file for more information.
This example shows how to run [FreeRTOS](https://www.freertos.org/) on the NEORV32 processor. It features the default
"blinky_demo" and the more sophisticated "full_demo" demo applications. See the comments in `main.c` and the according
source files for more information.
 
The chip-specific extensions folder (`chip_specific_extensions/neorv32`) should be in `$(FREERTOS_HOME)/Source/portable/GCC/RISC-V/chip_specific_extensions`,
but is placed in this source directory for simplicity.
9,20 → 10,20
 
## Hardware Requirements
 
* 8kB DMEM and 16kB IMEM
* MTIME (machine timer)
* DMEM/IMEM requriements depend on the actual application (for example: 8kB DMEM and 16kB IMEM for *blinky_demo*)
* MTIME (machine timer) + UART + GPIO
* `Zicsr` CPU extension
 
 
## Instructions
 
Download FreeRTOS from the [official GitHub repository](https://github.com/FreeRTOS/FreeRTOS).
Download FreeRTOS from the [official GitHub repository](https://github.com/FreeRTOS/FreeRTOS) or from the its official homepage.
 
$ git clone https://github.com/FreeRTOS/FreeRTOS.git
 
Open the makefile from this example folder and configure the `FREERTOS_HOME` variable to point to the `FreeRTOS/FreeRTOS` home folder.
Open the makefile from this example folder and configure the `FREERTOS_HOME` variable to point to your FreeRTOS home folder.
 
FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOS/FreeRTOS
FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOSv10.4.1
 
Compile the NEORV32 executable. Do not forget the `RUN_FREERTOS_DEMO` switch.
 
38,15 → 39,26
CMD:> e
Booting...
 
FreeRTOS V10.3.1
FreeRTOS V10.4.1
Blink
Blink
Blink
```
 
## FreeRTOS Plus
 
## Note
To automatically add source and include files from FreeRTOS plus extensions add one (or more) of the following arguments when invoking `make`:
 
* FreeRTOS-Plus-CLI: `USER_FLAGS+=-FREERTOS_PLUS_CLI`
* FreeRTOS-Plus-TCP: `USER_FLAGS+=-FREERTOS_PLUS_TCP`
 
Example:
 
$ make USER_FLAGS+=-DRUN_FREERTOS_DEMO USER_FLAGS+=-FREERTOS_PLUS_TCP clean_all exe
 
 
## Notes
 
The onfiguration of the FreeRTOS home folder (via `FREERTOS_HOME`) is corrupted if the compiler shows the following error:
 
```
/main.c
25,6 → 25,23
* 1 tab == 4 spaces!
*/
 
/******************************************************************************
* This project provides two demo applications. A simple blinky style project,
* and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
* select between the two. The simply blinky demo is implemented and described
* in main_blinky.c. The more comprehensive test and demo application is
* implemented and described in main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and standard FreeRTOS hook functions.
*
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
*
*/
 
/*
* Modified for the NEORV32 processor by Stephan Nolting.
*/
31,40 → 48,45
 
#ifdef RUN_FREERTOS_DEMO
 
#include <stdint.h>
 
/* FreeRTOS kernel includes. */
#include <FreeRTOS.h>
#include <semphr.h>
#include <queue.h>
#include <task.h>
 
/* NEORV32 includes. */
#include <neorv32.h>
 
/* misc */
//#include "driver_wrapper/uart_serial.h"
 
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
 
/* UART hardware constants. */
#define BAUD_RATE 19200
 
/*-----------------------------------------------------------*/
 
/******************************************************************************
* This project provides two demo applications. A simple blinky style project,
* and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
* select between the two. The simply blinky demo is implemented and described
* in main_blinky.c. The more comprehensive test and demo application is
* implemented and described in main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and standard FreeRTOS hook functions.
*
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
*
/*
* 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.
*/
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
extern void main_blinky( void );
#else
extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
 
extern void main_blinky( void );
extern void freertos_risc_v_trap_handler( void );
 
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. See https://www.freertos.org/a00016.html */
/*
* Prototypes for the standard FreeRTOS callback/hook functions implemented
* within this file. See https://www.freertos.org/a00016.html
*/
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
73,8 → 95,9
/* Prepare hardware to run the demo. */
static void prvSetupHardware( void );
 
/* Send a message to the UART initialised in prvSetupHardware. */
void vSendString( const char * const pcString );
/* System */
void vToggleLED( void );
void vSendString( const char * pcString );
 
/*-----------------------------------------------------------*/
 
82,9 → 105,16
{
prvSetupHardware();
 
neorv32_uart_printf("FreeRTOS %s\n", tskKERNEL_VERSION_NUMBER);
/* say hi */
neorv32_uart_printf("FreeRTOS %s on NEORV32 Demo\n\n", tskKERNEL_VERSION_NUMBER);
 
main_blinky();
/* 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
}
 
/*-----------------------------------------------------------*/
94,6 → 124,9
// configure trap handler entry point
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)&freertos_risc_v_trap_handler);
 
// clear GPIO.out port
neorv32_gpio_port_set(0);
 
// configure UART for default baud rate, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0, 0);
}
107,9 → 140,9
 
/*-----------------------------------------------------------*/
 
void vSendString( const char * const pcString )
void vSendString( const char * pcString )
{
neorv32_uart_print( (char *)pcString );
neorv32_uart_print( ( const char * ) pcString );
}
 
/*-----------------------------------------------------------*/
127,7 → 160,7
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
neorv32_uart_print("FreeRTOS_FAULT: vApplicationMallocFailedHook\n");
neorv32_uart_print("FreeRTOS_FAULT: vApplicationMallocFailedHook (solution: increase 'configTOTAL_HEAP_SIZE' in FreeRTOSConfig.h)\n");
__asm volatile( "ebreak" );
for( ;; );
}
167,7 → 200,13
 
void vApplicationTickHook( void )
{
 
/* The tests in the full demo expect some interaction with interrupts. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
{
extern void vFullDemoTickHook( void );
vFullDemoTickHook();
}
#endif
}
 
/*-----------------------------------------------------------*/
/makefile
73,22 → 73,31
# -----------------------------------------------------------------------------
ifneq (,$(findstring RUN_FREERTOS_DEMO,$(USER_FLAGS)))
# FreeRTOS home folder (adapt this!)
FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOS/FreeRTOS
FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOSv10.4.1
 
# Application
APP_SRC += blinky_demo/main_blinky.c
# FreeRTOS RISC-V specific
APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V/*.c)
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S
 
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V
 
# FreeRTOS core
APP_SRC += $(wildcard $(FREERTOS_HOME)/Source/*.c)
APP_SRC += $(wildcard $(FREERTOS_HOME)/Source/portable/MemMang/heap_1.c)
APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/*.c)
APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/portable/MemMang/heap_4.c)
 
APP_INC += -I $(FREERTOS_HOME)/Source/include
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Source/include
 
# FreeRTOS RISC-V specific
APP_SRC += $(wildcard $(FREERTOS_HOME)/Source/portable/GCC/RISC-V/*.c)
APP_SRC += $(FREERTOS_HOME)/Source/portable/GCC/RISC-V/portASM.S
# FreeRTOS sources for the full_demo
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/blocktim.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/dynamic.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/GenQTest.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/recmutex.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TaskNotify.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TimerDemo.c
 
APP_INC += -I $(FREERTOS_HOME)/Source/portable/GCC/RISC-V
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Demo/Common/include
 
# NEORV32 specific
ASM_INC += -DportasmHANDLE_INTERRUPT=SystemIrqHandler
96,10 → 105,42
APP_INC += -I chip_specific_extensions/neorv32
 
ASM_INC += -I chip_specific_extensions/neorv32
 
# Demo application
APP_SRC += blinky_demo/main_blinky.c
APP_SRC += full_demo/main_full.c
APP_SRC += full_demo/RegTest.s
endif
 
# -----------------
# FreeRTOS-Plus-CLI
# -----------------
ifneq (,$(findstring FREERTOS_PLUS_CLI,$(USER_FLAGS)))
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c
 
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI
endif
 
# -----------------
# FreeRTOS-Plus-TCP
# -----------------
ifneq (,$(findstring FREERTOS_PLUS_TCP,$(USER_FLAGS)))
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
 
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC
endif
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
219,7 → 260,7
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -D -S -z $< > $@
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.