mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-15 10:58:54 +00:00
v1.0.3
This commit is contained in:
@@ -12,5 +12,40 @@ config DRIVER_BARE_DRV_EN
|
||||
bool
|
||||
default y
|
||||
|
||||
if ! AIC_BOOTLOADER
|
||||
config AIC_BAREMETAL_CONSOLE_UART
|
||||
int "Baremetal console UART ID"
|
||||
range 0 8
|
||||
default 0
|
||||
endif
|
||||
|
||||
config ARCH_RISCV
|
||||
bool
|
||||
|
||||
config ARCH_RISCV_FPU
|
||||
bool
|
||||
|
||||
config ARCH_RISCV_FPU_S
|
||||
select ARCH_RISCV_FPU
|
||||
bool
|
||||
|
||||
config ARCH_RISCV_FPU_D
|
||||
select ARCH_RISCV_FPU
|
||||
bool
|
||||
|
||||
config ARCH_RISCV32
|
||||
select ARCH_RISCV
|
||||
bool
|
||||
|
||||
config ARCH_RISCV64
|
||||
select ARCH_RISCV
|
||||
select ARCH_CPU_64BIT
|
||||
bool
|
||||
|
||||
config ARCH_CSKY
|
||||
bool
|
||||
|
||||
source "kernel/freertos/Kconfig.kernel"
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
298
kernel/freertos/Kconfig.kernel
Normal file
298
kernel/freertos/Kconfig.kernel
Normal file
@@ -0,0 +1,298 @@
|
||||
menu "FreeRTOS Kernel"
|
||||
|
||||
menu "Tasks"
|
||||
|
||||
config FREERTOS_PREEMPTIVE_EN
|
||||
bool "Enable Preemptive"
|
||||
default y
|
||||
|
||||
config FREERTOS_TICK_RATE_HZ
|
||||
int "Frequency of the RTOS tick interrupt (Hz)"
|
||||
default 500
|
||||
---help---
|
||||
The tick interrupt is used to measure time. Therefore a higher tick frequency means time can
|
||||
be measured to a higher resolution. However, a high tick frequency also means that the RTOS
|
||||
kernel will use more CPU time so be less efficient. The RTOS demo applications all use a tick
|
||||
rate of 1000Hz. This is used to test the RTOS kernel and is higher than would normally be
|
||||
required.
|
||||
More than one task can share the same priority. The RTOS scheduler will share processor time
|
||||
between tasks of the same priority by switching between the tasks during each RTOS tick. A high
|
||||
tick rate frequency will therefore also have the effect of reducing the 'time slice' given to
|
||||
each task.
|
||||
|
||||
config FREERTOS_MAX_PRIORITIES
|
||||
int "Number of available priorities"
|
||||
default 200
|
||||
---help---
|
||||
Any number of tasks can share the same priority. Co-routines are prioritised separately -
|
||||
see configMAX_CO_ROUTINE_PRIORITIES.
|
||||
Each available priority consumes RAM within the RTOS kernel so this value should not
|
||||
be set any higher than actually required by your application.
|
||||
|
||||
config FREERTOS_MINIMAL_STACK_SIZE
|
||||
int "IDLE task stack size (words)"
|
||||
default 1024
|
||||
---help---
|
||||
The size of the stack used by the idle task. Generally this should not be reduced from
|
||||
the value set in the FreeRTOSConfig.h file provided with the demo application for the port
|
||||
you are using.
|
||||
Like the stack size parameter to the xTaskCreate() function, the stack size is specified
|
||||
in words, not bytes. If each item placed on the stack is 32-bits, then a stack size of 100
|
||||
means 400 bytes (each 32-bit stack item consuming 4 bytes).
|
||||
|
||||
config FREERTOS_MAX_TASK_NAME_LEN
|
||||
int "Maximum task name length"
|
||||
default 12
|
||||
---help---
|
||||
The maximum permissible length of the descriptive name given to a task when the task is
|
||||
created. The length is specified in the number of characters including the NULL termination
|
||||
byte.
|
||||
|
||||
config FREERTOS_IDLE_SHOULD_YIELD
|
||||
bool "Idle task should yield"
|
||||
depends on FREERTOS_PREEMPTIVE_EN
|
||||
default y
|
||||
---help---
|
||||
Tasks that share the same priority will time slice. Assuming none of the tasks get preempted,
|
||||
it might be assumed that each task of at a given priority will be allocated an equal amount
|
||||
of processing time - and if the shared priority is above the idle priority then this is indeed
|
||||
the case.
|
||||
When tasks share the idle priority the behaviour can be slightly different. When
|
||||
configIDLE_SHOULD_YIELD is set to 1 the idle task will yield immediately should any other task
|
||||
at the idle priority be ready to run.
|
||||
|
||||
menuconfig FREERTOS_USE_TASK_NOTIFICATIONS
|
||||
bool "Use task notifications"
|
||||
default y
|
||||
---help---
|
||||
Setting configUSE_TASK_NOTIFICATIONS to 1 (or leaving configUSE_TASK_NOTIFICATIONS undefined)
|
||||
will include direct to task notification functionality and its associated API in the build.
|
||||
Setting configUSE_TASK_NOTIFICATIONS to 0 will exclude direct to task notification functionality
|
||||
and its associated API from the build.
|
||||
Each task consumes 8 additional bytes of RAM when direct to task notifications are included in
|
||||
the build.
|
||||
|
||||
if FREERTOS_USE_TASK_NOTIFICATIONS
|
||||
config FREERTOS_USE_TASK_NOTIFICATION_ARRAY_ENTRIES
|
||||
int "Task notifications arry entries"
|
||||
default 3
|
||||
endif
|
||||
|
||||
config FREERTOS_USE_TIME_SLICING
|
||||
bool "Use time slicing"
|
||||
default y
|
||||
depends on FREERTOS_USE_QUEUE_SETS
|
||||
---help---
|
||||
By default (if configUSE_TIME_SLICING is not defined, or if configUSE_TIME_SLICING is defined as
|
||||
1) FreeRTOS uses prioritised preemptive scheduling with time slicing. That means the RTOS scheduler
|
||||
will always run the highest priority task that is in the Ready state, and will switch between tasks
|
||||
of equal priority on every RTOS tick interrupt. If configUSE_TIME_SLICING is set to 0 then the RTOS
|
||||
scheduler will still run the highest priority task that is in the Ready state, but will not switch
|
||||
between tasks of equal priority just because a tick interrupt has occurred.
|
||||
|
||||
config FREERTOS_NUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
int "Number of pointers in TLS"
|
||||
default 4
|
||||
---help---
|
||||
Sets the number of indexes in each task's thread local storage array.
|
||||
|
||||
config FREERTOS_MAIN_THREAD_STACK_SIZE
|
||||
int "Set main thread stack size"
|
||||
default 8096
|
||||
|
||||
config FREERTOS_MAIN_THREAD_PRIORITY
|
||||
int "Set main thread priority"
|
||||
default 32
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Hooks"
|
||||
|
||||
config FREERTOS_USE_IDLE_HOOK
|
||||
bool "Use idle hook"
|
||||
default n
|
||||
---help---
|
||||
Set to use idle hook or clear to omit it
|
||||
|
||||
config FREERTOS_USE_TICK_HOOK
|
||||
bool "Use tick hook"
|
||||
default n
|
||||
---help---
|
||||
Set if you wish to use a tick hook, or clear to omit an tick hook
|
||||
|
||||
config FREERTOS_USE_CHECK_STACK_OVERFLOW_HOOK
|
||||
bool "Use check stack overflow hook"
|
||||
default y
|
||||
---help---
|
||||
Check stack overflow
|
||||
|
||||
config FREERTOS_USE_MALLOC_FAILED_HOOK
|
||||
bool "Use malloc-failed hook"
|
||||
default y
|
||||
---help---
|
||||
The kernel uses a call to pvPortMalloc() to allocate memory from the heap each time a
|
||||
task, queue or semaphore is created. The official FreeRTOS download includes four sample
|
||||
memory allocation schemes for this purpose. The schemes are implemented in the heap_1.c,
|
||||
heap_2.c, heap_3.c, heap_4.c and heap_5.c source files respectively. configUSE_MALLOC_FAILED_HOOK
|
||||
is only relevant when one of these three sample schemes is being used. The malloc() failed
|
||||
hook function is a hook (or callback) function that, if defined and configured, will be
|
||||
called if pvPortMalloc() ever returns NULL. NULL will be returned only if there is
|
||||
insufficient FreeRTOS heap memory remaining for the requested allocation to succeed.
|
||||
If configUSE_MALLOC_FAILED_HOOK is set to 1 then the application must define a malloc()
|
||||
failed hook function. If configUSE_MALLOC_FAILED_HOOK is set to 0 then the malloc() failed
|
||||
hook function will not be called, even if one is defined. Malloc() failed hook functions
|
||||
must have the name and prototype shown below.
|
||||
void vApplicationMallocFailedHook( void );
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Primitives"
|
||||
|
||||
config FREERTOS_USE_MUTEXES
|
||||
bool "Mutexes"
|
||||
default y
|
||||
---help---
|
||||
Set to 1 to include mutex functionality in the build, or 0 to omit mutex functionality from the
|
||||
build. Readers should familiarise themselves with the differences between mutexes and binary semaphores
|
||||
in relation to the FreeRTOS functionality.
|
||||
|
||||
config FREERTOS_USE_RECURSIVE_MUTEXES
|
||||
bool "Recursive mutexes"
|
||||
default n
|
||||
depends on FREERTOS_USE_MUTEXES
|
||||
---help---
|
||||
Set to 1 to include recursive mutex functionality in the build, or 0 to omit recursive mutex
|
||||
functionality from the build.
|
||||
|
||||
config FREERTOS_USE_COUNTING_SEMAPHORES
|
||||
bool "Counting semaphores"
|
||||
default y
|
||||
---help---
|
||||
Set to 1 to include counting semaphore functionality in the build, or 0 to omit counting semaphore
|
||||
functionality from the build.
|
||||
|
||||
config FREERTOS_USE_ALTERNATIVE_API
|
||||
bool "Alternative queue API"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 to include the 'alternative' queue functions in the build, or 0 to omit the 'alternative'
|
||||
queue functions from the build. The alternative API is described within the queue.h header file. The
|
||||
alternative API is deprecated and should not be used in new designs.
|
||||
|
||||
config FREERTOS_USE_QUEUE_SETS
|
||||
bool "Queue sets"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 to include queue set functionality (the ability to block, or pend, on multiple queues and
|
||||
semaphores), or 0 to omit queue set functionality.
|
||||
|
||||
menuconfig FREERTOS_USE_CO_ROUTINES
|
||||
bool "Co-routines"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 to include co-routine functionality in the build, or 0 to omit co-routine functionality
|
||||
from the build. To include co-routines croutine.c must be included in the project.
|
||||
|
||||
if FREERTOS_USE_CO_ROUTINES
|
||||
|
||||
config FREERTOS_MAX_CO_ROUTINE_PRIORITIES
|
||||
int "Number of co-routine priorities"
|
||||
default 2
|
||||
---help---
|
||||
The number of priorities available to the application co-routines. Any number of co-routines can
|
||||
share the same priority.
|
||||
|
||||
endif
|
||||
|
||||
menuconfig FREERTOS_USE_TIMERS
|
||||
bool "Timers"
|
||||
default y
|
||||
---help---
|
||||
Set to 1 to include software timer functionality, or 0 to omit software timer functionality
|
||||
|
||||
if FREERTOS_USE_TIMERS
|
||||
|
||||
config FREERTOS_TIMER_TASK_PRIORITY
|
||||
int "Timer service task priority"
|
||||
default 1
|
||||
---help---
|
||||
Sets the priority of the software timer service/daemon task
|
||||
|
||||
config FREERTOS_TIMER_QUEUE_LENGTH
|
||||
int "Timer queue length"
|
||||
default 36
|
||||
---help---
|
||||
Sets the length of the software timer command queue
|
||||
|
||||
config FREERTOS_TIMER_TASK_STACK_DEPTH
|
||||
int "Timer task stack depth"
|
||||
default FREERTOS_MINIMAL_STACK_SIZE
|
||||
---help---
|
||||
Sets the stack depth allocated to the software timer service/daemon task
|
||||
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Libraries"
|
||||
|
||||
config FREERTOS_USE_NEWLIB_REENTRANT
|
||||
bool "Re-entrant newlib support"
|
||||
default n
|
||||
---help---
|
||||
If configUSE_NEWLIB_REENTRANT is set to 1 then a newlib reent structure will be allocated for each
|
||||
created task.
|
||||
|
||||
config FREERTOS_ENABLE_BACKWARD_COMPATIBILITY
|
||||
bool "Enable backward compatibility"
|
||||
default y
|
||||
---help---
|
||||
The FreeRTOS.h header file includes a set of #define macros that map the names of data types used
|
||||
in versions of FreeRTOS prior to version 8.0.0 to the names used in FreeRTOS version 8.0.0. The macros
|
||||
allow application code to update the version of FreeRTOS they are built against from a pre 8.0.0
|
||||
version to a post 8.0.0 version without modification. Setting configENABLE_BACKWARD_COMPATIBILITY to
|
||||
0 in FreeRTOSConfig.h excludes the macors from the build, and in so doing allowing validation that
|
||||
no pre version 8.0.0 names are being used
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Debug"
|
||||
|
||||
config FREERTOS_USE_TRACE_FACILITY
|
||||
bool "Enable trace facility"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 if you wish to include additional structure members and functions to assist with execution
|
||||
visualisation and tracing.
|
||||
|
||||
config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||
bool "Include vTaskList() and vTaskGetRunTimeStats()"
|
||||
default n
|
||||
depends on FREERTOS_USE_TRACE_FACILITY
|
||||
---help---
|
||||
Includes vTaskList() and vTaskGetRunTimeStats() to the build.
|
||||
|
||||
config FREERTOS_QUEUE_REGISTRY_SIZE
|
||||
int "Queue registry size"
|
||||
default 10
|
||||
---help---
|
||||
The queue registry has two purposes, both of which are associated with RTOS kernel aware debugging:
|
||||
1. It allows a textual name to be associated with a queue for easy queue identification within a
|
||||
debugging GUI.
|
||||
2. It contains the information required by a debugger to locate each registered queue and semaphore.
|
||||
The queue registry has no purpose unless you are using a RTOS kernel aware debugger.
|
||||
configQUEUE_REGISTRY_SIZE defines the maximum number of queues and semaphores that can be registered.
|
||||
Only those queues and semaphores that you want to view using a RTOS kernel aware debugger need be
|
||||
registered. See the API reference documentation for vQueueAddToRegistry() and vQueueUnregisterQueue()
|
||||
for more information.
|
||||
|
||||
config FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
bool "Generate run time stats"
|
||||
default n
|
||||
---help---
|
||||
The Run Time Stats page describes the use of this parameter.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
||||
18
kernel/freertos/SConscript
Normal file
18
kernel/freertos/SConscript
Normal file
@@ -0,0 +1,18 @@
|
||||
Import('PRJ_KERNEL')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
path = [cwd + '/include']
|
||||
path += [cwd + '/portable/GCC/RISC-V']
|
||||
path += [cwd + '/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions']
|
||||
|
||||
src = Glob('*.c')
|
||||
src += Glob('portable/MemMang/heap_5.c')
|
||||
src += Glob('portable/GCC/RISC-V/*.c')
|
||||
src += Glob('portable/GCC/RISC-V/*.S')
|
||||
|
||||
CPPDEFINES = []
|
||||
|
||||
group = DefineGroup('freertos', src, depend = ['KERNEL_FREERTOS'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
76
kernel/freertos/entry.c
Normal file
76
kernel/freertos/entry.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <aic_core.h>
|
||||
#include <board.h>
|
||||
#include <aic_tlsf.h>
|
||||
|
||||
#ifndef FREERTOS_MAIN_THREAD_STACK_SIZE
|
||||
#define MAIN_TASK_STACK_SIZE 8192
|
||||
#else
|
||||
#define MAIN_TASK_STACK_SIZE FREERTOS_MAIN_THREAD_STACK_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef FREERTOS_MAIN_THREAD_PRIORITY
|
||||
#define MAIN_TASK_PRI 32
|
||||
#else
|
||||
#define MAIN_TASK_PRI FREERTOS_MAIN_THREAD_PRIORITY
|
||||
#endif
|
||||
|
||||
extern void aic_board_sysclk_init(void);
|
||||
extern void aic_board_pinmux_init(void);
|
||||
extern int main(void);
|
||||
|
||||
HeapRegion_t xHeapRegions[] =
|
||||
{
|
||||
{ NULL, 0},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int freertos_heap_init (void)
|
||||
{
|
||||
xHeapRegions[0].pucStartAddress = ( uint8_t * )(&__heap_start);
|
||||
xHeapRegions[0].xSizeInBytes = (size_t)(&__heap_end) - (size_t)(&__heap_start);
|
||||
vPortDefineHeapRegions( xHeapRegions );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aic_hw_board_init(void)
|
||||
{
|
||||
freertos_heap_init();
|
||||
#ifdef TLSF_MEM_HEAP
|
||||
aic_tlsf_heap_init();
|
||||
#endif
|
||||
aic_board_sysclk_init();
|
||||
aic_board_pinmux_init();
|
||||
}
|
||||
|
||||
int entry(void)
|
||||
{
|
||||
TaskHandle_t xHandle;
|
||||
BaseType_t ret;
|
||||
|
||||
/* hw&heap init */
|
||||
aic_hw_board_init();
|
||||
|
||||
/* kernel init */
|
||||
|
||||
/* init task */
|
||||
ret = xTaskCreate((TaskFunction_t)main, "main", MAIN_TASK_STACK_SIZE/sizeof(StackType_t), NULL, configMAX_PRIORITIES-1-MAIN_TASK_PRI, &xHandle);
|
||||
if (ret != pdPASS) {
|
||||
printf("FreeRTOS create init main task fail.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* kernel start */
|
||||
vTaskStartScheduler();
|
||||
return 0;
|
||||
}
|
||||
281
kernel/freertos/include/FreeRTOSConfig.h
Normal file
281
kernel/freertos/include/FreeRTOSConfig.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* If you are: *
|
||||
* *
|
||||
* + New to FreeRTOS, *
|
||||
* + Wanting to learn FreeRTOS or multitasking in general quickly *
|
||||
* + Looking for basic training, *
|
||||
* + Wanting to improve your FreeRTOS skills and productivity *
|
||||
* *
|
||||
* then take a look at the FreeRTOS eBook *
|
||||
* *
|
||||
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* A pdf reference manual is also available. Both are usually delivered *
|
||||
* to your inbox within 20 minutes to two hours when purchased between 8am *
|
||||
* and 8pm GMT (although please allow up to 24 hours in case of *
|
||||
* exceptional circumstances). Thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
***NOTE*** The exception to the GPL is included to allow you to distribute
|
||||
a combined work that includes FreeRTOS without being obliged to provide the
|
||||
source code for proprietary components outside of the FreeRTOS kernel.
|
||||
FreeRTOS 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 General Public License for
|
||||
more details. You should have received a copy of the GNU General Public
|
||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||
by writing to Richard Barry, contact details for whom are available on the
|
||||
FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||
contact details.
|
||||
|
||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||
critical systems.
|
||||
|
||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
#include <stdio.h>
|
||||
#include <rtconfig.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.
|
||||
*----------------------------------------------------------*/
|
||||
#define configMTIME_BASE_ADDRESS ( ( 0xE0000000UL ) + 0xBFF8UL )
|
||||
#define configMTIMECMP_BASE_ADDRESS ( ( 0xE0000000UL ) + 0x4000UL )
|
||||
|
||||
#define portasmHANDLE_INTERRUPT Default_IRQHandler
|
||||
|
||||
#ifdef FREERTOS_PREEMPTIVE_EN
|
||||
#define configUSE_PREEMPTION 1
|
||||
#else
|
||||
#define configUSE_PREEMPTION 0
|
||||
#endif
|
||||
#ifdef AIC_CLK_CPU_FREQ
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) AIC_CLK_CPU_FREQ )
|
||||
#else
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 200000000 )
|
||||
#endif
|
||||
#ifdef FREERTOS_TICK_RATE_HZ
|
||||
#define configTICK_RATE_HZ FREERTOS_TICK_RATE_HZ
|
||||
#else
|
||||
#define configTICK_RATE_HZ 200
|
||||
#endif
|
||||
#ifdef FREERTOS_MAX_PRIORITIES
|
||||
#define configMAX_PRIORITIES FREERTOS_MAX_PRIORITIES
|
||||
#else
|
||||
#define configMAX_PRIORITIES 200
|
||||
#endif
|
||||
#ifdef FREERTOS_MINIMAL_STACK_SIZE
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) FREERTOS_MINIMAL_STACK_SIZE )
|
||||
#else
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) (256*4) )
|
||||
#endif
|
||||
#ifdef FREERTOS_MAX_TASK_NAME_LEN
|
||||
#define configMAX_TASK_NAME_LEN ( FREERTOS_MAX_TASK_NAME_LEN )
|
||||
#else
|
||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||
#endif
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#ifdef FREERTOS_IDLE_SHOULD_YIELD
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#else
|
||||
#define configIDLE_SHOULD_YIELD 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TASK_NOTIFICATIONS
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#else
|
||||
#define configUSE_TASK_NOTIFICATIONS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TASK_NOTIFICATION_ARRAY_ENTRIES
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES FREERTOS_USE_TASK_NOTIFICATION_ARRAY_ENTRIES
|
||||
#else
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_MUTEXES
|
||||
#define configUSE_MUTEXES 1
|
||||
#ifdef FREERTOS_USE_RECURSIVE_MUTEXES
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#else
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#endif
|
||||
#else
|
||||
#define configUSE_MUTEXES 0
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_COUNTING_SEMAPHORES
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#else
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_ALTERNATIVE_API
|
||||
#define configUSE_ALTERNATIVE_API 1 /* Deprecated! */
|
||||
#else
|
||||
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
|
||||
#endif
|
||||
#ifdef FREERTOS_QUEUE_REGISTRY_SIZE
|
||||
#define configQUEUE_REGISTRY_SIZE FREERTOS_QUEUE_REGISTRY_SIZE
|
||||
#else
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_QUEUE_SETS
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
#else
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TIME_SLICING
|
||||
#define configUSE_TIME_SLICING 1
|
||||
#else
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_NEWLIB_REENTRANT
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#else
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
#endif
|
||||
#ifdef FREERTOS_ENABLE_BACKWARD_COMPATIBILITY
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#else
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
#endif
|
||||
#ifdef FREERTOS_NUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS FREERTOS_NUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
#else
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 4
|
||||
#endif
|
||||
//#define configSTACK_DEPTH_TYPE uint16_t
|
||||
//#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
|
||||
/* Memory allocation related definitions. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) (24576 * 4))
|
||||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#ifdef FREERTOS_USE_IDLE_HOOK
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#else
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TICK_HOOK
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#else
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_CHECK_STACK_OVERFLOW_HOOK
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
#else
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_MALLOC_FAILED_HOOK
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#else
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#endif
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#ifdef FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#else
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TRACE_FACILITY
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#else
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
#else
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
#endif
|
||||
|
||||
/* Co-routine related definitions. */
|
||||
#ifdef FREERTOS_USE_CO_ROUTINES
|
||||
#define configUSE_CO_ROUTINES 1
|
||||
#else
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#endif
|
||||
#ifdef FREERTOS_MAX_CO_ROUTINE_PRIORITIES
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES FREERTOS_MAX_CO_ROUTINE_PRIORITIES
|
||||
#else
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||
#endif
|
||||
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#ifdef FREERTOS_USE_TIMERS
|
||||
#define configUSE_TIMERS 1
|
||||
#else
|
||||
#define configUSE_TIMERS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_TIMER_TASK_PRIORITY
|
||||
#define configTIMER_TASK_PRIORITY FREERTOS_TIMER_TASK_PRIORITY
|
||||
#else
|
||||
#define configTIMER_TASK_PRIORITY 1
|
||||
#endif
|
||||
#ifdef FREERTOS_TIMER_QUEUE_LENGTH
|
||||
#define configTIMER_QUEUE_LENGTH FREERTOS_TIMER_QUEUE_LENGTH
|
||||
#else
|
||||
#define configTIMER_QUEUE_LENGTH 36
|
||||
#endif
|
||||
#ifdef FREERTOS_TIMER_TASK_STACK_DEPTH
|
||||
#define configTIMER_TASK_STACK_DEPTH FREERTOS_TIMER_TASK_STACK_DEPTH
|
||||
#else
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
#endif
|
||||
|
||||
/* Interrupt nesting behaviour configuration. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( ( unsigned char ) 7 << ( unsigned char ) 5 ) /* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( ( unsigned char ) 5 << ( unsigned char ) 5 ) /* Priority 5, or 160 as only the top three bits are implemented. */
|
||||
|
||||
/* 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_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark2 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 0
|
||||
#define INCLUDE_xTaskGetHandle 0
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@@ -74,8 +74,8 @@ interrupt stack after the scheduler has started. */
|
||||
the ISR stack. */
|
||||
#define portISR_STACK_FILL_BYTE 0xee
|
||||
#else
|
||||
extern const uint32_t __freertos_irq_stack_top[];
|
||||
const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top;
|
||||
extern const uint32_t g_top_irqstack[];
|
||||
const StackType_t xISRStackTop = ( StackType_t ) g_top_irqstack;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -87,12 +87,14 @@ void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
/* Used to program the machine timer compare register. */
|
||||
uint64_t ullNextTime = 0ULL;
|
||||
const uint64_t *pullNextTime = &ullNextTime;
|
||||
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
|
||||
uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
|
||||
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
||||
#endif
|
||||
|
||||
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
|
||||
stack checking. A problem in the ISR stack will trigger an assert, not call the
|
||||
@@ -114,9 +116,18 @@ task stack, not the ISR stack). */
|
||||
#define portCHECK_ISR_STACK()
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */
|
||||
|
||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||
will be set to 0 prior to the first task being started. */
|
||||
portLONG ulCriticalNesting = 0x9999UL;
|
||||
|
||||
/* Used to record one tack want to swtich task after enter critical area, we need know it
|
||||
* and implement task switch after exit critical area */
|
||||
portLONG pendsvflag = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
|
||||
#if 0
|
||||
//#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
|
||||
|
||||
void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
@@ -151,6 +162,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void xPortStartFirstTask( void );
|
||||
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint32_t mtvec = 0;
|
||||
@@ -173,6 +186,7 @@ extern void xPortStartFirstTask( void );
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
#if 0
|
||||
/* If there is a CLINT then it is ok to use the default implementation
|
||||
in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
|
||||
configure whichever clock is to be used to generate the tick interrupt. */
|
||||
@@ -191,6 +205,7 @@ extern void xPortStartFirstTask( void );
|
||||
__asm volatile( "csrs mie, %0" :: "r"(0x800) );
|
||||
}
|
||||
#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */
|
||||
#endif
|
||||
|
||||
xPortStartFirstTask();
|
||||
|
||||
@@ -206,7 +221,64 @@ void vPortEndScheduler( void )
|
||||
for( ;; );
|
||||
}
|
||||
|
||||
void vTaskEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
ulCriticalNesting ++;
|
||||
}
|
||||
|
||||
void vTaskExitCritical( void )
|
||||
{
|
||||
if (ulCriticalNesting == 0) {
|
||||
while(1);
|
||||
}
|
||||
|
||||
ulCriticalNesting --;
|
||||
if (ulCriticalNesting == 0)
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
if (pendsvflag)
|
||||
{
|
||||
pendsvflag = 0;
|
||||
portYIELD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
portLONG ulDummy;
|
||||
|
||||
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
xTaskIncrementTick();
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
||||
}
|
||||
|
||||
#else
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
portLONG ulDummy;
|
||||
|
||||
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
if (xTaskIncrementTick() != pdFALSE)
|
||||
{
|
||||
portYIELD_FROM_ISR(pdTRUE);
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
|
||||
{
|
||||
for(;;);
|
||||
}
|
||||
|
||||
__attribute__((weak)) void vApplicationMallocFailedHook( void )
|
||||
{
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
* registers.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cpuport.h"
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#define portWORD_SIZE 8
|
||||
#define store_x sd
|
||||
@@ -67,6 +70,16 @@
|
||||
#error Assembler did not define __riscv_xlen
|
||||
#endif
|
||||
|
||||
#if defined(__riscv_d)
|
||||
#define portFWORD_SIZE 8
|
||||
#define store_f fsd
|
||||
#define load_f fld
|
||||
#elif defined(__riscv_f)
|
||||
#define store_f fsw
|
||||
#define load_f flw
|
||||
#define portFWORD_SIZE 4
|
||||
#endif
|
||||
|
||||
#include "freertos_risc_v_chip_specific_extensions.h"
|
||||
|
||||
/* Check the freertos_risc_v_chip_specific_extensions.h and/or command line
|
||||
@@ -85,10 +98,6 @@ definitions. */
|
||||
#error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_MTIME to either 1 (MTIME clock present) or 0 (MTIME clock not present). See https://www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html
|
||||
#endif
|
||||
|
||||
#ifndef portasmHANDLE_INTERRUPT
|
||||
#error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assembler command line or in the appropriate freertos_risc_v_chip_specific_extensions.h header file. https://www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html
|
||||
#endif
|
||||
|
||||
#ifndef portasmHAS_SIFIVE_CLINT
|
||||
#define portasmHAS_SIFIVE_CLINT 0
|
||||
#endif
|
||||
@@ -98,9 +107,18 @@ registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
|
||||
specific version of freertos_risc_v_chip_specific_extensions.h. See the notes
|
||||
at the top of this file. */
|
||||
#if defined(__riscv_p)
|
||||
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
|
||||
#else
|
||||
#define portCONTEXT_SIZE ( 30 * portWORD_SIZE )
|
||||
#endif
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
#define FLOAT_REG_NUM 32
|
||||
#define portFCONTEXT_SIZE ( FLOAT_REG_NUM * portFWORD_SIZE )
|
||||
#endif
|
||||
|
||||
.global xPortStartFirstTask
|
||||
.global PendSV_Handler
|
||||
.global freertos_risc_v_trap_handler
|
||||
.global pxPortInitialiseStack
|
||||
.extern pxCurrentTCB
|
||||
@@ -116,9 +134,75 @@ at the top of this file. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Functions: vPortYield
|
||||
*/
|
||||
.global vPortYield
|
||||
.type vPortYield, %function
|
||||
vPortYield:
|
||||
li t0, TSPEND_ADDR
|
||||
lb t1, (t0)
|
||||
li t2, 0x01
|
||||
or t1, t1, t2
|
||||
sb t1, (t0)
|
||||
|
||||
/* make sure wite instruction is complete */
|
||||
fence
|
||||
lb t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.i
|
||||
#else
|
||||
.long 0x01a0000b
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
.align 8
|
||||
.func
|
||||
PendSV_Handler:
|
||||
freertos_risc_v_trap_handler:
|
||||
#ifdef CONFIG_THEAD_EXT_SPSWAPEN
|
||||
csrrw sp, mscratch, sp
|
||||
#endif
|
||||
|
||||
// portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
addi sp, sp, -portFCONTEXT_SIZE
|
||||
store_f f0, 0 * portFWORD_SIZE( sp )
|
||||
store_f f1, 1 * portFWORD_SIZE( sp )
|
||||
store_f f2, 2 * portFWORD_SIZE( sp )
|
||||
store_f f3, 3 * portFWORD_SIZE( sp )
|
||||
store_f f4, 4 * portFWORD_SIZE( sp )
|
||||
store_f f5, 5 * portFWORD_SIZE( sp )
|
||||
store_f f6, 6 * portFWORD_SIZE( sp )
|
||||
store_f f7, 7 * portFWORD_SIZE( sp )
|
||||
store_f f8, 8 * portFWORD_SIZE( sp )
|
||||
store_f f9, 9 * portFWORD_SIZE( sp )
|
||||
store_f f10, 10 * portFWORD_SIZE( sp )
|
||||
store_f f11, 11 * portFWORD_SIZE( sp )
|
||||
store_f f12, 12 * portFWORD_SIZE( sp )
|
||||
store_f f13, 13 * portFWORD_SIZE( sp )
|
||||
store_f f14, 14 * portFWORD_SIZE( sp )
|
||||
store_f f15, 15 * portFWORD_SIZE( sp )
|
||||
store_f f16, 16 * portFWORD_SIZE( sp )
|
||||
store_f f17, 17 * portFWORD_SIZE( sp )
|
||||
store_f f18, 18 * portFWORD_SIZE( sp )
|
||||
store_f f19, 19 * portFWORD_SIZE( sp )
|
||||
store_f f20, 20 * portFWORD_SIZE( sp )
|
||||
store_f f21, 21 * portFWORD_SIZE( sp )
|
||||
store_f f22, 22 * portFWORD_SIZE( sp )
|
||||
store_f f23, 23 * portFWORD_SIZE( sp )
|
||||
store_f f24, 24 * portFWORD_SIZE( sp )
|
||||
store_f f25, 25 * portFWORD_SIZE( sp )
|
||||
store_f f26, 26 * portFWORD_SIZE( sp )
|
||||
store_f f27, 27 * portFWORD_SIZE( sp )
|
||||
store_f f28, 28 * portFWORD_SIZE( sp )
|
||||
store_f f29, 29 * portFWORD_SIZE( sp )
|
||||
store_f f30, 30 * portFWORD_SIZE( sp )
|
||||
store_f f31, 31 * portFWORD_SIZE( sp )
|
||||
#endif
|
||||
|
||||
addi sp, sp, -portCONTEXT_SIZE
|
||||
store_x x1, 1 * portWORD_SIZE( sp )
|
||||
store_x x5, 2 * portWORD_SIZE( sp )
|
||||
@@ -152,101 +236,30 @@ freertos_risc_v_trap_handler:
|
||||
csrr t0, mstatus /* Required for MPIE bit. */
|
||||
store_x t0, 29 * portWORD_SIZE( sp )
|
||||
|
||||
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_p)
|
||||
csrr t0, vxsat
|
||||
store_x t0, 30 * portWORD_SIZE( sp )
|
||||
#endif
|
||||
|
||||
csrr a1, mepc
|
||||
store_x a1, 0( sp ) /* Save updated exception return address. */
|
||||
|
||||
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
|
||||
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
|
||||
test_if_asynchronous:
|
||||
srli a2, a0, __riscv_xlen - 1 /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */
|
||||
beq a2, x0, handle_synchronous /* Branch past interrupt handing if not asynchronous. */
|
||||
store_x a1, 0( sp ) /* Asynch so save unmodified exception return address. */
|
||||
|
||||
handle_asynchronous:
|
||||
|
||||
#if( portasmHAS_MTIME != 0 )
|
||||
|
||||
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
|
||||
|
||||
addi t0, x0, 1
|
||||
|
||||
slli t0, t0, __riscv_xlen - 1 /* LSB is already set, shift into MSB. Shift 31 on 32-bit or 63 on 64-bit cores. */
|
||||
addi t1, t0, 7 /* 0x8000[]0007 == machine timer interrupt. */
|
||||
bne a0, t1, test_if_external_interrupt
|
||||
|
||||
load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */
|
||||
load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */
|
||||
|
||||
#if( __riscv_xlen == 32 )
|
||||
|
||||
/* Update the 64-bit mtimer compare match value in two 32-bit writes. */
|
||||
li t4, -1
|
||||
lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */
|
||||
lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */
|
||||
sw t4, 0(t0) /* Low word no smaller than old value to start with - will be overwritten below. */
|
||||
sw t3, 4(t0) /* Store high word of ullNextTime into compare register. No smaller than new value. */
|
||||
sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */
|
||||
lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
|
||||
add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */
|
||||
sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */
|
||||
add t6, t3, t5 /* Add overflow to high word of ullNextTime. */
|
||||
sw t4, 0(t1) /* Store new low word of ullNextTime. */
|
||||
sw t6, 4(t1) /* Store new high word of ullNextTime. */
|
||||
|
||||
#endif /* __riscv_xlen == 32 */
|
||||
|
||||
#if( __riscv_xlen == 64 )
|
||||
|
||||
/* Update the 64-bit mtimer compare match value. */
|
||||
ld t2, 0(t1) /* Load ullNextTime into t2. */
|
||||
sd t2, 0(t0) /* Store ullNextTime into compare register. */
|
||||
ld t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
|
||||
add t4, t0, t2 /* Add ullNextTime to the timer increments for one tick. */
|
||||
sd t4, 0(t1) /* Store ullNextTime. */
|
||||
|
||||
#endif /* __riscv_xlen == 64 */
|
||||
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal xTaskIncrementTick
|
||||
beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
||||
test_if_external_interrupt: /* If there is a CLINT and the mtimer interrupt is not pending then check to see if an external interrupt is pending. */
|
||||
addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */
|
||||
bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */
|
||||
|
||||
#endif /* portasmHAS_MTIME */
|
||||
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */
|
||||
j processed_source
|
||||
|
||||
handle_synchronous:
|
||||
addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */
|
||||
store_x a1, 0( sp ) /* Save updated exception return address. */
|
||||
|
||||
test_if_environment_call:
|
||||
li t0, 11 /* 11 == environment call. */
|
||||
bne a0, t0, is_exception /* Not an M environment call, so some other exception. */
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
||||
is_exception:
|
||||
csrr t0, mcause /* For viewing in the debugger only. */
|
||||
csrr t1, mepc /* For viewing in the debugger only */
|
||||
csrr t2, mstatus
|
||||
j is_exception /* No other exceptions handled yet. */
|
||||
#ifdef TSPEND_NEED_CLEAR
|
||||
/* clear software interrupt */
|
||||
li t0, TSPEND_ADDR
|
||||
li t1, 0x0
|
||||
sw t1, (t0)
|
||||
/* make sure wite instruction is complete */
|
||||
fence
|
||||
lb t1, (t0)
|
||||
#endif
|
||||
|
||||
as_yet_unhandled:
|
||||
csrr t0, mcause /* For viewing in the debugger only. */
|
||||
j as_yet_unhandled
|
||||
|
||||
processed_source:
|
||||
load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
load_x sp, 0( t1 ) /* Read sp from first TCB member. */
|
||||
|
||||
@@ -254,7 +267,10 @@ processed_source:
|
||||
load_x t0, 0( sp )
|
||||
csrw mepc, t0
|
||||
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_p)
|
||||
load_x t0, 30( sp )
|
||||
csrw vxsat, t0
|
||||
#endif
|
||||
|
||||
/* Load mstatus with the interrupt enable bits used by the task. */
|
||||
load_x t0, 29 * portWORD_SIZE( sp )
|
||||
@@ -290,6 +306,46 @@ processed_source:
|
||||
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
//portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
load_f f0, 0 * portFWORD_SIZE( sp )
|
||||
load_f f1, 1 * portFWORD_SIZE( sp )
|
||||
load_f f2, 2 * portFWORD_SIZE( sp )
|
||||
load_f f3, 3 * portFWORD_SIZE( sp )
|
||||
load_f f4, 4 * portFWORD_SIZE( sp )
|
||||
load_f f5, 5 * portFWORD_SIZE( sp )
|
||||
load_f f6, 6 * portFWORD_SIZE( sp )
|
||||
load_f f7, 7 * portFWORD_SIZE( sp )
|
||||
load_f f8, 8 * portFWORD_SIZE( sp )
|
||||
load_f f9, 9 * portFWORD_SIZE( sp )
|
||||
load_f f10, 10 * portFWORD_SIZE( sp )
|
||||
load_f f11, 11 * portFWORD_SIZE( sp )
|
||||
load_f f12, 12 * portFWORD_SIZE( sp )
|
||||
load_f f13, 13 * portFWORD_SIZE( sp )
|
||||
load_f f14, 14 * portFWORD_SIZE( sp )
|
||||
load_f f15, 15 * portFWORD_SIZE( sp )
|
||||
load_f f16, 16 * portFWORD_SIZE( sp )
|
||||
load_f f17, 17 * portFWORD_SIZE( sp )
|
||||
load_f f18, 18 * portFWORD_SIZE( sp )
|
||||
load_f f19, 19 * portFWORD_SIZE( sp )
|
||||
load_f f20, 20 * portFWORD_SIZE( sp )
|
||||
load_f f21, 21 * portFWORD_SIZE( sp )
|
||||
load_f f22, 22 * portFWORD_SIZE( sp )
|
||||
load_f f23, 23 * portFWORD_SIZE( sp )
|
||||
load_f f24, 24 * portFWORD_SIZE( sp )
|
||||
load_f f25, 25 * portFWORD_SIZE( sp )
|
||||
load_f f26, 26 * portFWORD_SIZE( sp )
|
||||
load_f f27, 27 * portFWORD_SIZE( sp )
|
||||
load_f f28, 28 * portFWORD_SIZE( sp )
|
||||
load_f f29, 29 * portFWORD_SIZE( sp )
|
||||
load_f f30, 30 * portFWORD_SIZE( sp )
|
||||
load_f f31, 31 * portFWORD_SIZE( sp )
|
||||
addi sp, sp, portFCONTEXT_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THEAD_EXT_SPSWAPEN
|
||||
csrrw sp, mscratch, sp
|
||||
#endif
|
||||
mret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -298,20 +354,15 @@ processed_source:
|
||||
.func
|
||||
xPortStartFirstTask:
|
||||
|
||||
#if( portasmHAS_SIFIVE_CLINT != 0 )
|
||||
/* If there is a clint then interrupts can branch directly to the FreeRTOS
|
||||
trap handler. Otherwise the interrupt controller will need to be configured
|
||||
outside of this file. */
|
||||
la t0, freertos_risc_v_trap_handler
|
||||
csrw mtvec, t0
|
||||
#endif /* portasmHAS_CLILNT */
|
||||
|
||||
load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
load_x sp, 0( sp ) /* Read sp from first TCB member. */
|
||||
|
||||
load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */
|
||||
load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */
|
||||
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_p)
|
||||
load_x t0, 30( sp )
|
||||
csrw vxsat, t0
|
||||
#endif
|
||||
|
||||
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
||||
@@ -346,6 +397,43 @@ xPortStartFirstTask:
|
||||
load_x x5, 2 * portWORD_SIZE( sp ) /* Initial x5 (t0) value. */
|
||||
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
//portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
load_f f0, 0 * portFWORD_SIZE( sp )
|
||||
load_f f1, 1 * portFWORD_SIZE( sp )
|
||||
load_f f2, 2 * portFWORD_SIZE( sp )
|
||||
load_f f3, 3 * portFWORD_SIZE( sp )
|
||||
load_f f4, 4 * portFWORD_SIZE( sp )
|
||||
load_f f5, 5 * portFWORD_SIZE( sp )
|
||||
load_f f6, 6 * portFWORD_SIZE( sp )
|
||||
load_f f7, 7 * portFWORD_SIZE( sp )
|
||||
load_f f8, 8 * portFWORD_SIZE( sp )
|
||||
load_f f9, 9 * portFWORD_SIZE( sp )
|
||||
load_f f10, 10 * portFWORD_SIZE( sp )
|
||||
load_f f11, 11 * portFWORD_SIZE( sp )
|
||||
load_f f12, 12 * portFWORD_SIZE( sp )
|
||||
load_f f13, 13 * portFWORD_SIZE( sp )
|
||||
load_f f14, 14 * portFWORD_SIZE( sp )
|
||||
load_f f15, 15 * portFWORD_SIZE( sp )
|
||||
load_f f16, 16 * portFWORD_SIZE( sp )
|
||||
load_f f17, 17 * portFWORD_SIZE( sp )
|
||||
load_f f18, 18 * portFWORD_SIZE( sp )
|
||||
load_f f19, 19 * portFWORD_SIZE( sp )
|
||||
load_f f20, 20 * portFWORD_SIZE( sp )
|
||||
load_f f21, 21 * portFWORD_SIZE( sp )
|
||||
load_f f22, 22 * portFWORD_SIZE( sp )
|
||||
load_f f23, 23 * portFWORD_SIZE( sp )
|
||||
load_f f24, 24 * portFWORD_SIZE( sp )
|
||||
load_f f25, 25 * portFWORD_SIZE( sp )
|
||||
load_f f26, 26 * portFWORD_SIZE( sp )
|
||||
load_f f27, 27 * portFWORD_SIZE( sp )
|
||||
load_f f28, 28 * portFWORD_SIZE( sp )
|
||||
load_f f29, 29 * portFWORD_SIZE( sp )
|
||||
load_f f30, 30 * portFWORD_SIZE( sp )
|
||||
load_f f31, 31 * portFWORD_SIZE( sp )
|
||||
addi sp, sp, portFCONTEXT_SIZE
|
||||
#endif
|
||||
ret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -415,6 +503,22 @@ xPortStartFirstTask:
|
||||
.align 8
|
||||
.func
|
||||
pxPortInitialiseStack:
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
addi t0, x0, FLOAT_REG_NUM /* The number of float registers. */
|
||||
chip_float_stack_frame: /* First add any float registers to the stack frame being created. */
|
||||
beq t0, x0, 1f /* No more float registers to save. */
|
||||
addi a0, a0, -portFWORD_SIZE /* Make space for float register. */
|
||||
store_f f0, 0(a0) /* Give the float register an initial value of zero. */
|
||||
addi t0, t0, -1 /* Decrement the count of float registers remaining. */
|
||||
j chip_float_stack_frame /* Until no more float registers. */
|
||||
1:
|
||||
#endif
|
||||
|
||||
#if defined(__riscv_p)
|
||||
csrr t0, vxsat
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x t0, 0(a0) /* vxsat onto the stack. */
|
||||
#endif
|
||||
|
||||
csrr t0, mstatus /* Obtain current mstatus value. */
|
||||
andi t0, t0, ~0x8 /* Ensure interrupts are disabled when the stack is restored within an ISR. Required when a task is created after the schedulre has been started, otherwise interrupts would be disabled anyway. */
|
||||
@@ -428,14 +532,7 @@ pxPortInitialiseStack:
|
||||
store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */
|
||||
addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */
|
||||
store_x x0, 0(a0) /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */
|
||||
addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */
|
||||
chip_specific_stack_frame: /* First add any chip specific registers to the stack frame being created. */
|
||||
beq t0, x0, 1f /* No more chip specific registers to save. */
|
||||
addi a0, a0, -portWORD_SIZE /* Make space for chip specific register. */
|
||||
store_x x0, 0(a0) /* Give the chip specific register an initial value of zero. */
|
||||
addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */
|
||||
j chip_specific_stack_frame /* Until no more chip specific registers. */
|
||||
1:
|
||||
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
||||
ret
|
||||
|
||||
@@ -90,15 +90,16 @@ not need to be guarded with a critical section. */
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
extern void vTaskSwitchContext( void );
|
||||
#define portYIELD() __asm volatile( "ecall" );
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portYIELD()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
#define portCRITICAL_NESTING_IN_TCB 1
|
||||
#define portCRITICAL_NESTING_IN_TCB 0
|
||||
extern void vTaskEnterCritical( void );
|
||||
extern void vTaskExitCritical( void );
|
||||
|
||||
@@ -113,7 +114,7 @@ extern void vTaskExitCritical( void );
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
|
||||
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
Reference in New Issue
Block a user