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) |