mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-11 00:27:45 -04:00
Merge branch 'main' into blocking_buffer
This commit is contained in:
commit
2869514910
122 changed files with 6081 additions and 3692 deletions
33
.github/.cSpellWords.txt
vendored
33
.github/.cSpellWords.txt
vendored
|
@ -59,6 +59,7 @@ brhi
|
|||
brne
|
||||
bswtrg
|
||||
BSWTRG
|
||||
Bytesto
|
||||
CANEN
|
||||
CANRX
|
||||
CANTX
|
||||
|
@ -89,13 +90,16 @@ CKGR
|
|||
CKLO
|
||||
CKPS
|
||||
CLDIV
|
||||
CLEARINTENA
|
||||
CLKA
|
||||
CLKB
|
||||
CLKDIS
|
||||
CLKEN
|
||||
clki
|
||||
CLKI
|
||||
CLKP
|
||||
CLKS
|
||||
CLKSOURCE
|
||||
CLKSTA
|
||||
CLRB
|
||||
CLRF
|
||||
|
@ -120,6 +124,7 @@ CODR
|
|||
comms
|
||||
COMPA
|
||||
CONFG
|
||||
coremqtt
|
||||
CORTUS
|
||||
coverity
|
||||
Coverity
|
||||
|
@ -152,6 +157,7 @@ crhook
|
|||
croutine
|
||||
CRTV
|
||||
CSAAT
|
||||
CSDK
|
||||
csrr
|
||||
csrs
|
||||
csrw
|
||||
|
@ -174,10 +180,15 @@ DATNB
|
|||
DATRDY
|
||||
DBGU
|
||||
DCDIC
|
||||
DCMOCK
|
||||
DCMR
|
||||
Dconfig
|
||||
DCOUNT
|
||||
decf
|
||||
decfsz
|
||||
decihours
|
||||
Decihours
|
||||
DECIHOURS
|
||||
DECNT
|
||||
DFPU
|
||||
DFREERTOS
|
||||
|
@ -310,6 +321,7 @@ FSR
|
|||
fwait
|
||||
GCACC
|
||||
GCTRL
|
||||
getpacketid
|
||||
getvect
|
||||
GIEH
|
||||
GIEL
|
||||
|
@ -370,6 +382,7 @@ ISRR
|
|||
ISR's
|
||||
ISRS
|
||||
ISRTICK
|
||||
isystem
|
||||
ITIF
|
||||
ITMC
|
||||
ITMK
|
||||
|
@ -512,6 +525,7 @@ MVTACHI
|
|||
MVTACLO
|
||||
MVTC
|
||||
MVTIPL
|
||||
mypy
|
||||
NCFGR
|
||||
NCPHA
|
||||
NEBP
|
||||
|
@ -521,6 +535,9 @@ NIOSII
|
|||
NIRQ
|
||||
NOGIC
|
||||
noheap
|
||||
nondet
|
||||
Nondet
|
||||
NONDET
|
||||
nostdint
|
||||
NPCS
|
||||
NRSTL
|
||||
|
@ -634,6 +651,9 @@ PUSHNE
|
|||
PUSHW
|
||||
pushx
|
||||
PWMC
|
||||
pylint
|
||||
pytest
|
||||
pyyaml
|
||||
RAMPZ
|
||||
RASR
|
||||
Rationalised
|
||||
|
@ -689,6 +709,7 @@ Rsvd
|
|||
RTAR
|
||||
RTCEN
|
||||
RTCSC
|
||||
RTICTL
|
||||
RTIE
|
||||
RTIF
|
||||
RTIFRC
|
||||
|
@ -712,6 +733,7 @@ RXRSM
|
|||
RXSETUP
|
||||
RXSUSP
|
||||
RXSYN
|
||||
RXTDIS
|
||||
RXTEN
|
||||
RXUBR
|
||||
SBYCR
|
||||
|
@ -725,6 +747,7 @@ SECU
|
|||
SENDA
|
||||
SETB
|
||||
SETEN
|
||||
SETINTENA
|
||||
SETPSW
|
||||
SETR
|
||||
setvect
|
||||
|
@ -847,8 +870,16 @@ TXUBR
|
|||
TXVC
|
||||
TXVDIS
|
||||
UDCP
|
||||
UNACKED
|
||||
uncrustify
|
||||
UNDADD
|
||||
unpadded
|
||||
Unpadded
|
||||
UNPADDED
|
||||
UNRE
|
||||
UNSUB
|
||||
UNSUBACK
|
||||
unsubscriptions
|
||||
unsuspended
|
||||
URAD
|
||||
URAT
|
||||
|
@ -864,8 +895,10 @@ utilises
|
|||
utilising
|
||||
VDDCORE
|
||||
vect
|
||||
Vect
|
||||
VECT
|
||||
VECTACTIVE
|
||||
VECTKEY
|
||||
visualisation
|
||||
vldmdbeq
|
||||
vldmia
|
||||
|
|
5
.github/scripts/kernel_checker.py
vendored
5
.github/scripts/kernel_checker.py
vendored
|
@ -62,7 +62,8 @@ KERNEL_IGNORED_EXTENSIONS = [
|
|||
'.bat',
|
||||
'.sh',
|
||||
'.txt',
|
||||
'.cmake'
|
||||
'.cmake',
|
||||
'.config'
|
||||
]
|
||||
|
||||
KERNEL_ASM_EXTENSIONS = [
|
||||
|
@ -94,7 +95,7 @@ KERNEL_IGNORED_PATTERNS = [
|
|||
r'.*IAR/78K0R/*',
|
||||
r'.*CCS/MSP430X/*',
|
||||
r'.*portable/template/*',
|
||||
r'.*sample_configuration/*'
|
||||
r'.*template_configuration/*'
|
||||
]
|
||||
|
||||
KERNEL_THIRD_PARTY_PATTERNS = [
|
||||
|
|
118
History.txt
118
History.txt
|
@ -1,5 +1,123 @@
|
|||
Documentation and download available at https://www.FreeRTOS.org/
|
||||
|
||||
Changes between FreeRTOS V11.0.0 and FreeRTOS V11.0.1 released December 21, 2023
|
||||
|
||||
+ Updated the SBOM file.
|
||||
|
||||
Changes between FreeRTOS V10.6.2 and FreeRTOS V11.0.0 released December 18, 2023
|
||||
|
||||
+ SMP merged into the mainline: While FreeRTOS introduced Asymmetric
|
||||
Multiprocessing (AMP) support in 2017, FreeRTOS Version 11.0.0 is the
|
||||
first to merge Symmetric Multiprocessing (SMP) support into the mainline
|
||||
release. SMP enables one instance of the FreeRTOS Kernel to schedule tasks
|
||||
across multiple identical processor cores. We thank Mike Bruno and Jerry
|
||||
McCarthy of XMOS and, Darian Liang, Sudeep Mohanty and Zim Kalinowski of
|
||||
Espressif Systems for their contributions.
|
||||
+ Switch MISRA compliance checking from PC Lint to Coverity, and update from
|
||||
MISRA C:2004 to MISRA C:2012.
|
||||
+ Add a template FreeRTOSConfig.h, inclusive of an abbreviated explanation of
|
||||
each configuration item. Application writers can use this template as a
|
||||
starting point to create the FreeRTOSConfig.h file for their application.
|
||||
+ Add a template FreeRTOS port which can be used as a starting point for
|
||||
developing a new FreeRTOS port.
|
||||
+ Add bounds checking and obfuscation to internal heap block pointers in
|
||||
heap_4.c and heap_5.c to help catch pointer corruptions. The application can
|
||||
enable these checks by setting configENABLE_HEAP_PROTECTOR to 1 in their
|
||||
FreeRTOSConfig.h. We thank @oliverlavery for their contribution.
|
||||
+ Update vTaskList and vTaskGetRunTimeStats APIs to replace the use of sprintf
|
||||
with snprintf.
|
||||
+ Add trace macros to ports that enable tracing the interaction of ISRs with
|
||||
scheduler events. We thank @conara for their contribution.
|
||||
+ Add trace macros that enable tracing of entering and exiting all APIs. We
|
||||
thank @Techcore123 for their contribution.
|
||||
+ Add uxTaskBasePriorityGet and uxTaskBasePriorityGetFromISR APIs to get the
|
||||
base priority of a task. The base priority of a task is the priority that
|
||||
was last assigned to the task - which due to priority inheritance, may not
|
||||
be the current priority of the task.
|
||||
+ Add pdTICKS_TO_MS macro to convert time in FreeRTOS ticks to time in
|
||||
milliseconds. We thank @Dazza0 for their contribution.
|
||||
+ Add default implementations of vApplicationGetIdleTaskMemory and
|
||||
vApplicationGetTimerTaskMemory. The application can enable these default
|
||||
implementations by setting configKERNEL_PROVIDED_STATIC_MEMORY to 1 in their
|
||||
FreeRTOSConfig.h. We thank @mdnr-g for their contribution.
|
||||
+ Update vTaskGetInfo to include start and end of the stack whenever both
|
||||
values are available. We thank @vinceburns for their contribution.
|
||||
+ Prevent tasks waiting for a notification from being resumed by calls to
|
||||
vTaskResume or vTaskResumeFromISR. We thank @Moral-Hao for their
|
||||
contribution.
|
||||
+ Add asserts to validate that the application has correctly installed
|
||||
FreeRTOS handlers for PendSV and SVCall interrupts on Cortex-M devices.
|
||||
We thank @jefftenney for their contribution.
|
||||
+ Rename ARM_CA53_64_BIT and ARM_CA53_64_BIT_SRE ports to Arm_AARCH64 and
|
||||
Arm_AARCH64_SRE respectively as these ports are applicable to all AArch64
|
||||
architecture. We thank @urutva for their contribution.
|
||||
+ Add CMake support to allow the application writer to select the RISC-V
|
||||
chip extension. We thank @JoeBenczarski for their contribution.
|
||||
+ Add CMake support to allow the application writer to build an application
|
||||
with static allocation only. We thank @conara for their contribution.
|
||||
+ Make taskYIELD available to unprivileged tasks for ARMv8-M ports.
|
||||
+ Update Cortex-M23 ports to not use PSPLIM_NS. We thank @urutva for their
|
||||
contribution.
|
||||
+ Update the SysTick setup code for ARMv8-M ports to first configure the clock
|
||||
source and then enable SysTick. This is needed to address a bug in QEMU
|
||||
versions older than 7.0.0, which causes an emulation error if SysTick is
|
||||
enabled without first selecting a valid clock source. We thank @jefftenney
|
||||
for their contribution.
|
||||
+ Add the port-optimized task selection algorithm optionally available for
|
||||
ARMv7-M ports to the ARMv8-M ports. We thank @jefftenney for their
|
||||
contribution.
|
||||
+ Improve the speed of pvPortMalloc in heap_4.c and heap_5.c by removing
|
||||
unnecessary steps while splitting a large memory block into two. We thank
|
||||
@Moral-Hao for their contribution.
|
||||
+ Shorten the critical section in pvPortMalloc in heap_2.c, heap_4.c and
|
||||
heap_5.c by moving the size calculation out of the critical section. We thank
|
||||
@Moral-Hao for their contribution.
|
||||
+ Update xTaskNotifyWait and ulTaskNotifyTake to remove the non-deterministic
|
||||
operation of traversing a linked link from a critical section. We thank
|
||||
@karver8 for their contribution.
|
||||
+ Fix stack end and stack size computation in POSIX port to meet the stack
|
||||
alignment requirements on MacOS. We thank @tegimeki for their contribution.
|
||||
+ Update the vTaskPrioritySet implementation to use the new priority when the
|
||||
task has inherited priority from a mutex it is holding, and the new priority
|
||||
is bigger than the inherited priority. We thank @Moral-Hao for their
|
||||
contribution.
|
||||
+ Add stack alignment adjustment if stack grows upwards. We thank @ivq for
|
||||
their contribution.
|
||||
+ Fix pxTopOfStack calculation in configINIT_TLS_BLOCK when picolib C is
|
||||
selected as the C library implementation to ensure that
|
||||
pxPortInitialiseStack does not overwrite the data in the TLS block portion
|
||||
of the stack. We thank @bebebib-rs for their contribution.
|
||||
+ Fix vPortEndScheduler() for the MSVC port so that the function
|
||||
prvProcessSimulatedInterrupts is not stuck in an infinite loop when the
|
||||
scheduler is stopped. We thank @Ju1He1 for their contribution.
|
||||
+ Add the Pull Request (PR) Process explaining the stages a PR goes through.
|
||||
|
||||
Changes between FreeRTOS V10.6.1 and FreeRTOS V10.6.2 released November 29, 2023
|
||||
|
||||
+ Add the following improvements to the new MPU wrapper (mpu_wrappers_v2.c)
|
||||
introduced in version 10.6.0:
|
||||
- Introduce Access Control List (ACL) feature to allow the application
|
||||
writer to control an unprivileged task’s access to kernel objects.
|
||||
- Update the system call entry mechanism to only require one Supervisor
|
||||
Call (SVC) instruction.
|
||||
- Wrap parameters for system calls with more than four parameters in a
|
||||
struct to avoid special handling during system call entry.
|
||||
- Fix 2 possible integer overflows.
|
||||
- Convert some asserts to run time parameter checks.
|
||||
|
||||
Changes between FreeRTOS V10.6.0 and FreeRTOS V10.6.1 released August 17, 2023
|
||||
|
||||
+ Add runtime parameter checks to functions in mpu_wrappers_v2.c file.
|
||||
The same checks are already performed in API implementations using
|
||||
asserts.
|
||||
We thank the following people for their inputs in these changes:
|
||||
- Lan Luo, Zixia Liu of School of Computer Science and Technology,
|
||||
Anhui University of Technology, China.
|
||||
- Xinwen Fu of Department of Computer Science, University of
|
||||
Massachusetts Lowell, USA.
|
||||
- Xinhui Shao, Yumeng Wei, Huaiyu Yan, Zhen Ling of School of
|
||||
Computer Science and Engineering, Southeast University, China.
|
||||
|
||||
Changes between FreeRTOS V10.5.1 and FreeRTOS 10.6.0 released July 13, 2023
|
||||
|
||||
+ Add a new MPU wrapper that places additional restrictions on unprivileged
|
||||
|
|
129
MISRA.md
129
MISRA.md
|
@ -8,8 +8,8 @@ has to be efficient. To achieve that and to increase the performance, it
|
|||
deviates from some MISRA rules. The specific deviations, suppressed inline,
|
||||
are listed below.
|
||||
|
||||
Additionally, [MISRA configuration](#misra-configuration) contains project
|
||||
wide deviations.
|
||||
Additionally, [MISRA configuration file](examples/coverity/coverity_misra.config)
|
||||
contains project wide deviations.
|
||||
|
||||
### Suppressed with Coverity Comments
|
||||
To find the violation references in the source files run grep on the source code
|
||||
|
@ -20,25 +20,46 @@ grep 'MISRA Ref 8.4.1' . -rI
|
|||
|
||||
#### Rule 8.4
|
||||
|
||||
MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an
|
||||
object or function with external linkage is defined.
|
||||
|
||||
_Ref 8.4.1_
|
||||
- pxCurrentTCB(s) is defined with external linkage but it is only referenced
|
||||
from the assembly code in the port files. Therefore, adding a declaration in
|
||||
header file is not useful as the assembly code will still need to declare it
|
||||
separately.
|
||||
|
||||
- MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an
|
||||
object or function with external linkage is defined.
|
||||
This rule requires that a compatible declaration is made available
|
||||
in a header file when an object with external linkage is defined.
|
||||
pxCurrentTCB(s) is defined with external linkage but it is only
|
||||
referenced from the assembly code in the port files. Therefore, adding
|
||||
a declaration in header file is not useful as the assembly code will
|
||||
still need to declare it separately.
|
||||
_Ref 8.4.2_
|
||||
- xQueueRegistry is defined with external linkage because it is accessed by the
|
||||
kernel unit tests. It is not meant to be directly accessed by the application
|
||||
and therefore, not declared in a header file.
|
||||
|
||||
#### Rule 8.6
|
||||
|
||||
MISRA C:2012 Rule 8.6: An identifier with external linkage shall have exactly
|
||||
one external definition.
|
||||
|
||||
_Ref 8.6.1_
|
||||
- This rule prohibits an identifier with external linkage to have multiple
|
||||
definitions or no definition. FreeRTOS hook functions are implemented in
|
||||
the application and therefore, have no definition in the Kernel code.
|
||||
|
||||
#### Rule 11.1
|
||||
MISRA C:2012 Rule 11.1: Conversions shall not be performed between a pointer to
|
||||
function and any other type.
|
||||
|
||||
_Ref 11.1.1_
|
||||
- The pointer to function is casted into void to avoid unused parameter
|
||||
compiler warning when Stream Buffer's Tx and Rx Completed callback feature is
|
||||
not used.
|
||||
|
||||
#### Rule 11.3
|
||||
|
||||
_Ref 11.3.1_
|
||||
MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to
|
||||
object type and a pointer to a different object type.
|
||||
|
||||
- MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to
|
||||
object type and a pointer to a different object type.
|
||||
This rule prohibits casting a pointer to object into a pointer to a
|
||||
_Ref 11.3.1_
|
||||
- This rule prohibits casting a pointer to object into a pointer to a
|
||||
different object because it may result in an incorrectly aligned pointer,
|
||||
leading to undefined behavior. Even if the casting produces a correctly
|
||||
aligned pointer, the behavior may be still undefined if the pointer is
|
||||
|
@ -50,42 +71,48 @@ _Ref 11.3.1_
|
|||
checked using configASSERT.
|
||||
|
||||
|
||||
### MISRA configuration
|
||||
#### Rule 11.5
|
||||
|
||||
Copy below content to `misra.conf` to run Coverity on FreeRTOS-Kernel.
|
||||
MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to
|
||||
void into pointer to object.
|
||||
This rule prohibits conversion of a pointer to void into a pointer to
|
||||
object because it may result in an incorrectly aligned pointer leading
|
||||
to undefined behavior.
|
||||
|
||||
```
|
||||
// MISRA C-2012 Rules
|
||||
{
|
||||
version : "2.0",
|
||||
standard : "c2012",
|
||||
title: "Coverity MISRA Configuration",
|
||||
deviations : [
|
||||
// Disable the following rules.
|
||||
{
|
||||
deviation: "Directive 4.8",
|
||||
reason: "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.9",
|
||||
reason: "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 1.2",
|
||||
reason: "The __attribute__ tags are used via macros which are defined in port files."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 3.1",
|
||||
reason: "We post HTTP links in code comments which contain // inside comments blocks."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.7",
|
||||
reason: "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 11.5",
|
||||
reason: "Allow casts from `void *`. List owner, pvOwner, is stored as `void *` and are cast to various types for use in functions."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
_Ref 11.5.1_
|
||||
- The memory blocks returned by pvPortMalloc() are guaranteed to meet the
|
||||
architecture alignment requirements specified by portBYTE_ALIGNMENT.
|
||||
The casting of the pointer to void returned by pvPortMalloc() is,
|
||||
therefore, safe because it is guaranteed to be aligned.
|
||||
|
||||
_Ref 11.5.2_
|
||||
- The conversion from a pointer to void into a pointer to EventGroup_t is
|
||||
safe because it is a pointer to EventGroup_t, which is returned to the
|
||||
application at the time of event group creation for data hiding
|
||||
purposes.
|
||||
|
||||
_Ref 11.5.3_
|
||||
- The conversion from a pointer to void in list macros for list item owner
|
||||
is safe because the type of the pointer stored and retrieved is the
|
||||
same.
|
||||
|
||||
_Ref 11.5.4_
|
||||
- The conversion from a pointer to void into a pointer to EventGroup_t is
|
||||
safe because it is a pointer to EventGroup_t, which is passed as a
|
||||
parameter to the xTimerPendFunctionCallFromISR API when the callback is
|
||||
pended.
|
||||
|
||||
_Ref 11.5.5_
|
||||
- The conversion from a pointer to void into a pointer to uint8_t is safe
|
||||
because data storage buffers are implemented as uint8_t arrays for the
|
||||
ease of sizing, alignment and access.
|
||||
|
||||
#### Rule 21.6
|
||||
|
||||
MISRA C-2012 Rule 21.6: The Standard Library input/output functions shall not
|
||||
be used.
|
||||
|
||||
_Ref 21.6.1_
|
||||
- The Standard Library function snprintf is used in vTaskListTasks and
|
||||
vTaskGetRunTimeStatistics APIs, both of which are utility functions only and
|
||||
are not considered part of core kernel implementation.
|
||||
|
|
|
@ -124,8 +124,8 @@ See the readme file in the ```./portable``` directory for more information.
|
|||
|
||||
- The ```./include``` directory contains the real time kernel header files.
|
||||
|
||||
- The ```./sample_configuration``` directory contains a sample `FreeRTOSConfig.h` to help jumpstart a new project.
|
||||
See the [FreeRTOSConfig.h](examples/sample_configuration/FreeRTOSConfig.h) file for instructions.
|
||||
- The ```./template_configuration``` directory contains a sample `FreeRTOSConfig.h` to help jumpstart a new project.
|
||||
See the [FreeRTOSConfig.h](examples/template_configuration/FreeRTOSConfig.h) file for instructions.
|
||||
|
||||
### Code Formatting
|
||||
|
||||
|
|
|
@ -110,6 +110,9 @@
|
|||
traceENTER_xCoRoutineCreate( pxCoRoutineCode, uxPriority, uxIndex );
|
||||
|
||||
/* Allocate the memory that will store the co-routine control block. */
|
||||
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||
|
||||
if( pxCoRoutine )
|
||||
|
|
|
@ -40,11 +40,10 @@
|
|||
#include "timers.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
||||
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
* for the header files above, but not in this file, in order to generate the
|
||||
* correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
typedef struct EventGroupDef_t
|
||||
{
|
||||
|
@ -94,7 +93,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
|||
* event group structure. */
|
||||
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||
} /*lint !e529 xSize is referenced if configASSERT() is defined. */
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* The user has provided a statically allocated event group - use it. */
|
||||
|
@ -143,20 +142,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
|||
|
||||
traceENTER_xEventGroupCreate();
|
||||
|
||||
/* Allocate the event group. Justification for MISRA deviation as
|
||||
* follows: pvPortMalloc() always ensures returned memory blocks are
|
||||
* aligned per the requirements of the MCU stack. In this case
|
||||
* pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||
* alignment requirements of the EventGroup_t structure - which (if you
|
||||
* follow it through) is the alignment requirements of the TickType_t type
|
||||
* (EventBits_t being of TickType_t itself). Therefore, whenever the
|
||||
* stack alignment requirements are greater than or equal to the
|
||||
* TickType_t alignment requirements the cast is safe. In other cases,
|
||||
* where the natural word size of the architecture is less than
|
||||
* sizeof( TickType_t ), the TickType_t variables will be accessed in two
|
||||
* or more reads operations, and the alignment requirements is only that
|
||||
* of each individual read. */
|
||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
|
||||
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
|
@ -176,7 +165,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
|||
}
|
||||
else
|
||||
{
|
||||
traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
|
||||
traceEVENT_GROUP_CREATE_FAILED();
|
||||
}
|
||||
|
||||
traceRETURN_xEventGroupCreate( pxEventBits );
|
||||
|
@ -516,7 +505,7 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
|||
traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear );
|
||||
|
||||
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
||||
|
||||
traceRETURN_xEventGroupClearBitsFromISR( xReturn );
|
||||
|
||||
|
@ -543,7 +532,7 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
|||
traceRETURN_xEventGroupGetBitsFromISR( uxReturn );
|
||||
|
||||
return uxReturn;
|
||||
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
|
@ -565,7 +554,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
|||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxListEnd = listGET_END_MARKER( pxList );
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||
|
@ -745,11 +734,14 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
|||
/* For internal use only - execute a 'set bits' command that was pended from
|
||||
* an interrupt. */
|
||||
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToSet )
|
||||
uint32_t ulBitsToSet )
|
||||
{
|
||||
traceENTER_vEventGroupSetBitsCallback( pvEventGroup, ulBitsToSet );
|
||||
|
||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
/* MISRA Ref 11.5.4 [Callback function parameter] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
||||
|
||||
traceRETURN_vEventGroupSetBitsCallback();
|
||||
}
|
||||
|
@ -758,11 +750,14 @@ void vEventGroupSetBitsCallback( void * pvEventGroup,
|
|||
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||
* an interrupt. */
|
||||
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToClear )
|
||||
uint32_t ulBitsToClear )
|
||||
{
|
||||
traceENTER_vEventGroupClearBitsCallback( pvEventGroup, ulBitsToClear );
|
||||
|
||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
/* MISRA Ref 11.5.4 [Callback function parameter] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
|
||||
|
||||
traceRETURN_vEventGroupClearBitsCallback();
|
||||
}
|
||||
|
@ -816,7 +811,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
|||
traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||
|
||||
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||
|
||||
traceRETURN_xEventGroupSetBitsFromISR( xReturn );
|
||||
|
||||
|
@ -831,7 +826,11 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
|||
UBaseType_t uxEventGroupGetNumber( void * xEventGroup )
|
||||
{
|
||||
UBaseType_t xReturn;
|
||||
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
|
||||
/* MISRA Ref 11.5.2 [Opaque pointer] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||
|
||||
traceENTER_uxEventGroupGetNumber( xEventGroup );
|
||||
|
||||
|
@ -859,7 +858,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
|||
{
|
||||
traceENTER_vEventGroupSetNumber( xEventGroup, uxEventGroupNumber );
|
||||
|
||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
/* MISRA Ref 11.5.2 [Opaque pointer] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;
|
||||
|
||||
traceRETURN_vEventGroupSetNumber();
|
||||
}
|
||||
|
|
|
@ -7,18 +7,15 @@ set(FREERTOS_KERNEL_PATH "../../")
|
|||
# Add the freertos_config for FreeRTOS-Kernel
|
||||
add_library(freertos_config INTERFACE)
|
||||
|
||||
target_include_directories(freertos_config
|
||||
INTERFACE
|
||||
"../template_configuration"
|
||||
)
|
||||
|
||||
if (DEFINED FREERTOS_SMP_EXAMPLE AND FREERTOS_SMP_EXAMPLE STREQUAL "1")
|
||||
message(STATUS "Build FreeRTOS SMP example")
|
||||
target_include_directories(freertos_config
|
||||
INTERFACE
|
||||
"../sample_configuration/smp"
|
||||
)
|
||||
else()
|
||||
message(STATUS "Build FreeRTOS example")
|
||||
target_include_directories(freertos_config
|
||||
INTERFACE
|
||||
"../sample_configuration"
|
||||
)
|
||||
# Adding the following configurations to build SMP template port
|
||||
add_compile_options( -DconfigNUMBER_OF_CORES=2 -DconfigUSE_PASSIVE_IDLE_HOOK=0 )
|
||||
endif()
|
||||
|
||||
# Select the heap port. values between 1-4 will pick a heap.
|
||||
|
|
|
@ -33,17 +33,16 @@
|
|||
* https://freertos.org/FreeRTOS-quick-start-guide.html
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <queue.h>
|
||||
#include <timers.h>
|
||||
#include <semphr.h>
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
static StaticTask_t exampleTaskTCB;
|
||||
static StackType_t exampleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
void exampleTask( void * parameters )
|
||||
{
|
||||
/* Unused parameters. */
|
||||
|
@ -55,9 +54,13 @@ void exampleTask( void * parameters )
|
|||
vTaskDelay( 100 ); /* delay 100 ticks */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main( void )
|
||||
{
|
||||
static StaticTask_t exampleTaskTCB;
|
||||
static StackType_t exampleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
printf( "Example FreeRTOS Project\n" );
|
||||
|
||||
xTaskCreateStatic( exampleTask,
|
||||
|
@ -65,8 +68,8 @@ void main( void )
|
|||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
configMAX_PRIORITIES - 1,
|
||||
exampleTaskStack,
|
||||
&exampleTaskTCB );
|
||||
&( exampleTaskStack[ 0 ] ),
|
||||
&( exampleTaskTCB ) );
|
||||
|
||||
/* Start the scheduler. */
|
||||
vTaskStartScheduler();
|
||||
|
@ -76,6 +79,7 @@ void main( void )
|
|||
/* Should not reach here. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationStackOverflowHook( TaskHandle_t xTask,
|
||||
char * pcTaskName )
|
||||
|
@ -85,3 +89,4 @@ void vApplicationStackOverflowHook( TaskHandle_t xTask,
|
|||
( void ) xTask;
|
||||
( void ) pcTaskName;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
39
examples/coverity/CMakeLists.txt
Normal file
39
examples/coverity/CMakeLists.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(coverity)
|
||||
|
||||
set(FREERTOS_KERNEL_PATH "../../")
|
||||
FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}*.c)
|
||||
|
||||
# Coverity incorrectly infers the type of pdTRUE and pdFALSE as boolean because
|
||||
# of their names. This generates multiple false positive warnings about type
|
||||
# mismatch. Replace pdTRUE with pdPASS and pdFALSE with pdFAIL to avoid these
|
||||
# false positive warnings. This workaround will not be needed after Coverity
|
||||
# fixes the issue of incorrectly inferring the type of pdTRUE and pdFALSE as
|
||||
# boolean.
|
||||
add_custom_target(fix_source ALL
|
||||
COMMAND sed -i -b -e 's/pdFALSE/pdFAIL/g' -e 's/pdTRUE/pdPASS/g' ${FREERTOS_KERNEL_SOURCE}
|
||||
DEPENDS ${FREERTOS_KERNEL_SOURCE})
|
||||
|
||||
# Add the freertos_config for FreeRTOS-Kernel.
|
||||
add_library(freertos_config INTERFACE)
|
||||
|
||||
target_include_directories(freertos_config
|
||||
INTERFACE
|
||||
./)
|
||||
|
||||
# Select the heap. Values between 1-5 will pick a heap.
|
||||
set(FREERTOS_HEAP "3" CACHE STRING "" FORCE)
|
||||
|
||||
# Select the FreeRTOS port.
|
||||
set(FREERTOS_PORT "TEMPLATE" CACHE STRING "" FORCE)
|
||||
|
||||
# Add the FreeRTOS-Kernel subdirectory.
|
||||
add_subdirectory(${FREERTOS_KERNEL_PATH} FreeRTOS-Kernel)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
../cmake_example/main.c)
|
||||
|
||||
add_dependencies(${PROJECT_NAME} fix_source)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} freertos_kernel freertos_config)
|
135
examples/coverity/FreeRTOSConfig.h
Normal file
135
examples/coverity/FreeRTOSConfig.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/******************************************************************************/
|
||||
/* Hardware description related definitions. **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 )
|
||||
|
||||
/******************************************************************************/
|
||||
/* Scheduling behaviour related definitions. **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configTICK_RATE_HZ ( 100U )
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_TIME_SLICING 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_TICKLESS_IDLE 1
|
||||
#define configMAX_PRIORITIES 5U
|
||||
#define configMINIMAL_STACK_SIZE 128U
|
||||
#define configMAX_TASK_NAME_LEN 4U
|
||||
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_64_BITS
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1U
|
||||
#define configQUEUE_REGISTRY_SIZE 0U
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
|
||||
#define configSTACK_DEPTH_TYPE size_t
|
||||
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* Software timer related definitions. ****************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1U )
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
#define configTIMER_QUEUE_LENGTH 10U
|
||||
|
||||
/******************************************************************************/
|
||||
/* Memory allocation related definitions. *************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configTOTAL_HEAP_SIZE 4096U
|
||||
#define configAPPLICATION_ALLOCATED_HEAP 1
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
#define configUSE_MINI_LIST_ITEM 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* Interrupt nesting behaviour configuration. *********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 0U
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0U
|
||||
#define configMAX_API_CALL_INTERRUPT_PRIORITY 0U
|
||||
|
||||
/******************************************************************************/
|
||||
/* Hook and callback function related definitions. ****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* Run time and task stats gathering related definitions. *********************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
#define configKERNEL_PROVIDED_STATIC_MEMORY 1
|
||||
|
||||
/******************************************************************************/
|
||||
/* Definitions that include or exclude functionality. *************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
#define configUSE_APPLICATION_TASK_TAG 1
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_xResumeFromISR 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
58
examples/coverity/README.md
Normal file
58
examples/coverity/README.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
# MISRA Compliance for FreeRTOS-Kernel
|
||||
FreeRTOS-Kernel is MISRA C:2012 compliant. This directory contains a project to
|
||||
run [Synopsys Coverity](https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html)
|
||||
for checking MISRA compliance.
|
||||
|
||||
> **Note**
|
||||
Coverity version 2022.6.1 incorrectly infers the type of `pdTRUE` and `pdFALSE`
|
||||
as boolean because of their names, resulting in multiple false positive warnings
|
||||
about type mismatch. We replace `pdTRUE` with `pdPASS` and `pdFALSE` with
|
||||
`pdFAIL` to avoid these false positive warnings. This workaround will not be
|
||||
needed after Coverity fixes the issue of incorrectly inferring the type of
|
||||
`pdTRUE` and `pdFALSE` as boolean.
|
||||
|
||||
Deviations from the MISRA C:2012 guidelines are documented in
|
||||
[MISRA.md](../../MISRA.md) and [coverity_misra.config](coverity_misra.config)
|
||||
files.
|
||||
|
||||
## Getting Started
|
||||
### Prerequisites
|
||||
Coverity can be run on any platform mentioned [here](https://sig-docs.synopsys.com/polaris/topics/c_coverity-compatible-platforms.html).
|
||||
The following are the prerequisites to generate coverity report:
|
||||
|
||||
1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`).
|
||||
2. GCC compiler.
|
||||
- See download and installation instructions [here](https://gcc.gnu.org/install/).
|
||||
3. Clone the repo using the following command:
|
||||
- `git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git ./FreeRTOS-Kernel`
|
||||
|
||||
### Generating Report
|
||||
Go to the root directory of the FreeRTOS-Kernel repo and run the following
|
||||
commands in a terminal:
|
||||
1. Update the compiler configuration in Coverity:
|
||||
~~~
|
||||
cov-configure --force --compiler cc --comptype gcc
|
||||
~~~
|
||||
2. Create the build files using CMake in a `build` directory:
|
||||
~~~
|
||||
cmake -B build -S examples/coverity
|
||||
~~~
|
||||
3. Build the (pseudo) application:
|
||||
~~~
|
||||
cd build/
|
||||
cov-build --emit-complementary-info --dir cov-out make
|
||||
~~~
|
||||
4. Go to the Coverity output directory (`cov-out`) and begin Coverity static
|
||||
analysis:
|
||||
~~~
|
||||
cd cov-out/
|
||||
cov-analyze --dir ./cov-out \
|
||||
--coding-standard-config ../examples/coverity/coverity_misra.config \
|
||||
--tu-pattern "file('.*/FreeRTOS/Source/[A-Za-z_]*\.c')
|
||||
~~~
|
||||
5. Generate the HTML report:
|
||||
~~~
|
||||
cov-format-errors --dir ./cov-out --html-output html-output
|
||||
~~~
|
||||
|
||||
HTML report should now be generated in a directory named `html-output`.
|
97
examples/coverity/coverity_misra.config
Normal file
97
examples/coverity/coverity_misra.config
Normal file
|
@ -0,0 +1,97 @@
|
|||
// MISRA C-2012 Rules
|
||||
|
||||
{
|
||||
version : "2.0",
|
||||
standard : "c2012",
|
||||
title: "Coverity MISRA Configuration",
|
||||
deviations : [
|
||||
// Disable the following rules.
|
||||
{
|
||||
deviation: "Rule 3.1",
|
||||
reason: "We post HTTP links in code comments which contain // inside comments blocks."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 14.4",
|
||||
reason: "do while( 0 ) pattern is used in macros to prevent extra semi-colon."
|
||||
},
|
||||
|
||||
// Disable the following advisory rules and directives.
|
||||
{
|
||||
deviation: "Directive 4.4",
|
||||
reason: "Code snippet is used in comment to help explanation."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.5",
|
||||
reason: "Allow names that MISRA considers ambiguous."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.6",
|
||||
reason: "Allow port to use primitive type with typedefs."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.8",
|
||||
reason: "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.9",
|
||||
reason: "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 2.3",
|
||||
reason: "FreeRTOS defines types which is used in application."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 2.4",
|
||||
reason: "Allow to define unused tag."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 2.5",
|
||||
reason: "Allow to define unused macro."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 5.9",
|
||||
reason: "Allow to define identifier with the same name in structure and global variable."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.7",
|
||||
reason: "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.9",
|
||||
reason: "Allow to object to be defined in wider scope for debug purpose."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.13",
|
||||
reason: "Allow to not to use const-qualified type for callback function."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 11.4",
|
||||
reason: "Allow to convert between a pointer to object and an interger type for stack alignment."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 15.4",
|
||||
reason: "Allow to use multiple break statements in a loop."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 15.5",
|
||||
reason: "Allow to use multiple points of exit."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 17.8",
|
||||
reason: "Allow to update the parameters of a function."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 18.4",
|
||||
reason: "Allow to use pointer arithmetic."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 19.2",
|
||||
reason: "Allow to use union."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 20.5",
|
||||
reason: "Allow to use #undef for MPU wrappers."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* This file provides an example FreeRTOSConfig.h header file, inclusive of an
|
||||
* abbreviated explanation of each configuration item. Online and reference
|
||||
* documentation provides more information.
|
||||
* https://www.freertos.org/a00110.html
|
||||
*
|
||||
* Constant values enclosed in square brackets ('[' and ']') must be completed
|
||||
* before this file will build.
|
||||
*
|
||||
* Use the FreeRTOSConfig.h supplied with the RTOS port in use rather than this
|
||||
* generic file, if one is available.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __FREERTOS_CONFIG_SMP_H__
|
||||
#define __FREERTOS_CONFIG_SMP_H__
|
||||
|
||||
#include "../FreeRTOSConfig.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Scheduling behaviour related definitions. **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Set configNUMBER_OF_CORES to greater than 1 to enable running one instance of
|
||||
* FreeRTOS kernel to schedule tasks across multiple identical processor cores. */
|
||||
#define configNUMBER_OF_CORES 2
|
||||
|
||||
/******************************************************************************/
|
||||
/* Hook and callback function related definitions. ****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Set the following configUSE_* constants to 1 to include the named hook
|
||||
* functionality in the build. Set to 0 to exclude the hook functionality from the
|
||||
* build. The application writer is responsible for providing the hook function
|
||||
* for any set to 1. See https://www.freertos.org/a00016.html */
|
||||
#define configUSE_PASSIVE_IDLE_HOOK 0
|
||||
|
||||
#endif /* __FREERTOS_CONFIG_SMP_H__ */
|
|
@ -1,10 +0,0 @@
|
|||
# Configuration support for FreeRTOS SMP
|
||||
|
||||
## Overview
|
||||
The FreeRTOSConfig.h provided in this folder is a sample configuration that will
|
||||
assist you in preparing the configuration to enable SMP support in the FreeRTOS
|
||||
Kernel for your application.
|
||||
|
||||
Based on single core sample configuration file, this configuration file is created
|
||||
with minimal configuration change. More SMP scheduler configurations can be found
|
||||
in [Symmetric Multiprocessing (SMP) with FreeRTOS](https://freertos.org/symmetric-multiprocessing-introduction.html)
|
|
@ -39,8 +39,8 @@
|
|||
* generic file, if one is available.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __FREERTOS_CONFIG_H__
|
||||
#define __FREERTOS_CONFIG_H__
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/******************************************************************************/
|
||||
/* Hardware description related definitions. **********************************/
|
||||
|
@ -63,7 +63,7 @@
|
|||
* frequency, as normal, and configSYSTICK_CLOCK_HZ to the SysTick clock
|
||||
* frequency. Not used if left undefined.
|
||||
* The default value is undefined (commented out). If you need this value bring it
|
||||
* back and set it to a suitable value */
|
||||
* back and set it to a suitable value. */
|
||||
|
||||
/*
|
||||
#define configSYSTICK_CLOCK_HZ [Platform specific]
|
||||
|
@ -79,14 +79,14 @@
|
|||
|
||||
/* Set configUSE_PREEMPTION to 1 to use pre-emptive scheduling. Set
|
||||
* configUSE_PREEMPTION to 0 to use co-operative scheduling.
|
||||
* See https://www.freertos.org/single-core-amp-smp-rtos-scheduling.html */
|
||||
* See https://www.freertos.org/single-core-amp-smp-rtos-scheduling.html. */
|
||||
#define configUSE_PREEMPTION 1
|
||||
|
||||
/* Set configUSE_TIME_SLICING to 1 to have the scheduler switch between Ready
|
||||
* state tasks of equal priority on every tick interrupt. Set
|
||||
* configUSE_TIME_SLICING to 0 to prevent the scheduler switching between Ready
|
||||
* state tasks just because there was a tick interrupt. See
|
||||
* https://freertos.org/single-core-amp-smp-rtos-scheduling.html */
|
||||
* https://freertos.org/single-core-amp-smp-rtos-scheduling.html. */
|
||||
#define configUSE_TIME_SLICING 0
|
||||
|
||||
/* Set configUSE_PORT_OPTIMISED_TASK_SELECTION to 1 to select the next task to
|
||||
|
@ -162,6 +162,13 @@
|
|||
* Defaults to 0 if left undefined. */
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
|
||||
|
||||
/* When configUSE_MINI_LIST_ITEM is set to 0, MiniListItem_t and ListItem_t are
|
||||
* both the same. When configUSE_MINI_LIST_ITEM is set to 1, MiniListItem_t contains
|
||||
* 3 fewer fields than ListItem_t which saves some RAM at the cost of violating
|
||||
* strict aliasing rules which some compilers depend on for optimization. Defaults
|
||||
* to 1 if left undefined. */
|
||||
#define configUSE_MINI_LIST_ITEM 1
|
||||
|
||||
/* Sets the type used by the parameter to xTaskCreate() that specifies the stack
|
||||
* size of the task being created. The same type is used to return information
|
||||
* about stack usage in various other API calls. Defaults to size_t if left
|
||||
|
@ -174,6 +181,19 @@
|
|||
* space if messages never go above a length that could be held in a uint8_t. */
|
||||
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
|
||||
/* If configHEAP_CLEAR_MEMORY_ON_FREE is set to 1, then blocks of memory allocated
|
||||
* using pvPortMalloc() will be cleared (i.e. set to zero) when freed using
|
||||
* vPortFree(). Defaults to 0 if left undefined. */
|
||||
#define configHEAP_CLEAR_MEMORY_ON_FREE 1
|
||||
|
||||
/* vTaskList and vTaskGetRunTimeStats APIs take a buffer as a parameter and assume
|
||||
* that the length of the buffer is configSTATS_BUFFER_MAX_LENGTH. Defaults to
|
||||
* 0xFFFF if left undefined.
|
||||
* New applications are recommended to use vTaskListTasks and
|
||||
* vTaskGetRunTimeStatistics APIs instead and supply the length of the buffer
|
||||
* explicitly to avoid memory corruption. */
|
||||
#define configSTATS_BUFFER_MAX_LENGTH 0xFFFF
|
||||
|
||||
/* Set configUSE_NEWLIB_REENTRANT to 1 to have a newlib reent structure
|
||||
* allocated for each task. Set to 0 to not support newlib reent structures.
|
||||
* Default to 0 if left undefined.
|
||||
|
@ -194,7 +214,7 @@
|
|||
* build. Set to 0 to exclude software timer functionality from the build. The
|
||||
* FreeRTOS/source/timers.c source file must be included in the build if
|
||||
* configUSE_TIMERS is set to 1. Default to 0 if left undefined. See
|
||||
* https://www.freertos.org/RTOS-software-timer.html */
|
||||
* https://www.freertos.org/RTOS-software-timer.html. */
|
||||
#define configUSE_TIMERS 1
|
||||
|
||||
/* configTIMER_TASK_PRIORITY sets the priority used by the timer task. Only
|
||||
|
@ -224,20 +244,20 @@
|
|||
* that create FreeRTOS objects (tasks, queues, etc.) using statically allocated
|
||||
* memory in the build. Set to 0 to exclude the ability to create statically
|
||||
* allocated objects from the build. Defaults to 0 if left undefined. See
|
||||
* https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html */
|
||||
* https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
|
||||
/* Set configSUPPORT_DYNAMIC_ALLOCATION to 1 to include FreeRTOS API functions
|
||||
* that create FreeRTOS objects (tasks, queues, etc.) using dynamically allocated
|
||||
* memory in the build. Set to 0 to exclude the ability to create dynamically
|
||||
* allocated objects from the build. Defaults to 1 if left undefined. See
|
||||
* https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html */
|
||||
* https://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html. */
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
|
||||
/* Sets the total size of the FreeRTOS heap, in bytes, when heap_1.c, heap_2.c
|
||||
* or heap_4.c are included in the build. This value is defaulted to 4096 bytes but
|
||||
* it must be tailored to each application. Note the heap will appear in the .bss
|
||||
* section. See https://www.freertos.org/a00111.html */
|
||||
* section. See https://www.freertos.org/a00111.html. */
|
||||
#define configTOTAL_HEAP_SIZE 4096
|
||||
|
||||
/* Set configAPPLICATION_ALLOCATED_HEAP to 1 to have the application allocate
|
||||
|
@ -253,6 +273,11 @@
|
|||
* Defaults to 0 if left undefined. */
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
|
||||
/* Set configENABLE_HEAP_PROTECTOR to 1 to enable bounds checking and obfuscation
|
||||
* to internal heap block pointers in heap_4.c and heap_5.c to help catch pointer
|
||||
* corruptions. Defaults to 0 if left undefined. */
|
||||
#define configENABLE_HEAP_PROTECTOR 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* Interrupt nesting behaviour configuration. *********************************/
|
||||
/******************************************************************************/
|
||||
|
@ -283,12 +308,20 @@
|
|||
/* Set the following configUSE_* constants to 1 to include the named hook
|
||||
* functionality in the build. Set to 0 to exclude the hook functionality from the
|
||||
* build. The application writer is responsible for providing the hook function
|
||||
* for any set to 1. See https://www.freertos.org/a00016.html */
|
||||
* for any set to 1. See https://www.freertos.org/a00016.html. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
|
||||
/* Set configUSE_SB_COMPLETED_CALLBACK to 1 to have send and receive completed
|
||||
* callbacks for each instance of a stream buffer or message buffer. When the
|
||||
* option is set to 1, APIs xStreamBufferCreateWithCallback() and
|
||||
* xStreamBufferCreateStaticWithCallback() (and likewise APIs for message
|
||||
* buffer) can be used to create a stream buffer or message buffer instance
|
||||
* with application provided callbacks. Defaults to 0 if left undefined. */
|
||||
#define configUSE_SB_COMPLETED_CALLBACK 0
|
||||
|
||||
/* Set configCHECK_FOR_STACK_OVERFLOW to 1 or 2 for FreeRTOS to check for a
|
||||
* stack overflow at the time of a context switch. Set to 0 to not look for a
|
||||
* stack overflow. If configCHECK_FOR_STACK_OVERFLOW is 1 then the check only
|
||||
|
@ -307,9 +340,9 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* Set configGENERATE_RUN_TIME_STATS to 1 to have FreeRTOS collect data on the
|
||||
* processing time used by each task. Set to 0 to not collect the data. The
|
||||
* application writer needs to provide a clock source if set to 1. Defaults to 0
|
||||
* if left undefined. See https://www.freertos.org/rtos-run-time-stats.html */
|
||||
* processing time used by each task. Set to 0 to not collect the data. The
|
||||
* application writer needs to provide a clock source if set to 1. Defaults to 0
|
||||
* if left undefined. See https://www.freertos.org/rtos-run-time-stats.html. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
|
||||
/* Set configUSE_TRACE_FACILITY to include additional task structure members
|
||||
|
@ -325,6 +358,21 @@
|
|||
* undefined. */
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* Co-routine related definitions. ********************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Set configUSE_CO_ROUTINES 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. Defaults to 0 if left
|
||||
* undefined. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
|
||||
/* configMAX_CO_ROUTINE_PRIORITIES defines the number of priorities available
|
||||
* to the application co-routines. Any number of co-routines can share the same
|
||||
* priority. Defaults to 0 if left undefined. */
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 1
|
||||
|
||||
/******************************************************************************/
|
||||
/* Debugging assistance. ******************************************************/
|
||||
/******************************************************************************/
|
||||
|
@ -346,7 +394,7 @@
|
|||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M MPU specific definitions. *****************************************/
|
||||
/* FreeRTOS MPU specific definitions. *****************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* If configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS is set to 1 then
|
||||
|
@ -380,16 +428,93 @@
|
|||
* escalations originating from outside of the kernel code itself. Set to 1 to
|
||||
* allow application tasks to raise privilege. Defaults to 1 if left undefined.
|
||||
* Only used by the FreeRTOS Cortex-M MPU ports, not the standard ARMv7-M Cortex-M
|
||||
* port.*/
|
||||
* port. */
|
||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1
|
||||
|
||||
/* Set configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS to 1 to allow unprivileged
|
||||
* tasks enter critical sections (effectively mask interrupts). Set to 0 to
|
||||
* prevent unprivileged tasks entering critical sections. Defaults to 1 if left
|
||||
* undefined. Only used by the FreeRTOS Cortex-M MPU ports, not the standard
|
||||
* ARMv7-M Cortex-M port.*/
|
||||
* ARMv7-M Cortex-M port. */
|
||||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0
|
||||
|
||||
/* FreeRTOS Kernel version 10.6.0 introduced a new v2 MPU wrapper, namely
|
||||
* mpu_wrappers_v2.c. Set configUSE_MPU_WRAPPERS_V1 to 0 to use the new v2 MPU
|
||||
* wrapper. Set configUSE_MPU_WRAPPERS_V1 to 1 to use the old v1 MPU wrapper
|
||||
* (mpu_wrappers.c). Defaults to 0 if left undefined. */
|
||||
#define configUSE_MPU_WRAPPERS_V1 0
|
||||
|
||||
/* When using the v2 MPU wrapper, set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to
|
||||
* the total number of kernel objects, which includes tasks, queues, semaphores,
|
||||
* mutexes, event groups, timers, stream buffers and message buffers, in your
|
||||
* application. The application will not be able to have more than
|
||||
* configPROTECTED_KERNEL_OBJECT_POOL_SIZE kernel objects at any point of
|
||||
* time. */
|
||||
#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 10
|
||||
|
||||
/* When using the v2 MPU wrapper, set configSYSTEM_CALL_STACK_SIZE to the size
|
||||
* of the system call stack in words. Each task has a statically allocated
|
||||
* memory buffer of this size which is used as the stack to execute system
|
||||
* calls. For example, if configSYSTEM_CALL_STACK_SIZE is defined as 128 and
|
||||
* there are 10 tasks in the application, the total amount of memory used for
|
||||
* system call stacks is 128 * 10 = 1280 words. */
|
||||
#define configSYSTEM_CALL_STACK_SIZE 128
|
||||
|
||||
/* When using the v2 MPU wrapper, set configENABLE_ACCESS_CONTROL_LIST to 1 to
|
||||
* enable Access Control List (ACL) feature. When ACL is enabled, an
|
||||
* unprivileged task by default does not have access to any kernel object other
|
||||
* than itself. The application writer needs to explicitly grant the
|
||||
* unprivileged task access to the kernel objects it needs using the APIs
|
||||
* provided for the same. Defaults to 0 if left undefined. */
|
||||
#define configENABLE_ACCESS_CONTROL_LIST 1
|
||||
|
||||
/******************************************************************************/
|
||||
/* SMP( Symmetric MultiProcessing ) Specific Configuration definitions. *******/
|
||||
/******************************************************************************/
|
||||
|
||||
/* Set configNUMBER_OF_CORES to the number of available processor cores. Defaults
|
||||
* to 1 if left undefined. */
|
||||
|
||||
/*
|
||||
#define configNUMBER_OF_CORES [Num of available cores]
|
||||
*/
|
||||
|
||||
/* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), set
|
||||
* configRUN_MULTIPLE_PRIORITIES to 0 to allow multiple tasks to run
|
||||
* simultaneously only if they do not have equal priority, thereby maintaining
|
||||
* the paradigm of a lower priority task never running if a higher priority task
|
||||
* is able to run. If configRUN_MULTIPLE_PRIORITIES is set to 1, multiple tasks
|
||||
* with different priorities may run simultaneously - so a higher and lower
|
||||
* priority task may run on different cores at the same time. */
|
||||
#define configRUN_MULTIPLE_PRIORITIES 0
|
||||
|
||||
/* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), set
|
||||
* configUSE_CORE_AFFINITY to 1 to enable core affinity feature. When core
|
||||
* affinity feature is enabled, the vTaskCoreAffinitySet and vTaskCoreAffinityGet
|
||||
* APIs can be used to set and retrieve which cores a task can run on. If
|
||||
* configUSE_CORE_AFFINITY is set to 0 then the FreeRTOS scheduler is free to
|
||||
* run any task on any available core. */
|
||||
#define configUSE_CORE_AFFINITY 0
|
||||
|
||||
/* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), if
|
||||
* configUSE_TASK_PREEMPTION_DISABLE is set to 1, individual tasks can be set to
|
||||
* either pre-emptive or co-operative mode using the vTaskPreemptionDisable and
|
||||
* vTaskPreemptionEnable APIs. */
|
||||
#define configUSE_TASK_PREEMPTION_DISABLE 0
|
||||
|
||||
/* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), set
|
||||
* configUSE_PASSIVE_IDLE_HOOK to 1 to allow the application writer to use
|
||||
* the passive idle task hook to add background functionality without the overhead
|
||||
* of a separate task. Defaults to 0 if left undefined. */
|
||||
#define configUSE_PASSIVE_IDLE_HOOK 0
|
||||
|
||||
/* When using SMP (i.e. configNUMBER_OF_CORES is greater than one),
|
||||
* configTIMER_SERVICE_TASK_CORE_AFFINITY allows the application writer to set
|
||||
* the core affinity of the RTOS Daemon/Timer Service task. Defaults to
|
||||
* tskNO_AFFINITY if left undefined. */
|
||||
#define configTIMER_SERVICE_TASK_CORE_AFFINITY tskNO_AFFINITY
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* ARMv8-M secure side port related definitions. ******************************/
|
||||
/******************************************************************************/
|
||||
|
@ -440,4 +565,4 @@
|
|||
#define INCLUDE_xTaskGetHandle 0
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
|
||||
#endif /* __FREERTOS_CONFIG_H__ */
|
||||
#endif /* FREERTOS_CONFIG_H */
|
|
@ -365,6 +365,17 @@
|
|||
#define configPRECONDITION_DEFINED 1
|
||||
#endif
|
||||
|
||||
#ifndef configCHECK_HANDLER_INSTALLATION
|
||||
#define configCHECK_HANDLER_INSTALLATION 1
|
||||
#else
|
||||
|
||||
/* The application has explicitly defined configCHECK_HANDLER_INSTALLATION
|
||||
* to 1. The checks requires configASSERT() to be defined. */
|
||||
#if ( ( configCHECK_HANDLER_INSTALLATION == 1 ) && ( configASSERT_DEFINED == 0 ) )
|
||||
#error You must define configASSERT() when configCHECK_HANDLER_INSTALLATION is 1.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef portMEMORY_BARRIER
|
||||
#define portMEMORY_BARRIER()
|
||||
#endif
|
||||
|
@ -498,12 +509,36 @@
|
|||
|
||||
#endif /* configUSE_TIMERS */
|
||||
|
||||
#ifndef portHAS_NESTED_INTERRUPTS
|
||||
#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) && defined( portCLEAR_INTERRUPT_MASK_FROM_ISR )
|
||||
#define portHAS_NESTED_INTERRUPTS 1
|
||||
#else
|
||||
#define portHAS_NESTED_INTERRUPTS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
|
||||
#if ( portHAS_NESTED_INTERRUPTS == 1 )
|
||||
#error portSET_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1)
|
||||
#else
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#endif
|
||||
#else
|
||||
#if ( portHAS_NESTED_INTERRUPTS == 0 )
|
||||
#error portSET_INTERRUPT_MASK_FROM_ISR must not be defined for ports that do not support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
|
||||
#if ( portHAS_NESTED_INTERRUPTS == 1 )
|
||||
#error portCLEAR_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1)
|
||||
#else
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue )
|
||||
#endif
|
||||
#else
|
||||
#if ( portHAS_NESTED_INTERRUPTS == 0 )
|
||||
#error portCLEAR_INTERRUPT_MASK_FROM_ISR must not be defined for ports that do not support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef portCLEAN_UP_TCB
|
||||
|
@ -518,6 +553,10 @@
|
|||
#define portSETUP_TCB( pxTCB ) ( void ) ( pxTCB )
|
||||
#endif
|
||||
|
||||
#ifndef portTASK_SWITCH_HOOK
|
||||
#define portTASK_SWITCH_HOOK( pxTCB ) ( void ) ( pxTCB )
|
||||
#endif
|
||||
|
||||
#ifndef configQUEUE_REGISTRY_SIZE
|
||||
#define configQUEUE_REGISTRY_SIZE 0U
|
||||
#endif
|
||||
|
@ -1886,14 +1925,20 @@
|
|||
#ifndef traceENTER_xTaskGetIdleTaskHandle
|
||||
#define traceENTER_xTaskGetIdleTaskHandle()
|
||||
#endif
|
||||
#else
|
||||
#ifndef traceENTER_xTaskGetIdleTaskHandle
|
||||
#define traceENTER_xTaskGetIdleTaskHandle( xCoreID )
|
||||
#endif
|
||||
|
||||
#if ( configNUMBER_OF_CORES == 1 )
|
||||
#ifndef traceRETURN_xTaskGetIdleTaskHandle
|
||||
#define traceRETURN_xTaskGetIdleTaskHandle( xIdleTaskHandle )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef traceRETURN_xTaskGetIdleTaskHandle
|
||||
#define traceRETURN_xTaskGetIdleTaskHandle( xIdleTaskHandle )
|
||||
#ifndef traceENTER_xTaskGetIdleTaskHandleForCore
|
||||
#define traceENTER_xTaskGetIdleTaskHandleForCore( xCoreID )
|
||||
#endif
|
||||
|
||||
#ifndef traceRETURN_xTaskGetIdleTaskHandleForCore
|
||||
#define traceRETURN_xTaskGetIdleTaskHandleForCore( xIdleTaskHandle )
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_vTaskStepTick
|
||||
|
@ -2464,6 +2509,22 @@
|
|||
#define traceRETURN_xStreamBufferReceiveCompletedFromISR( xReturn )
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_uxStreamBufferGetStreamBufferNotificationIndex
|
||||
#define traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer )
|
||||
#endif
|
||||
|
||||
#ifndef traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex
|
||||
#define traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( uxNotificationIndex )
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_vStreamBufferSetStreamBufferNotificationIndex
|
||||
#define traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex )
|
||||
#endif
|
||||
|
||||
#ifndef traceRETURN_vStreamBufferSetStreamBufferNotificationIndex
|
||||
#define traceRETURN_vStreamBufferSetStreamBufferNotificationIndex()
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_uxStreamBufferGetStreamBufferNumber
|
||||
#define traceENTER_uxStreamBufferGetStreamBufferNumber( xStreamBuffer )
|
||||
#endif
|
||||
|
@ -3226,6 +3287,7 @@ typedef struct xSTATIC_STREAM_BUFFER
|
|||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
void * pvDummy5[ 2 ];
|
||||
#endif
|
||||
UBaseType_t uxDummy6;
|
||||
} StaticStreamBuffer_t;
|
||||
|
||||
/* Message buffers are built on stream buffers. */
|
||||
|
|
|
@ -33,6 +33,14 @@
|
|||
* This file implements atomic functions by disabling interrupts globally.
|
||||
* Implementations with architecture specific atomic instructions can be
|
||||
* provided under each compiler directory.
|
||||
*
|
||||
* The atomic interface can be used in FreeRTOS tasks on all FreeRTOS ports. It
|
||||
* can also be used in Interrupt Service Routines (ISRs) on FreeRTOS ports that
|
||||
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1). The
|
||||
* atomic interface must not be used in ISRs on FreeRTOS ports that do not
|
||||
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
|
||||
* because ISRs on these ports cannot be interrupted and therefore, do not need
|
||||
* atomics in ISRs.
|
||||
*/
|
||||
|
||||
#ifndef ATOMIC_H
|
||||
|
@ -59,7 +67,7 @@
|
|||
* ATOMIC_ENTER_CRITICAL().
|
||||
*
|
||||
*/
|
||||
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
|
||||
#if ( portHAS_NESTED_INTERRUPTS == 1 )
|
||||
|
||||
/* Nested interrupt scheme is supported in this port. */
|
||||
#define ATOMIC_ENTER_CRITICAL() \
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
typedef void * CoRoutineHandle_t;
|
||||
|
||||
/* Defines the prototype to which co-routine functions must conform. */
|
||||
typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t,
|
||||
UBaseType_t );
|
||||
typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t xHandle,
|
||||
UBaseType_t uxIndex );
|
||||
|
||||
typedef struct corCoRoutineControlBlock
|
||||
{
|
||||
|
|
|
@ -807,9 +807,9 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
|||
|
||||
/* For internal use only. */
|
||||
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
|
|
@ -151,7 +151,7 @@ struct xLIST_ITEM
|
|||
struct xLIST * configLIST_VOLATILE pxContainer; /**< Pointer to the list in which this list item is placed (if any). */
|
||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
};
|
||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||
typedef struct xLIST_ITEM ListItem_t;
|
||||
|
||||
#if ( configUSE_MINI_LIST_ITEM == 1 )
|
||||
struct xMINI_LIST_ITEM
|
||||
|
|
|
@ -229,14 +229,6 @@
|
|||
#define xStreamBufferReceiveCompletedFromISR MPU_xStreamBufferReceiveCompletedFromISR
|
||||
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||
|
||||
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
||||
* macro so applications can place data in privileged access sections
|
||||
* (useful when using statically allocated objects). */
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
|
||||
|
||||
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
|
||||
|
||||
#define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) )
|
||||
|
@ -265,15 +257,12 @@
|
|||
|
||||
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
|
||||
|
||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
/* Ensure API functions go in the privileged execution section. */
|
||||
#define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) )
|
||||
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||
#define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) )
|
||||
|
||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
#else /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
#define PRIVILEGED_FUNCTION
|
||||
|
|
|
@ -200,7 +200,7 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
|||
*
|
||||
* This hook function is called when allocation failed.
|
||||
*/
|
||||
void vApplicationMallocFailedHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */
|
||||
void vApplicationMallocFailedHook( void );
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* Defines the prototype to which task functions must conform. Defined in this
|
||||
* file to ensure the type is known before portable.h is included.
|
||||
*/
|
||||
typedef void (* TaskFunction_t)( void * );
|
||||
typedef void (* TaskFunction_t)( void * arg );
|
||||
|
||||
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
||||
* overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||
|
|
100
include/queue.h
100
include/queue.h
|
@ -1187,7 +1187,10 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
|||
* // has a priority higher than or equal to the priority of the currently
|
||||
* // executing task (the task this interrupt interrupted). Perform a context
|
||||
* // switch so this interrupt returns directly to the unblocked task.
|
||||
* portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
|
||||
* // The macro used is port specific and will be either
|
||||
* // portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to the documentation
|
||||
* // page for the port being used.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
|
@ -1260,8 +1263,11 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
|||
* // Now the buffer is empty we can switch context if necessary.
|
||||
* if( xHigherPriorityTaskWoken )
|
||||
* {
|
||||
* // Actual macro used here is port specific.
|
||||
* portYIELD_FROM_ISR ();
|
||||
* // As xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||
* // switch should be requested. The macro used is port specific and
|
||||
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||
* // refer to the documentation page for the port being used.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
|
@ -1337,11 +1343,14 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
|||
*
|
||||
* } while( portINPUT_BYTE( BUFFER_COUNT ) );
|
||||
*
|
||||
* // Now the buffer is empty we can switch context if necessary. Note that the
|
||||
* // name of the yield function required is port specific.
|
||||
* // Now the buffer is empty we can switch context if necessary.
|
||||
* if( xHigherPriorityTaskWokenByPost )
|
||||
* {
|
||||
* portYIELD_FROM_ISR();
|
||||
* // As xHigherPriorityTaskWokenByPost is now set to pdTRUE then a context
|
||||
* // switch should be requested. The macro used is port specific and
|
||||
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||
* // refer to the documentation page for the port being used.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWokenByPost );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
|
@ -1455,6 +1464,8 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FU
|
|||
BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configUSE_CO_ROUTINES == 1 )
|
||||
|
||||
/*
|
||||
* The functions defined above are for passing data to and from tasks. The
|
||||
* functions below are the equivalents for passing data to and from
|
||||
|
@ -1464,40 +1475,55 @@ UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEG
|
|||
* should not be called directly from application code. Instead use the macro
|
||||
* wrappers defined within croutine.h.
|
||||
*/
|
||||
BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue,
|
||||
BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue,
|
||||
const void * pvItemToQueue,
|
||||
BaseType_t xCoRoutinePreviouslyWoken );
|
||||
BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue,
|
||||
BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue,
|
||||
void * pvBuffer,
|
||||
BaseType_t * pxTaskWoken );
|
||||
BaseType_t xQueueCRSend( QueueHandle_t xQueue,
|
||||
BaseType_t xQueueCRSend( QueueHandle_t xQueue,
|
||||
const void * pvItemToQueue,
|
||||
TickType_t xTicksToWait );
|
||||
BaseType_t xQueueCRReceive( QueueHandle_t xQueue,
|
||||
BaseType_t xQueueCRReceive( QueueHandle_t xQueue,
|
||||
void * pvBuffer,
|
||||
TickType_t xTicksToWait );
|
||||
|
||||
#endif /* if ( configUSE_CO_ROUTINES == 1 ) */
|
||||
|
||||
/*
|
||||
* For internal use only. Use xSemaphoreCreateMutex(),
|
||||
* xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling
|
||||
* these functions directly.
|
||||
*/
|
||||
QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
|
||||
QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType,
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType,
|
||||
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||
QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
|
||||
#endif
|
||||
|
||||
#if ( configUSE_COUNTING_SEMAPHORES == 1 )
|
||||
QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
|
||||
QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
|
||||
#endif
|
||||
|
||||
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount,
|
||||
StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
|
||||
TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For internal use only. Use xSemaphoreTakeMutexRecursive() or
|
||||
* xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
|
||||
* For internal use only. Use xSemaphoreTakeRecursive() or
|
||||
* xSemaphoreGiveRecursive() instead of calling these functions directly.
|
||||
*/
|
||||
BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
@ -1537,7 +1563,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
#if ( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
void vQueueAddToRegistry( QueueHandle_t xQueue,
|
||||
const char * pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * pcQueueName ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1566,7 +1592,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
|
|||
* returned.
|
||||
*/
|
||||
#if ( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
const char * pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1653,7 +1679,9 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
|
|||
* @return If the queue set is created successfully then a handle to the created
|
||||
* queue set is returned. Otherwise NULL is returned.
|
||||
*/
|
||||
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
||||
#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Adds a queue or semaphore to a queue set that was previously created by a
|
||||
|
@ -1677,8 +1705,10 @@ QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILE
|
|||
* queue set because it is already a member of a different queue set then pdFAIL
|
||||
* is returned.
|
||||
*/
|
||||
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Removes a queue or semaphore from a queue set. A queue or semaphore can only
|
||||
|
@ -1697,8 +1727,10 @@ BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
|||
* then pdPASS is returned. If the queue was not in the queue set, or the
|
||||
* queue (or semaphore) was not empty, then pdFAIL is returned.
|
||||
*/
|
||||
BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xQueueSelectFromSet() selects from the members of a queue set a queue or
|
||||
|
@ -1734,13 +1766,17 @@ BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
|||
* in the queue set that is available, or NULL if no such queue or semaphore
|
||||
* exists before before the specified block time expires.
|
||||
*/
|
||||
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A version of xQueueSelectFromSet() that can be used from an ISR.
|
||||
*/
|
||||
QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* Not public API functions. */
|
||||
void vQueueWaitForMessageRestricted( QueueHandle_t xQueue,
|
||||
|
@ -1748,10 +1784,20 @@ void vQueueWaitForMessageRestricted( QueueHandle_t xQueue,
|
|||
const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
|
||||
BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;
|
||||
void vQueueSetQueueNumber( QueueHandle_t xQueue,
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void vQueueSetQueueNumber( QueueHandle_t xQueue,
|
||||
UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
UBaseType_t uxQueueGetQueueItemSize( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxQueueGetQueueLength( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@
|
|||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
|
@ -77,7 +78,8 @@
|
|||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
|
@ -89,14 +91,15 @@
|
|||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
do { \
|
||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
|
||||
\
|
||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
|
@ -120,7 +123,8 @@
|
|||
/* Has the extremity of the task stack ever been written over? */ \
|
||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
|
|
|
@ -911,6 +911,57 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
|
|||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Get the task notification index used for the supplied stream buffer which can
|
||||
* be set using vStreamBufferSetStreamBufferNotificationIndex. If the task
|
||||
* notification index for the stream buffer is not changed using
|
||||
* vStreamBufferSetStreamBufferNotificationIndex, this function returns the
|
||||
* default value (tskDEFAULT_INDEX_TO_NOTIFY).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer for which the task
|
||||
* notification index is retrieved.
|
||||
*
|
||||
* @return The task notification index for the stream buffer.
|
||||
*
|
||||
* \defgroup uxStreamBufferGetStreamBufferNotificationIndex uxStreamBufferGetStreamBufferNotificationIndex
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* void vStreamBufferSetStreamBufferNotificationIndex ( StreamBuffer_t xStreamBuffer, UBaseType_t uxNotificationIndex );
|
||||
* @endcode
|
||||
*
|
||||
* Set the task notification index used for the supplied stream buffer.
|
||||
* Successive calls to stream buffer APIs (like xStreamBufferSend or
|
||||
* xStreamBufferReceive) for this stream buffer will use this new index for
|
||||
* their task notifications.
|
||||
*
|
||||
* If this function is not called, the default index (tskDEFAULT_INDEX_TO_NOTIFY)
|
||||
* is used for task notifications. It is recommended to call this function
|
||||
* before attempting to send or receive data from the stream buffer to avoid
|
||||
* inconsistencies.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer for which the task
|
||||
* notification index is set.
|
||||
*
|
||||
* @param uxNotificationIndex The task notification index to set.
|
||||
*
|
||||
* \defgroup vStreamBufferSetStreamBufferNotificationIndex vStreamBufferSetStreamBufferNotificationIndex
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer,
|
||||
UBaseType_t uxNotificationIndex ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* Functions below here are not part of the public API. */
|
||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
|
@ -919,14 +970,15 @@ StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
|||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
|
151
include/task.h
151
include/task.h
|
@ -96,7 +96,7 @@ typedef const struct tskTaskControlBlock * ConstTaskHandle_t;
|
|||
* Defines the prototype to which the application task hook function must
|
||||
* conform.
|
||||
*/
|
||||
typedef BaseType_t (* TaskHookFunction_t)( void * );
|
||||
typedef BaseType_t (* TaskHookFunction_t)( void * arg );
|
||||
|
||||
/* Task states returned by eTaskGetState. */
|
||||
typedef enum
|
||||
|
@ -144,7 +144,7 @@ typedef struct xMEMORY_REGION
|
|||
typedef struct xTASK_PARAMETERS
|
||||
{
|
||||
TaskFunction_t pvTaskCode;
|
||||
const char * pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * pcName;
|
||||
configSTACK_DEPTH_TYPE usStackDepth;
|
||||
void * pvParameters;
|
||||
UBaseType_t uxPriority;
|
||||
|
@ -160,7 +160,7 @@ typedef struct xTASK_PARAMETERS
|
|||
typedef struct xTASK_STATUS
|
||||
{
|
||||
TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */
|
||||
const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */
|
||||
UBaseType_t xTaskNumber; /* A number unique to the task. */
|
||||
eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */
|
||||
UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
|
||||
|
@ -379,7 +379,7 @@ typedef enum
|
|||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * const pcName,
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
|
@ -388,7 +388,7 @@ typedef enum
|
|||
|
||||
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
BaseType_t xTaskCreateAffinitySet( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * const pcName,
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
|
@ -506,7 +506,7 @@ typedef enum
|
|||
*/
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
|
@ -516,7 +516,7 @@ typedef enum
|
|||
|
||||
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
TaskHandle_t xTaskCreateStaticAffinitySet( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
|
@ -752,8 +752,10 @@ typedef enum
|
|||
* \defgroup vTaskAllocateMPURegions vTaskAllocateMPURegions
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
|
||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||
void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
|
||||
const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -960,7 +962,9 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
|||
* \defgroup xTaskAbortDelay xTaskAbortDelay
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#if ( INCLUDE_xTaskAbortDelay == 1 )
|
||||
BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -1070,7 +1074,9 @@ UBaseType_t uxTaskBasePriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_
|
|||
* state of the task might change between the function being called, and the
|
||||
* functions return value being tested by the calling task.
|
||||
*/
|
||||
eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#if ( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) )
|
||||
eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -1128,10 +1134,12 @@ eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
|||
* \defgroup vTaskGetInfo vTaskGetInfo
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskGetInfo( TaskHandle_t xTask,
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void vTaskGetInfo( TaskHandle_t xTask,
|
||||
TaskStatus_t * pxTaskStatus,
|
||||
BaseType_t xGetFreeStackSpace,
|
||||
eTaskState eState ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -1737,7 +1745,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;
|
|||
* \defgroup pcTaskGetName pcTaskGetName
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -1755,7 +1763,9 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e
|
|||
* \defgroup pcTaskGetHandle pcTaskGetHandle
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#if ( INCLUDE_xTaskGetHandle == 1 )
|
||||
TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -1814,7 +1824,9 @@ TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /
|
|||
* actual spaces on the stack rather than bytes) since the task referenced by
|
||||
* xTask was created.
|
||||
*/
|
||||
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
|
||||
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task.h
|
||||
|
@ -1843,7 +1855,9 @@ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTIO
|
|||
* actual spaces on the stack rather than bytes) since the task referenced by
|
||||
* xTask was created.
|
||||
*/
|
||||
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 )
|
||||
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* When using trace macros it is sometimes necessary to include task.h before
|
||||
* FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined,
|
||||
|
@ -1922,6 +1936,9 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
|
|||
* @param xTask the task that just exceeded its stack boundaries.
|
||||
* @param pcTaskName A character string containing the name of the offending task.
|
||||
*/
|
||||
/* MISRA Ref 8.6.1 [External linkage] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */
|
||||
/* coverity[misra_c_2012_rule_8_6_violation] */
|
||||
void vApplicationStackOverflowHook( TaskHandle_t xTask,
|
||||
char * pcTaskName );
|
||||
|
||||
|
@ -1940,6 +1957,9 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
|
|||
* the overhead of a separate task.
|
||||
* NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK.
|
||||
*/
|
||||
/* MISRA Ref 8.6.1 [External linkage] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */
|
||||
/* coverity[misra_c_2012_rule_8_6_violation] */
|
||||
void vApplicationIdleHook( void );
|
||||
|
||||
#endif
|
||||
|
@ -1955,7 +1975,10 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
|
|||
*
|
||||
* This hook function is called in the system tick handler after any OS work is completed.
|
||||
*/
|
||||
void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */
|
||||
/* MISRA Ref 8.6.1 [External linkage] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */
|
||||
/* coverity[misra_c_2012_rule_8_6_violation] */
|
||||
void vApplicationTickHook( void );
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1976,7 +1999,7 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
|
|||
*/
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
|
||||
StackType_t ** ppxIdleTaskStackBuffer,
|
||||
uint32_t * pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */
|
||||
uint32_t * pulIdleTaskStackSize );
|
||||
|
||||
/**
|
||||
* task.h
|
||||
|
@ -2023,31 +2046,35 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
|
|||
* wants. The return value is the value returned by the task hook function
|
||||
* registered by the user.
|
||||
*/
|
||||
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||
void * pvParameter ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xTaskGetIdleTaskHandle() is only available if
|
||||
* INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* Simply returns the handle of the idle task. It is not valid to call
|
||||
* xTaskGetIdleTaskHandle() before the scheduler has been started.
|
||||
* In single-core FreeRTOS, this function simply returns the handle of the idle
|
||||
* task. It is not valid to call xTaskGetIdleTaskHandle() before the scheduler
|
||||
* has been started.
|
||||
*
|
||||
* In the FreeRTOS SMP, there are a total of configNUMBER_OF_CORES idle tasks:
|
||||
* 1. 1 Active idle task which does all the housekeeping.
|
||||
* 2. ( configNUMBER_OF_CORES - 1 ) Passive idle tasks which do nothing.
|
||||
* These idle tasks are created to ensure that each core has an idle task to run when
|
||||
* no other task is available to run.
|
||||
*
|
||||
* Set xCoreID to 0 to get the Active idle task handle. Set xCoreID to
|
||||
* 1,2 ... ( configNUMBER_OF_CORES - 1 ) to get the Passive idle task
|
||||
* handles.
|
||||
* no other task is available to run. Call xTaskGetIdleTaskHandle() or
|
||||
* xTaskGetIdleTaskHandleForCore() with xCoreID set to 0 to get the Active
|
||||
* idle task handle. Call xTaskGetIdleTaskHandleForCore() with xCoreID set to
|
||||
* 1,2 ... ( configNUMBER_OF_CORES - 1 ) to get the Passive idle task handles.
|
||||
*/
|
||||
#if ( configNUMBER_OF_CORES == 1 )
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
#if ( configNUMBER_OF_CORES == 1 )
|
||||
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||
TaskHandle_t xTaskGetIdleTaskHandle( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCore( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
#endif /* #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
|
||||
|
||||
/**
|
||||
* configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for
|
||||
|
@ -2146,9 +2173,11 @@ BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
|||
* }
|
||||
* @endcode
|
||||
*/
|
||||
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||
const UBaseType_t uxArraySize,
|
||||
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -2201,8 +2230,10 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
|||
* \defgroup vTaskListTasks vTaskListTasks
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
void vTaskListTasks( char * pcWriteBuffer,
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||
void vTaskListTasks( char * pcWriteBuffer,
|
||||
size_t uxBufferLength ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -2316,8 +2347,10 @@ void vTaskListTasks( char * pcWriteBuffer,
|
|||
* \defgroup vTaskGetRunTimeStatistics vTaskGetRunTimeStatistics
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
void vTaskGetRunTimeStatistics( char * pcWriteBuffer,
|
||||
size_t uxBufferLength ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configUSE_TRACE_FACILITY == 1 ) )
|
||||
void vTaskGetRunTimeStatistics( char * pcWriteBuffer,
|
||||
size_t uxBufferLength ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -2414,8 +2447,10 @@ void vTaskGetRunTimeStatistics( char * pcWriteBuffer,
|
|||
* \defgroup ulTaskGetRunTimeCounter ulTaskGetRunTimeCounter
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -2454,8 +2489,10 @@ configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask )
|
|||
* \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION;
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) PRIVILEGED_FUNCTION;
|
||||
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION;
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* task. h
|
||||
|
@ -3537,7 +3574,9 @@ TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
|
|||
/*
|
||||
* Return the handle of the task running on specified core.
|
||||
*/
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
#if ( configNUMBER_OF_CORES > 1 )
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Shortcut used by the queue implementation to prevent unnecessary call to
|
||||
|
@ -3577,14 +3616,18 @@ void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder,
|
|||
/*
|
||||
* Get the uxTaskNumber assigned to the task referenced by the xTask parameter.
|
||||
*/
|
||||
UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the uxTaskNumber of the task referenced by the xTask parameter to
|
||||
* uxHandle.
|
||||
*/
|
||||
void vTaskSetTaskNumber( TaskHandle_t xTask,
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void vTaskSetTaskNumber( TaskHandle_t xTask,
|
||||
const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only available when configUSE_TICKLESS_IDLE is set to 1.
|
||||
|
@ -3594,7 +3637,9 @@ void vTaskSetTaskNumber( TaskHandle_t xTask,
|
|||
* to date with the actual execution time by being skipped forward by a time
|
||||
* equal to the idle period.
|
||||
*/
|
||||
void vTaskStepTick( TickType_t xTicksToJump ) PRIVILEGED_FUNCTION;
|
||||
#if ( configUSE_TICKLESS_IDLE != 0 )
|
||||
void vTaskStepTick( TickType_t xTicksToJump ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only available when configUSE_TICKLESS_IDLE is set to 1.
|
||||
|
@ -3610,7 +3655,9 @@ void vTaskStepTick( TickType_t xTicksToJump ) PRIVILEGED_FUNCTION;
|
|||
* critical section between the timer being stopped and the sleep mode being
|
||||
* entered to ensure it is ok to proceed into the sleep mode.
|
||||
*/
|
||||
eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
|
||||
#if ( configUSE_TICKLESS_IDLE != 0 )
|
||||
eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For internal use only. Increment the mutex held count when a mutex is
|
||||
|
@ -3628,7 +3675,9 @@ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNC
|
|||
* For internal use only. Same as portYIELD_WITHIN_API() in single core FreeRTOS.
|
||||
* For SMP this is not defined by the port.
|
||||
*/
|
||||
void vTaskYieldWithinAPI( void );
|
||||
#if ( configNUMBER_OF_CORES > 1 )
|
||||
void vTaskYieldWithinAPI( void );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function is only intended for use when implementing a port of the scheduler
|
||||
|
@ -3638,7 +3687,9 @@ void vTaskYieldWithinAPI( void );
|
|||
* It should be used in the implementation of portENTER_CRITICAL if port is running a
|
||||
* multiple core FreeRTOS.
|
||||
*/
|
||||
void vTaskEnterCritical( void );
|
||||
#if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) || ( configNUMBER_OF_CORES > 1 ) )
|
||||
void vTaskEnterCritical( void );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function is only intended for use when implementing a port of the scheduler
|
||||
|
@ -3648,7 +3699,9 @@ void vTaskEnterCritical( void );
|
|||
* It should be used in the implementation of portEXIT_CRITICAL if port is running a
|
||||
* multiple core FreeRTOS.
|
||||
*/
|
||||
void vTaskExitCritical( void );
|
||||
#if ( ( portCRITICAL_NESTING_IN_TCB == 1 ) || ( configNUMBER_OF_CORES > 1 ) )
|
||||
void vTaskExitCritical( void );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function is only intended for use when implementing a port of the scheduler
|
||||
|
@ -3656,7 +3709,9 @@ void vTaskExitCritical( void );
|
|||
* should be used in the implementation of portENTER_CRITICAL_FROM_ISR if port is
|
||||
* running a multiple core FreeRTOS.
|
||||
*/
|
||||
UBaseType_t vTaskEnterCriticalFromISR( void );
|
||||
#if ( configNUMBER_OF_CORES > 1 )
|
||||
UBaseType_t vTaskEnterCriticalFromISR( void );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function is only intended for use when implementing a port of the scheduler
|
||||
|
@ -3664,7 +3719,9 @@ UBaseType_t vTaskEnterCriticalFromISR( void );
|
|||
* should be used in the implementation of portEXIT_CRITICAL_FROM_ISR if port is
|
||||
* running a multiple core FreeRTOS.
|
||||
*/
|
||||
void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
|
||||
#if ( configNUMBER_OF_CORES > 1 )
|
||||
void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
|
||||
#endif
|
||||
|
||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||
|
||||
|
|
|
@ -34,10 +34,8 @@
|
|||
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||
#endif
|
||||
|
||||
/*lint -save -e537 This headers are only multiply included if the application code
|
||||
* happens to also be including task.h. */
|
||||
#include "task.h"
|
||||
/*lint -restore */
|
||||
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
@ -88,8 +86,8 @@ typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
|||
* Defines the prototype to which functions used with the
|
||||
* xTimerPendFunctionCallFromISR() function must conform.
|
||||
*/
|
||||
typedef void (* PendedFunction_t)( void *,
|
||||
uint32_t );
|
||||
typedef void (* PendedFunction_t)( void * arg1,
|
||||
uint32_t arg2 );
|
||||
|
||||
/**
|
||||
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
|
@ -229,7 +227,7 @@ typedef void (* PendedFunction_t)( void *,
|
|||
* @endverbatim
|
||||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const BaseType_t xAutoReload,
|
||||
void * const pvTimerID,
|
||||
|
@ -359,7 +357,7 @@ typedef void (* PendedFunction_t)( void *,
|
|||
* @endverbatim
|
||||
*/
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const BaseType_t xAutoReload,
|
||||
void * const pvTimerID,
|
||||
|
@ -1198,10 +1196,12 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
|||
* }
|
||||
* @endverbatim
|
||||
*/
|
||||
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
||||
#if ( INCLUDE_xTimerPendFunctionCall == 1 )
|
||||
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
||||
void * pvParameter1,
|
||||
uint32_t ulParameter2,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
|
@ -1235,10 +1235,12 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
|||
* timer daemon task, otherwise pdFALSE is returned.
|
||||
*
|
||||
*/
|
||||
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
#if ( INCLUDE_xTimerPendFunctionCall == 1 )
|
||||
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
void * pvParameter1,
|
||||
uint32_t ulParameter2,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* const char * const pcTimerGetName( TimerHandle_t xTimer );
|
||||
|
@ -1249,7 +1251,7 @@ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
|||
*
|
||||
* @return The name assigned to the timer specified by the xTimer parameter.
|
||||
*/
|
||||
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload );
|
||||
|
@ -1408,6 +1410,9 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer,
|
|||
*
|
||||
* This hook function is called form the timer task once when the task starts running.
|
||||
*/
|
||||
/* MISRA Ref 8.6.1 [External linkage] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-86 */
|
||||
/* coverity[misra_c_2012_rule_8_6_violation] */
|
||||
void vApplicationDaemonTaskStartupHook( void );
|
||||
|
||||
#endif
|
||||
|
|
13
list.c
13
list.c
|
@ -37,11 +37,10 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "list.h"
|
||||
|
||||
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
|
||||
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
|
||||
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
|
||||
* defined for the header files above, but not in this file, in order to
|
||||
* generate the correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* PUBLIC LIST API documented in list.h
|
||||
|
@ -54,7 +53,7 @@ void vListInitialise( List_t * const pxList )
|
|||
/* The list structure contains a list item which is used to mark the
|
||||
* end of the list. To initialise the list the list end is inserted
|
||||
* as the only list entry. */
|
||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
|
||||
|
||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||
|
||||
|
@ -64,8 +63,8 @@ void vListInitialise( List_t * const pxList )
|
|||
|
||||
/* The list end next and previous pointers point to itself so we know
|
||||
* when the list is empty. */
|
||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
|
||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
|
||||
|
||||
/* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
|
||||
#if ( configUSE_MINI_LIST_ITEM == 0 )
|
||||
|
@ -190,7 +189,7 @@ void vListInsert( List_t * const pxList,
|
|||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
**********************************************************************/
|
||||
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
|
||||
{
|
||||
/* There is nothing to do here, just iterating to the wanted
|
||||
* insertion position. */
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -27,22 +27,22 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Changes from V1.00:
|
||||
*
|
||||
Changes from V1.00:
|
||||
|
||||
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||
+ efficient portSWITCH_CONTEXT().
|
||||
efficient portSWITCH_CONTEXT().
|
||||
+ ISR function definitions renamed to include the prv prefix.
|
||||
+
|
||||
+ Changes from V2.6.1
|
||||
+
|
||||
|
||||
Changes from V2.6.1
|
||||
|
||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||
+ macro to be consistent with the later ports.
|
||||
*/
|
||||
macro to be consistent with the later ports.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#include <dos.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -69,16 +69,14 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
|||
static void prvExitFunction( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
* being used. */
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
* being used. */
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
|
@ -91,9 +89,9 @@ static void __interrupt __far prvYieldProcessor( void );
|
|||
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||
|
||||
/* Points to the original routine installed on the vector we use for manual
|
||||
* context switches. This is then used to restore the original routine during
|
||||
* prvExitFunction(). */
|
||||
static void( __interrupt __far * pxOldSwitchISR )();
|
||||
context switches. This is then used to restore the original routine during
|
||||
prvExitFunction(). */
|
||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||
|
||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||
static jmp_buf xJumpBuf;
|
||||
|
@ -106,14 +104,14 @@ BaseType_t xPortStartScheduler( void )
|
|||
/* This is called with interrupts already disabled. */
|
||||
|
||||
/* Remember what was on the interrupts we are going to use
|
||||
* so we can put them back later if required. */
|
||||
so we can put them back later if required. */
|
||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
* vector. */
|
||||
vector. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Put our tick switch function on the timer interrupt. */
|
||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||
|
@ -146,8 +144,8 @@ BaseType_t xPortStartScheduler( void )
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
/* Get the scheduler to update the task states following the tick. */
|
||||
|
@ -160,15 +158,15 @@ BaseType_t xPortStartScheduler( void )
|
|||
/* Reset the PIC ready for the next time. */
|
||||
portRESET_PIC();
|
||||
}
|
||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#else
|
||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||
{
|
||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||
* so we don't have to switch in the context of the next task. */
|
||||
so we don't have to switch in the context of the next task. */
|
||||
xTaskIncrementTick();
|
||||
portRESET_PIC();
|
||||
}
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
|
@ -181,31 +179,30 @@ static void __interrupt __far prvYieldProcessor( void )
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Jump back to the processor state prior to starting the
|
||||
* scheduler. This means we are not going to be using a
|
||||
* task stack frame so the task can be deleted. */
|
||||
scheduler. This means we are not going to be using a
|
||||
task stack frame so the task can be deleted. */
|
||||
longjmp( xJumpBuf, 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvExitFunction( void )
|
||||
{
|
||||
const uint16_t usTimerDisable = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
const uint16_t usTimerDisable = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
|
||||
/* Interrupts should be disabled here anyway - but no
|
||||
* harm in making sure. */
|
||||
harm in making sure. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( xSchedulerRunning == pdTRUE )
|
||||
{
|
||||
/* Put back the switch interrupt routines that was in place
|
||||
* before the scheduler started. */
|
||||
before the scheduler started. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||
}
|
||||
|
||||
/* Disable the timer used for the tick to ensure the scheduler is
|
||||
* not called before restoring interrupts. There was previously nothing
|
||||
* on this timer so there is no old ISR to restore. */
|
||||
not called before restoring interrupts. There was previously nothing
|
||||
on this timer so there is no old ISR to restore. */
|
||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
||||
|
||||
/* Restart the DOS tick. */
|
||||
|
@ -220,18 +217,18 @@ static void prvExitFunction( void )
|
|||
|
||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||
{
|
||||
const uint16_t usMaxCountRegister = 0xff5a;
|
||||
const uint16_t usTimerPriorityRegister = 0xff32;
|
||||
const uint16_t usTimerEnable = 0xC000;
|
||||
const uint16_t usRetrigger = 0x0001;
|
||||
const uint16_t usTimerHighPriority = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
const uint16_t usMaxCountRegister = 0xff5a;
|
||||
const uint16_t usTimerPriorityRegister = 0xff32;
|
||||
const uint16_t usTimerEnable = 0xC000;
|
||||
const uint16_t usRetrigger = 0x0001;
|
||||
const uint16_t usTimerHighPriority = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
|
||||
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
||||
|
||||
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
||||
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
||||
|
||||
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||
|
||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
||||
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
||||
|
|
|
@ -52,7 +52,7 @@ typedef portSTACK_TYPE StackType_t;
|
|||
typedef short BaseType_t;
|
||||
typedef unsigned short UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -64,22 +64,21 @@ typedef unsigned short UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portENTER_CRITICAL() \
|
||||
__asm { pushf } \
|
||||
__asm { cli } \
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm { popf }
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm { cli }
|
||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||
|
||||
#define portENABLE_INTERRUPTS() __asm { sti }
|
||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portNOP() __asm { nop }
|
||||
#define portNOP() __asm{ nop }
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portSWITCH_INT_NUMBER 0x80
|
||||
#define portYIELD() __asm { int portSWITCH_INT_NUMBER }
|
||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 2
|
||||
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||
|
@ -94,7 +93,7 @@ typedef unsigned short UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
|
|
@ -27,16 +27,16 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Changes from V2.6.1
|
||||
*
|
||||
Changes from V2.6.1
|
||||
|
||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||
+ macro to be consistent with the later ports.
|
||||
+
|
||||
+ Changes from V4.0.1
|
||||
+
|
||||
macro to be consistent with the later ports.
|
||||
|
||||
Changes from V4.0.1
|
||||
|
||||
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
||||
+ its proper value when the scheduler exits.
|
||||
*/
|
||||
its proper value when the scheduler exits.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
|
@ -47,9 +47,9 @@
|
|||
#include "portasm.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the industrial
|
||||
* PC port.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the industrial
|
||||
* PC port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||
|
||||
|
@ -62,21 +62,19 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
|||
static void prvExitFunction( void );
|
||||
|
||||
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
||||
* directly. We chain to the DOS tick as close as possible to the standard DOS
|
||||
* tick rate. */
|
||||
directly. We chain to the DOS tick as close as possible to the standard DOS
|
||||
tick rate. */
|
||||
static void prvPortResetPIC( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
* scheduler is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
* being used. */
|
||||
scheduler is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
* being used. */
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
|
@ -84,7 +82,7 @@ static void prvPortResetPIC( void );
|
|||
static void __interrupt __far prvYieldProcessor( void );
|
||||
|
||||
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||
* scheduler exits. */
|
||||
scheduler exits. */
|
||||
static void prvSetTickFrequencyDefault( void );
|
||||
|
||||
/*lint -e956 File scopes necessary here. */
|
||||
|
@ -96,10 +94,10 @@ static int16_t sDOSTickCounter;
|
|||
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||
|
||||
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
||||
static void( __interrupt __far * pxOldSwitchISR )();
|
||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||
|
||||
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
||||
static void( __interrupt __far * pxOldSwitchISRPlus1 )();
|
||||
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
|
||||
|
||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||
static jmp_buf xJumpBuf;
|
||||
|
@ -109,12 +107,12 @@ static jmp_buf xJumpBuf;
|
|||
/*-----------------------------------------------------------*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
pxISR pxOriginalTickISR;
|
||||
pxISR pxOriginalTickISR;
|
||||
|
||||
/* This is called with interrupts already disabled. */
|
||||
|
||||
/* Remember what was on the interrupts we are going to use
|
||||
* so we can put them back later if required. */
|
||||
so we can put them back later if required. */
|
||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
||||
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||
|
@ -122,16 +120,16 @@ BaseType_t xPortStartScheduler( void )
|
|||
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
* vector. */
|
||||
vector. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
/* Put the old tick on a different interrupt number so we can
|
||||
* call it when we want. */
|
||||
call it when we want. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
* scheduler is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
scheduler is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Put our tick switch function on the timer interrupt. */
|
||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||
|
@ -144,8 +142,8 @@ BaseType_t xPortStartScheduler( void )
|
|||
#endif
|
||||
|
||||
/* Setup a counter that is used to call the DOS interrupt as close
|
||||
* to it's original frequency as can be achieved given our chosen tick
|
||||
* frequency. */
|
||||
to it's original frequency as can be achieved given our chosen tick
|
||||
frequency. */
|
||||
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
||||
|
||||
/* Clean up function if we want to return to DOS. */
|
||||
|
@ -167,8 +165,8 @@ BaseType_t xPortStartScheduler( void )
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
* scheduler is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
scheduler is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
/* Get the scheduler to update the task states following the tick. */
|
||||
|
@ -181,15 +179,15 @@ BaseType_t xPortStartScheduler( void )
|
|||
/* Reset the PIC ready for the next time. */
|
||||
prvPortResetPIC();
|
||||
}
|
||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#else
|
||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||
{
|
||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||
* so we don't have to switch in the context of the next task. */
|
||||
so we don't have to switch in the context of the next task. */
|
||||
xTaskIncrementTick();
|
||||
prvPortResetPIC();
|
||||
}
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
|
@ -202,22 +200,19 @@ static void __interrupt __far prvYieldProcessor( void )
|
|||
static void prvPortResetPIC( void )
|
||||
{
|
||||
/* We are going to call the DOS tick interrupt at as close a
|
||||
* frequency to the normal DOS tick as possible. */
|
||||
frequency to the normal DOS tick as possible. */
|
||||
|
||||
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
||||
--sDOSTickCounter;
|
||||
|
||||
if( sDOSTickCounter <= 0 )
|
||||
{
|
||||
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
||||
__asm {
|
||||
int portSWITCH_INT_NUMBER + 1
|
||||
};
|
||||
__asm{ int portSWITCH_INT_NUMBER + 1 };
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the PIC as the DOS tick is not being called to
|
||||
* do it. */
|
||||
do it. */
|
||||
__asm
|
||||
{
|
||||
mov al, 20H
|
||||
|
@ -230,20 +225,19 @@ static void prvPortResetPIC( void )
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Jump back to the processor state prior to starting the
|
||||
* scheduler. This means we are not going to be using a
|
||||
* task stack frame so the task can be deleted. */
|
||||
scheduler. This means we are not going to be using a
|
||||
task stack frame so the task can be deleted. */
|
||||
longjmp( xJumpBuf, 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvExitFunction( void )
|
||||
{
|
||||
void( __interrupt __far * pxOriginalTickISR )();
|
||||
void ( __interrupt __far *pxOriginalTickISR )();
|
||||
|
||||
/* Interrupts should be disabled here anyway - but no
|
||||
* harm in making sure. */
|
||||
harm in making sure. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( xSchedulerRunning == pdTRUE )
|
||||
{
|
||||
/* Set the DOS tick back onto the timer ticker. */
|
||||
|
@ -252,29 +246,28 @@ static void prvExitFunction( void )
|
|||
prvSetTickFrequencyDefault();
|
||||
|
||||
/* Put back the switch interrupt routines that was in place
|
||||
* before the scheduler started. */
|
||||
before the scheduler started. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||
}
|
||||
|
||||
/* The tick timer is back how DOS wants it. We can re-enable
|
||||
* interrupts without the scheduler being called. */
|
||||
interrupts without the scheduler being called. */
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||
{
|
||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
uint32_t ulOutput;
|
||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
uint32_t ulOutput;
|
||||
|
||||
/* Setup the 8245 to tick at the wanted frequency. */
|
||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||
ulOutput = ulPIT_CONST / ulTickRateHz;
|
||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||
portOUTPUT_BYTE( usPIT0, ( uint16_t )( ulOutput & ( uint32_t ) 0xff ) );
|
||||
ulOutput >>= 8;
|
||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||
}
|
||||
|
@ -282,13 +275,13 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
|||
|
||||
static void prvSetTickFrequencyDefault( void )
|
||||
{
|
||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
|
||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||
portOUTPUT_BYTE( usPIT0, 0 );
|
||||
portOUTPUT_BYTE( usPIT0, 0 );
|
||||
portOUTPUT_BYTE( usPIT0,0 );
|
||||
portOUTPUT_BYTE( usPIT0,0 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ typedef portSTACK_TYPE StackType_t;
|
|||
typedef short BaseType_t;
|
||||
typedef unsigned short UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -64,22 +64,21 @@ typedef unsigned short UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
#define portENTER_CRITICAL() \
|
||||
__asm { pushf } \
|
||||
__asm { cli } \
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm { popf }
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm { cli }
|
||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||
|
||||
#define portENABLE_INTERRUPTS() __asm { sti }
|
||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portNOP() __asm { nop }
|
||||
#define portNOP() __asm{ nop }
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portSWITCH_INT_NUMBER 0x80
|
||||
#define portYIELD() __asm { int portSWITCH_INT_NUMBER }
|
||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||
#define portDOS_TICK_RATE ( 18.20648 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portTICKS_PER_DOS_TICK ( ( uint16_t ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) )
|
||||
|
@ -94,7 +93,7 @@ typedef unsigned short UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
|
|
@ -48,16 +48,16 @@ void portSWITCH_CONTEXT( void );
|
|||
void portFIRST_CONTEXT( void );
|
||||
|
||||
/* There are slightly different versions depending on whether you are building
|
||||
* to include debugger information. If debugger information is used then there
|
||||
* are a couple of extra bytes left of the ISR stack (presumably for use by the
|
||||
* debugger). The true stack pointer is then stored in the bp register. We add
|
||||
* 2 to the stack pointer to remove the extra bytes before we restore our context. */
|
||||
to include debugger information. If debugger information is used then there
|
||||
are a couple of extra bytes left of the ISR stack (presumably for use by the
|
||||
debugger). The true stack pointer is then stored in the bp register. We add
|
||||
2 to the stack pointer to remove the extra bytes before we restore our context. */
|
||||
|
||||
#define portSWITCH_CONTEXT() \
|
||||
asm { mov ax, seg pxCurrentTCB } \
|
||||
asm { mov ds, ax } \
|
||||
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||
asm { mov es : 0x2[ bx ], ss } \
|
||||
asm { mov es:0x2[ bx ], ss } \
|
||||
asm { mov es:[ bx ], sp } \
|
||||
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||
|
@ -84,4 +84,4 @@ void portFIRST_CONTEXT( void );
|
|||
__asm { iret }
|
||||
|
||||
|
||||
#endif /* ifndef PORT_ASM_H */
|
||||
#endif
|
||||
|
|
|
@ -27,16 +27,16 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Changes from V1.00:
|
||||
*
|
||||
Changes from V1.00:
|
||||
|
||||
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
||||
+ same format used by the compiler. This allows the compiler generated
|
||||
+ interrupt mechanism to be used for context switches.
|
||||
+
|
||||
+ Changes from V2.6.1
|
||||
+
|
||||
same format used by the compiler. This allows the compiler generated
|
||||
interrupt mechanism to be used for context switches.
|
||||
|
||||
Changes from V2.6.1
|
||||
|
||||
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
#include <dos.h>
|
||||
|
@ -46,14 +46,12 @@
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* See header file for description. */
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t DS_Reg = 0;
|
||||
StackType_t DS_Reg = 0;
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
* This is just useful for debugging. */
|
||||
This is just useful for debugging. */
|
||||
|
||||
*pxTopOfStack = 0x1111;
|
||||
pxTopOfStack--;
|
||||
|
@ -70,8 +68,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||
|
||||
/* We are going to start the scheduler using a return from interrupt
|
||||
* instruction to load the program counter, so first there would be the
|
||||
* function call with parameters preamble. */
|
||||
instruction to load the program counter, so first there would be the
|
||||
function call with parameters preamble. */
|
||||
|
||||
*pxTopOfStack = FP_SEG( pvParameters );
|
||||
pxTopOfStack--;
|
||||
|
@ -91,8 +89,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* The remaining registers would be pushed on the stack by our context
|
||||
* switch function. These are loaded with values simply to make debugging
|
||||
* easier. */
|
||||
switch function. These are loaded with values simply to make debugging
|
||||
easier. */
|
||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||
|
@ -105,9 +103,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* We need the true data segment. */
|
||||
__asm {
|
||||
MOV DS_Reg, DS
|
||||
};
|
||||
__asm{ MOV DS_Reg, DS };
|
||||
|
||||
*pxTopOfStack = DS_Reg; /* DS */
|
||||
pxTopOfStack--;
|
||||
|
|
|
@ -81,7 +81,6 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
# ARMv6-M / Cortex-M0 Raspberry PI RP2040 port for GCC
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_RP2040>:
|
||||
ThirdParty/GCC/RP2040/idle_task_static_memory.c
|
||||
ThirdParty/GCC/RP2040/port.c>
|
||||
|
||||
# ARMv7-M ports for GCC
|
||||
|
@ -89,11 +88,13 @@ add_library(freertos_kernel_port STATIC
|
|||
GCC/ARM_CM3/port.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM3_MPU>:
|
||||
GCC/ARM_CM3_MPU/port.c>
|
||||
GCC/ARM_CM3_MPU/port.c
|
||||
GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c>
|
||||
|
||||
# ARMv7E-M ports for GCC
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM4_MPU>:
|
||||
GCC/ARM_CM4_MPU/port.c>
|
||||
GCC/ARM_CM4_MPU/port.c
|
||||
GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM4F>:
|
||||
GCC/ARM_CM4F/port.c>
|
||||
|
@ -104,7 +105,8 @@ add_library(freertos_kernel_port STATIC
|
|||
# ARMv8-M ports for GCC
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM23_NONSECURE>:
|
||||
GCC/ARM_CM23/non_secure/port.c
|
||||
GCC/ARM_CM23/non_secure/portasm.c>
|
||||
GCC/ARM_CM23/non_secure/portasm.c
|
||||
GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM23_SECURE>:
|
||||
GCC/ARM_CM23/secure/secure_context_port.c
|
||||
|
@ -114,11 +116,13 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM23_NTZ_NONSECURE>:
|
||||
GCC/ARM_CM23_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM23_NTZ/non_secure/portasm.c>
|
||||
GCC/ARM_CM23_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM33_NONSECURE>:
|
||||
GCC/ARM_CM33/non_secure/port.c
|
||||
GCC/ARM_CM33/non_secure/portasm.c>
|
||||
GCC/ARM_CM33/non_secure/portasm.c
|
||||
GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM33_SECURE>:
|
||||
GCC/ARM_CM33/secure/secure_context_port.c
|
||||
|
@ -128,16 +132,19 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM33_NTZ_NONSECURE>:
|
||||
GCC/ARM_CM33_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM33_NTZ/non_secure/portasm.c>
|
||||
GCC/ARM_CM33_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM33_TFM>:
|
||||
GCC/ARM_CM33_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM33_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM35P_NONSECURE>:
|
||||
GCC/ARM_CM35P/non_secure/port.c
|
||||
GCC/ARM_CM35P/non_secure/portasm.c>
|
||||
GCC/ARM_CM35P/non_secure/portasm.c
|
||||
GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM35P_SECURE>:
|
||||
GCC/ARM_CM35P/secure/secure_context_port.c
|
||||
|
@ -147,12 +154,14 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM35P_NTZ_NONSECURE>:
|
||||
GCC/ARM_CM35P_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM35P_NTZ/non_secure/portasm.c>
|
||||
GCC/ARM_CM35P_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
# ARMv8.1-M ports for GCC
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_NONSECURE>:
|
||||
GCC/ARM_CM55/non_secure/port.c
|
||||
GCC/ARM_CM55/non_secure/portasm.c>
|
||||
GCC/ARM_CM55/non_secure/portasm.c
|
||||
GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_SECURE>:
|
||||
GCC/ARM_CM55/secure/secure_context_port.c
|
||||
|
@ -162,16 +171,19 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_NTZ_NONSECURE>:
|
||||
GCC/ARM_CM55_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM55_NTZ/non_secure/portasm.c>
|
||||
GCC/ARM_CM55_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_TFM>:
|
||||
GCC/ARM_CM55_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM55_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:
|
||||
GCC/ARM_CM85/non_secure/port.c
|
||||
GCC/ARM_CM85/non_secure/portasm.c>
|
||||
GCC/ARM_CM85/non_secure/portasm.c
|
||||
GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_SECURE>:
|
||||
GCC/ARM_CM85/secure/secure_context_port.c
|
||||
|
@ -181,11 +193,13 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NTZ_NONSECURE>:
|
||||
GCC/ARM_CM85_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM85_NTZ/non_secure/portasm.c>
|
||||
GCC/ARM_CM85_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_TFM>:
|
||||
GCC/ARM_CM85_NTZ/non_secure/port.c
|
||||
GCC/ARM_CM85_NTZ/non_secure/portasm.c
|
||||
GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||
|
||||
# ARMv7-R ports for GCC
|
||||
|
@ -392,7 +406,8 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM4F_MPU>:
|
||||
IAR/ARM_CM4F_MPU/port.c
|
||||
IAR/ARM_CM4F_MPU/portasm.s>
|
||||
IAR/ARM_CM4F_MPU/portasm.s
|
||||
IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM7>:
|
||||
IAR/ARM_CM7/r0p1/port.c
|
||||
|
@ -401,7 +416,8 @@ add_library(freertos_kernel_port STATIC
|
|||
# ARMv8-M Ports for IAR EWARM
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM23_NONSECURE>:
|
||||
IAR/ARM_CM23/non_secure/port.c
|
||||
IAR/ARM_CM23/non_secure/portasm.s>
|
||||
IAR/ARM_CM23/non_secure/portasm.s
|
||||
IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM23_SECURE>:
|
||||
IAR/ARM_CM23/secure/secure_context_port_asm.s
|
||||
|
@ -411,11 +427,13 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM23_NTZ_NONSECURE>:
|
||||
IAR/ARM_CM23_NTZ/non_secure/port.c
|
||||
IAR/ARM_CM23_NTZ/non_secure/portasm.s>
|
||||
IAR/ARM_CM23_NTZ/non_secure/portasm.s
|
||||
IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM33_NONSECURE>:
|
||||
IAR/ARM_CM33/non_secure/port.c
|
||||
IAR/ARM_CM33/non_secure/portasm.s>
|
||||
IAR/ARM_CM33/non_secure/portasm.s
|
||||
IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM33_SECURE>:
|
||||
IAR/ARM_CM33/secure/secure_context_port_asm.s
|
||||
|
@ -425,11 +443,13 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM33_NTZ_NONSECURE>:
|
||||
IAR/ARM_CM33_NTZ/non_secure/port.c
|
||||
IAR/ARM_CM33_NTZ/non_secure/portasm.s>
|
||||
IAR/ARM_CM33_NTZ/non_secure/portasm.s
|
||||
IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM35P_NONSECURE>:
|
||||
IAR/ARM_CM35P/non_secure/port.c
|
||||
IAR/ARM_CM35P/non_secure/portasm.s>
|
||||
IAR/ARM_CM35P/non_secure/portasm.s
|
||||
IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM35P_SECURE>:
|
||||
IAR/ARM_CM35P/secure/secure_context_port_asm.s
|
||||
|
@ -439,12 +459,14 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM35P_NTZ_NONSECURE>:
|
||||
IAR/ARM_CM35P_NTZ/non_secure/port.c
|
||||
IAR/ARM_CM35P_NTZ/non_secure/portasm.s>
|
||||
IAR/ARM_CM35P_NTZ/non_secure/portasm.s
|
||||
IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
# ARMv8.1-M ports for IAR EWARM
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_NONSECURE>:
|
||||
IAR/ARM_CM55/non_secure/port.c
|
||||
IAR/ARM_CM55/non_secure/portasm.s>
|
||||
IAR/ARM_CM55/non_secure/portasm.s
|
||||
IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_SECURE>:
|
||||
IAR/ARM_CM55/secure/secure_context_port_asm.s
|
||||
|
@ -454,11 +476,13 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_NTZ_NONSECURE>:
|
||||
IAR/ARM_CM55_NTZ/non_secure/port.c
|
||||
IAR/ARM_CM55_NTZ/non_secure/portasm.s>
|
||||
IAR/ARM_CM55_NTZ/non_secure/portasm.s
|
||||
IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:
|
||||
IAR/ARM_CM85/non_secure/port.c
|
||||
IAR/ARM_CM85/non_secure/portasm.s>
|
||||
IAR/ARM_CM85/non_secure/portasm.s
|
||||
IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_SECURE>:
|
||||
IAR/ARM_CM85/secure/secure_context_port_asm.s
|
||||
|
@ -468,7 +492,8 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NTZ_NONSECURE>:
|
||||
IAR/ARM_CM85_NTZ/non_secure/port.c
|
||||
IAR/ARM_CM85_NTZ/non_secure/portasm.s>
|
||||
IAR/ARM_CM85_NTZ/non_secure/portasm.s
|
||||
IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||
|
||||
# ARMv7-R Ports for IAR EWARM
|
||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CRX_NOGIC>:
|
||||
|
@ -660,7 +685,8 @@ add_library(freertos_kernel_port STATIC
|
|||
|
||||
# ARMv7E-M ports for ARM RVDS / armcc
|
||||
$<$<STREQUAL:${FREERTOS_PORT},RVDS_ARM_CM4_MPU>:
|
||||
RVDS/ARM_CM4_MPU/port.c>
|
||||
RVDS/ARM_CM4_MPU/port.c
|
||||
RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c>
|
||||
|
||||
$<$<STREQUAL:${FREERTOS_PORT},RVDS_ARM_CM4F>:
|
||||
RVDS/ARM_CM4F/port.c>
|
||||
|
@ -724,7 +750,10 @@ if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR
|
|||
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR
|
||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE"
|
||||
)
|
||||
target_sources(freertos_kernel_port PRIVATE Common/mpu_wrappers.c)
|
||||
target_sources(freertos_kernel_port PRIVATE
|
||||
Common/mpu_wrappers.c
|
||||
Common/mpu_wrappers_v2.c
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(freertos_kernel_port PUBLIC
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||
|
||||
/* Supervisor mode set. */
|
||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||
|
||||
/* The clock prescale into the timer peripheral. */
|
||||
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
||||
|
@ -46,23 +46,20 @@ asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
|||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* 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. */
|
||||
will be set to 0 prior to the first task being started. */
|
||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
uint32_t ulOriginalA5;
|
||||
|
||||
__asm {
|
||||
MOVE.L A5, ulOriginalA5
|
||||
};
|
||||
uint32_t ulOriginalA5;
|
||||
|
||||
__asm{ MOVE.L A5, ulOriginalA5 };
|
||||
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Exception stack frame starts with the return address. */
|
||||
|
@ -87,7 +84,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
|
@ -110,7 +107,7 @@ static void prvSetupTimerInterrupt( void )
|
|||
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||
* when this code executes. */
|
||||
when this code executes. */
|
||||
RTCSC_RTIE = 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -126,20 +123,19 @@ void vPortEnterCritical( void )
|
|||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
/* Guard against context switches being pended simultaneously with a
|
||||
* critical section being entered. */
|
||||
critical section being entered. */
|
||||
do
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( INTC_FRC == 0UL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
} while( 1 );
|
||||
}
|
||||
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -147,7 +143,6 @@ void vPortEnterCritical( void )
|
|||
void vPortExitCritical( void )
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
|
@ -157,7 +152,7 @@ void vPortExitCritical( void )
|
|||
|
||||
void vPortYieldHandler( void )
|
||||
{
|
||||
uint32_t ulSavedInterruptMask;
|
||||
uint32_t ulSavedInterruptMask;
|
||||
|
||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
|
@ -171,7 +166,7 @@ void vPortYieldHandler( void )
|
|||
|
||||
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||
{
|
||||
uint32_t ulSavedInterruptMask;
|
||||
uint32_t ulSavedInterruptMask;
|
||||
|
||||
/* Clear the interrupt. */
|
||||
RTCSC |= RTCSC_RTIF_MASK;
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef long BaseType_t;
|
|||
typedef unsigned long UBaseType_t;
|
||||
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -102,10 +102,11 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do \
|
||||
{ \
|
||||
|
|
|
@ -34,38 +34,36 @@
|
|||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||
|
||||
/* Supervisor mode set. */
|
||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||
|
||||
/* 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. */
|
||||
will be set to 0 prior to the first task being started. */
|
||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
lea.l( -60, % sp ), % sp; \
|
||||
movem.l % d0 - % fp, ( % sp ); \
|
||||
move.l pxCurrentTCB, % a0; \
|
||||
move.l % sp, ( % a0 );
|
||||
lea.l (-60, %sp), %sp; \
|
||||
movem.l %d0-%fp, (%sp); \
|
||||
move.l pxCurrentTCB, %a0; \
|
||||
move.l %sp, (%a0);
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
move.l pxCurrentTCB, % a0; \
|
||||
move.l( % a0 ), % sp; \
|
||||
movem.l( % sp ), % d0 - % fp; \
|
||||
lea.l % sp@( 60 ), % sp; \
|
||||
move.l pxCurrentTCB, %a0; \
|
||||
move.l (%a0), %sp; \
|
||||
movem.l (%sp), %d0-%fp; \
|
||||
lea.l %sp@(60), %sp; \
|
||||
rte
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Exception stack frame starts with the return address. */
|
||||
|
@ -84,7 +82,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
|
@ -109,20 +107,19 @@ void vPortEnterCritical( void )
|
|||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
/* Guard against context switches being pended simultaneously with a
|
||||
* critical section being entered. */
|
||||
critical section being entered. */
|
||||
do
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( MCF_INTC0_INTFRCH == 0UL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
} while( 1 );
|
||||
}
|
||||
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -130,7 +127,6 @@ void vPortEnterCritical( void )
|
|||
void vPortExitCritical( void )
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
|
@ -140,7 +136,7 @@ void vPortExitCritical( void )
|
|||
|
||||
void vPortYieldHandler( void )
|
||||
{
|
||||
uint32_t ulSavedInterruptMask;
|
||||
uint32_t ulSavedInterruptMask;
|
||||
|
||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||
|
|
|
@ -58,7 +58,7 @@ typedef portSTACK_TYPE StackType_t;
|
|||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -101,8 +101,8 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
|
@ -43,29 +43,29 @@
|
|||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||
* scheduler startup function. */
|
||||
scheduler startup function. */
|
||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||
|
||||
/* Manual context switch function. This is the SWI ISR. */
|
||||
void interrupt vPortYield( void );
|
||||
/* Manual context switch function. This is the SWI ISR. */
|
||||
void interrupt vPortYield( void );
|
||||
|
||||
/* Tick context switch function. This is the timer ISR. */
|
||||
void interrupt vPortTickInterrupt( void );
|
||||
/* Tick context switch function. This is the timer ISR. */
|
||||
void interrupt vPortTickInterrupt( void );
|
||||
|
||||
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||
* start the scheduler directly because the header file containing the
|
||||
* xPortStartScheduler() prototype is part of the common kernel code, and
|
||||
* therefore cannot use the CODE_SEG pragma. */
|
||||
static BaseType_t xBankedStartScheduler( void );
|
||||
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||
start the scheduler directly because the header file containing the
|
||||
xPortStartScheduler() prototype is part of the common kernel code, and
|
||||
therefore cannot use the CODE_SEG pragma. */
|
||||
static BaseType_t xBankedStartScheduler( void );
|
||||
|
||||
#pragma CODE_SEG DEFAULT
|
||||
|
||||
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||
* critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||
* until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||
* depth. Each task maintains it's own critical nesting depth variable so
|
||||
* uxCriticalNesting is saved and restored from the task stack during a context
|
||||
* switch. */
|
||||
critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||
until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||
depth. Each task maintains it's own critical nesting depth variable so
|
||||
uxCriticalNesting is saved and restored from the task stack during a context
|
||||
switch. */
|
||||
volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -73,33 +73,31 @@ volatile UBaseType_t uxCriticalNesting = 0xff;
|
|||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
/*
|
||||
* Place a few bytes of known values on the bottom of the stack.
|
||||
* This can be uncommented to provide useful stack markers when debugging.
|
||||
*
|
||||
* pxTopOfStack = ( StackType_t ) 0x11;
|
||||
* pxTopOfStack--;
|
||||
* pxTopOfStack = ( StackType_t ) 0x22;
|
||||
* pxTopOfStack--;
|
||||
* pxTopOfStack = ( StackType_t ) 0x33;
|
||||
* pxTopOfStack--;
|
||||
Place a few bytes of known values on the bottom of the stack.
|
||||
This can be uncommented to provide useful stack markers when debugging.
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x11;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x22;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x33;
|
||||
pxTopOfStack--;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
* expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||
* expected by the HCS12 RTI instruction. */
|
||||
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||
expected by the HCS12 RTI instruction. */
|
||||
|
||||
|
||||
/* The address of the task function is placed in the stack byte at a time. */
|
||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 1 );
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 1 );
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 0 );
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 0 );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Next are all the registers that form part of the task context. */
|
||||
|
@ -117,15 +115,15 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* A register contains parameter high byte. */
|
||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 0 );
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 0 );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* B register contains parameter low byte. */
|
||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 1 );
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 1 );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||
* "I" bit of CCR is cleared */
|
||||
"I" bit of CCR is cleared */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
pxTopOfStack--;
|
||||
|
||||
|
@ -136,7 +134,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
#endif
|
||||
|
||||
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||
* a critical section). */
|
||||
a critical section). */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
|
||||
return pxTopOfStack;
|
||||
|
@ -159,10 +157,10 @@ static void prvSetupTimerInterrupt( void )
|
|||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* xPortStartScheduler() does not start the scheduler directly because
|
||||
* the header file containing the xPortStartScheduler() prototype is part
|
||||
* of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||
* Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||
* which does use the CODE_SEG pragma. */
|
||||
the header file containing the xPortStartScheduler() prototype is part
|
||||
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||
Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||
which does use the CODE_SEG pragma. */
|
||||
|
||||
return xBankedStartScheduler();
|
||||
}
|
||||
|
@ -173,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
static BaseType_t xBankedStartScheduler( void )
|
||||
{
|
||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||
* disabled when this function is called. */
|
||||
disabled when this function is called. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Restore the context of the first task. */
|
||||
|
@ -224,15 +222,15 @@ void interrupt vPortTickInterrupt( void )
|
|||
TFLG1 = 1;
|
||||
|
||||
/* Restore the context of a task - which may be a different task
|
||||
* to that interrupted. */
|
||||
to that interrupted. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
#else /* if configUSE_PREEMPTION == 1 */
|
||||
#else
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
TFLG1 = 1;
|
||||
}
|
||||
#endif /* if configUSE_PREEMPTION == 1 */
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma CODE_SEG DEFAULT
|
||||
|
|
|
@ -53,7 +53,7 @@ typedef portSTACK_TYPE StackType_t;
|
|||
typedef signed char BaseType_t;
|
||||
typedef unsigned char UBaseType_t;
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -83,12 +83,12 @@ typedef unsigned char UBaseType_t;
|
|||
* directly. Each task maintains its own nesting count.
|
||||
*/
|
||||
#define portENTER_CRITICAL() \
|
||||
{ \
|
||||
{ \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
portDISABLE_INTERRUPTS(); \
|
||||
uxCriticalNesting++; \
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||
|
@ -96,7 +96,7 @@ typedef unsigned char UBaseType_t;
|
|||
* section and interrupts can be re-enabled.
|
||||
*/
|
||||
#define portEXIT_CRITICAL() \
|
||||
{ \
|
||||
{ \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
uxCriticalNesting--; \
|
||||
|
@ -104,7 +104,7 @@ typedef unsigned char UBaseType_t;
|
|||
{ \
|
||||
portENABLE_INTERRUPTS(); \
|
||||
} \
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
@ -120,8 +120,7 @@ typedef unsigned char UBaseType_t;
|
|||
*/
|
||||
|
||||
#ifdef BANKED_MODEL
|
||||
|
||||
/*
|
||||
/*
|
||||
* Load the stack pointer for the task, then pull the critical nesting
|
||||
* count and PPAGE register from the stack. The remains of the
|
||||
* context are restored by the RTI instruction.
|
||||
|
@ -139,7 +138,7 @@ typedef unsigned char UBaseType_t;
|
|||
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* By the time this macro is called the processor has already stacked the
|
||||
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||
* the task stack pointer.
|
||||
|
@ -156,9 +155,9 @@ typedef unsigned char UBaseType_t;
|
|||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "sts 0, x" ); \
|
||||
}
|
||||
#else /* ifdef BANKED_MODEL */
|
||||
#else
|
||||
|
||||
/*
|
||||
/*
|
||||
* These macros are as per the BANKED versions above, but without saving
|
||||
* and restoring the PPAGE register.
|
||||
*/
|
||||
|
@ -184,7 +183,7 @@ typedef unsigned char UBaseType_t;
|
|||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "sts 0, x" ); \
|
||||
}
|
||||
#endif /* ifdef BANKED_MODEL */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Utility macro to call macros above in correct order in order to perform a
|
||||
|
@ -199,7 +198,7 @@ typedef unsigned char UBaseType_t;
|
|||
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
|
|
@ -75,9 +75,9 @@
|
|||
|
||||
/* Save the floating point context, if any. */
|
||||
FMRXNE R1, FPSCR
|
||||
PUSHNE {R1}
|
||||
VPUSHNE {D0-D15}
|
||||
VPUSHNE {D16-D31}
|
||||
PUSHNE {R1}
|
||||
|
||||
/* Save ulPortTaskHasFPUContext itself. */
|
||||
PUSH {R3}
|
||||
|
@ -106,9 +106,9 @@
|
|||
CMP R1, #0
|
||||
|
||||
/* Restore the floating point context, if any. */
|
||||
POPNE {R0}
|
||||
VPOPNE {D16-D31}
|
||||
VPOPNE {D0-D15}
|
||||
POPNE {R0}
|
||||
VMSRNE FPSCR, R0
|
||||
|
||||
/* Restore the critical section nesting depth. */
|
||||
|
@ -145,8 +145,15 @@
|
|||
FreeRTOS_SWI_Handler:
|
||||
/* Save the context of the current task and select a new task to run. */
|
||||
portSAVE_CONTEXT
|
||||
|
||||
/* Ensure bit 2 of the stack pointer is clear. */
|
||||
MOV r2, sp
|
||||
AND r2, r2, #4
|
||||
SUB sp, sp, r2
|
||||
|
||||
LDR R0, vTaskSwitchContextConst
|
||||
BLX R0
|
||||
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
|
||||
|
@ -256,7 +263,13 @@ switch_before_exit:
|
|||
/* Call the function that selects the new task to execute.
|
||||
vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD
|
||||
instructions, or 8 byte aligned stack allocated data. LR does not need
|
||||
saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */
|
||||
saving as a new LR will be loaded by portRESTORE_CONTEXT anyway.
|
||||
Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for
|
||||
future use. */
|
||||
MOV r2, sp
|
||||
AND r2, r2, #4
|
||||
SUB sp, sp, r2
|
||||
|
||||
LDR R0, vTaskSwitchContextConst
|
||||
BLX R0
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
|
@ -51,6 +54,10 @@
|
|||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
|
@ -200,9 +207,9 @@ void vPortSVCHandler( void )
|
|||
|
||||
void vPortStartFirstTask( void )
|
||||
{
|
||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||
* table offset register that can be used to locate the initial stack value.
|
||||
* Not all M0 parts have the application vector table at address 0. */
|
||||
/* Don't reset the MSP stack as is done on CM3/4 devices. The vector table
|
||||
* in some CM0 devices cannot be modified and thus may not hold the
|
||||
* application's initial MSP value. */
|
||||
__asm volatile (
|
||||
" .syntax unified \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
||||
|
@ -231,7 +238,42 @@ void vPortStartFirstTask( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the function xPortPendSVHandler for PendSV
|
||||
* interrupt.
|
||||
* 2. Indirect Routing - Install separate handler for PendSV interrupt and
|
||||
* route program control from that handler to xPortPendSVHandler function.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
/* Point pxVectorTable to the interrupt vector table. Systems without
|
||||
* a VTOR register provide the value zero in the VTOR register and
|
||||
* the vector table itself is located at the address 0x00000000. */
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handler for PendSV interrupt. We do not check the installation of the
|
||||
* SysTick handler because the application may choose to drive the RTOS
|
||||
* tick using a timer other than the SysTick timer by overriding the
|
||||
* weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handler. For help installing the FreeRTOS handler, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -34,10 +34,14 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
|
@ -52,6 +56,11 @@
|
|||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -259,6 +268,40 @@ static void prvPortStartFirstTask( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -343,9 +386,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to access and manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
|
@ -87,7 +90,6 @@
|
|||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
@ -95,6 +97,11 @@
|
|||
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
||||
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -414,7 +421,6 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
|||
switch( ucSVCNumber )
|
||||
{
|
||||
case portSVC_START_SCHEDULER:
|
||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
||||
prvRestoreContextOfFirstTask();
|
||||
break;
|
||||
|
||||
|
@ -737,6 +743,40 @@ static void prvRestoreContextOfFirstTask( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -821,11 +861,12 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
||||
* handler higher priority so it can be used to exit a critical section (where
|
||||
* lower priorities are masked). */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
|
||||
/* Configure the regions in the MPU that are common to all tasks. */
|
||||
prvSetupMPU();
|
||||
|
@ -1054,12 +1095,28 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
|||
|
||||
static void prvSetupMPU( void )
|
||||
{
|
||||
#if defined( __ARMCC_VERSION )
|
||||
|
||||
/* Declaration when these variable are defined in code instead of being
|
||||
* exported from linker scripts. */
|
||||
extern uint32_t * __privileged_functions_start__;
|
||||
extern uint32_t * __privileged_functions_end__;
|
||||
extern uint32_t * __FLASH_segment_start__;
|
||||
extern uint32_t * __FLASH_segment_end__;
|
||||
extern uint32_t * __privileged_data_start__;
|
||||
extern uint32_t * __privileged_data_end__;
|
||||
#else
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
extern uint32_t __FLASH_segment_start__[];
|
||||
extern uint32_t __FLASH_segment_end__[];
|
||||
extern uint32_t __privileged_data_start__[];
|
||||
extern uint32_t __privileged_data_end__[];
|
||||
#endif /* if defined( __ARMCC_VERSION ) */
|
||||
|
||||
/* Ensure that the device has the expected MPU type */
|
||||
configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE );
|
||||
|
||||
/* Check the expected MPU is present. */
|
||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
||||
|
@ -1188,10 +1245,22 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
|||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
#if defined( __ARMCC_VERSION )
|
||||
|
||||
/* Declaration when these variable are defined in code instead of being
|
||||
* exported from linker scripts. */
|
||||
extern uint32_t * __SRAM_segment_start__;
|
||||
extern uint32_t * __SRAM_segment_end__;
|
||||
extern uint32_t * __privileged_data_start__;
|
||||
extern uint32_t * __privileged_data_end__;
|
||||
#else
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __SRAM_segment_start__[];
|
||||
extern uint32_t __SRAM_segment_end__[];
|
||||
extern uint32_t __privileged_data_start__[];
|
||||
extern uint32_t __privileged_data_end__[];
|
||||
#endif /* if defined( __ARMCC_VERSION ) */
|
||||
|
||||
int32_t lIndex;
|
||||
uint32_t ul;
|
||||
|
||||
|
@ -1311,7 +1380,15 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,15 @@ typedef unsigned long UBaseType_t;
|
|||
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
|
||||
|
||||
/* MPU settings that can be overriden in FreeRTOSConfig.h. */
|
||||
#ifndef configTOTAL_MPU_REGIONS
|
||||
/* Define to 8 for backward compatibility. */
|
||||
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||
#elif( configTOTAL_MPU_REGIONS != 8UL )
|
||||
/* The Cortex M3 only supports 8 MPU regions. For more information refer to:
|
||||
* https://developer.arm.com/documentation/dui0552/a/cortex-m3-peripherals/optional-memory-protection-unit */
|
||||
#error configTOTAL_MPU_REGIONS must be 8 for this port.
|
||||
#endif /* configTOTAL_MPU_REGIONS Check */
|
||||
#define portSTACK_REGION ( 3UL )
|
||||
#define portGENERAL_PERIPHERALS_REGION ( 4UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 5UL )
|
||||
|
|
|
@ -38,10 +38,14 @@
|
|||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
|
@ -62,6 +66,11 @@
|
|||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -302,6 +311,40 @@ BaseType_t xPortStartScheduler( void )
|
|||
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -386,9 +429,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to access and manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
|
@ -97,7 +100,6 @@
|
|||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
|
||||
|
@ -109,6 +111,11 @@
|
|||
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
||||
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -448,7 +455,6 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
|||
switch( ucSVCNumber )
|
||||
{
|
||||
case portSVC_START_SCHEDULER:
|
||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
||||
prvRestoreContextOfFirstTask();
|
||||
break;
|
||||
|
||||
|
@ -823,6 +829,40 @@ BaseType_t xPortStartScheduler( void )
|
|||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||
#endif
|
||||
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -907,11 +947,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
||||
* handler higher priority so it can be used to exit a critical section (where
|
||||
* lower priorities are masked). */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Configure the regions in the MPU that are common to all tasks. */
|
||||
prvSetupMPU();
|
||||
|
@ -1483,7 +1523,15 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -38,10 +38,14 @@
|
|||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
|
@ -56,6 +60,11 @@
|
|||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -290,6 +299,40 @@ static void prvPortStartFirstTask( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -374,9 +417,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -296,8 +296,8 @@ static void prvSetupTimerInterrupt( void )
|
|||
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||
* count is incremented after the context is saved.
|
||||
*/
|
||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void ) __attribute__( ( naked ) );
|
||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void )
|
||||
interrupt( TIMERA0_VECTOR ) void prvTickISR( void ) __attribute__( ( naked ) );
|
||||
interrupt( TIMERA0_VECTOR ) void prvTickISR( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
@ -320,8 +320,8 @@ static void prvSetupTimerInterrupt( void )
|
|||
* tick count. We don't need to switch context, this can only be done by
|
||||
* manual calls to taskYIELD();
|
||||
*/
|
||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void );
|
||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void )
|
||||
interrupt( TIMERA0_VECTOR ) void prvTickISR( void );
|
||||
interrupt( TIMERA0_VECTOR ) void prvTickISR( void )
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#define portSHORT int
|
||||
#define portSTACK_TYPE uint16_t
|
||||
#define portBASE_TYPE short
|
||||
#define portPOINTER_SIZE_TYPE uint16_t
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef short BaseType_t;
|
||||
|
@ -118,6 +119,11 @@ extern void vPortYield( void ) __attribute__( ( naked ) );
|
|||
#define portBYTE_ALIGNMENT 2
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
|
||||
/* GCC used to define these but doesn't any more */
|
||||
#define interrupt(vector) __attribute__((__interrupt__(vector)))
|
||||
#define wakeup __attribute__((__wakeup__))
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
|
|
|
@ -111,9 +111,6 @@ extern void vTaskSwitchContext( void );
|
|||
/* Critical section management. */
|
||||
#define portCRITICAL_NESTING_IN_TCB 0
|
||||
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "csrc mstatus, 8" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( "csrs mstatus, 8" )
|
||||
|
||||
|
|
|
@ -1,158 +1,109 @@
|
|||
; /*
|
||||
* ; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* ; *
|
||||
* ; * SPDX-License-Identifier: MIT
|
||||
* ; *
|
||||
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* ; * this software and associated documentation files (the "Software"), to deal in
|
||||
* ; * the Software without restriction, including without limitation the rights to
|
||||
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* ; * subject to the following conditions:
|
||||
* ; *
|
||||
* ; * The above copyright notice and this permission notice shall be included in all
|
||||
* ; * copies or substantial portions of the Software.
|
||||
* ; *
|
||||
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ; *
|
||||
* ; * https://www.FreeRTOS.org
|
||||
* ; * https://github.com/FreeRTOS
|
||||
* ; *
|
||||
* ; */
|
||||
;/*
|
||||
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * https://www.FreeRTOS.org
|
||||
; * https://github.com/FreeRTOS
|
||||
; *
|
||||
; */
|
||||
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN ulCriticalNesting
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN ulPortTaskHasFPUContext
|
||||
EXTERN ulAsmAPIPriorityMask
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN ulCriticalNesting
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN ulPortTaskHasFPUContext
|
||||
EXTERN ulAsmAPIPriorityMask
|
||||
|
||||
portSAVE_CONTEXT macro
|
||||
|
||||
;
|
||||
Save the LR and SPSR onto the system mode stack before switching to
|
||||
;
|
||||
system mode to save the remaining system mode registers
|
||||
SRSDB sp !, # SYS_MODE
|
||||
CPS # SYS_MODE
|
||||
PUSH {
|
||||
R0 - R12, R14
|
||||
}
|
||||
; Save the LR and SPSR onto the system mode stack before switching to
|
||||
; system mode to save the remaining system mode registers
|
||||
SRSDB sp!, #SYS_MODE
|
||||
CPS #SYS_MODE
|
||||
PUSH {R0-R12, R14}
|
||||
|
||||
;
|
||||
Push the critical nesting count
|
||||
LDR R2, = ulCriticalNesting
|
||||
LDR R1, [ R2 ]
|
||||
PUSH {
|
||||
R1
|
||||
}
|
||||
; Push the critical nesting count
|
||||
LDR R2, =ulCriticalNesting
|
||||
LDR R1, [R2]
|
||||
PUSH {R1}
|
||||
|
||||
;
|
||||
Does the task have a floating point context that needs saving ? If
|
||||
;
|
||||
ulPortTaskHasFPUContext is 0 then no.
|
||||
LDR R2, = ulPortTaskHasFPUContext
|
||||
LDR R3, [ R2 ]
|
||||
CMP R3, # 0
|
||||
|
||||
;
|
||||
Save the floating point context,
|
||||
|
||||
if any
|
||||
FMRXNE R1, FPSCR
|
||||
VPUSHNE {
|
||||
D0 - D15
|
||||
}
|
||||
; Does the task have a floating point context that needs saving? If
|
||||
; ulPortTaskHasFPUContext is 0 then no.
|
||||
LDR R2, =ulPortTaskHasFPUContext
|
||||
LDR R3, [R2]
|
||||
CMP R3, #0
|
||||
|
||||
; Save the floating point context, if any
|
||||
FMRXNE R1, FPSCR
|
||||
VPUSHNE {D0-D15}
|
||||
#if configFPU_D32 == 1
|
||||
VPUSHNE {
|
||||
D16 - D31
|
||||
}
|
||||
#endif; configFPU_D32
|
||||
PUSHNE {
|
||||
R1
|
||||
}
|
||||
VPUSHNE {D16-D31}
|
||||
#endif ; configFPU_D32
|
||||
PUSHNE {R1}
|
||||
|
||||
;
|
||||
Save ulPortTaskHasFPUContext itself
|
||||
PUSH {
|
||||
R3
|
||||
}
|
||||
; Save ulPortTaskHasFPUContext itself
|
||||
PUSH {R3}
|
||||
|
||||
;
|
||||
Save the stack pointer in the TCB
|
||||
LDR R0, = pxCurrentTCB
|
||||
LDR R1, [ R0 ]
|
||||
STR SP, [ R1 ]
|
||||
; Save the stack pointer in the TCB
|
||||
LDR R0, =pxCurrentTCB
|
||||
LDR R1, [R0]
|
||||
STR SP, [R1]
|
||||
|
||||
endm
|
||||
endm
|
||||
|
||||
; /**********************************************************************/
|
||||
|
||||
portRESTORE_CONTEXT macro
|
||||
|
||||
;
|
||||
Set the SP to point to the stack of the task being restored.
|
||||
LDR R0, = pxCurrentTCB
|
||||
LDR R1, [ R0 ]
|
||||
LDR SP, [ R1 ]
|
||||
; Set the SP to point to the stack of the task being restored.
|
||||
LDR R0, =pxCurrentTCB
|
||||
LDR R1, [R0]
|
||||
LDR SP, [R1]
|
||||
|
||||
;
|
||||
Is there a floating point context to restore ? If the restored
|
||||
;
|
||||
ulPortTaskHasFPUContext is zero then no.
|
||||
LDR R0, = ulPortTaskHasFPUContext
|
||||
POP {
|
||||
R1
|
||||
}
|
||||
STR R1, [ R0 ]
|
||||
CMP R1, # 0
|
||||
|
||||
;
|
||||
Restore the floating point context,
|
||||
|
||||
if any
|
||||
POPNE {
|
||||
R0
|
||||
}
|
||||
; Is there a floating point context to restore? If the restored
|
||||
; ulPortTaskHasFPUContext is zero then no.
|
||||
LDR R0, =ulPortTaskHasFPUContext
|
||||
POP {R1}
|
||||
STR R1, [R0]
|
||||
CMP R1, #0
|
||||
|
||||
; Restore the floating point context, if any
|
||||
POPNE {R0}
|
||||
#if configFPU_D32 == 1
|
||||
VPOPNE {
|
||||
D16 - D31
|
||||
}
|
||||
#endif; configFPU_D32
|
||||
VPOPNE {
|
||||
D0 - D15
|
||||
}
|
||||
VMSRNE FPSCR, R0
|
||||
VPOPNE {D16-D31}
|
||||
#endif ; configFPU_D32
|
||||
VPOPNE {D0-D15}
|
||||
VMSRNE FPSCR, R0
|
||||
|
||||
;
|
||||
Restore the critical section nesting depth
|
||||
LDR R0, = ulCriticalNesting
|
||||
POP {
|
||||
R1
|
||||
}
|
||||
STR R1, [ R0 ]
|
||||
; Restore the critical section nesting depth
|
||||
LDR R0, =ulCriticalNesting
|
||||
POP {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
;
|
||||
Restore all system mode registers other than the SP( which is already
|
||||
;
|
||||
being used )
|
||||
POP
|
||||
{
|
||||
R0 - R12, R14
|
||||
}
|
||||
; Restore all system mode registers other than the SP (which is already
|
||||
; being used)
|
||||
POP {R0-R12, R14}
|
||||
|
||||
Return to the task code, loading CPSR on the way.CPSR has the interrupt
|
||||
;
|
||||
enable bit set appropriately
|
||||
; Return to the task code, loading CPSR on the way. CPSR has the interrupt
|
||||
; enable bit set appropriately for the task about to execute.
|
||||
RFEIA sp!
|
||||
|
||||
for the task about to execute.
|
||||
RFEIA sp !
|
||||
|
||||
endm
|
||||
endm
|
||||
|
|
|
@ -1,160 +1,111 @@
|
|||
; /*
|
||||
* ; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* ; *
|
||||
* ; * SPDX-License-Identifier: MIT
|
||||
* ; *
|
||||
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* ; * this software and associated documentation files (the "Software"), to deal in
|
||||
* ; * the Software without restriction, including without limitation the rights to
|
||||
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* ; * subject to the following conditions:
|
||||
* ; *
|
||||
* ; * The above copyright notice and this permission notice shall be included in all
|
||||
* ; * copies or substantial portions of the Software.
|
||||
* ; *
|
||||
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ; *
|
||||
* ; * https://www.FreeRTOS.org
|
||||
* ; * https://github.com/FreeRTOS
|
||||
* ; *
|
||||
* ; */
|
||||
;/*
|
||||
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * https://www.FreeRTOS.org
|
||||
; * https://github.com/FreeRTOS
|
||||
; *
|
||||
; */
|
||||
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN ulCriticalNesting
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN ulPortTaskHasFPUContext
|
||||
EXTERN ulAsmAPIPriorityMask
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN ulCriticalNesting
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN ulPortTaskHasFPUContext
|
||||
EXTERN ulAsmAPIPriorityMask
|
||||
|
||||
portSAVE_CONTEXT macro
|
||||
|
||||
;
|
||||
Save the LR and SPSR onto the system mode stack before switching to
|
||||
;
|
||||
system mode to save the remaining system mode registers
|
||||
SRSDB sp !, # SYS_MODE
|
||||
CPS # SYS_MODE
|
||||
PUSH {
|
||||
R0 - R12, R14
|
||||
}
|
||||
; Save the LR and SPSR onto the system mode stack before switching to
|
||||
; system mode to save the remaining system mode registers
|
||||
SRSDB sp!, #SYS_MODE
|
||||
CPS #SYS_MODE
|
||||
PUSH {R0-R12, R14}
|
||||
|
||||
;
|
||||
Push the critical nesting count
|
||||
LDR R2, = ulCriticalNesting
|
||||
LDR R1, [ R2 ]
|
||||
PUSH {
|
||||
R1
|
||||
}
|
||||
; Push the critical nesting count
|
||||
LDR R2, =ulCriticalNesting
|
||||
LDR R1, [R2]
|
||||
PUSH {R1}
|
||||
|
||||
;
|
||||
Does the task have a floating point context that needs saving ? If
|
||||
;
|
||||
ulPortTaskHasFPUContext is 0 then no.
|
||||
LDR R2, = ulPortTaskHasFPUContext
|
||||
LDR R3, [ R2 ]
|
||||
CMP R3, # 0
|
||||
; Does the task have a floating point context that needs saving? If
|
||||
; ulPortTaskHasFPUContext is 0 then no.
|
||||
LDR R2, =ulPortTaskHasFPUContext
|
||||
LDR R3, [R2]
|
||||
CMP R3, #0
|
||||
|
||||
;
|
||||
Save the floating point context,
|
||||
; Save the floating point context, if any
|
||||
FMRXNE R1, FPSCR
|
||||
VPUSHNE {D0-D15}
|
||||
VPUSHNE {D16-D31}
|
||||
PUSHNE {R1}
|
||||
|
||||
if any
|
||||
FMRXNE R1, FPSCR
|
||||
VPUSHNE {
|
||||
D0 - D15
|
||||
}
|
||||
; Save ulPortTaskHasFPUContext itself
|
||||
PUSH {R3}
|
||||
|
||||
VPUSHNE {
|
||||
D16 - D31
|
||||
}
|
||||
PUSHNE {
|
||||
R1
|
||||
}
|
||||
; Save the stack pointer in the TCB
|
||||
LDR R0, =pxCurrentTCB
|
||||
LDR R1, [R0]
|
||||
STR SP, [R1]
|
||||
|
||||
;
|
||||
Save ulPortTaskHasFPUContext itself
|
||||
PUSH {
|
||||
R3
|
||||
}
|
||||
|
||||
;
|
||||
Save the stack pointer in the TCB
|
||||
LDR R0, = pxCurrentTCB
|
||||
LDR R1, [ R0 ]
|
||||
STR SP, [ R1 ]
|
||||
|
||||
endm
|
||||
endm
|
||||
|
||||
; /**********************************************************************/
|
||||
|
||||
portRESTORE_CONTEXT macro
|
||||
|
||||
;
|
||||
Set the SP to point to the stack of the task being restored.
|
||||
LDR R0, = pxCurrentTCB
|
||||
LDR R1, [ R0 ]
|
||||
LDR SP, [ R1 ]
|
||||
; Set the SP to point to the stack of the task being restored.
|
||||
LDR R0, =pxCurrentTCB
|
||||
LDR R1, [R0]
|
||||
LDR SP, [R1]
|
||||
|
||||
;
|
||||
Is there a floating point context to restore ? If the restored
|
||||
;
|
||||
ulPortTaskHasFPUContext is zero then no.
|
||||
LDR R0, = ulPortTaskHasFPUContext
|
||||
POP {
|
||||
R1
|
||||
}
|
||||
STR R1, [ R0 ]
|
||||
CMP R1, # 0
|
||||
; Is there a floating point context to restore? If the restored
|
||||
; ulPortTaskHasFPUContext is zero then no.
|
||||
LDR R0, =ulPortTaskHasFPUContext
|
||||
POP {R1}
|
||||
STR R1, [R0]
|
||||
CMP R1, #0
|
||||
|
||||
;
|
||||
Restore the floating point context,
|
||||
; Restore the floating point context, if any
|
||||
POPNE {R0}
|
||||
VPOPNE {D16-D31}
|
||||
VPOPNE {D0-D15}
|
||||
VMSRNE FPSCR, R0
|
||||
|
||||
if any
|
||||
POPNE {
|
||||
R0
|
||||
}
|
||||
; Restore the critical section nesting depth
|
||||
LDR R0, =ulCriticalNesting
|
||||
POP {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
VPOPNE {
|
||||
D16 - D31
|
||||
}
|
||||
VPOPNE {
|
||||
D0 - D15
|
||||
}
|
||||
VMSRNE FPSCR, R0
|
||||
; Ensure the priority mask is correct for the critical nesting depth
|
||||
LDR R2, =portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS
|
||||
CMP R1, #0
|
||||
MOVEQ R4, #255
|
||||
LDRNE R4, =( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT )
|
||||
STR R4, [r2]
|
||||
|
||||
;
|
||||
Restore the critical section nesting depth
|
||||
LDR R0, = ulCriticalNesting
|
||||
POP {
|
||||
R1
|
||||
}
|
||||
STR R1, [ R0 ]
|
||||
; Restore all system mode registers other than the SP (which is already
|
||||
; being used)
|
||||
POP {R0-R12, R14}
|
||||
|
||||
;
|
||||
Ensure the priority mask is correct
|
||||
; Return to the task code, loading CPSR on the way.
|
||||
RFEIA sp!
|
||||
|
||||
for the critical nesting depth
|
||||
LDR R2, = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS
|
||||
CMP R1, # 0
|
||||
MOVEQ R4, # 255
|
||||
LDRNE R4, = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT )
|
||||
STR R4, [ r2 ]
|
||||
|
||||
;
|
||||
Restore all system mode registers other than the SP( which is already
|
||||
;
|
||||
being used )
|
||||
POP
|
||||
{
|
||||
R0 - R12, R14
|
||||
}
|
||||
|
||||
Return to the task code, loading CPSR on the way.
|
||||
RFEIA sp !
|
||||
|
||||
endm
|
||||
endm
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
|
@ -53,6 +56,10 @@
|
|||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
|
@ -121,6 +128,10 @@ extern void vPortStartFirstTask( void );
|
|||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*
|
||||
* FreeRTOS handlers implemented in assembly.
|
||||
*/
|
||||
extern void xPortPendSVHandler( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -168,6 +179,41 @@ static void prvTaskExitError( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the function xPortPendSVHandler for PendSV
|
||||
* interrupt.
|
||||
* 2. Indirect Routing - Install separate handler for PendSV interrupt and
|
||||
* route program control from that handler to xPortPendSVHandler function.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
/* Point pxVectorTable to the interrupt vector table. Systems without
|
||||
* a VTOR register provide the value zero in the VTOR register and
|
||||
* the vector table itself is located at the address 0x00000000. */
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handler for PendSV interrupt. We do not check the installation of the
|
||||
* SysTick handler because the application may choose to drive the RTOS
|
||||
* tick using a timer other than the SysTick timer by overriding the
|
||||
* weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handler. For help installing the FreeRTOS handler, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
|
|
@ -91,15 +91,15 @@ xPortPendSVHandler:
|
|||
|
||||
vPortSVCHandler;
|
||||
/* This function is no longer used, but retained for backward
|
||||
compatibility. */
|
||||
* compatibility. */
|
||||
bx lr
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortStartFirstTask
|
||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||
table offset register that can be used to locate the initial stack value.
|
||||
Not all M0 parts have the application vector table at address 0. */
|
||||
/* Don't reset the MSP stack as is done on CM3/4 devices. The vector table
|
||||
* in some CM0 devices cannot be modified and thus may not hold the
|
||||
* application's initial MSP value. */
|
||||
|
||||
ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
|
||||
ldr r1, [r3]
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -41,10 +41,14 @@
|
|||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
|
@ -59,6 +63,11 @@
|
|||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -121,6 +130,11 @@ extern void vPortStartFirstTask( void );
|
|||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*
|
||||
* FreeRTOS handlers implemented in assembly.
|
||||
*/
|
||||
extern void vPortSVCHandler( void );
|
||||
extern void xPortPendSVHandler( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
|
@ -208,6 +222,40 @@ static void prvTaskExitError( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -292,9 +340,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,14 @@
|
|||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
|
@ -69,6 +73,11 @@
|
|||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -141,6 +150,11 @@ extern void vPortEnableVFP( void );
|
|||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*
|
||||
* FreeRTOS handlers implemented in assembly.
|
||||
*/
|
||||
extern void vPortSVCHandler( void );
|
||||
extern void xPortPendSVHandler( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
|
@ -246,6 +260,40 @@ BaseType_t xPortStartScheduler( void )
|
|||
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -330,9 +378,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
|
|
|
@ -69,6 +69,9 @@
|
|||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
|
@ -108,7 +111,11 @@
|
|||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
|
@ -282,6 +289,11 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
void vPortSwitchToUserMode( void );
|
||||
|
||||
/*
|
||||
* FreeRTOS handlers implemented in assembly.
|
||||
*/
|
||||
extern void vPortSVCHandler( void ) PRIVILEGED_FUNCTION;
|
||||
extern void xPortPendSVHandler( void ) PRIVILEGED_FUNCTION;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
|
@ -384,7 +396,6 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */
|
|||
switch( ucSVCNumber )
|
||||
{
|
||||
case portSVC_START_SCHEDULER:
|
||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
||||
vPortRestoreContextOfFirstTask();
|
||||
break;
|
||||
|
||||
|
@ -713,6 +724,40 @@ BaseType_t xPortStartScheduler( void )
|
|||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||
#endif
|
||||
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -797,9 +842,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Configure the regions in the MPU that are common to all tasks. */
|
||||
prvSetupMPU();
|
||||
|
@ -1206,7 +1253,15 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,14 @@
|
|||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SHPR2_REG ( *( ( volatile uint32_t * ) 0xe000ed1c ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
|
@ -63,6 +67,11 @@
|
|||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -135,6 +144,11 @@ extern void vPortEnableVFP( void );
|
|||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*
|
||||
* FreeRTOS handlers implemented in assembly.
|
||||
*/
|
||||
extern void vPortSVCHandler( void );
|
||||
extern void xPortPendSVHandler( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
|
@ -234,6 +248,40 @@ static void prvTaskExitError( void )
|
|||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -318,9 +366,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Prototype of all Interrupt Service Routines (ISRs).
|
||||
*/
|
||||
typedef void ( * portISR_t )( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
|
@ -101,10 +107,18 @@
|
|||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
|
||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
|
||||
*/
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to check the validity of an interrupt priority.
|
||||
*/
|
||||
|
@ -1598,9 +1612,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
|
||||
* for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* SVC_Handler and PendSV_Handler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint32_t ulImplementedPrioBits = 0;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
|
@ -1609,11 +1656,8 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
* ensure interrupt entry is as fast and simple as possible.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = portNVIC_SHPR2_REG;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
* possible bits. */
|
||||
* First, determine the number of priority bits available. Write to all
|
||||
* possible bits in the priority setting for SVCall. */
|
||||
portNVIC_SHPR2_REG = 0xFF000000;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -1636,7 +1680,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
* of bits read back. */
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulImplementedPrioBits++;
|
||||
|
@ -1674,16 +1717,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
portNVIC_SHPR2_REG = ulOriginalPriority;
|
||||
}
|
||||
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
|
||||
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
/* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
|
||||
* the highest priority. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
|
@ -1865,7 +1906,15 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -31,54 +31,54 @@
|
|||
|
||||
portSAVE_CONTEXT macro
|
||||
|
||||
IMPORT pxCurrentTCB
|
||||
IMPORT usCriticalNesting
|
||||
IMPORT pxCurrentTCB
|
||||
IMPORT usCriticalNesting
|
||||
|
||||
/* Save the remaining registers. */
|
||||
push r4
|
||||
push r5
|
||||
push r6
|
||||
push r7
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov.w &usCriticalNesting, r14
|
||||
push r14
|
||||
/* Save the remaining registers. */
|
||||
push r4
|
||||
push r5
|
||||
push r6
|
||||
push r7
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov.w &usCriticalNesting, r14
|
||||
push r14
|
||||
mov.w &pxCurrentTCB, r12
|
||||
mov.w r1, 0 ( r12 )
|
||||
endm
|
||||
mov.w r1, 0(r12)
|
||||
endm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portRESTORE_CONTEXT macro
|
||||
mov.w & pxCurrentTCB, r12
|
||||
mov.w @r12, r1
|
||||
pop r15
|
||||
mov.w r15, &usCriticalNesting
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop r7
|
||||
pop r6
|
||||
pop r5
|
||||
pop r4
|
||||
mov.w &pxCurrentTCB, r12
|
||||
mov.w @r12, r1
|
||||
pop r15
|
||||
mov.w r15, &usCriticalNesting
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop r7
|
||||
pop r6
|
||||
pop r5
|
||||
pop r4
|
||||
|
||||
/* The last thing on the stack will be the status register.
|
||||
/* The last thing on the stack will be the status register.
|
||||
* Ensure the power down bits are clear ready for the next
|
||||
* time this power down register is popped from the stack. */
|
||||
bic.w # 0xf0, 0 ( SP )
|
||||
bic.w #0xf0, 0(SP)
|
||||
|
||||
reti
|
||||
endm
|
||||
reti
|
||||
endm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ifndef PORTASM_H */
|
||||
|
|
|
@ -113,9 +113,6 @@ extern void vTaskSwitchContext( void );
|
|||
/* Critical section management. */
|
||||
#define portCRITICAL_NESTING_IN_TCB 0
|
||||
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Tern EE 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the Tern EE 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Library includes. */
|
||||
#include <embedded.h>
|
||||
|
@ -55,16 +55,14 @@
|
|||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
* being used. */
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
* being used. */
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
|
@ -72,20 +70,18 @@ static void prvSetupTimerInterrupt( void );
|
|||
static void __interrupt __far prvYieldProcessor( void );
|
||||
|
||||
/* The timer initialisation functions leave interrupts enabled,
|
||||
* which is not what we want. This ISR is installed temporarily in case
|
||||
* the timer fires before we get a change to disable interrupts again. */
|
||||
which is not what we want. This ISR is installed temporarily in case
|
||||
the timer fires before we get a change to disable interrupts again. */
|
||||
static void __interrupt __far prvDummyISR( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* See header file for description. */
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t DS_Reg = 0;
|
||||
StackType_t DS_Reg = 0;
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
* This is just useful for debugging. */
|
||||
This is just useful for debugging. */
|
||||
|
||||
*pxTopOfStack = 0x1111;
|
||||
pxTopOfStack--;
|
||||
|
@ -95,8 +91,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* We are going to start the scheduler using a return from interrupt
|
||||
* instruction to load the program counter, so first there would be the
|
||||
* function call with parameters preamble. */
|
||||
instruction to load the program counter, so first there would be the
|
||||
function call with parameters preamble. */
|
||||
|
||||
*pxTopOfStack = FP_SEG( pvParameters );
|
||||
pxTopOfStack--;
|
||||
|
@ -116,8 +112,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* The remaining registers would be pushed on the stack by our context
|
||||
* switch function. These are loaded with values simply to make debugging
|
||||
* easier. */
|
||||
switch function. These are loaded with values simply to make debugging
|
||||
easier. */
|
||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||
|
@ -130,9 +126,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* We need the true data segment. */
|
||||
__asm {
|
||||
MOV DS_Reg, DS
|
||||
};
|
||||
__asm{ MOV DS_Reg, DS };
|
||||
|
||||
*pxTopOfStack = DS_Reg; /* DS */
|
||||
pxTopOfStack--;
|
||||
|
@ -151,7 +145,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
/* This is called with interrupts already disabled. */
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
* vector. */
|
||||
vector. */
|
||||
setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
/* Setup the tick interrupt. */
|
||||
|
@ -168,15 +162,15 @@ BaseType_t xPortStartScheduler( void )
|
|||
static void __interrupt __far prvDummyISR( void )
|
||||
{
|
||||
/* The timer initialisation functions leave interrupts enabled,
|
||||
* which is not what we want. This ISR is installed temporarily in case
|
||||
* the timer fires before we get a change to disable interrupts again. */
|
||||
which is not what we want. This ISR is installed temporarily in case
|
||||
the timer fires before we get a change to disable interrupts again. */
|
||||
outport( portEIO_REGISTER, portCLEAR_INTERRUPT );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
/* Get the scheduler to update the task states following the tick. */
|
||||
|
@ -189,17 +183,17 @@ static void __interrupt __far prvDummyISR( void )
|
|||
/* Reset interrupt. */
|
||||
outport( portEIO_REGISTER, portCLEAR_INTERRUPT );
|
||||
}
|
||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#else
|
||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||
{
|
||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||
* so we don't have to switch in the context of the next task. */
|
||||
so we don't have to switch in the context of the next task. */
|
||||
xTaskIncrementTick();
|
||||
|
||||
/* Reset interrupt. */
|
||||
outport( portEIO_REGISTER, portCLEAR_INTERRUPT );
|
||||
}
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
|
@ -217,25 +211,23 @@ void vPortEndScheduler( void )
|
|||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
const uint16_t usTimerACompare = portTIMER_COMPARE, usTimerAMode = portENABLE_TIMER_AND_INTERRUPT;
|
||||
const uint16_t usT2_IRQ = 0x13;
|
||||
const uint16_t usTimerACompare = portTIMER_COMPARE, usTimerAMode = portENABLE_TIMER_AND_INTERRUPT;
|
||||
const uint16_t usT2_IRQ = 0x13;
|
||||
|
||||
/* Configure the timer, the dummy handler is used here as the init
|
||||
* function leaves interrupts enabled. */
|
||||
function leaves interrupts enabled. */
|
||||
t2_init( usTimerAMode, usTimerACompare, prvDummyISR );
|
||||
|
||||
/* Disable interrupts again before installing the real handlers. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
* being used. */
|
||||
being used. */
|
||||
setvect( usT2_IRQ, prvPreemptiveTick );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
* being used. */
|
||||
being used. */
|
||||
setvect( usT2_IRQ, prvNonPreemptiveTick );
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ void portFIRST_CONTEXT( void );
|
|||
asm { mov ax, seg pxCurrentTCB } \
|
||||
asm { mov ds, ax } \
|
||||
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||
asm { mov es : 0x2[ bx ], ss } \
|
||||
asm { mov es:0x2[ bx ], ss } \
|
||||
asm { mov es:[ bx ], sp } \
|
||||
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef short BaseType_t;
|
|||
typedef unsigned short UBaseType_t;
|
||||
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -71,22 +71,21 @@ typedef unsigned short UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portENTER_CRITICAL() \
|
||||
__asm { pushf } \
|
||||
__asm { cli } \
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm { popf }
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm { cli }
|
||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||
|
||||
#define portENABLE_INTERRUPTS() __asm { sti }
|
||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portNOP() __asm { nop }
|
||||
#define portNOP() __asm{ nop }
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portSWITCH_INT_NUMBER 0x80
|
||||
#define portYIELD() __asm { int portSWITCH_INT_NUMBER }
|
||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 2
|
||||
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||
|
@ -100,8 +99,8 @@ typedef unsigned short UBaseType_t;
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Tern EE 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
* Implementation of functions defined in portable.h for the Tern EE 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Library includes. */
|
||||
#include <embedded.h>
|
||||
|
@ -57,16 +57,14 @@
|
|||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
* being used. */
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
* being used. */
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
|
@ -75,19 +73,15 @@ static void __interrupt __far prvYieldProcessor( void );
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* See header file for description. */
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t DS_Reg = 0;
|
||||
StackType_t DS_Reg = 0;
|
||||
|
||||
/* We need the true data segment. */
|
||||
__asm {
|
||||
MOV DS_Reg, DS
|
||||
};
|
||||
__asm{ MOV DS_Reg, DS };
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
* This is just useful for debugging. */
|
||||
This is just useful for debugging. */
|
||||
|
||||
*pxTopOfStack = 0x1111;
|
||||
pxTopOfStack--;
|
||||
|
@ -97,8 +91,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* We are going to start the scheduler using a return from interrupt
|
||||
* instruction to load the program counter, so first there would be the
|
||||
* function call with parameters preamble. */
|
||||
instruction to load the program counter, so first there would be the
|
||||
function call with parameters preamble. */
|
||||
|
||||
*pxTopOfStack = FP_OFF( pvParameters );
|
||||
pxTopOfStack--;
|
||||
|
@ -114,8 +108,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
pxTopOfStack--;
|
||||
|
||||
/* The remaining registers would be pushed on the stack by our context
|
||||
* switch function. These are loaded with values simply to make debugging
|
||||
* easier. */
|
||||
switch function. These are loaded with values simply to make debugging
|
||||
easier. */
|
||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||
|
@ -144,7 +138,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
/* This is called with interrupts already disabled. */
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
* vector. */
|
||||
vector. */
|
||||
setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
/* Setup the tick interrupt. */
|
||||
|
@ -159,8 +153,8 @@ BaseType_t xPortStartScheduler( void )
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
/* Get the scheduler to update the task states following the tick. */
|
||||
|
@ -173,17 +167,17 @@ BaseType_t xPortStartScheduler( void )
|
|||
/* Reset interrupt. */
|
||||
outport( portEIO_REGISTER, portCLEAR_INTERRUPT );
|
||||
}
|
||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#else
|
||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||
{
|
||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||
* so we don't have to switch in the context of the next task. */
|
||||
so we don't have to switch in the context of the next task. */
|
||||
xTaskIncrementTick();
|
||||
|
||||
/* Reset interrupt. */
|
||||
outport( portEIO_REGISTER, portCLEAR_INTERRUPT );
|
||||
}
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
|
@ -201,21 +195,19 @@ void vPortEndScheduler( void )
|
|||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
const uint32_t ulCompareValue = portTIMER_COMPARE;
|
||||
uint16_t usTimerCompare;
|
||||
const uint32_t ulCompareValue = portTIMER_COMPARE;
|
||||
uint16_t usTimerCompare;
|
||||
|
||||
usTimerCompare = ( uint16_t ) ( ulCompareValue >> 4 );
|
||||
t2_init( portENABLE_TIMER, portPRESCALE_VALUE, NULL );
|
||||
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
* being used. */
|
||||
being used. */
|
||||
t1_init( portENABLE_TIMER_AND_INTERRUPT, usTimerCompare, usTimerCompare, prvPreemptiveTick );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
* being used. */
|
||||
being used. */
|
||||
t1_init( portENABLE_TIMER_AND_INTERRUPT, usTimerCompare, usTimerCompare, prvNonPreemptiveTick );
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -48,15 +48,15 @@ void portEND_SWITCHING_ISR( void );
|
|||
void portFIRST_CONTEXT( void );
|
||||
|
||||
#define portEND_SWITCHING_ISR() \
|
||||
asm { mov bx, [ pxCurrentTCB ] } \
|
||||
asm { mov word ptr[ bx ], sp } \
|
||||
asm { mov bx, [pxCurrentTCB] } \
|
||||
asm { mov word ptr [bx], sp } \
|
||||
asm { call far ptr vTaskSwitchContext } \
|
||||
asm { mov bx, [ pxCurrentTCB ] } \
|
||||
asm { mov sp, [ bx ] }
|
||||
asm { mov bx, [pxCurrentTCB] } \
|
||||
asm { mov sp, [bx] }
|
||||
|
||||
#define portFIRST_CONTEXT() \
|
||||
asm { mov bx, [ pxCurrentTCB ] } \
|
||||
asm { mov sp, [ bx ] } \
|
||||
asm { mov bx, [pxCurrentTCB] } \
|
||||
asm { mov sp, [bx] } \
|
||||
asm { pop bp } \
|
||||
asm { pop di } \
|
||||
asm { pop si } \
|
||||
|
@ -69,4 +69,4 @@ void portFIRST_CONTEXT( void );
|
|||
asm { iret }
|
||||
|
||||
|
||||
#endif /* ifndef PORT_ASM_H */
|
||||
#endif
|
||||
|
|
|
@ -59,9 +59,9 @@ typedef short BaseType_t;
|
|||
typedef unsigned short UBaseType_t;
|
||||
|
||||
|
||||
typedef void ( __interrupt __far * pxISR )();
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
|
||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||
|
@ -73,22 +73,21 @@ typedef void ( __interrupt __far * pxISR )();
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portENTER_CRITICAL() \
|
||||
__asm { pushf } \
|
||||
__asm { cli } \
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm { popf }
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm { cli }
|
||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||
|
||||
#define portENABLE_INTERRUPTS() __asm { sti }
|
||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portNOP() __asm { nop }
|
||||
#define portNOP() __asm{ nop }
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portSWITCH_INT_NUMBER 0x80
|
||||
#define portYIELD() __asm { int portSWITCH_INT_NUMBER }
|
||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 2
|
||||
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||
|
@ -102,8 +101,8 @@ typedef void ( __interrupt __far * pxISR )();
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||
#endif
|
||||
|
||||
/* Prototype of all Interrupt Service Routines (ISRs). */
|
||||
typedef void ( * portISR_t )( void );
|
||||
|
||||
/* Constants required to access and manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
|
@ -87,7 +90,6 @@
|
|||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL )
|
||||
#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */
|
||||
|
@ -99,6 +101,11 @@
|
|||
#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 )
|
||||
#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 )
|
||||
|
||||
/* Constants used to check the installation of the FreeRTOS interrupt handlers. */
|
||||
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) )
|
||||
#define portVECTOR_INDEX_SVC ( 11 )
|
||||
#define portVECTOR_INDEX_PENDSV ( 14 )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
|
@ -386,7 +393,6 @@ void vSVCHandler_C( uint32_t * pulParam )
|
|||
switch( ucSVCNumber )
|
||||
{
|
||||
case portSVC_START_SCHEDULER:
|
||||
portNVIC_SHPR2_REG |= portNVIC_SVC_PRI;
|
||||
prvRestoreContextOfFirstTask();
|
||||
break;
|
||||
|
||||
|
@ -822,6 +828,40 @@ BaseType_t xPortStartScheduler( void )
|
|||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||
#endif
|
||||
|
||||
/* An application can install FreeRTOS interrupt handlers in one of the
|
||||
* folllowing ways:
|
||||
* 1. Direct Routing - Install the functions vPortSVCHandler and
|
||||
* xPortPendSVHandler for SVCall and PendSV interrupts respectively.
|
||||
* 2. Indirect Routing - Install separate handlers for SVCall and PendSV
|
||||
* interrupts and route program control from those handlers to
|
||||
* vPortSVCHandler and xPortPendSVHandler functions.
|
||||
*
|
||||
* Applications that use Indirect Routing must set
|
||||
* configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
|
||||
* routing, which is validated here when configCHECK_HANDLER_INSTALLATION
|
||||
* is 1, should be preferred when possible. */
|
||||
#if ( configCHECK_HANDLER_INSTALLATION == 1 )
|
||||
{
|
||||
const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
|
||||
|
||||
/* Validate that the application has correctly installed the FreeRTOS
|
||||
* handlers for SVCall and PendSV interrupts. We do not check the
|
||||
* installation of the SysTick handler because the application may
|
||||
* choose to drive the RTOS tick using a timer other than the SysTick
|
||||
* timer by overriding the weak function vPortSetupTimerInterrupt().
|
||||
*
|
||||
* Assertion failures here indicate incorrect installation of the
|
||||
* FreeRTOS handlers. For help installing the FreeRTOS handlers, see
|
||||
* https://www.FreeRTOS.org/FAQHelp.html.
|
||||
*
|
||||
* Systems with a configurable address for the interrupt vector table
|
||||
* can also encounter assertion failures or even system faults here if
|
||||
* VTOR is not set correctly to point to the application's vector table. */
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == vPortSVCHandler );
|
||||
configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == xPortPendSVHandler );
|
||||
}
|
||||
#endif /* configCHECK_HANDLER_INSTALLATION */
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint8_t ucOriginalPriority;
|
||||
|
@ -907,10 +947,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
||||
* handler higher priority so it can be used to exit a critical section (where
|
||||
* lower priorities are masked). */
|
||||
* handler highest priority so it can be used to exit a critical section
|
||||
* (where lower priorities are masked). */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
portNVIC_SHPR2_REG = 0;
|
||||
|
||||
/* Configure the regions in the MPU that are common to all tasks. */
|
||||
prvSetupMPU();
|
||||
|
@ -1196,6 +1237,7 @@ __asm void vPortEnableVFP( void )
|
|||
orr r1, r1, #( 0xf << 20 ) /* Enable CP10 and CP11 coprocessors, then save back. */
|
||||
str r1, [ r0 ]
|
||||
bx r14
|
||||
nop
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1466,7 +1508,16 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
|
|||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d4cccca2971d6ffca581564f8142069cb854bd15
|
||||
Subproject commit f051e9bff812aa3c10c5417e064671a1c4eeb314
|
159
portable/ThirdParty/GCC/Posix/port.c
vendored
159
portable/ThirdParty/GCC/Posix/port.c
vendored
|
@ -51,6 +51,10 @@
|
|||
*----------------------------------------------------------*/
|
||||
#include "portmacro.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
@ -60,6 +64,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_vm.h>
|
||||
|
@ -68,6 +73,7 @@
|
|||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "list.h"
|
||||
#include "timers.h"
|
||||
#include "utils/wait_for_event.h"
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -81,6 +87,7 @@ typedef struct THREAD
|
|||
void * pvParams;
|
||||
BaseType_t xDying;
|
||||
struct event * ev;
|
||||
ListItem_t xThreadListItem;
|
||||
} Thread_t;
|
||||
|
||||
/*
|
||||
|
@ -101,9 +108,11 @@ static sigset_t xAllSignals;
|
|||
static sigset_t xSchedulerOriginalSignalMask;
|
||||
static pthread_t hMainThread = ( pthread_t ) NULL;
|
||||
static volatile BaseType_t uxCriticalNesting;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t xSchedulerEnd = pdFALSE;
|
||||
static pthread_t hTimerTickThread;
|
||||
static bool xTimerTickThreadShouldRun;
|
||||
static uint64_t prvStartTimeNs;
|
||||
static List_t xThreadList;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupSignalsAndSchedulerPolicy( void );
|
||||
|
@ -127,6 +136,17 @@ void prvFatalError( const char * pcCall,
|
|||
fprintf( stderr, "%s: %s\n", pcCall, strerror( iErrno ) );
|
||||
abort();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvPortSetCurrentThreadName(char * pxThreadName)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
pthread_setname_np(pxThreadName);
|
||||
#else
|
||||
pthread_setname_np(pthread_self(), pxThreadName);
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
|
@ -163,19 +183,27 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
thread->pvParams = pvParameters;
|
||||
thread->xDying = pdFALSE;
|
||||
|
||||
/* Ensure ulStackSize is at least PTHREAD_STACK_MIN */
|
||||
ulStackSize = (ulStackSize < PTHREAD_STACK_MIN) ? PTHREAD_STACK_MIN : ulStackSize;
|
||||
|
||||
pthread_attr_init( &xThreadAttributes );
|
||||
iRet = pthread_attr_setstack( &xThreadAttributes, pxEndOfStack, ulStackSize );
|
||||
iRet = pthread_attr_setstacksize( &xThreadAttributes, ulStackSize );
|
||||
|
||||
if( iRet != 0 )
|
||||
{
|
||||
fprintf( stderr, "[WARN] pthread_attr_setstack failed with return value: %d. Default stack will be used.\n", iRet );
|
||||
fprintf( stderr, "[WARN] Increase the stack size to PTHREAD_STACK_MIN.\n" );
|
||||
fprintf( stderr, "[WARN] pthread_attr_setstacksize failed with return value: %d. Default stack size will be used.\n", iRet );
|
||||
}
|
||||
|
||||
thread->ev = event_create();
|
||||
|
||||
vListInitialiseItem( &thread->xThreadListItem );
|
||||
listSET_LIST_ITEM_OWNER( &thread->xThreadListItem, thread );
|
||||
|
||||
vPortEnterCritical();
|
||||
|
||||
/* Add the new thread in xThreadList. */
|
||||
vListInsertEnd( &xThreadList, &thread->xThreadListItem );
|
||||
|
||||
iRet = pthread_create( &thread->pthread, &xThreadAttributes,
|
||||
prvWaitForStart, thread );
|
||||
|
||||
|
@ -206,8 +234,11 @@ BaseType_t xPortStartScheduler( void )
|
|||
{
|
||||
int iSignal;
|
||||
sigset_t xSignals;
|
||||
ListItem_t * pxIterator;
|
||||
const ListItem_t * pxEndMarker;
|
||||
|
||||
hMainThread = pthread_self();
|
||||
prvPortSetCurrentThreadName("Scheduler");
|
||||
|
||||
/* Start the timer that generates the tick ISR(SIGALRM).
|
||||
* Interrupts are disabled here already. */
|
||||
|
@ -231,15 +262,28 @@ BaseType_t xPortStartScheduler( void )
|
|||
sigwait( &xSignals, &iSignal );
|
||||
}
|
||||
|
||||
/* Cancel the Idle task and free its resources */
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
vPortCancelThread( xTaskGetIdleTaskHandle() );
|
||||
#endif
|
||||
/* Cancel all the running thread. */
|
||||
pxEndMarker = listGET_END_MARKER( &xThreadList );
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
/* Cancel the Timer task and free its resources */
|
||||
vPortCancelThread( xTimerGetTimerDaemonTaskHandle() );
|
||||
#endif /* configUSE_TIMERS */
|
||||
for( pxIterator = listGET_HEAD_ENTRY( &xThreadList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) )
|
||||
{
|
||||
Thread_t * pxThread = ( Thread_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
|
||||
|
||||
pthread_cancel( pxThread->pthread );
|
||||
event_signal( pxThread->ev );
|
||||
pthread_join( pxThread->pthread, NULL );
|
||||
event_delete( pxThread->ev );
|
||||
}
|
||||
|
||||
/*
|
||||
* clear out the variable that is used to end the scheduler, otherwise
|
||||
* subsequent scheduler restarts will end immediately.
|
||||
*/
|
||||
xSchedulerEnd = pdFALSE;
|
||||
|
||||
/* Reset the pthread_once_t structure. This is required if the port
|
||||
* starts the scheduler again. */
|
||||
hSigSetupThread = PTHREAD_ONCE_INIT;
|
||||
|
||||
/* Restore original signal mask. */
|
||||
( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
|
||||
|
@ -250,30 +294,15 @@ BaseType_t xPortStartScheduler( void )
|
|||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
struct itimerval itimer;
|
||||
struct sigaction sigtick;
|
||||
Thread_t * xCurrentThread;
|
||||
|
||||
/* Stop the timer and ignore any pending SIGALRMs that would end
|
||||
* up running on the main thread when it is resumed. */
|
||||
itimer.it_value.tv_sec = 0;
|
||||
itimer.it_value.tv_usec = 0;
|
||||
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_usec = 0;
|
||||
( void ) setitimer( ITIMER_REAL, &itimer, NULL );
|
||||
|
||||
sigtick.sa_flags = 0;
|
||||
sigtick.sa_handler = SIG_IGN;
|
||||
sigemptyset( &sigtick.sa_mask );
|
||||
sigaction( SIGALRM, &sigtick, NULL );
|
||||
/* Stop the timer tick thread. */
|
||||
xTimerTickThreadShouldRun = false;
|
||||
pthread_join( hTimerTickThread, NULL );
|
||||
|
||||
/* Signal the scheduler to exit its loop. */
|
||||
xSchedulerEnd = pdTRUE;
|
||||
( void ) pthread_kill( hMainThread, SIG_RESUME );
|
||||
|
||||
xCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
||||
prvSuspendSelf( xCurrentThread );
|
||||
pthread_exit( NULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -359,45 +388,41 @@ static uint64_t prvGetTimeNs( void )
|
|||
|
||||
return ( uint64_t ) t.tv_sec * ( uint64_t ) 1000000000UL + ( uint64_t ) t.tv_nsec;
|
||||
}
|
||||
|
||||
static uint64_t prvStartTimeNs;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* commented as part of the code below in vPortSystemTickHandler,
|
||||
* to adjust timing according to full demo requirements */
|
||||
/* static uint64_t prvTickCount; */
|
||||
|
||||
static void * prvTimerTickHandler( void * arg )
|
||||
{
|
||||
( void ) arg;
|
||||
|
||||
prvPortSetCurrentThreadName("Scheduler timer");
|
||||
|
||||
while( xTimerTickThreadShouldRun )
|
||||
{
|
||||
/*
|
||||
* signal to the active task to cause tick handling or
|
||||
* preemption (if enabled)
|
||||
*/
|
||||
Thread_t * thread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
||||
pthread_kill( thread->pthread, SIGALRM );
|
||||
usleep( portTICK_RATE_MICROSECONDS );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
struct itimerval itimer;
|
||||
int iRet;
|
||||
|
||||
/* Initialise the structure with the current timer information. */
|
||||
iRet = getitimer( ITIMER_REAL, &itimer );
|
||||
|
||||
if( iRet == -1 )
|
||||
{
|
||||
prvFatalError( "getitimer", errno );
|
||||
}
|
||||
|
||||
/* Set the interval between timer events. */
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_usec = portTICK_RATE_MICROSECONDS;
|
||||
|
||||
/* Set the current count-down. */
|
||||
itimer.it_value.tv_sec = 0;
|
||||
itimer.it_value.tv_usec = portTICK_RATE_MICROSECONDS;
|
||||
|
||||
/* Set-up the timer interrupt. */
|
||||
iRet = setitimer( ITIMER_REAL, &itimer, NULL );
|
||||
|
||||
if( iRet == -1 )
|
||||
{
|
||||
prvFatalError( "setitimer", errno );
|
||||
}
|
||||
xTimerTickThreadShouldRun = true;
|
||||
pthread_create( &hTimerTickThread, NULL, prvTimerTickHandler, NULL );
|
||||
|
||||
prvStartTimeNs = prvGetTimeNs();
|
||||
}
|
||||
|
@ -454,15 +479,22 @@ void vPortThreadDying( void * pxTaskToDelete,
|
|||
|
||||
pxThread->xDying = pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortCancelThread( void * pxTaskToDelete )
|
||||
{
|
||||
Thread_t * pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete );
|
||||
|
||||
/* Remove the thread from xThreadList. */
|
||||
vPortEnterCritical();
|
||||
uxListRemove( &pxThreadToCancel->xThreadListItem );
|
||||
vPortExitCritical();
|
||||
|
||||
/*
|
||||
* The thread has already been suspended so it can be safely cancelled.
|
||||
*/
|
||||
pthread_cancel( pxThreadToCancel->pthread );
|
||||
event_signal( pxThreadToCancel->ev );
|
||||
pthread_join( pxThreadToCancel->pthread, NULL );
|
||||
event_delete( pxThreadToCancel->ev );
|
||||
}
|
||||
|
@ -478,6 +510,9 @@ static void * prvWaitForStart( void * pvParams )
|
|||
uxCriticalNesting = 0;
|
||||
vPortEnableInterrupts();
|
||||
|
||||
/* Set thread name */
|
||||
prvPortSetCurrentThreadName(pcTaskGetName(xTaskGetCurrentTaskHandle()));
|
||||
|
||||
/* Call the task's entry point. */
|
||||
pxThread->pxCode( pxThread->pvParams );
|
||||
|
||||
|
@ -538,6 +573,7 @@ static void prvSuspendSelf( Thread_t * thread )
|
|||
* - A thread with all signals blocked with pthread_sigmask().
|
||||
*/
|
||||
event_wait( thread->ev );
|
||||
pthread_testcancel();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -558,6 +594,9 @@ static void prvSetupSignalsAndSchedulerPolicy( void )
|
|||
|
||||
hMainThread = pthread_self();
|
||||
|
||||
/* Setup thread list to record all the task which are not deleted. */
|
||||
vListInitialise( &xThreadList );
|
||||
|
||||
/* Initialise common signal masks. */
|
||||
sigfillset( &xAllSignals );
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT AND BSD-3-Clause
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
|
||||
StackType_t ** ppxIdleTaskStackBuffer,
|
||||
uint32_t * pulIdleTaskStackSize )
|
||||
{
|
||||
/* If the buffers to be provided to the Idle task are declared inside this
|
||||
* function then they must be declared static - otherwise they will be allocated on
|
||||
* the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
||||
* state will be stored. */
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Idle task's stack. */
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||
* Note that, as the array is necessarily of type StackType_t,
|
||||
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
2
portable/ThirdParty/GCC/RP2040/library.cmake
vendored
2
portable/ThirdParty/GCC/RP2040/library.cmake
vendored
|
@ -46,9 +46,9 @@ target_compile_definitions(FreeRTOS-Kernel INTERFACE
|
|||
add_library(FreeRTOS-Kernel-Static INTERFACE)
|
||||
target_compile_definitions(FreeRTOS-Kernel-Static INTERFACE
|
||||
configSUPPORT_STATIC_ALLOCATION=1
|
||||
configKERNEL_PROVIDED_STATIC_MEMORY=1
|
||||
)
|
||||
|
||||
target_sources(FreeRTOS-Kernel-Static INTERFACE ${CMAKE_CURRENT_LIST_DIR}/idle_task_static_memory.c)
|
||||
target_link_libraries(FreeRTOS-Kernel-Static INTERFACE FreeRTOS-Kernel)
|
||||
|
||||
add_library(FreeRTOS-Kernel-Heap1 INTERFACE)
|
||||
|
|
2
portable/ThirdParty/Partner-Supported-Ports
vendored
2
portable/ThirdParty/Partner-Supported-Ports
vendored
|
@ -1 +1 @@
|
|||
Subproject commit d38f59dbcdfabbe71361764e194e1ad6202f902c
|
||||
Subproject commit da0185fbf1215706af66d020a67edf912193979a
|
41
portable/ThirdParty/XCC/Xtensa/port.c
vendored
41
portable/ThirdParty/XCC/Xtensa/port.c
vendored
|
@ -37,39 +37,34 @@
|
|||
|
||||
|
||||
/* Defined in portasm.h */
|
||||
extern void _frxt_tick_timer_init( void );
|
||||
extern void _frxt_tick_timer_init(void);
|
||||
|
||||
/* Defined in xtensa_context.S */
|
||||
extern void _xt_coproc_init( void );
|
||||
extern void _xt_coproc_init(void);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||
* any details of its type. */
|
||||
any details of its type. */
|
||||
typedef void TCB_t;
|
||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||
|
||||
unsigned port_xSchedulerRunning = 0; /* Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting */
|
||||
unsigned port_interruptNesting = 0; /* Interrupt nesting level */
|
||||
unsigned port_xSchedulerRunning = 0; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting
|
||||
unsigned port_interruptNesting = 0; // Interrupt nesting level
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* User exception dispatcher when exiting */
|
||||
void _xt_user_exit( void );
|
||||
// User exception dispatcher when exiting
|
||||
void _xt_user_exit(void);
|
||||
|
||||
/*
|
||||
* Stack initialization
|
||||
*/
|
||||
#if portUSING_MPU_WRAPPERS
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged )
|
||||
#else
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
#endif
|
||||
{
|
||||
StackType_t * sp;
|
||||
|
@ -134,14 +129,14 @@ void _xt_user_exit( void );
|
|||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the Xtensa port will get stopped. If required simply
|
||||
* disable the tick interrupt here. */
|
||||
disable the tick interrupt here. */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Interrupts are disabled at this point and stack contains PS with enabled interrupts when task context is restored */
|
||||
// Interrupts are disabled at this point and stack contains PS with enabled interrupts when task context is restored
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/* Initialize co-processor management for tasks. Leave CPENABLE alone. */
|
||||
|
@ -155,14 +150,14 @@ BaseType_t xPortStartScheduler( void )
|
|||
_frxt_tick_timer_init();
|
||||
|
||||
#if XT_USE_THREAD_SAFE_CLIB
|
||||
/* Init C library */
|
||||
// Init C library
|
||||
vPortClibInit();
|
||||
#endif
|
||||
|
||||
port_xSchedulerRunning = 1;
|
||||
|
||||
/* Cannot be directly called from C; never returns */
|
||||
__asm__ volatile ( "call0 _frxt_dispatch\n" );
|
||||
// Cannot be directly called from C; never returns
|
||||
__asm__ volatile ("call0 _frxt_dispatch\n");
|
||||
|
||||
/* Should not get here. */
|
||||
return pdTRUE;
|
||||
|
@ -195,13 +190,13 @@ BaseType_t xPortSysTickHandler( void )
|
|||
* Used to set coprocessor area in stack. Current hack is to reuse MPU pointer for coprocessor area.
|
||||
*/
|
||||
#if portUSING_MPU_WRAPPERS
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
{
|
||||
#if XCHAL_CP_NUM > 0
|
||||
xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 ) );
|
||||
xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 ));
|
||||
xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) xMPUSettings->coproc_area ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
|
||||
xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( uint32_t ) xMPUSettings->coproc_area - XT_CP_SIZE ) & ~0xf );
|
||||
|
||||
|
@ -209,5 +204,5 @@ BaseType_t xPortSysTickHandler( void )
|
|||
* clear the stack area after we return. This is done in pxPortInitialiseStack().
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* if portUSING_MPU_WRAPPERS */
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#endif
|
||||
|
||||
#define portbenchmarkINTERRUPT_DISABLE()
|
||||
#define portbenchmarkINTERRUPT_RESTORE( newstate )
|
||||
#define portbenchmarkINTERRUPT_RESTORE(newstate)
|
||||
#define portbenchmarkIntLatency()
|
||||
#define portbenchmarkIntWait()
|
||||
#define portbenchmarkReset()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue