This commit is contained in:
刘可亮
2024-01-27 08:47:24 +08:00
parent d3bd993b5f
commit 9f7ba67007
2345 changed files with 74421 additions and 76616 deletions

View File

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

View 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

View 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
View 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;
}

View 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 */

View File

@@ -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(;;);
}

View File

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

View File

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