2014-01-21 01:53:30 +08:00
/*
2014-02-18 22:01:57 +08:00
FreeRTOS V8 .0 .0 - Copyright ( C ) 2014 Real Time Engineers Ltd .
2014-01-21 01:53:30 +08:00
All rights reserved
VISIT http : //www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* FreeRTOS provides completely free yet professionally developed , *
* robust , strictly quality controlled , supported , and cross *
* platform software that has become a de facto standard . *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book , reference *
* manual , or both from : http : //www.FreeRTOS.org/Documentation *
* *
* Thank you ! *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
This file is part of the FreeRTOS distribution .
FreeRTOS is free software ; you can redistribute it and / or modify it under
the terms of the GNU General Public License ( version 2 ) as published by the
Free Software Foundation > > ! AND MODIFIED BY ! < < the FreeRTOS exception .
> > ! NOTE : The modification to the GPL is included to allow you to distribute
> > ! a combined work that includes FreeRTOS without being obliged to provide
> > ! the source code for proprietary components outside of the FreeRTOS
> > ! kernel .
FreeRTOS is distributed in the hope that it will be useful , but WITHOUT ANY
WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE . Full license text is available from the following
link : http : //www.freertos.org/a00114.html
1 tab = = 4 spaces !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Having a problem ? Start by reading the FAQ " My application does *
* not run , what could be wrong ? " *
* *
* http : //www.FreeRTOS.org/FAQHelp.html *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
http : //www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd . contact details .
http : //www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS + Trace - an indispensable productivity tool , a DOS
compatible FAT file system , and our tiny thread aware UDP / IP stack .
http : //www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand . Low cost OpenRTOS
licenses offer ticketed support , indemnification and middleware .
http : //www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability .
1 tab = = 4 spaces !
*/
/* Standard includes. */
# include <stdlib.h>
/* Scheduler includes. */
# include "FreeRTOS.h"
# include "task.h"
# ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
# error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: //www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
# endif
# ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
# error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: //www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
# endif
# ifndef configUNIQUE_INTERRUPT_PRIORITIES
# error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: //www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
# endif
# ifndef configSETUP_TICK_INTERRUPT
# error configSETUP_TICK_INTERRUPT() must be defined. See http: //www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
# endif /* configSETUP_TICK_INTERRUPT */
# ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
# error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: //www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
# endif
# if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
# error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0
# endif
# if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES
# error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority
# endif
# if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Check the configuration. */
# if( configMAX_PRIORITIES > 32 )
# error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
# endif
# endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/* In case security extensions are implemented. */
# if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
# error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
# endif
2014-04-23 23:23:54 +08:00
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
portmacro . h . */
2014-01-25 01:09:31 +08:00
# ifndef configCLEAR_TICK_INTERRUPT
# define configCLEAR_TICK_INTERRUPT()
# endif
2014-01-21 01:53:30 +08:00
/* A critical section is exited when the critical section nesting count reaches
this value . */
# define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
/* In all GICs 255 can be written to the priority mask register to unmask all
( but the lowest ) interrupt priority . */
2014-03-26 01:12:31 +08:00
# define portUNMASK_VALUE ( 0xFFUL )
2014-01-21 01:53:30 +08:00
/* Tasks are not created with a floating point context, but can be given a
floating point context after they have been created . A variable is stored as
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
does not have an FPU context , or any other value if the task does have an FPU
context . */
# define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
/* Constants required to setup the initial task context. */
2014-02-04 22:49:48 +08:00
# define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, IRQ enabled FIQ enabled. */
2014-01-21 01:53:30 +08:00
# define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
# define portINTERRUPT_ENABLE_BIT ( 0x80UL )
# define portTHUMB_MODE_ADDRESS ( 0x01UL )
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
point is zero . */
# define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
/* Masks all bits in the APSR other than the mode bits. */
# define portAPSR_MODE_BITS_MASK ( 0x1F )
/* The value of the mode bits in the APSR when the CPU is executing in user
mode . */
# define portAPSR_USER_MODE ( 0x10 )
2014-01-24 21:27:56 +08:00
/* The critical section macros only mask interrupts up to an application
determined priority level . Sometimes it is necessary to turn interrupt off in
the CPU itself before modifying certain hardware registers . */
# define portCPU_IRQ_DISABLE() \
2014-01-25 01:09:31 +08:00
__asm volatile ( " CPSID i " ) ; \
__asm volatile ( " DSB " ) ; \
2014-01-24 21:27:56 +08:00
__asm volatile ( " ISB " ) ;
# define portCPU_IRQ_ENABLE() \
2014-01-25 01:09:31 +08:00
__asm volatile ( " CPSIE i " ) ; \
__asm volatile ( " DSB " ) ; \
2014-01-24 21:27:56 +08:00
__asm volatile ( " ISB " ) ;
2014-01-21 01:53:30 +08:00
/* Macro to unmask all interrupt priorities. */
2014-01-25 01:09:31 +08:00
# define portCLEAR_INTERRUPT_MASK() \
{ \
2014-01-24 21:27:56 +08:00
portCPU_IRQ_DISABLE ( ) ; \
2014-01-25 01:09:31 +08:00
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE ; \
__asm ( " DSB \n " \
" ISB \n " ) ; \
2014-01-24 21:27:56 +08:00
portCPU_IRQ_ENABLE ( ) ; \
2014-01-21 01:53:30 +08:00
}
2014-01-22 23:39:58 +08:00
# define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
# define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
# define portBIT_0_SET ( ( uint8_t ) 0x01 )
2014-01-21 01:53:30 +08:00
/*-----------------------------------------------------------*/
/*
* Starts the first task executing . This function is necessarily written in
* assembly code so is implemented in portASM . s .
*/
extern void vPortRestoreTaskContext ( void ) ;
/*-----------------------------------------------------------*/
/* A variable is used to keep track of the critical section nesting. This
variable has to be stored as part of the task context and must be initialised to
a non zero value to ensure interrupts don ' t inadvertently become unmasked before
the scheduler starts . As it is stored as part of the task context it will
automatically be set to 0 when the first task is started . */
volatile uint32_t ulCriticalNesting = 9999UL ;
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
a floating point context must be saved and restored for the task . */
uint32_t ulPortTaskHasFPUContext = pdFALSE ;
/* Set to 1 to pend a context switch from an ISR. */
uint32_t ulPortYieldRequired = pdFALSE ;
/* Counts the interrupt nesting depth. A context switch is only performed if
if the nesting depth is 0. */
uint32_t ulPortInterruptNesting = 0UL ;
__attribute__ ( ( used ) ) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ;
__attribute__ ( ( used ) ) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ;
2014-01-22 23:39:58 +08:00
__attribute__ ( ( used ) ) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ;
__attribute__ ( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ;
2014-01-21 01:53:30 +08:00
/*-----------------------------------------------------------*/
/*
* See header file for description .
*/
StackType_t * pxPortInitialiseStack ( StackType_t * pxTopOfStack , TaskFunction_t pxCode , void * pvParameters )
{
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT ( ) macro .
The fist real value on the stack is the status register , which is set for
system mode , with interrupts enabled . A few NULLs are added first to ensure
GDB does not try decoding a non - existent return address . */
* pxTopOfStack = ( StackType_t ) NULL ;
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) NULL ;
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) NULL ;
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) portINITIAL_SPSR ;
if ( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) ! = 0x00UL )
{
/* The task will start in THUMB mode. */
* pxTopOfStack | = portTHUMB_MODE_BIT ;
}
pxTopOfStack - - ;
/* Next the return address, which in this case is the start of the task. */
* pxTopOfStack = ( StackType_t ) pxCode ;
pxTopOfStack - - ;
/* Next all the registers other than the stack pointer. */
* pxTopOfStack = ( StackType_t ) 0x00000000 ; /* R14 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x12121212 ; /* R12 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x11111111 ; /* R11 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x10101010 ; /* R10 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x09090909 ; /* R9 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x08080808 ; /* R8 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x07070707 ; /* R7 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x06060606 ; /* R6 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x05050505 ; /* R5 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x04040404 ; /* R4 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x03030303 ; /* R3 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x02020202 ; /* R2 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) 0x01010101 ; /* R1 */
pxTopOfStack - - ;
* pxTopOfStack = ( StackType_t ) pvParameters ; /* R0 */
pxTopOfStack - - ;
/* The task will start with a critical nesting count of 0 as interrupts are
enabled . */
* pxTopOfStack = portNO_CRITICAL_NESTING ;
pxTopOfStack - - ;
/* The task will start without a floating point context. A task that uses
the floating point hardware must call vPortTaskUsesFPU ( ) before executing
any floating point instructions . */
* pxTopOfStack = portNO_FLOATING_POINT_CONTEXT ;
return pxTopOfStack ;
}
/*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler ( void )
{
uint32_t ulAPSR ;
2014-01-22 23:39:58 +08:00
# if( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority ;
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ) ;
volatile uint8_t ucMaxPriorityValue ;
/* Determine how many priority bits are implemented in the GIC.
Save the interrupt priority value that is about to be clobbered . */
ulOriginalPriority = * pucFirstUserPriorityRegister ;
/* Determine the number of priority bits available. First write to
all possible bits . */
* pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE ;
/* Read the value back to see how many bits stuck. */
ucMaxPriorityValue = * pucFirstUserPriorityRegister ;
/* Shift to the least significant bits. */
while ( ( ucMaxPriorityValue & portBIT_0_SET ) ! = portBIT_0_SET )
{
ucMaxPriorityValue > > = ( uint8_t ) 0x01 ;
}
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
value . */
configASSERT ( ucMaxPriorityValue = = portLOWEST_INTERRUPT_PRIORITY ) ;
/* Restore the clobbered interrupt priority register to its original
value . */
* pucFirstUserPriorityRegister = ulOriginalPriority ;
}
# endif /* conifgASSERT_DEFINED */
2014-01-21 01:53:30 +08:00
/* Only continue if the CPU is not in User mode. The CPU must be in a
Privileged mode for the scheduler to start . */
__asm volatile ( " MRS %0, APSR " : " =r " ( ulAPSR ) ) ;
ulAPSR & = portAPSR_MODE_BITS_MASK ;
configASSERT ( ulAPSR ! = portAPSR_USER_MODE ) ;
if ( ulAPSR ! = portAPSR_USER_MODE )
{
/* Only continue if the binary point value is set to its lowest possible
setting . See the comments in vPortValidateInterruptPriority ( ) below for
more information . */
configASSERT ( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) < = portMAX_BINARY_POINT_VALUE ) ;
if ( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) < = portMAX_BINARY_POINT_VALUE )
{
2014-01-28 20:32:03 +08:00
/* Interrupts are turned off in the CPU itself to ensure tick does
not execute while the scheduler is being started . Interrupts are
automatically turned back on in the CPU when the first task starts
executing . */
2014-01-24 21:27:56 +08:00
portCPU_IRQ_DISABLE ( ) ;
2014-01-28 20:32:03 +08:00
/* Start the timer that generates the tick ISR. */
2014-01-21 01:53:30 +08:00
configSETUP_TICK_INTERRUPT ( ) ;
2014-01-28 20:32:03 +08:00
/* Start the first task executing. */
2014-01-21 01:53:30 +08:00
vPortRestoreTaskContext ( ) ;
}
}
/* Will only get here if xTaskStartScheduler() was called with the CPU in
a non - privileged mode or the binary point register was not set to its lowest
possible value . */
return 0 ;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler ( void )
{
/* Not implemented in ports where there is nothing to return to.
Artificially force an assert . */
configASSERT ( ulCriticalNesting = = 1000UL ) ;
}
/*-----------------------------------------------------------*/
void vPortEnterCritical ( void )
{
2014-01-24 21:27:56 +08:00
/* Mask interrupts up to the max syscall interrupt priority. */
2014-01-21 01:53:30 +08:00
ulPortSetInterruptMask ( ) ;
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly . Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL ( ) has been called . */
ulCriticalNesting + + ;
}
/*-----------------------------------------------------------*/
void vPortExitCritical ( void )
{
if ( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as the critical section is being
exited . */
ulCriticalNesting - - ;
/* If the nesting level has reached zero then all interrupt
priorities must be re - enabled . */
if ( ulCriticalNesting = = portNO_CRITICAL_NESTING )
{
/* Critical nesting has reached zero so all interrupt priorities
should be unmasked . */
portCLEAR_INTERRUPT_MASK ( ) ;
}
}
}
/*-----------------------------------------------------------*/
void FreeRTOS_Tick_Handler ( void )
{
/* Set interrupt mask before altering scheduler structures. The tick
handler runs at the lowest priority , so interrupts cannot already be masked ,
2014-01-24 21:27:56 +08:00
so there is no need to save and restore the current mask value . It is
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
updated . */
portCPU_IRQ_DISABLE ( ) ;
2014-03-26 01:12:31 +08:00
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ;
2014-01-21 01:53:30 +08:00
__asm ( " dsb \n "
2014-01-24 21:27:56 +08:00
" isb \n " ) ;
portCPU_IRQ_ENABLE ( ) ;
2014-01-21 01:53:30 +08:00
/* Increment the RTOS tick. */
if ( xTaskIncrementTick ( ) ! = pdFALSE )
{
ulPortYieldRequired = pdTRUE ;
}
/* Ensure all interrupt priorities are active again. */
portCLEAR_INTERRUPT_MASK ( ) ;
2014-01-25 01:09:31 +08:00
configCLEAR_TICK_INTERRUPT ( ) ;
2014-01-21 01:53:30 +08:00
}
/*-----------------------------------------------------------*/
void vPortTaskUsesFPU ( void )
{
uint32_t ulInitialFPSCR = 0 ;
/* A task is registering the fact that it needs an FPU context. Set the
FPU flag ( which is saved as part of the task context ) . */
ulPortTaskHasFPUContext = pdTRUE ;
/* Initialise the floating point status register. */
__asm ( " FMXR FPSCR, %0 " : : " r " ( ulInitialFPSCR ) ) ;
}
/*-----------------------------------------------------------*/
void vPortClearInterruptMask ( uint32_t ulNewMaskValue )
{
if ( ulNewMaskValue = = pdFALSE )
{
portCLEAR_INTERRUPT_MASK ( ) ;
}
}
/*-----------------------------------------------------------*/
uint32_t ulPortSetInterruptMask ( void )
{
uint32_t ulReturn ;
2014-01-24 21:27:56 +08:00
/* Interrupt in the CPU must be turned off while the ICCPMR is being
updated . */
portCPU_IRQ_DISABLE ( ) ;
2014-03-26 01:12:31 +08:00
if ( portICCPMR_PRIORITY_MASK_REGISTER = = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) )
2014-01-21 01:53:30 +08:00
{
/* Interrupts were already masked. */
ulReturn = pdTRUE ;
}
else
{
ulReturn = pdFALSE ;
2014-03-26 01:12:31 +08:00
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ;
2014-01-21 01:53:30 +08:00
__asm ( " dsb \n "
" isb \n " ) ;
}
2014-01-24 21:27:56 +08:00
portCPU_IRQ_ENABLE ( ) ;
2014-01-21 01:53:30 +08:00
return ulReturn ;
}
/*-----------------------------------------------------------*/
# if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority ( void )
{
/* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function . ISR safe FreeRTOS API functions must * only * be called
from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY .
Numerically low interrupt priority numbers represent logically high
interrupt priorities , therefore the priority of the interrupt must
be set to a value equal to or numerically * higher * than
configMAX_SYSCALL_INTERRUPT_PRIORITY .
FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible .
The following links provide detailed information :
http : //www.freertos.org/RTOS-Cortex-M3-M4.html
http : //www.freertos.org/FAQHelp.html */
2014-03-26 01:12:31 +08:00
configASSERT ( portICCRPR_RUNNING_PRIORITY_REGISTER > = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY < < portPRIORITY_SHIFT ) ) ;
2014-01-21 01:53:30 +08:00
/* Priority grouping: The interrupt controller (GIC) allows the bits
that define each interrupt ' s priority to be split between bits that
define the interrupt ' s pre - emption priority bits and bits that define
the interrupt ' s sub - priority . For simplicity all bits must be defined
to be pre - emption priority bits . The following assertion will fail if
this is not the case ( if some bits represent a sub - priority ) .
The priority grouping is configured by the GIC ' s binary point register
( ICCBPR ) . Writting 0 to ICCBPR will ensure it is set to its lowest
possible value ( which may be above 0 ) . */
configASSERT ( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) < = portMAX_BINARY_POINT_VALUE ) ;
}
# endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/