Style: Revert more uncrustified files

This commit is contained in:
Alfred Gedeon 2020-08-11 21:56:04 -07:00
parent 88e692ff55
commit 134063a82f
65 changed files with 29977 additions and 29667 deletions

View file

@ -1,111 +1,82 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
#include "FreeRTOSConfig.h"
;
Variables used by scheduler
;
------------------------------------------------------------------------------
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
; Variables used by scheduler
;------------------------------------------------------------------------------
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
;
------------------------------------------------------------------------------
;
portSAVE_CONTEXT MACRO
;
Saves the context of the general purpose registers, CS and ES( only in far
;
memory mode ) registers the usCriticalNesting Value and the Stack Pointer
;
of the active Task onto the task stack
;
------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; portSAVE_CONTEXT MACRO
; Saves the context of the general purpose registers, CS and ES (only in far
; memory mode) registers the usCriticalNesting Value and the Stack Pointer
; of the active Task onto the task stack
;------------------------------------------------------------------------------
portSAVE_CONTEXT MACRO
PUSH AX;
Save AX Register to stack.
PUSH AX ; Save AX Register to stack.
PUSH HL
MOV A, CS;
Save CS register.
MOV A, CS ; Save CS register.
XCH A, X
MOV A, ES;
Save ES register.
MOV A, ES ; Save ES register.
PUSH AX
PUSH DE;
Save the remaining general purpose registers.
PUSH DE ; Save the remaining general purpose registers.
PUSH BC
MOVW AX, usCriticalNesting;
Save the usCriticalNesting value.
MOVW AX, usCriticalNesting ; Save the usCriticalNesting value.
PUSH AX
MOVW AX, pxCurrentTCB;
Save the Stack pointer.
MOVW AX, pxCurrentTCB ; Save the Stack pointer.
MOVW HL, AX
MOVW AX, SP
MOVW[ HL ], AX
MOVW AX, SP
MOVW [HL], AX
ENDM
;
------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
; portRESTORE_CONTEXT MACRO
; Restores the task Stack Pointer then use this to restore usCriticalNesting,
; general purpose registers and the CS and ES (only in far memory mode)
; of the selected task from the task stack
;------------------------------------------------------------------------------
portRESTORE_CONTEXT MACRO
;
Restores the task Stack Pointer then use this to restore usCriticalNesting,
;
general purpose registers and the CS and ES( only in far memory mode )
;
of the selected task from the task stack
;
------------------------------------------------------------------------------
portRESTORE_CONTEXT MACRO
MOVW AX, pxCurrentTCB;
Restore the Stack pointer.
MOVW AX, pxCurrentTCB ; Restore the Stack pointer.
MOVW HL, AX
MOVW AX, [ HL ]
MOVW SP, AX
POP AX;
Restore usCriticalNesting value.
MOVW AX, [HL]
MOVW SP, AX
POP AX ; Restore usCriticalNesting value.
MOVW usCriticalNesting, AX
POP BC;
Restore the necessary general purpose registers.
POP BC ; Restore the necessary general purpose registers.
POP DE
POP AX;
Restore the ES register.
POP AX ; Restore the ES register.
MOV ES, A
XCH A, X;
Restore the CS register.
XCH A, X ; Restore the CS register.
MOV CS, A
POP HL;
Restore general purpose register HL.
POP AX;
Restore AX.
POP HL ; Restore general purpose register HL.
POP AX ; Restore AX.
ENDM
;
------------------------------------------------------------------------------
;------------------------------------------------------------------------------

View file

@ -33,8 +33,8 @@
#include "task.h"
/* The critical nesting value is initialised to a non zero value to ensure
* interrupts don't accidentally become enabled before the scheduler is started. */
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
interrupts don't accidentally become enabled before the scheduler is started. */
#define portINITIAL_CRITICAL_NESTING (( uint16_t ) 10)
/* Initial PSW value allocated to a newly created task.
* 1100011000000000
@ -47,25 +47,25 @@
* |--------------------- Zero Flag set
* ---------------------- Global Interrupt Flag set (enabled)
*/
#define portPSW ( 0xc6UL )
#define portPSW (0xc6UL)
/* 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;
/* Most ports implement critical sections by placing the interrupt flags on
* the stack before disabling interrupts. Exiting the critical section is then
* simply a case of popping the flags from the stack. As 78K0 IAR does not use
* a frame pointer this cannot be done as modifying the stack will clobber all
* the stack variables. Instead each task maintains a count of the critical
* section nesting depth. Each time a critical section is entered the count is
* incremented. Each time a critical section is left the count is decremented -
* with interrupts only being re-enabled if the count is zero.
*
* usCriticalNesting will get set to zero when the scheduler starts, but must
* not be initialised to zero as this will cause problems during the startup
* sequence. */
the stack before disabling interrupts. Exiting the critical section is then
simply a case of popping the flags from the stack. As 78K0 IAR does not use
a frame pointer this cannot be done as modifying the stack will clobber all
the stack variables. Instead each task maintains a count of the critical
section nesting depth. Each time a critical section is entered the count is
incremented. Each time a critical section is left the count is decremented -
with interrupts only being re-enabled if the count is zero.
usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as this will cause problems during the startup
sequence. */
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/
@ -81,16 +81,14 @@ static void prvSetupTimerInterrupt( void );
*
* See the header file portable.h.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
uint32_t * pulLocal;
uint32_t *pulLocal;
#if configMEMORY_MODE == 1
{
/* Parameters are passed in on the stack, and written using a 32bit value
* hence a space is left for the second two bytes. */
hence a space is left for the second two bytes. */
pxTopOfStack--;
/* Write in the parameter value. */
@ -99,14 +97,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* These values are just spacers. The return address of the function
* would normally be written here. */
would normally be written here. */
*pxTopOfStack = ( StackType_t ) 0xcdcd;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xcdcd;
pxTopOfStack--;
/* The start address / PSW value is also written in as a 32bit value,
* so leave a space for the second two bytes. */
so leave a space for the second two bytes. */
pxTopOfStack--;
/* Task function start address combined with the PSW. */
@ -118,11 +116,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) 0x1111;
pxTopOfStack--;
}
#else /* if configMEMORY_MODE == 1 */
#else
{
/* Task function address is written to the stack first. As it is
* written as a 32bit value a space is left on the stack for the second
* two bytes. */
written as a 32bit value a space is left on the stack for the second
two bytes. */
pxTopOfStack--;
/* Task function start address combined with the PSW. */
@ -134,7 +132,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack--;
}
#endif /* if configMEMORY_MODE == 1 */
#endif
/* An initial value for the HL register. */
*pxTopOfStack = ( StackType_t ) 0x2222;
@ -151,11 +149,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Finally the critical section nesting count is set to zero when the task
* first starts. */
first starts. */
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack we have generated so this can
* be stored in the task control block for the task. */
be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
@ -163,7 +161,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
/* Setup the hardware to generate the tick. Interrupts are disabled when
* this function is called. */
this function is called. */
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run. */
@ -177,7 +175,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the 78K0R port will get stopped. If required simply
* disable the tick interrupt here. */
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
@ -192,7 +190,7 @@ static void prvSetupTimerInterrupt( void )
TT0 = 0xff;
/* Interrupt of Timer Array Unit Channel 5 is disabled to set the interrupt
* priority. */
priority. */
TMMK05 = 1;
/* Clear Timer Array Unit Channel 5 interrupt flag. */
@ -224,3 +222,4 @@ static void prvSetupTimerInterrupt( void )
TS0 |= 0x0020;
}
/*-----------------------------------------------------------*/

View file

@ -26,11 +26,11 @@
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -44,38 +44,38 @@
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint16_t
#define portBASE_TYPE short
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint16_t
#define portBASE_TYPE short
typedef portSTACK_TYPE StackType_t;
typedef short BaseType_t;
typedef unsigned short UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef short BaseType_t;
typedef unsigned short UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if (configUSE_16_BIT_TICKS==1)
typedef unsigned int TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() __asm( "DI" )
#define portENABLE_INTERRUPTS() __asm( "EI" )
#define portDISABLE_INTERRUPTS() __asm ( "DI" )
#define portENABLE_INTERRUPTS() __asm ( "EI" )
/*-----------------------------------------------------------*/
/* Critical section control macros. */
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
#define portENTER_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
@ -83,11 +83,11 @@
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
}
#define portEXIT_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
#define portEXIT_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
@ -101,44 +101,45 @@
portENABLE_INTERRUPTS(); \
} \
} \
}
}
/*-----------------------------------------------------------*/
/* Task utilities. */
extern void vPortStart( void );
#define portYIELD() __asm( "BRK" )
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
#define portNOP() __asm( "NOP" )
extern void vPortStart( void );
#define portYIELD() __asm( "BRK" )
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
#define portNOP() __asm( "NOP" )
/*-----------------------------------------------------------*/
/* Hardwware specifics. */
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* 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 )
static __interrupt void P0_isr( void );
static __interrupt void P0_isr (void);
/* --------------------------------------------------------------------------*/
/* Option-bytes and security ID */
/* --------------------------------------------------------------------------*/
#define OPT_BYTES_SIZE 4
#define SECU_ID_SIZE 10
#define WATCHDOG_DISABLED 0x00
#define LVI_ENABLED 0xFE
#define LVI_DISABLED 0xFF
#define RESERVED_FF 0xFF
#define OCD_DISABLED 0x04
#define OCD_ENABLED 0x81
#define OCD_ENABLED_ERASE 0x80
#define OPT_BYTES_SIZE 4
#define SECU_ID_SIZE 10
#define WATCHDOG_DISABLED 0x00
#define LVI_ENABLED 0xFE
#define LVI_DISABLED 0xFF
#define RESERVED_FF 0xFF
#define OCD_DISABLED 0x04
#define OCD_ENABLED 0x81
#define OCD_ENABLED_ERASE 0x80
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -34,7 +34,7 @@
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Check the configuration. */
#if ( configMAX_PRIORITIES > 32 )
#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 */
@ -48,14 +48,14 @@
#endif
/* A critical section is exited when the critical section nesting count reaches
* this value. */
this value. */
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
/* 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. */
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. */
@ -67,7 +67,7 @@
#define portAPSR_MODE_BITS_MASK ( 0x1F )
/* The value of the mode bits in the APSR when the CPU is executing in user
* mode. */
mode. */
#define portAPSR_USER_MODE ( 0x10 )
/*-----------------------------------------------------------*/
@ -86,21 +86,21 @@ static void prvTaskExitError( 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. */
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. */
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. */
if the nesting depth is 0. */
uint32_t ulPortInterruptNesting = 0UL;
@ -109,16 +109,14 @@ uint32_t ulPortInterruptNesting = 0UL;
/*
* 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 )
{
/* 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. */
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 = NULL;
pxTopOfStack--;
*pxTopOfStack = NULL;
@ -170,13 +168,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are
* enabled. */
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. */
the floating point hardware must call vPortTaskUsesFPU() before executing
any floating point instructions. */
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
return pxTopOfStack;
@ -186,28 +184,24 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
static void prvTaskExitError( void )
{
/* A function that implements a task must not exit or attempt to return to
* its caller as there is nothing to return to. If a task wants to exit it
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
* defined, then stop here so application writers can catch the error. */
its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ).
Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT( ulPortInterruptNesting == ~0UL );
portDISABLE_INTERRUPTS();
for( ; ; )
{
}
for( ;; );
}
/*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void )
{
uint32_t ulAPSR;
uint32_t ulAPSR;
/* Only continue if the CPU is not in User mode. The CPU must be in a
* Privileged mode for the scheduler to start. */
Privileged mode for the scheduler to start. */
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) );
ulAPSR &= portAPSR_MODE_BITS_MASK;
configASSERT( ulAPSR != portAPSR_USER_MODE );
@ -219,8 +213,8 @@ BaseType_t xPortStartScheduler( void )
}
/* Will only get here if vTaskStartScheduler() was called with the CPU in
* a non-privileged mode or the binary point register was not set to its lowest
* possible value. */
a non-privileged mode or the binary point register was not set to its lowest
possible value. */
return 0;
}
/*-----------------------------------------------------------*/
@ -228,7 +222,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( ulCriticalNesting == 1000UL );
}
/*-----------------------------------------------------------*/
@ -238,15 +232,15 @@ void vPortEnterCritical( void )
portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
* assert() if it is being called from an interrupt context. Only API
* functions that end in "FromISR" can be used in an interrupt. Only assert if
* the critical nesting count is 1 to protect against recursive calls if the
* assert function also uses a critical section. */
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( ulCriticalNesting == 1 )
{
configASSERT( ulPortInterruptNesting == 0 );
@ -259,15 +253,15 @@ void vPortExitCritical( void )
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as the critical section is being
* exited. */
exited. */
ulCriticalNesting--;
/* If the nesting level has reached zero then all interrupt
* priorities must be re-enabled. */
priorities must be re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Critical nesting has reached zero so all interrupt priorities
* should be unmasked. */
should be unmasked. */
portENABLE_INTERRUPTS();
}
}
@ -291,13 +285,16 @@ void FreeRTOS_Tick_Handler( void )
void vPortTaskUsesFPU( void )
{
uint32_t ulInitialFPSCR = 0;
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). */
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 ) );
__asm( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) );
}
/*-----------------------------------------------------------*/

View file

@ -1,127 +1,113 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
EXTERN 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, if any
FMRXNE R1, FPSCR
VPUSHNE { D0 - D15 }
; 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
; 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 }
; 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 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 for the task about to execute.
RFEIA sp!
endm
;
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
}
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 !
endm

View file

@ -26,10 +26,10 @@
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/* IAR includes. */
#ifdef __ICCARM__
#ifdef __ICCARM__
#include <intrinsics.h>
@ -37,7 +37,7 @@
extern "C" {
#endif
/*-----------------------------------------------------------
/*-----------------------------------------------------------
* Port specific definitions.
*
* The settings in this file configure FreeRTOS correctly for the given hardware
@ -47,7 +47,7 @@
*-----------------------------------------------------------
*/
/* Type definitions. */
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
@ -63,23 +63,23 @@
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Hardware specifics. */
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Task utilities. */
/* Task utilities. */
/* Called at the end of an ISR that can cause a context switch. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
/* Called at the end of an ISR that can cause a context switch. */
#define portEND_SWITCHING_ISR( xSwitchRequired )\
{ \
extern uint32_t ulPortYieldRequired; \
\
@ -93,9 +93,9 @@
#define portYIELD() __asm volatile ( "SWI 0" ); __ISB()
/*-----------------------------------------------------------
* Critical section control
*----------------------------------------------------------*/
/*-----------------------------------------------------------
* Critical section control
*----------------------------------------------------------*/
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
@ -107,55 +107,56 @@
#define portDISABLE_INTERRUPTS() __disable_irq(); __DSB(); __ISB() /* No priority mask register so global disable is used. */
#define portENABLE_INTERRUPTS() __enable_irq()
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_state(); __disable_irq() /* No priority mask register so global disable is used. */
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) __set_interrupt_state( x )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) __set_interrupt_state(x)
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
* not required for this port but included in case common demo code that uses these
* macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/* Task function macros as described on the FreeRTOS.org WEB site. These are
not required for this port but included in case common demo code that uses these
macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* Prototype of the FreeRTOS tick handler. This must be installed as the
* handler for whichever peripheral is used to generate the RTOS tick. */
/* Prototype of the FreeRTOS tick handler. This must be installed as the
handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void );
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
* before any floating point instructions are executed. */
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
before any floating point instructions are executed. */
void vPortTaskUsesFPU( void );
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
/* Architecture specific optimisations. */
/* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#endif
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Store/clear the ready priorities in a bit map. */
/* Store/clear the ready priorities in a bit map. */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __CLZ( uxReadyPriorities ) )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#define portNOP() __asm volatile ( "NOP" )
#define portNOP() __asm volatile( "NOP" )
#ifdef __cplusplus
} /* extern C */
#endif
/* Suppress warnings that are generated by the IAR tools, but cannot be
* fixed in the source code because to do so would cause other compilers to
* generate warnings. */
/* Suppress warnings that are generated by the IAR tools, but cannot be
fixed in the source code because to do so would cause other compilers to
generate warnings. */
#pragma diag_suppress=Pe191
#pragma diag_suppress=Pa082
#endif /* __ICCARM__ */
#endif /* __ICCARM__ */
#endif /* PORTMACRO_H */

View file

@ -36,23 +36,23 @@
#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 */
#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 */
#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 */
#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 */
#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 */
#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
@ -65,7 +65,7 @@
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Check the configuration. */
#if ( configMAX_PRIORITIES > 32 )
#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 */
@ -80,18 +80,18 @@
#endif
/* A critical section is exited when the critical section nesting count reaches
* this value. */
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. */
(but the lowest) interrupt priority. */
#define portUNMASK_VALUE ( 0xFFUL )
/* 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. */
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. */
@ -100,25 +100,25 @@
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
* point is zero. */
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. */
mode. */
#define portAPSR_USER_MODE ( 0x10 )
/* Macro to unmask all interrupt priorities. */
#define portCLEAR_INTERRUPT_MASK() \
{ \
{ \
__disable_irq(); \
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
__asm( "DSB \n" \
"ISB \n"); \
"ISB \n" ); \
__enable_irq(); \
}
}
/*-----------------------------------------------------------*/
@ -136,21 +136,21 @@ static void prvTaskExitError( 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. */
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. */
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. */
if the nesting depth is 0. */
uint32_t ulPortInterruptNesting = 0UL;
@ -159,16 +159,14 @@ uint32_t ulPortInterruptNesting = 0UL;
/*
* 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 )
{
/* 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. */
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 = NULL;
pxTopOfStack--;
*pxTopOfStack = NULL;
@ -220,13 +218,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are
* enabled. */
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. */
the floating point hardware must call vPortTaskUsesFPU() before executing
any floating point instructions. */
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
return pxTopOfStack;
@ -236,36 +234,32 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
static void prvTaskExitError( void )
{
/* A function that implements a task must not exit or attempt to return to
* its caller as there is nothing to return to. If a task wants to exit it
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
* defined, then stop here so application writers can catch the error. */
its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ).
Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT( ulPortInterruptNesting == ~0UL );
portDISABLE_INTERRUPTS();
for( ; ; )
{
}
for( ;; );
}
/*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void )
{
uint32_t ulAPSR;
uint32_t ulAPSR;
/* Only continue if the CPU is not in User mode. The CPU must be in a
* Privileged mode for the scheduler to start. */
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. */
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 )
@ -279,8 +273,8 @@ BaseType_t xPortStartScheduler( void )
}
/* Will only get here if vTaskStartScheduler() was called with the CPU in
* a non-privileged mode or the binary point register was not set to its lowest
* possible value. */
a non-privileged mode or the binary point register was not set to its lowest
possible value. */
return 0;
}
/*-----------------------------------------------------------*/
@ -288,7 +282,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( ulCriticalNesting == 1000UL );
}
/*-----------------------------------------------------------*/
@ -299,15 +293,15 @@ void vPortEnterCritical( void )
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. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
* assert() if it is being called from an interrupt context. Only API
* functions that end in "FromISR" can be used in an interrupt. Only assert if
* the critical nesting count is 1 to protect against recursive calls if the
* assert function also uses a critical section. */
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( ulCriticalNesting == 1 )
{
configASSERT( ulPortInterruptNesting == 0 );
@ -320,15 +314,15 @@ void vPortExitCritical( void )
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as the critical section is being
* exited. */
exited. */
ulCriticalNesting--;
/* If the nesting level has reached zero then all interrupt
* priorities must be re-enabled. */
priorities must be re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Critical nesting has reached zero so all interrupt priorities
* should be unmasked. */
should be unmasked. */
portCLEAR_INTERRUPT_MASK();
}
}
@ -338,12 +332,12 @@ void vPortExitCritical( void )
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,
* so there is no need to save and restore the current mask value. */
handler runs at the lowest priority, so interrupts cannot already be masked,
so there is no need to save and restore the current mask value. */
__disable_irq();
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm( "DSB \n"
"ISB \n");
"ISB \n" );
__enable_irq();
/* Increment the RTOS tick. */
@ -360,14 +354,14 @@ void FreeRTOS_Tick_Handler( void )
void vPortTaskUsesFPU( void )
{
uint32_t ulInitialFPSCR = 0;
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). */
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 ) );
__asm( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) );
}
/*-----------------------------------------------------------*/
@ -382,10 +376,9 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
uint32_t ulPortSetInterruptMask( void )
{
uint32_t ulReturn;
uint32_t ulReturn;
__disable_irq();
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
{
/* Interrupts were already masked. */
@ -396,50 +389,51 @@ uint32_t ulPortSetInterruptMask( void )
ulReturn = pdFALSE;
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm( "DSB \n"
"ISB \n");
"ISB \n" );
}
__enable_irq();
return ulReturn;
}
/*-----------------------------------------------------------*/
#if ( configASSERT_DEFINED == 1 )
#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 */
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 */
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
/* 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). */
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 */

View file

@ -1,129 +1,115 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
EXTERN 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, if any
FMRXNE R1, FPSCR
VPUSHNE { D0 - D15 }
VPUSHNE { D16 - D31 }
PUSHNE { R1 }
; Save the floating point context, if any
FMRXNE R1, FPSCR
VPUSHNE {D0-D15}
VPUSHNE {D16-D31}
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
; 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 }
VPOPNE { D16 - D31 }
VPOPNE { D0 - D15 }
VMSRNE FPSCR, R0
; Restore the floating point context, if any
POPNE {R0}
VPOPNE {D16-D31}
VPOPNE {D0-D15}
VMSRNE FPSCR, R0
; Restore the critical section nesting depth
LDR R0, =ulCriticalNesting
POP {R1}
STR R1, [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 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
;
Restore the critical section nesting depth
LDR R0, = ulCriticalNesting
POP { R1 }
STR R1, [ 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 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

View file

@ -26,10 +26,10 @@
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/* IAR includes. */
#ifdef __ICCARM__
#ifdef __ICCARM__
#include <intrinsics.h>
@ -37,7 +37,7 @@
extern "C" {
#endif
/*-----------------------------------------------------------
/*-----------------------------------------------------------
* Port specific definitions.
*
* The settings in this file configure FreeRTOS correctly for the given hardware
@ -47,7 +47,7 @@
*-----------------------------------------------------------
*/
/* Type definitions. */
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
@ -63,23 +63,23 @@
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Hardware specifics. */
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Task utilities. */
/* Task utilities. */
/* Called at the end of an ISR that can cause a context switch. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
/* Called at the end of an ISR that can cause a context switch. */
#define portEND_SWITCHING_ISR( xSwitchRequired )\
{ \
extern uint32_t ulPortYieldRequired; \
\
@ -93,56 +93,56 @@
#define portYIELD() __asm( "SWI 0" );
/*-----------------------------------------------------------
* Critical section control
*----------------------------------------------------------*/
/*-----------------------------------------------------------
* Critical section control
*----------------------------------------------------------*/
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern uint32_t ulPortSetInterruptMask( void );
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
/* These macros do not globally disable/enable interrupts. They do mask off
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
/* These macros do not globally disable/enable interrupts. They do mask off
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
* not required for this port but included in case common demo code that uses these
* macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/* Task function macros as described on the FreeRTOS.org WEB site. These are
not required for this port but included in case common demo code that uses these
macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* Prototype of the FreeRTOS tick handler. This must be installed as the
* handler for whichever peripheral is used to generate the RTOS tick. */
/* Prototype of the FreeRTOS tick handler. This must be installed as the
handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void );
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
* before any floating point instructions are executed. */
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
before any floating point instructions are executed. */
void vPortTaskUsesFPU( void );
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
/* Architecture specific optimisations. */
/* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#endif
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Store/clear the ready priorities in a bit map. */
/* Store/clear the ready priorities in a bit map. */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __CLZ( uxReadyPriorities ) )
@ -153,56 +153,57 @@
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
#endif /* configASSERT */
#define portNOP() __asm volatile ( "NOP" )
#define portNOP() __asm volatile( "NOP" )
#ifdef __cplusplus
} /* extern C */
#endif
/* Suppress warnings that are generated by the IAR tools, but cannot be
* fixed in the source code because to do so would cause other compilers to
* generate warnings. */
/* Suppress warnings that are generated by the IAR tools, but cannot be
fixed in the source code because to do so would cause other compilers to
generate warnings. */
#pragma diag_suppress=Pe191
#pragma diag_suppress=Pa082
#endif /* __ICCARM__ */
#endif /* __ICCARM__ */
/* The number of bits to shift for an interrupt priority is dependent on the
* number of bits implemented by the interrupt controller. */
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
number of bits implemented by the interrupt controller. */
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
#define portPRIORITY_SHIFT 4
#define portMAX_BINARY_POINT_VALUE 3
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
#define portPRIORITY_SHIFT 3
#define portMAX_BINARY_POINT_VALUE 2
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
#define portPRIORITY_SHIFT 2
#define portMAX_BINARY_POINT_VALUE 1
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
#define portPRIORITY_SHIFT 1
#define portMAX_BINARY_POINT_VALUE 0
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
#define portPRIORITY_SHIFT 0
#define portMAX_BINARY_POINT_VALUE 0
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
#else
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
#endif
/* Interrupt controller access addresses. */
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
#endif /* PORTMACRO_H */

View file

@ -34,7 +34,7 @@
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Check the configuration. */
#if ( configMAX_PRIORITIES > 32 )
#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 */
@ -48,14 +48,14 @@
#endif
/* A critical section is exited when the critical section nesting count reaches
* this value. */
this value. */
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
/* 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. */
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. */
@ -67,12 +67,12 @@
#define portAPSR_MODE_BITS_MASK ( 0x1F )
/* The value of the mode bits in the APSR when the CPU is executing in user
* mode. */
mode. */
#define portAPSR_USER_MODE ( 0x10 )
/* Let the user override the pre-loading of the initial LR with the address of
* prvTaskExitError() in case it messes up unwinding of the stack in the
* debugger. */
prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */
#ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else
@ -95,21 +95,21 @@ static void prvTaskExitError( 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. */
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. */
a floating point context must be saved and restored for the task. */
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
/* Set to 1 to pend a context switch from an ISR. */
volatile uint32_t ulPortYieldRequired = pdFALSE;
/* Counts the interrupt nesting depth. A context switch is only performed if
* if the nesting depth is 0. */
if the nesting depth is 0. */
volatile uint32_t ulPortInterruptNesting = 0UL;
/*-----------------------------------------------------------*/
@ -117,16 +117,14 @@ volatile uint32_t ulPortInterruptNesting = 0UL;
/*
* 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 )
{
/* 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. */
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;
@ -178,13 +176,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are
* enabled. */
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. */
the floating point hardware must call vPortTaskUsesFPU() before executing
any floating point instructions. */
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
return pxTopOfStack;
@ -194,28 +192,24 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
static void prvTaskExitError( void )
{
/* A function that implements a task must not exit or attempt to return to
* its caller as there is nothing to return to. If a task wants to exit it
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
* defined, then stop here so application writers can catch the error. */
its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ).
Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT( ulPortInterruptNesting == ~0UL );
portDISABLE_INTERRUPTS();
for( ; ; )
{
}
for( ;; );
}
/*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void )
{
uint32_t ulAPSR;
uint32_t ulAPSR;
/* Only continue if the CPU is not in User mode. The CPU must be in a
* Privileged mode for the scheduler to start. */
Privileged mode for the scheduler to start. */
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) );
ulAPSR &= portAPSR_MODE_BITS_MASK;
configASSERT( ulAPSR != portAPSR_USER_MODE );
@ -230,10 +224,10 @@ BaseType_t xPortStartScheduler( void )
}
/* Will only get here if vTaskStartScheduler() was called with the CPU in
* a non-privileged mode or the binary point register was not set to its lowest
* possible value. prvTaskExitError() is referenced to prevent a compiler
* warning about it being defined but not referenced in the case that the user
* defines their own exit address. */
a non-privileged mode or the binary point register was not set to its lowest
possible value. prvTaskExitError() is referenced to prevent a compiler
warning about it being defined but not referenced in the case that the user
defines their own exit address. */
( void ) prvTaskExitError;
return 0;
}
@ -242,7 +236,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( ulCriticalNesting == 1000UL );
}
/*-----------------------------------------------------------*/
@ -252,15 +246,15 @@ void vPortEnterCritical( void )
portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
* assert() if it is being called from an interrupt context. Only API
* functions that end in "FromISR" can be used in an interrupt. Only assert if
* the critical nesting count is 1 to protect against recursive calls if the
* assert function also uses a critical section. */
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( ulCriticalNesting == 1 )
{
configASSERT( ulPortInterruptNesting == 0 );
@ -273,15 +267,15 @@ void vPortExitCritical( void )
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as the critical section is being
* exited. */
exited. */
ulCriticalNesting--;
/* If the nesting level has reached zero then all interrupt
* priorities must be re-enabled. */
priorities must be re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Critical nesting has reached zero so all interrupt priorities
* should be unmasked. */
should be unmasked. */
portENABLE_INTERRUPTS();
}
}
@ -290,7 +284,7 @@ void vPortExitCritical( void )
void FreeRTOS_Tick_Handler( void )
{
uint32_t ulInterruptStatus;
uint32_t ulInterruptStatus;
ulInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
@ -308,13 +302,15 @@ void FreeRTOS_Tick_Handler( void )
void vPortTaskUsesFPU( void )
{
uint32_t ulInitialFPSCR = 0;
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). */
FPU flag (which is saved as part of the task context). */
ulPortTaskHasFPUContext = pdTRUE;
/* Initialise the floating point status register. */
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) );
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) );
}
/*-----------------------------------------------------------*/

View file

@ -26,13 +26,13 @@
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -45,139 +45,137 @@
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* Task utilities. */
/* Called at the end of an ISR that can cause a context switch. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern volatile uint32_t ulPortYieldRequired; \
#define portEND_SWITCHING_ISR( xSwitchRequired )\
{ \
extern volatile uint32_t ulPortYieldRequired; \
\
if( xSwitchRequired != pdFALSE ) \
{ \
ulPortYieldRequired = pdTRUE; \
} \
}
}
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#define portYIELD() \
__asm volatile ( "SWI 0 \n"\
"ISB ");
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#define portYIELD() __asm volatile ( "SWI 0 \n" \
"ISB " );
/*-----------------------------------------------------------
* Critical section control
*----------------------------------------------------------*/
* Critical section control
*----------------------------------------------------------*/
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern uint32_t ulPortSetInterruptMask( void );
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
extern void vPortInstallFreeRTOSVectorTable( void );
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern uint32_t ulPortSetInterruptMask( void );
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
extern void vPortInstallFreeRTOSVectorTable( void );
/* The I bit within the CPSR. */
#define portINTERRUPT_ENABLE_BIT ( 1 << 7 )
#define portINTERRUPT_ENABLE_BIT ( 1 << 7 )
/* In the absence of a priority mask register, these functions and macros
* globally enable and disable interrupts. */
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
#define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n");
#define portDISABLE_INTERRUPTS() \
__asm volatile ( "CPSID i \n" \
globally enable and disable interrupts. */
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
#define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n" );
#define portDISABLE_INTERRUPTS() __asm volatile ( "CPSID i \n" \
"DSB \n" \
"ISB ");
#pragma inline
static inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void )
{
volatile uint32_t ulCPSR;
__asm volatile ( "MRS %0, CPSR" : "=r" ( ulCPSR ) );
"ISB " );
#pragma inline
static inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void )
{
volatile uint32_t ulCPSR;
__asm volatile ( "MRS %0, CPSR" : "=r" (ulCPSR) );
ulCPSR &= portINTERRUPT_ENABLE_BIT;
portDISABLE_INTERRUPTS();
return ulCPSR;
}
}
#define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) if( x == 0 ) portENABLE_INTERRUPTS()
#define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) if( x == 0 ) portENABLE_INTERRUPTS()
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
* not required for this port but included in case common demo code that uses these
* macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
not required for this port but included in case common demo code that uses these
macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* Prototype of the FreeRTOS tick handler. This must be installed as the
* handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void );
handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void );
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
* before any floating point instructions are executed. */
void vPortTaskUsesFPU( void );
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
before any floating point instructions are executed. */
void vPortTaskUsesFPU( void );
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
/* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#endif
#endif
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Store/clear the ready priorities in a bit map. */
/* Store/clear the ready priorities in a bit map. */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __CLZ( uxReadyPriorities ) )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#define portNOP() __asm volatile ( "NOP" )
#define portINLINE inline
#define portNOP() __asm volatile( "NOP" )
#define portINLINE inline
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
* the source code because to do so would cause other compilers to generate
* warnings. */
#pragma diag_suppress=Pe191
#pragma diag_suppress=Pa082
the source code because to do so would cause other compilers to generate
warnings. */
#pragma diag_suppress=Pe191
#pragma diag_suppress=Pa082
#ifdef __cplusplus
#ifdef __cplusplus
} /* extern C */
#endif
#endif
#endif /* PORTMACRO_H */

View file

@ -31,8 +31,8 @@
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the AVR/IAR port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the AVR/IAR port.
*----------------------------------------------------------*/
/* Start tasks with interrupts enables. */
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
@ -48,7 +48,7 @@
/*-----------------------------------------------------------*/
/* Stores the critical section nesting. This must not be initialised to 0.
* It will be initialised when a task starts. */
It will be initialised when a task starts. */
#define portNO_CRITICAL_NESTING ( ( UBaseType_t ) 0 )
UBaseType_t uxCriticalNesting = 0x50;
@ -70,15 +70,13 @@ extern void vPortStart( 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 )
{
uint16_t usAddress;
StackType_t * pxTopOfHardwareStack;
uint16_t usAddress;
StackType_t *pxTopOfHardwareStack;
/* 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 = 0x11;
pxTopOfStack--;
@ -88,7 +86,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Remember where the top of the hardware stack is - this is required
* below. */
below. */
pxTopOfHardwareStack = pxTopOfStack;
@ -99,20 +97,20 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
/* The IAR compiler requires two stacks per task. First there is the
* hardware call stack which uses the AVR stack pointer. Second there is the
* software stack (local variables, parameter passing, etc.) which uses the
* AVR Y register.
*
* This function places both stacks within the memory block passed in as the
* first parameter. The hardware stack is placed at the bottom of the memory
* block. A gap is then left for the hardware stack to grow. Next the software
* stack is placed. The amount of space between the software and hardware
* stacks is defined by configCALL_STACK_SIZE.
*
*
*
* The first part of the stack is the hardware stack. Place the start
* address of the task on the hardware stack. */
hardware call stack which uses the AVR stack pointer. Second there is the
software stack (local variables, parameter passing, etc.) which uses the
AVR Y register.
This function places both stacks within the memory block passed in as the
first parameter. The hardware stack is placed at the bottom of the memory
block. A gap is then left for the hardware stack to grow. Next the software
stack is placed. The amount of space between the software and hardware
stacks is defined by configCALL_STACK_SIZE.
The first part of the stack is the hardware stack. Place the start
address of the task on the hardware stack. */
usAddress = ( uint16_t ) pxCode;
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
pxTopOfStack--;
@ -123,23 +121,23 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
/* Leave enough space for the hardware stack before starting the software
* stack. The '- 2' is because we have already used two spaces for the
* address of the start of the task. */
stack. The '- 2' is because we have already used two spaces for the
address of the start of the task. */
pxTopOfStack -= ( configCALL_STACK_SIZE - 2 );
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
* portSAVE_CONTEXT places the flags on the stack immediately after r0
* to ensure the interrupts get disabled as soon as possible, and so ensuring
* the stack use is minimal should a context switch interrupt occur. */
portSAVE_CONTEXT places the flags on the stack immediately after r0
to ensure the interrupts get disabled as soon as possible, and so ensuring
the stack use is minimal should a context switch interrupt occur. */
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
pxTopOfStack--;
*pxTopOfStack = portFLAGS_INT_ENABLED;
pxTopOfStack--;
/* Next place the address of the hardware stack. This is required so
* the AVR stack pointer can be restored to point to the hardware stack. */
the AVR stack pointer can be restored to point to the hardware stack. */
pxTopOfHardwareStack -= portBYTES_USED_BY_RETURN_ADDRESS;
usAddress = ( uint16_t ) pxTopOfHardwareStack;
@ -154,6 +152,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
/* Now the remaining registers. */
*pxTopOfStack = ( StackType_t ) 0x01; /* R1 */
pxTopOfStack--;
@ -217,7 +216,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* The Y register is not stored as it is used as the software stack and
* gets saved into the task control block. */
gets saved into the task control block. */
*pxTopOfStack = ( StackType_t ) 0x30; /* R30 Z */
pxTopOfStack--;
@ -238,8 +237,8 @@ BaseType_t xPortStartScheduler( void )
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run.
* Normally we would just call portRESTORE_CONTEXT() here, but as the IAR
* compiler does not fully support inline assembler we have to make a call.*/
Normally we would just call portRESTORE_CONTEXT() here, but as the IAR
compiler does not fully support inline assembler we have to make a call.*/
vPortStart();
/* Should not get here! */
@ -250,7 +249,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the AVR port will get stopped. If required simply
* disable the tick interrupt here. */
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
@ -259,11 +258,11 @@ void vPortEndScheduler( void )
*/
static void prvSetupTimerInterrupt( void )
{
uint32_t ulCompareMatch;
uint8_t ucHighByte, ucLowByte;
uint32_t ulCompareMatch;
uint8_t ucHighByte, ucLowByte;
/* Using 16bit timer 1 to generate the tick. Correct fuses must be
* selected for the configCPU_CLOCK_HZ clock. */
selected for the configCPU_CLOCK_HZ clock. */
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
@ -274,7 +273,7 @@ static void prvSetupTimerInterrupt( void )
ulCompareMatch -= ( uint32_t ) 1;
/* Setup compare match value for compare match A. Interrupts are disabled
* before this is called so we need not worry here. */
before this is called so we need not worry here. */
ucLowByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
ulCompareMatch >>= 8;
ucHighByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
@ -286,14 +285,14 @@ static void prvSetupTimerInterrupt( void )
TCCR1B = ucLowByte;
/* Enable the interrupt - this is okay as interrupt are currently globally
* disabled. */
disabled. */
TIMSK |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
}
/*-----------------------------------------------------------*/
#if configUSE_PREEMPTION == 1
/*
/*
* Tick ISR for preemptive scheduler. We can use a __task attribute as
* the context is saved at the start of vPortYieldFromTick(). The tick
* count is incremented after the context is saved.
@ -301,12 +300,12 @@ static void prvSetupTimerInterrupt( void )
__task void SIG_OUTPUT_COMPARE1A( void )
{
vPortYieldFromTick();
asm ( "reti" );
asm( "reti" );
}
#else
/*
/*
* Tick ISR for the cooperative scheduler. All this does is increment the
* tick count. We don't need to switch context, this can only be done by
* manual calls to taskYIELD();
@ -318,7 +317,7 @@ static void prvSetupTimerInterrupt( void )
{
xTaskIncrementTick();
}
#endif /* if configUSE_PREEMPTION == 1 */
#endif
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
@ -331,9 +330,10 @@ void vPortEnterCritical( void )
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == portNO_CRITICAL_NESTING )
{
portENABLE_INTERRUPTS();
}
}

View file

@ -26,18 +26,18 @@
*/
/*
* Changes from V1.2.3
*
Changes from V1.2.3
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
+ base 16.
*/
base 16.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -50,61 +50,63 @@
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT int
#define portSTACK_TYPE uint8_t
#define portBASE_TYPE char
#define portPOINTER_SIZE_TYPE uint16_t
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT int
#define portSTACK_TYPE uint8_t
#define portBASE_TYPE char
#define portPOINTER_SIZE_TYPE uint16_t
typedef portSTACK_TYPE StackType_t;
typedef signed char BaseType_t;
typedef unsigned char UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef signed char BaseType_t;
typedef unsigned char UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() asm ( "cli" )
#define portENABLE_INTERRUPTS() asm ( "sei" )
#define portDISABLE_INTERRUPTS() asm( "cli" )
#define portENABLE_INTERRUPTS() asm( "sei" )
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 1
#define portNOP() asm ( "nop" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 1
#define portNOP() asm( "nop" )
/*-----------------------------------------------------------*/
/* Kernel utilities. */
void vPortYield( void );
#define portYIELD() vPortYield()
void vPortYield( void );
#define portYIELD() vPortYield()
#ifdef IAR_MEGA_AVR
#ifdef IAR_MEGA_AVR
#define outb( PORT, VALUE ) PORT = VALUE
#endif
#endif
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,5 +1,4 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port source for AVR32 UC3.
@ -54,7 +53,7 @@
#include "usart.h"
#endif
#if ( configTICK_USE_TC == 1 )
#if( configTICK_USE_TC==1 )
#include "tc.h"
#endif
@ -67,7 +66,7 @@
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
volatile uint32_t ulCriticalNesting = 9999UL;
#if ( configTICK_USE_TC == 0 )
#if( configTICK_USE_TC==0 )
static void prvScheduleNextTick( void );
#else
static void prvClearTcInt( void );
@ -82,11 +81,11 @@ static void prvSetupTimerInterrupt( void );
* Low-level initialization routine called during startup, before the main
* function.
*/
int __low_level_init( void )
int __low_level_init(void)
{
#if configHEAP_INIT
#pragma segment = "HEAP"
BaseType_t * pxMem;
BaseType_t *pxMem;
#endif
/* Enable exceptions. */
@ -124,13 +123,13 @@ int __low_level_init( void )
};
/* Initialize the USART used for the debug trace with the configured parameters. */
extern volatile avr32_usart_t * volatile stdio_usart_base;
extern volatile avr32_usart_t *volatile stdio_usart_base;
stdio_usart_base = configDBG_USART;
gpio_enable_module( DBG_USART_GPIO_MAP,
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[ 0 ] ) );
usart_init_rs232( configDBG_USART, &DBG_USART_OPTIONS, configCPU_CLOCK_HZ );
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
usart_init_rs232(configDBG_USART, &DBG_USART_OPTIONS, configCPU_CLOCK_HZ);
}
#endif /* if configDBG */
#endif
/* Request initialization of data segments. */
return 1;
@ -138,10 +137,9 @@ int __low_level_init( void )
/*-----------------------------------------------------------*/
/* Added as there is no such function in FreeRTOS. */
void * pvPortRealloc( void * pv,
size_t xWantedSize )
void *pvPortRealloc( void *pv, size_t xWantedSize )
{
void * pvReturn;
void *pvReturn;
vTaskSuspendAll();
{
@ -154,28 +152,26 @@ void * pvPortRealloc( void * pv,
/*-----------------------------------------------------------*/
/* The cooperative scheduler requires a normal IRQ service routine to
* simply increment the system tick. */
simply increment the system tick. */
/* The preemptive scheduler is defined as "naked" as the full context is saved
* on entry as part of the context switch. */
#pragma shadow_registers = full /* Naked. */
on entry as part of the context switch. */
#pragma shadow_registers = full // Naked.
static void vTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT_OS_INT();
#if ( configTICK_USE_TC == 1 )
#if( configTICK_USE_TC==1 )
/* Clear the interrupt flag. */
prvClearTcInt();
#else
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
* clock cycles from now. */
clock cycles from now. */
prvScheduleNextTick();
#endif
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
* calls in a critical section . */
calls in a critical section . */
portENTER_CRITICAL();
xTaskIncrementTick();
portEXIT_CRITICAL();
@ -185,7 +181,7 @@ static void vTick( void )
}
/*-----------------------------------------------------------*/
#pragma shadow_registers = full /* Naked. */
#pragma shadow_registers = full // Naked.
void SCALLYield( void )
{
/* Save the context of the interrupted task. */
@ -196,9 +192,9 @@ void SCALLYield( void )
/*-----------------------------------------------------------*/
/* The code generated by the GCC compiler uses the stack in different ways at
* different optimisation levels. The interrupt flags can therefore not always
* be saved to the stack. Instead the critical section nesting level is stored
* in a variable, which is then saved as part of the stack context. */
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
#pragma optimize = no_inline
void vPortEnterCritical( void )
{
@ -206,8 +202,8 @@ void vPortEnterCritical( void )
portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -215,10 +211,9 @@ void vPortEnterCritical( void )
#pragma optimize = no_inline
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
if(ulCriticalNesting > portNO_CRITICAL_NESTING)
{
ulCriticalNesting--;
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable all interrupt/exception. */
@ -234,12 +229,10 @@ void vPortExitCritical( 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 )
{
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* When the task starts, it will expect to find the function parameter in R12. */
pxTopOfStack--;
@ -268,7 +261,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -282,70 +275,65 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the AVR32 port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
* clock cycles from now. */
#if ( configTICK_USE_TC == 0 )
static void prvScheduleFirstTick( void )
clock cycles from now. */
#if( configTICK_USE_TC==0 )
static void prvScheduleFirstTick(void)
{
uint32_t lCycles;
lCycles = Get_system_register( AVR32_COUNT );
lCycles += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
/* If lCycles ends up to be 0, make it 1 so that the COMPARE and exception */
/* generation feature does not get disabled. */
if( 0 == lCycles )
lCycles = Get_system_register(AVR32_COUNT);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
Set_system_register( AVR32_COMPARE, lCycles );
Set_system_register(AVR32_COMPARE, lCycles);
}
#pragma optimize = no_inline
static void prvScheduleNextTick( void )
static void prvScheduleNextTick(void)
{
uint32_t lCycles, lCount;
lCycles = Get_system_register( AVR32_COMPARE );
lCycles += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
/* If lCycles ends up to be 0, make it 1 so that the COMPARE and exception */
/* generation feature does not get disabled. */
if( 0 == lCycles )
lCycles = Get_system_register(AVR32_COMPARE);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
lCount = Get_system_register( AVR32_COUNT );
lCount = Get_system_register(AVR32_COUNT);
if( lCycles < lCount )
{ /* We missed a tick, recover for the next. */
lCycles += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
{ // We missed a tick, recover for the next.
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
}
Set_system_register( AVR32_COMPARE, lCycles );
Set_system_register(AVR32_COMPARE, lCycles);
}
#else /* if ( configTICK_USE_TC == 0 ) */
#else
#pragma optimize = no_inline
static void prvClearTcInt( void )
static void prvClearTcInt(void)
{
AVR32_TC.channel[ configTICK_TC_CHANNEL ].sr;
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
}
#endif /* if ( configTICK_USE_TC == 0 ) */
#endif
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void )
static void prvSetupTimerInterrupt(void)
{
#if ( configTICK_USE_TC == 1 )
volatile avr32_tc_t * tc = &AVR32_TC;
#if( configTICK_USE_TC==1 )
/* Options for waveform genration. */
volatile avr32_tc_t *tc = &AVR32_TC;
// Options for waveform genration.
tc_waveform_opt_t waveform_opt =
{
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
@ -360,7 +348,7 @@ static void prvSetupTimerInterrupt( void )
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, /* Waveform selection: Up mode without automatic trigger on RC compare. */
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
.enetrg = FALSE, /* External event trigger enable. */
.eevt = 0, /* External event selection. */
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
@ -374,44 +362,45 @@ static void prvSetupTimerInterrupt( void )
tc_interrupt_t tc_interrupt =
{
.etrgs = 0,
.ldrbs = 0,
.ldras = 0,
.cpcs = 1,
.cpbs = 0,
.cpas = 0,
.lovrs = 0,
.covfs = 0,
.etrgs=0,
.ldrbs=0,
.ldras=0,
.cpcs =1,
.cpbs =0,
.cpas =0,
.lovrs=0,
.covfs=0,
};
#endif /* if ( configTICK_USE_TC == 1 ) */
#endif
/* Disable all interrupt/exception. */
portDISABLE_INTERRUPTS();
/* Register the compare interrupt handler to the interrupt controller and
* enable the compare interrupt. */
enable the compare interrupt. */
#if ( configTICK_USE_TC == 1 )
#if( configTICK_USE_TC==1 )
{
INTC_register_interrupt( ( __int_handler ) & vTick, configTICK_TC_IRQ, INT0 );
INTC_register_interrupt((__int_handler)&vTick, configTICK_TC_IRQ, INT0);
/* Initialize the timer/counter. */
tc_init_waveform( tc, &waveform_opt );
tc_init_waveform(tc, &waveform_opt);
/* Set the compare triggers.
* Remember TC counter is 16-bits, so counting second is not possible!
* That's why we configure it to count ms. */
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4 ) / configTICK_RATE_HZ );
Remember TC counter is 16-bits, so counting second is not possible!
That's why we configure it to count ms. */
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
/* Start the timer/counter. */
tc_start( tc, configTICK_TC_CHANNEL );
tc_start(tc, configTICK_TC_CHANNEL);
}
#else /* if ( configTICK_USE_TC == 1 ) */
#else
{
INTC_register_interrupt( ( __int_handler ) & vTick, AVR32_CORE_COMPARE_IRQ, INT0 );
INTC_register_interrupt((__int_handler)&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
prvScheduleFirstTick();
}
#endif /* if ( configTICK_USE_TC == 1 ) */
#endif
}

View file

@ -1,5 +1,4 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port header for AVR32 UC3.
@ -43,7 +42,7 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/*-----------------------------------------------------------
* Port specific definitions.
@ -54,63 +53,63 @@
* These settings should not be altered.
*-----------------------------------------------------------
*/
#include <avr32/io.h>
#include "intc.h"
#include "compiler.h"
#include <avr32/io.h>
#include "intc.h"
#include "compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#define TASK_DELAY_MS( x ) ( ( x ) / portTICK_PERIOD_MS )
#define TASK_DELAY_S( x ) ( ( x ) * 1000 / portTICK_PERIOD_MS )
#define TASK_DELAY_MIN( x ) ( ( x ) * 60 * 1000 / portTICK_PERIOD_MS )
#define TASK_DELAY_MS(x) ( (x) /portTICK_PERIOD_MS )
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_PERIOD_MS )
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_PERIOD_MS )
#define configTICK_TC_IRQ ATPASTE2( AVR32_TC_IRQ, configTICK_TC_CHANNEL )
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portNOP() { __asm__ __volatile__ ( "nop" ); }
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portNOP() {__asm__ __volatile__ ("nop");}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* INTC-specific. */
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
#define DISABLE_INT_LEVEL( int_lev ) Disable_interrupt_level( int_lev )
#define ENABLE_INT_LEVEL( int_lev ) Enable_interrupt_level( int_lev )
#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
/*
@ -126,33 +125,32 @@
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
*/
#if configDBG
#define portDBG_TRACE( ... ) \
#if configDBG
#define portDBG_TRACE(...) \
{ \
fputs( __FILE__ ":" ASTRINGZ( __LINE__ ) ": ", stdout ); \
printf( __VA_ARGS__ ); \
fputs( "\r\n", stdout ); \
fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout); \
printf(__VA_ARGS__); \
fputs("\r\n", stdout); \
}
#else
#define portDBG_TRACE( ... )
#endif
#else
#define portDBG_TRACE(...)
#endif
/* Critical section management. */
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/* Added as there is no such function in FreeRTOS. */
extern void * pvPortRealloc( void * pv,
size_t xSize );
extern void *pvPortRealloc( void *pv, size_t xSize );
/*-----------------------------------------------------------*/
@ -161,34 +159,34 @@
/*
* Restore Context for cases other than INTi.
*/
#define portRESTORE_CONTEXT() \
{ \
#define portRESTORE_CONTEXT() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"ld.w r0, r8[0] \n\t" \
"ld.w sp, r0[0] \n\t" \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t" \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"st.w r8[0], r0 \n\t" \
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t" \
"ldm sp++, r0-r7 \n\t"\
/* R0-R7 should not be used below this line */ \
/* Skip PC and SR (will do it at the end) */ \
"sub sp, -2*4 \n\t" \
"sub sp, -2*4 \n\t"\
/* Restore R8..R12 and LR */ \
"ldm sp++, r8-r12, lr \n\t" \
"ldm sp++, r8-r12, lr \n\t"\
/* Restore SR */ \
"ld.w r0, sp[-8*4] \n\t"/* R0 is modified, is restored later. */\
"mtsr "ASTRINGZ ( AVR32_SR ) ", r0 \n\t" \
"ld.w r0, sp[-8*4] \n\t" /* R0 is modified, is restored later. */\
"mtsr "ASTRINGZ(AVR32_SR)", r0 \n\t"\
/* Restore r0 */ \
"ld.w r0, sp[-9*4] \n\t"\
/* Restore PC */ \
@ -198,7 +196,7 @@
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
}
/*
@ -209,49 +207,49 @@
* are not the same between INT0..3 exceptions and the scall exception.
*/
/* Task context stack layout: */
/* R8 (*) */
/* R9 (*) */
/* R10 (*) */
/* R11 (*) */
/* R12 (*) */
/* R14/LR (*) */
/* R15/PC (*) */
/* SR (*) */
/* R0 */
/* R1 */
/* R2 */
/* R3 */
/* R4 */
/* R5 */
/* R6 */
/* R7 */
/* ulCriticalNesting */
/* (*) automatically done for INT0..INT3, but not for SCALL */
// Task context stack layout:
// R8 (*)
// R9 (*)
// R10 (*)
// R11 (*)
// R12 (*)
// R14/LR (*)
// R15/PC (*)
// SR (*)
// R0
// R1
// R2
// R3
// R4
// R5
// R6
// R7
// ulCriticalNesting
// (*) automatically done for INT0..INT3, but not for SCALL
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
#if configUSE_PREEMPTION == 0
/*
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
*/
#define portSAVE_CONTEXT_OS_INT() \
{ \
#define portSAVE_CONTEXT_OS_INT() \
{ \
/* Save R0..R7 */ \
__asm__ __volatile__ ( "stm --sp, r0-r7" ); \
__asm__ __volatile__ ("stm --sp, r0-r7"); \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context save. */ \
}
}
/*
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
*/
#define portRESTORE_CONTEXT_OS_INT() \
{ \
#define portRESTORE_CONTEXT_OS_INT() \
{ \
__asm__ __volatile__ ( \
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
@ -260,30 +258,30 @@
/* there is also no context restore. */ \
"rete" \
); \
}
}
#else /* if configUSE_PREEMPTION == 0 */
#else
/*
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
*/
#define portSAVE_CONTEXT_OS_INT() \
{ \
#define portSAVE_CONTEXT_OS_INT() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
/* When we come here */ \
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
\
__asm__ __volatile__ ( \
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t" \
"stm --sp, r0-r7 \n\t"\
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"ld.w r0, r8[0] \n\t" \
"st.w --sp, r0 \n\t" \
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0 \n\t"\
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
@ -293,32 +291,32 @@
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
"ld.w r0, sp[9*4] \n\t"/* Read SR in stack */ \
"bfextu r0, r0, 22, 3 \n\t"/* Extract the mode bits to R0. */ \
"cp.w r0, 1 \n\t"/* Compare the mode bits with supervisor mode(b'001) */ \
"brhi LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ ( __LINE__ ) " \n\t" \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
/* NOTE: we don't enter a critical section here because all interrupt handlers */ \
/* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \
/* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \
/* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t"\
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp \n"\
\
"LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ ( __LINE__ ) ":" \
"LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \
); \
}
}
/*
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
*/
#define portRESTORE_CONTEXT_OS_INT() \
{ \
#define portRESTORE_CONTEXT_OS_INT() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
@ -328,15 +326,15 @@
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
__asm__ __volatile__ ( \
"ld.w r0, sp[9*4] \n\t"/* Read SR in stack */ \
"bfextu r0, r0, 22, 3 \n\t"/* Extract the mode bits to R0. */ \
"cp.w r0, 1 \n\t"/* Compare the mode bits with supervisor mode(b'001) */ \
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ ( __LINE__ ) \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) \
); \
\
/* Else */ \
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
@ -345,17 +343,17 @@
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"ld.w r0, r8[0] \n\t" \
"ld.w sp, r0[0] \n" \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n"\
\
"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ ( __LINE__ ) ": \n\t" \
"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t" \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t"\
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
@ -368,9 +366,9 @@
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
}
#endif /* if configUSE_PREEMPTION == 0 */
#endif
/*
@ -379,10 +377,10 @@
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
*
*/
#define portSAVE_CONTEXT_SCALL() \
{ \
#define portSAVE_CONTEXT_SCALL() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
/* If SR[M2:M0] == 001 */ \
@ -396,21 +394,21 @@
\
__asm__ __volatile__ ( \
/* in order to save R0-R7 */ \
"sub sp, 6*4 \n\t" \
"sub sp, 6*4 \n\t"\
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t" \
"stm --sp, r0-r7 \n\t"\
\
/* in order to save R8-R12 and LR */ \
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
"sub r7, sp,-16*4 \n\t" \
"sub r7, sp,-16*4 \n\t"\
/* Copy PC and SR in other places in the stack. */ \
"ld.w r0, r7[-2*4] \n\t"/* Read SR */ \
"st.w r7[-8*4], r0 \n\t"/* Copy SR */ \
"ld.w r0, r7[-1*4] \n\t"/* Read PC */ \
"st.w r7[-7*4], r0 \n\t"/* Copy PC */ \
"ld.w r0, r7[-2*4] \n\t" /* Read SR */\
"st.w r7[-8*4], r0 \n\t" /* Copy SR */\
"ld.w r0, r7[-1*4] \n\t" /* Read PC */\
"st.w r7[-7*4], r0 \n\t" /* Copy PC */\
\
/* Save R8..R12 and LR on the stack. */ \
"stm --r7, r8-r12, lr \n\t" \
"stm --r7, r8-r12, lr \n\t"\
\
/* Arriving here we have the following stack organizations: */ \
/* R8..R12, LR, PC, SR, R0..R7. */ \
@ -418,8 +416,8 @@
/* Now we can finalize the save. */ \
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0" \
); \
@ -432,27 +430,27 @@
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
__asm__ __volatile__ ( \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t"\
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp" \
); \
}
}
/*
* portRESTORE_CONTEXT() for SupervisorCALL exception.
*/
#define portRESTORE_CONTEXT_SCALL() \
{ \
#define portRESTORE_CONTEXT_SCALL() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Restore all registers */ \
\
/* Set SP to point to new stack */ \
__asm__ __volatile__ ( \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0]" \
); \
@ -462,9 +460,9 @@
\
__asm__ __volatile__ ( \
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t" \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* skip PC and SR */ \
@ -475,10 +473,10 @@
\
/* RETS will take care of the extra PC and SR restore. */ \
/* So, we have to prepare the stack for this. */ \
"ld.w r0, r7[-8*4] \n\t"/* Read SR */\
"st.w r7[-2*4], r0 \n\t"/* Copy SR */\
"ld.w r0, r7[-7*4] \n\t"/* Read PC */\
"st.w r7[-1*4], r0 \n\t"/* Copy PC */\
"ld.w r0, r7[-8*4] \n\t" /* Read SR */\
"st.w r7[-2*4], r0 \n\t" /* Copy SR */\
"ld.w r0, r7[-7*4] \n\t" /* Read PC */\
"st.w r7[-1*4], r0 \n\t" /* Copy PC */\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
@ -491,33 +489,33 @@
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
}
/*
* The ISR used depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
#if configUSE_PREEMPTION == 0
/*
* ISR entry and exit macros. These are only required if a task switch
* is required from the ISR.
*/
#define portENTER_SWITCHING_ISR() \
{ \
#define portENTER_SWITCHING_ISR() \
{ \
/* Save R0..R7 */ \
__asm__ __volatile__ ( "stm --sp, r0-r7" ); \
__asm__ __volatile__ ("stm --sp, r0-r7"); \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context save. */ \
}
}
/*
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
*/
#define portEXIT_SWITCHING_ISR() \
{ \
#define portEXIT_SWITCHING_ISR() \
{ \
__asm__ __volatile__ ( \
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
@ -526,31 +524,31 @@
/* there is also no context restore. */ \
"rete" \
); \
}
}
#else /* if configUSE_PREEMPTION == 0 */
#else
/*
* ISR entry and exit macros. These are only required if a task switch
* is required from the ISR.
*/
#define portENTER_SWITCHING_ISR() \
{ \
#define portENTER_SWITCHING_ISR() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
/* When we come here */ \
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
\
__asm__ __volatile__ ( \
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t" \
"stm --sp, r0-r7 \n\t"\
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"ld.w r0, r8[0] \n\t" \
"st.w --sp, r0 \n\t" \
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0 \n\t"\
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
@ -560,29 +558,29 @@
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
"ld.w r0, sp[9*4] \n\t"/* Read SR in stack */ \
"bfextu r0, r0, 22, 3 \n\t"/* Extract the mode bits to R0. */ \
"cp.w r0, 1 \n\t"/* Compare the mode bits with supervisor mode(b'001) */ \
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ ( __LINE__ ) " \n\t" \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t"\
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp \n"\
\
"LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ ( __LINE__ ) ":" \
"LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \
); \
}
}
/*
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
*/
#define portEXIT_SWITCHING_ISR() \
{ \
#define portEXIT_SWITCHING_ISR() \
{ \
extern volatile uint32_t ulCriticalNesting; \
extern volatile void * volatile pxCurrentTCB; \
extern volatile void *volatile pxCurrentTCB; \
\
__asm__ __volatile__ ( \
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
@ -590,42 +588,42 @@
/* level and allow other lower interrupt level to occur). */ \
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
/* did not previously save SP in its TCB. */ \
"ld.w r0, sp[9*4] \n\t"/* Read SR in stack */ \
"bfextu r0, r0, 22, 3 \n\t"/* Extract the mode bits to R0. */ \
"cp.w r0, 1 \n\t"/* Compare the mode bits with supervisor mode(b'001) */ \
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ ( __LINE__ ) " \n\t" \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
\
/* If a switch is required then we just need to call */ \
/* vTaskSwitchContext() as the context has already been */ \
/* saved. */ \
"cp.w r12, 1 \n\t"/* Check if Switch context is required. */ \
"brne LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ ( __LINE__ ) ":C" \
"cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
"brne LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":C" \
); \
\
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
\
__asm__ __volatile__ ( \
"LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ ( __LINE__ ) ": \n\t" \
"LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
/* Restore the context of which ever task is now the highest */ \
/* priority that is ready to run. */ \
\
/* Restore all registers */ \
\
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( pxCurrentTCB ) ") \n\t" \
"ld.w r0, r8[0] \n\t" \
"ld.w sp, r0[0] \n" \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n"\
\
"LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ ( __LINE__ ) ": \n\t" \
"LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t" \
"mov r8, LWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t" \
"orh r8, HWRD("ASTRINGZ ( ulCriticalNesting ) ") \n\t"\
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
@ -638,19 +636,19 @@
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
}
#endif /* if configUSE_PREEMPTION == 0 */
#endif
#define portYIELD() { __asm__ __volatile__ ( "scall" ); }
#define portYIELD() {__asm__ __volatile__ ("scall");}
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,18 +1,17 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief System-specific implementation of the \ref __read function used by
* the standard library.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
*
* \brief System-specific implementation of the \ref __read function used by
the standard library.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
@ -53,7 +52,7 @@ _STD_BEGIN
#pragma module_name = "?__read"
extern volatile avr32_usart_t * volatile stdio_usart_base;
extern volatile avr32_usart_t *volatile stdio_usart_base;
/*! \brief Reads a number of bytes, at most \a size, into the memory area
@ -66,27 +65,22 @@ extern volatile avr32_usart_t * volatile stdio_usart_base;
* \return The number of bytes read, \c 0 at the end of the file, or
* \c _LLIO_ERROR on failure.
*/
size_t __read( int handle,
uint8_t * buffer,
size_t size )
size_t __read(int handle, uint8_t *buffer, size_t size)
{
int nChars = 0;
/* This implementation only reads from stdin. */
/* For all other file handles, it returns failure. */
if( handle != _LLIO_STDIN )
// This implementation only reads from stdin.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDIN)
{
return _LLIO_ERROR;
}
for( ; size > 0; --size )
{
int c = usart_getchar( stdio_usart_base );
if( c < 0 )
for (; size > 0; --size)
{
int c = usart_getchar(stdio_usart_base);
if (c < 0)
break;
}
*buffer++ = c;
++nChars;

View file

@ -1,18 +1,17 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief System-specific implementation of the \ref __write function used by
* the standard library.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
*
* \brief System-specific implementation of the \ref __write function used by
the standard library.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
@ -53,8 +52,8 @@ _STD_BEGIN
#pragma module_name = "?__write"
/*! Pointer to the base of the USART module instance to use for stdio. */
__no_init volatile avr32_usart_t * volatile stdio_usart_base;
//! Pointer to the base of the USART module instance to use for stdio.
__no_init volatile avr32_usart_t *volatile stdio_usart_base;
/*! \brief Writes a number of bytes, at most \a size, from the memory area
@ -70,28 +69,26 @@ __no_init volatile avr32_usart_t * volatile stdio_usart_base;
*
* \return The number of bytes written, or \c _LLIO_ERROR on failure.
*/
size_t __write( int handle,
const uint8_t * buffer,
size_t size )
size_t __write(int handle, const uint8_t *buffer, size_t size)
{
size_t nChars = 0;
if( buffer == 0 )
if (buffer == 0)
{
/* This means that we should flush internal buffers. */
// This means that we should flush internal buffers.
return 0;
}
/* This implementation only writes to stdout and stderr. */
/* For all other file handles, it returns failure. */
if( ( handle != _LLIO_STDOUT ) && ( handle != _LLIO_STDERR ) )
// This implementation only writes to stdout and stderr.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
{
return _LLIO_ERROR;
}
for( ; size != 0; --size )
for (; size != 0; --size)
{
if( usart_putchar( stdio_usart_base, *buffer++ ) < 0 )
if (usart_putchar(stdio_usart_base, *buffer++) < 0)
{
return _LLIO_ERROR;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,123 +1,105 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
;
Push R0 as we are going to use the register.
STMDB SP !, { R0 }
; Push R0 as we are going to use the register.
STMDB SP!, {R0}
;
Set R0 to point to the task stack pointer.
STMDB SP, { SP } ^
NOP
SUB SP, SP, # 4
LDMIA SP !, { R0 }
; Set R0 to point to the task stack pointer.
STMDB SP, {SP}^
NOP
SUB SP, SP, #4
LDMIA SP!, {R0}
;
Push the return address onto the stack.
STMDB R0 !, { LR }
; Push the return address onto the stack.
STMDB R0!, {LR}
;
Now we have saved LR we can use it instead of R0.
; Now we have saved LR we can use it instead of R0.
MOV LR, R0
;
Pop R0 so we can save it onto the system mode stack.
LDMIA SP !, { R0 }
; Pop R0 so we can save it onto the system mode stack.
LDMIA SP!, {R0}
;
Push all the system mode registers onto the task stack.
STMDB LR, { R0 - LR } ^
NOP
SUB LR, LR, # 60
; Push all the system mode registers onto the task stack.
STMDB LR, {R0-LR}^
NOP
SUB LR, LR, #60
;
Push the SPSR onto the task stack.
; Push the SPSR onto the task stack.
MRS R0, SPSR
STMDB LR !, { R0 }
STMDB LR!, {R0}
LDR R0, = ulCriticalNesting
LDR R0, [ R0 ]
STMDB LR !, { R0 }
LDR R0, =ulCriticalNesting
LDR R0, [R0]
STMDB LR!, {R0}
;
Store the new top of stack for the task.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
STR LR, [ R0 ]
; Store the new top of stack for the task.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
STR LR, [R0]
ENDM
ENDM
portRESTORE_CONTEXT MACRO
;
Set the LR to the task stack.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
LDR LR, [ R0 ]
; Set the LR to the task stack.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
LDR LR, [R0]
;
The critical nesting depth is the first item on the stack.
;
Load it into the ulCriticalNesting variable.
LDR R0, = ulCriticalNesting
LDMFD LR !, { R1 }
STR R1, [ R0 ]
; The critical nesting depth is the first item on the stack.
; Load it into the ulCriticalNesting variable.
LDR R0, =ulCriticalNesting
LDMFD LR!, {R1}
STR R1, [R0]
;
Get the SPSR from the stack.
LDMFD LR !, { R0 }
MSR SPSR_cxsf, R0
; Get the SPSR from the stack.
LDMFD LR!, {R0}
MSR SPSR_cxsf, R0
;
Restore all system mode registers for the task.
LDMFD LR, { R0 - R14 } ^
NOP
; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^
NOP
;
Restore the return address.
LDR LR, [ LR, # + 60 ]
; Restore the return address.
LDR LR, [LR, #+60]
;
; And return - correcting the offset in the LR to obtain the
; correct address.
SUBS PC, LR, #4
And return -correcting the offset in the LR to obtain the
;
ENDM
correct address.
SUBS PC, LR, # 4
ENDM

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -26,8 +26,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Atmel ARM7 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the Atmel ARM7 port.
*----------------------------------------------------------*/
/* Standard includes. */
@ -59,8 +59,8 @@
static void prvSetupTimerInterrupt( void );
/* ulCriticalNesting will get set to zero when the first task starts. It
* cannot be initialised to 0 as this will cause interrupts to be enabled
* during the kernel initialisation process. */
cannot be initialised to 0 as this will cause interrupts to be enabled
during the kernel initialisation process. */
uint32_t ulCriticalNesting = ( uint32_t ) 9999;
/*-----------------------------------------------------------*/
@ -71,24 +71,22 @@ uint32_t ulCriticalNesting = ( uint32_t ) 9999;
*
* 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 * pxOriginalTOS;
StackType_t *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert
* is not really required. */
is not really required. */
pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
* start of the task. The offset is added to make the return address appear
* as it would within an IRQ ISR. */
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
@ -122,7 +120,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R0. */
R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--;
@ -138,8 +136,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
* instead be stored in a variable, which is then saved as part of the
* tasks context. */
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
@ -148,10 +146,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void vPortStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -165,22 +163,22 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
#if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to
* simply increment the system tick. */
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
static __arm __irq void vPortNonPreemptiveTick( void );
static __arm __irq void vPortNonPreemptiveTick( void )
{
uint32_t ulDummy;
/* Increment the tick count - which may wake some tasks but as the
* preemptive scheduler is not being used any woken task is not given
* processor time no matter what its priority. */
preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */
xTaskIncrementTick();
/* Clear the PIT interrupt. */
@ -190,33 +188,37 @@ void vPortEndScheduler( void )
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
}
#else /* if configUSE_PREEMPTION == 0 */
#else
/* Currently the IAR port requires the preemptive tick function to be
* defined in an asm file. */
/* Currently the IAR port requires the preemptive tick function to be
defined in an asm file. */
#endif /* if configUSE_PREEMPTION == 0 */
#endif
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
* on whether the preemptive or cooperative scheduler is being used. */
on whether the preemptive or cooperative scheduler is being used. */
#if configUSE_PREEMPTION == 0
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPortNonPreemptiveTick );
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPortNonPreemptiveTick );
#else
extern void( vPortPreemptiveTick )( void );
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPortPreemptiveTick );
extern void ( vPortPreemptiveTick )( void );
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPortPreemptiveTick );
#endif
/* Configure the PIT period. */
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
/* Enable the interrupt. Global interrupts are disables at this point so
* this is safe. */
this is safe. */
AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_SYS );
}
/*-----------------------------------------------------------*/
@ -227,8 +229,8 @@ void vPortEnterCritical( void )
__disable_interrupt();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -241,7 +243,7 @@ void vPortExitCritical( void )
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
* re-enabled. */
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
__enable_interrupt();
@ -249,3 +251,9 @@ void vPortExitCritical( void )
}
}
/*-----------------------------------------------------------*/

View file

@ -27,11 +27,11 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -44,66 +44,68 @@
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
}
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,96 +1,78 @@
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
;
Push R0 as we are going to use the register.
STMDB SP !, { R0 }
; Push R0 as we are going to use the register.
STMDB SP!, {R0}
;
Set R0 to point to the task stack pointer.
STMDB SP, { SP } ^
NOP
SUB SP, SP, # 4
LDMIA SP !, { R0 }
; Set R0 to point to the task stack pointer.
STMDB SP, {SP}^
NOP
SUB SP, SP, #4
LDMIA SP!, {R0}
;
Push the return address onto the stack.
STMDB R0 !, { LR }
; Push the return address onto the stack.
STMDB R0!, {LR}
;
Now we have saved LR we can use it instead of R0.
; Now we have saved LR we can use it instead of R0.
MOV LR, R0
;
Pop R0 so we can save it onto the system mode stack.
LDMIA SP !, { R0 }
; Pop R0 so we can save it onto the system mode stack.
LDMIA SP!, {R0}
;
Push all the system mode registers onto the task stack.
STMDB LR, { R0 - LR } ^
NOP
SUB LR, LR, # 60
; Push all the system mode registers onto the task stack.
STMDB LR, {R0-LR}^
NOP
SUB LR, LR, #60
;
Push the SPSR onto the task stack.
; Push the SPSR onto the task stack.
MRS R0, SPSR
STMDB LR !, { R0 }
STMDB LR!, {R0}
LDR R0, = ulCriticalNesting
LDR R0, [ R0 ]
STMDB LR !, { R0 }
LDR R0, =ulCriticalNesting
LDR R0, [R0]
STMDB LR!, {R0}
;
Store the new top of stack for the task.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
STR LR, [ R0 ]
; Store the new top of stack for the task.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
STR LR, [R0]
ENDM
ENDM
portRESTORE_CONTEXT MACRO
;
Set the LR to the task stack.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
LDR LR, [ R0 ]
; Set the LR to the task stack.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
LDR LR, [R0]
;
The critical nesting depth is the first item on the stack.
;
Load it into the ulCriticalNesting variable.
LDR R0, = ulCriticalNesting
LDMFD LR !, { R1 }
STR R1, [ R0 ]
; The critical nesting depth is the first item on the stack.
; Load it into the ulCriticalNesting variable.
LDR R0, =ulCriticalNesting
LDMFD LR!, {R1}
STR R1, [R0]
;
Get the SPSR from the stack.
LDMFD LR !, { R0 }
MSR SPSR_cxsf, R0
; Get the SPSR from the stack.
LDMFD LR!, {R0}
MSR SPSR_cxsf, R0
;
Restore all system mode registers for the task.
LDMFD LR, { R0 - R14 } ^
NOP
; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^
NOP
;
Restore the return address.
LDR LR, [ LR, # + 60 ]
; Restore the return address.
LDR LR, [LR, #+60]
;
; And return - correcting the offset in the LR to obtain the
; correct address.
SUBS PC, LR, #4
And return -correcting the offset in the LR to obtain the
;
ENDM
correct address.
SUBS PC, LR, # 4
ENDM

View file

@ -26,8 +26,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Atmel ARM7 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the Atmel ARM7 port.
*----------------------------------------------------------*/
/* Standard includes. */
@ -74,8 +74,8 @@ static void prvSetupTimerInterrupt( void );
static void vPortTickISR( void );
/* ulCriticalNesting will get set to zero when the first task starts. It
* cannot be initialised to 0 as this will cause interrupts to be enabled
* during the kernel initialisation process. */
cannot be initialised to 0 as this will cause interrupts to be enabled
during the kernel initialisation process. */
uint32_t ulCriticalNesting = ( uint32_t ) 9999;
/*-----------------------------------------------------------*/
@ -86,24 +86,22 @@ uint32_t ulCriticalNesting = ( uint32_t ) 9999;
*
* 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 * pxOriginalTOS;
StackType_t *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert
* is not really required. */
is not really required. */
pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
* start of the task. The offset is added to make the return address appear
* as it would within an IRQ ISR. */
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
@ -137,7 +135,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R0. */
R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--;
@ -154,8 +152,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
* instead be stored in a variable, which is then saved as part of the
* tasks context. */
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
@ -164,10 +162,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void vPortStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -181,17 +179,17 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
static __arm void vPortTickISR( void )
{
volatile uint32_t ulDummy;
volatile uint32_t ulDummy;
/* Increment the tick count - which may wake some tasks but as the
* preemptive scheduler is not being used any woken task is not given
* processor time no matter what its priority. */
preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
@ -209,7 +207,7 @@ static __arm void vPortTickISR( void )
static void prvSetupTimerInterrupt( void )
{
const uint32_t ulPeriodIn_uS = ( 1.0 / ( double ) configTICK_RATE_HZ ) * port1SECOND_IN_uS;
const uint32_t ulPeriodIn_uS = ( 1.0 / ( double ) configTICK_RATE_HZ ) * port1SECOND_IN_uS;
/* Setup the PIT for the required frequency. */
PIT_Init( ulPeriodIn_uS, BOARD_MCK / port1MHz_IN_Hz );
@ -228,8 +226,8 @@ void vPortEnterCritical( void )
__disable_irq();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -242,7 +240,7 @@ void vPortExitCritical( void )
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
* re-enabled. */
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
__enable_irq();
@ -250,3 +248,9 @@ void vPortExitCritical( void )
}
}
/*-----------------------------------------------------------*/

View file

@ -27,13 +27,13 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -46,67 +46,69 @@
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() __disable_irq()
#define portENABLE_INTERRUPTS() __enable_irq()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() __disable_irq()
#define portENABLE_INTERRUPTS() __enable_irq()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
}
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,123 +1,105 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
;
Push R0 as we are going to use the register.
STMDB SP !, { R0 }
; Push R0 as we are going to use the register.
STMDB SP!, {R0}
;
Set R0 to point to the task stack pointer.
STMDB SP, { SP } ^
NOP
SUB SP, SP, # 4
LDMIA SP !, { R0 }
; Set R0 to point to the task stack pointer.
STMDB SP, {SP}^
NOP
SUB SP, SP, #4
LDMIA SP!, {R0}
;
Push the return address onto the stack.
STMDB R0 !, { LR }
; Push the return address onto the stack.
STMDB R0!, {LR}
;
Now we have saved LR we can use it instead of R0.
; Now we have saved LR we can use it instead of R0.
MOV LR, R0
;
Pop R0 so we can save it onto the system mode stack.
LDMIA SP !, { R0 }
; Pop R0 so we can save it onto the system mode stack.
LDMIA SP!, {R0}
;
Push all the system mode registers onto the task stack.
STMDB LR, { R0 - LR } ^
NOP
SUB LR, LR, # 60
; Push all the system mode registers onto the task stack.
STMDB LR, {R0-LR}^
NOP
SUB LR, LR, #60
;
Push the SPSR onto the task stack.
; Push the SPSR onto the task stack.
MRS R0, SPSR
STMDB LR !, { R0 }
STMDB LR!, {R0}
LDR R0, = ulCriticalNesting
LDR R0, [ R0 ]
STMDB LR !, { R0 }
LDR R0, =ulCriticalNesting
LDR R0, [R0]
STMDB LR!, {R0}
;
Store the new top of stack for the task.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
STR LR, [ R0 ]
; Store the new top of stack for the task.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
STR LR, [R0]
ENDM
ENDM
portRESTORE_CONTEXT MACRO
;
Set the LR to the task stack.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
LDR LR, [ R0 ]
; Set the LR to the task stack.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
LDR LR, [R0]
;
The critical nesting depth is the first item on the stack.
;
Load it into the ulCriticalNesting variable.
LDR R0, = ulCriticalNesting
LDMFD LR !, { R1 }
STR R1, [ R0 ]
; The critical nesting depth is the first item on the stack.
; Load it into the ulCriticalNesting variable.
LDR R0, =ulCriticalNesting
LDMFD LR!, {R1}
STR R1, [R0]
;
Get the SPSR from the stack.
LDMFD LR !, { R0 }
MSR SPSR_cxsf, R0
; Get the SPSR from the stack.
LDMFD LR!, {R0}
MSR SPSR_cxsf, R0
;
Restore all system mode registers for the task.
LDMFD LR, { R0 - R14 } ^
NOP
; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^
NOP
;
Restore the return address.
LDR LR, [ LR, # + 60 ]
; Restore the return address.
LDR LR, [LR, #+60]
;
; And return - correcting the offset in the LR to obtain the
; correct address.
SUBS PC, LR, #4
And return -correcting the offset in the LR to obtain the
;
ENDM
correct address.
SUBS PC, LR, # 4
ENDM

View file

@ -26,16 +26,16 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Philips ARM7 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the Philips ARM7 port.
*----------------------------------------------------------*/
/*
* Changes from V3.2.2
*
Changes from V3.2.2
+ Bug fix - The prescale value for the timer setup is now written to T0PR
+ instead of T0PC. This bug would have had no effect unless a prescale
+ value was actually used.
*/
instead of T0PC. This bug would have had no effect unless a prescale
value was actually used.
*/
/* Standard includes. */
#include <stdlib.h>
@ -83,8 +83,8 @@
static void prvSetupTimerInterrupt( void );
/* ulCriticalNesting will get set to zero when the first task starts. It
* cannot be initialised to 0 as this will cause interrupts to be enabled
* during the kernel initialisation process. */
cannot be initialised to 0 as this will cause interrupts to be enabled
during the kernel initialisation process. */
uint32_t ulCriticalNesting = ( uint32_t ) 9999;
/*-----------------------------------------------------------*/
@ -95,20 +95,18 @@ uint32_t ulCriticalNesting = ( uint32_t ) 9999;
*
* 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 * pxOriginalTOS;
StackType_t *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
* start of the task. The offset is added to make the return address appear
* as it would within an IRQ ISR. */
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
@ -142,7 +140,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R0. */
R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--;
@ -158,8 +156,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
* instead be stored in a variable, which is then saved as part of the
* tasks context. */
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
@ -168,10 +166,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void vPortStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -185,20 +183,20 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
#if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to
* simply increment the system tick. */
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
static __arm __irq void vPortNonPreemptiveTick( void );
static __arm __irq void vPortNonPreemptiveTick( void )
{
/* Increment the tick count - which may wake some tasks but as the
* preemptive scheduler is not being used any woken task is not given
* processor time no matter what its priority. */
preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */
xTaskIncrementTick();
/* Ready for the next interrupt. */
@ -206,10 +204,10 @@ void vPortEndScheduler( void )
VICVectAddr = portCLEAR_VIC_INTERRUPT;
}
#else /* if configUSE_PREEMPTION == 0 */
#else
/* This function is called from an asm wrapper, so does not require the __irq
* keyword. */
/* This function is called from an asm wrapper, so does not require the __irq
keyword. */
void vPortPreemptiveTick( void );
void vPortPreemptiveTick( void )
{
@ -217,8 +215,8 @@ void vPortEndScheduler( void )
if( xTaskIncrementTick() != pdFALSE )
{
/* The new tick value might unblock a task. Ensure the highest task that
* is ready to execute is the task that will execute when the tick ISR
* exits. */
is ready to execute is the task that will execute when the tick ISR
exits. */
vTaskSwitchContext();
}
@ -227,23 +225,23 @@ void vPortEndScheduler( void )
VICVectAddr = portCLEAR_VIC_INTERRUPT;
}
#endif /* if configUSE_PREEMPTION == 0 */
#endif
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
uint32_t ulCompareMatch;
uint32_t ulCompareMatch;
/* A 1ms tick does not require the use of the timer prescale. This is
* defaulted to zero but can be used if necessary. */
defaulted to zero but can be used if necessary. */
T0PR = portPRESCALE_VALUE;
/* Calculate the match value required for our wanted tick rate. */
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
/* Protect against divide by zero. Using an if() statement still results
* in a warning - hence the #if. */
in a warning - hence the #if. */
#if portPRESCALE_VALUE != 0
{
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
@ -260,25 +258,25 @@ static void prvSetupTimerInterrupt( void )
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
/* The ISR installed depends on whether the preemptive or cooperative
* scheduler is being used. */
scheduler is being used. */
#if configUSE_PREEMPTION == 1
{
extern void( vPortPreemptiveTickEntry )( void );
extern void ( vPortPreemptiveTickEntry )( void );
VICVectAddr0 = ( uint32_t ) vPortPreemptiveTickEntry;
}
#else
{
extern void( vNonPreemptiveTick )( void );
extern void ( vNonPreemptiveTick )( void );
VICVectAddr0 = ( int32_t ) vPortNonPreemptiveTick;
}
#endif /* if configUSE_PREEMPTION == 1 */
#endif
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
/* Start the timer - interrupts are disabled when this function is called
* so it is okay to do this here. */
so it is okay to do this here. */
T0TCR = portENABLE_TIMER;
}
/*-----------------------------------------------------------*/
@ -289,8 +287,8 @@ void vPortEnterCritical( void )
__disable_interrupt();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -303,7 +301,7 @@ void vPortExitCritical( void )
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
* re-enabled. */
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
__enable_interrupt();
@ -311,3 +309,9 @@ void vPortExitCritical( void )
}
}
/*-----------------------------------------------------------*/

View file

@ -27,13 +27,13 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -46,66 +46,68 @@
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
}
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -30,28 +30,28 @@
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the MSP430 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the MSP430 port.
*----------------------------------------------------------*/
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
* not the MCLK. */
not the MCLK. */
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
/* 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;
/* Each task maintains a count of the critical section nesting depth. Each
* time a critical section is entered the count is incremented. Each time a
* critical section is exited the count is decremented - with interrupts only
* being re-enabled if the count is zero.
*
* usCriticalNesting will get set to zero when the scheduler starts, but must
* not be initialised to zero as this will cause problems during the startup
* sequence. */
time a critical section is entered the count is incremented. Each time a
critical section is exited the count is decremented - with interrupts only
being re-enabled if the count is zero.
usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as this will cause problems during the startup
sequence. */
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/
@ -69,26 +69,24 @@ void vPortSetupTimerInterrupt( void );
*
* See the header file portable.h.
*/
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 is just useful for debugging and can be included if required.
*
* pxTopOfStack = ( StackType_t ) 0x1111;
* pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x2222;
* pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x3333;
* pxTopOfStack--;
Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging and can be included if required.
*pxTopOfStack = ( StackType_t ) 0x1111;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x2222;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x3333;
pxTopOfStack--;
*/
/* The msp430 automatically pushes the PC then SR onto the stack before
* executing an ISR. We want the stack to look just as if this has happened
* so place a pointer to the start of the task on the stack first - followed
* by the flags we want the task to use when it starts up. */
executing an ISR. We want the stack to look just as if this has happened
so place a pointer to the start of the task on the stack first - followed
by the flags we want the task to use when it starts up. */
*pxTopOfStack = ( StackType_t ) pxCode;
pxTopOfStack--;
*pxTopOfStack = portFLAGS_INT_ENABLED;
@ -113,7 +111,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R15. */
R15. */
*pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack--;
@ -125,12 +123,12 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* 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 is
* initially set to zero. */
This variable has to be stored as part of the task context and is
initially set to zero. */
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack we have generated so this can
* be stored in the task control block for the task. */
be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
@ -138,7 +136,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
void vPortEndScheduler( void )
{
/* It is unlikely that the MSP430 port will get stopped. If required simply
* disable the tick interrupt here. */
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
@ -170,3 +168,6 @@ void vPortSetupTimerInterrupt( void )
TACTL |= MC_1;
}
/*-----------------------------------------------------------*/

View file

@ -30,54 +30,55 @@
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.
* 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 )
/* 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)
reti
endm
reti
endm
/*-----------------------------------------------------------*/
#endif /* ifndef PORTASM_H */
#endif

View file

@ -52,7 +52,7 @@ typedef short BaseType_t;
typedef unsigned short UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
@ -71,8 +71,8 @@ typedef unsigned short UBaseType_t;
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
{ \
extern volatile uint16_t usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
@ -80,11 +80,11 @@ typedef unsigned short UBaseType_t;
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
}
#define portEXIT_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
{ \
extern volatile uint16_t usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
@ -98,7 +98,7 @@ typedef unsigned short UBaseType_t;
portENABLE_INTERRUPTS(); \
} \
} \
}
}
/*-----------------------------------------------------------*/
/* Task utilities. */
@ -119,14 +119,15 @@ extern void vPortYield( void );
/*-----------------------------------------------------------*/
/* 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 )
#if configINTERRUPT_EXAMPLE_METHOD == 2
extern void vTaskSwitchContext( void );
#define portYIELD_FROM_ISR( x ) if( x ) vTaskSwitchContext()
extern void vTaskSwitchContext( void );
#define portYIELD_FROM_ISR( x ) if( x ) vTaskSwitchContext()
#endif
#endif /* PORTMACRO_H */

View file

@ -60,3 +60,4 @@
#endif
#endif /* DATA_MODEL_H */

View file

@ -30,28 +30,28 @@
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the MSP430X port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the MSP430X port.
*----------------------------------------------------------*/
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
* not the MCLK. */
not the MCLK. */
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
/* 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;
/* Each task maintains a count of the critical section nesting depth. Each
* time a critical section is entered the count is incremented. Each time a
* critical section is exited the count is decremented - with interrupts only
* being re-enabled if the count is zero.
*
* usCriticalNesting will get set to zero when the scheduler starts, but must
* not be initialised to zero as this will cause problems during the startup
* sequence. */
time a critical section is entered the count is incremented. Each time a
critical section is exited the count is decremented - with interrupts only
being re-enabled if the count is zero.
usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as this will cause problems during the startup
sequence. */
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/
@ -69,28 +69,26 @@ void vPortSetupTimerInterrupt( void );
*
* See the header file portable.h.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
uint16_t * pusTopOfStack;
uint32_t * pulTopOfStack;
uint16_t *pusTopOfStack;
uint32_t *pulTopOfStack;
/*
* Place a few bytes of known values on the bottom of the stack.
* This is just useful for debugging and can be included if required.
*
* pxTopOfStack = ( StackType_t ) 0x1111;
* pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x2222;
* pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x3333;
Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging and can be included if required.
*pxTopOfStack = ( StackType_t ) 0x1111;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x2222;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x3333;
*/
/* StackType_t is either 16 bits or 32 bits depending on the data model.
* Some stacked items do not change size depending on the data model so have
* to be explicitly cast to the correct size so this function will work
* whichever data model is being used. */
Some stacked items do not change size depending on the data model so have
to be explicitly cast to the correct size so this function will work
whichever data model is being used. */
if( sizeof( StackType_t ) == sizeof( uint16_t ) )
{
/* Make room for a 20 bit value stored as a 32 bit value. */
@ -102,7 +100,6 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
{
pulTopOfStack = ( uint32_t * ) pxTopOfStack;
}
*pulTopOfStack = ( uint32_t ) pxCode;
pusTopOfStack = ( uint16_t * ) pulTopOfStack;
@ -139,20 +136,20 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x4444;
pxTopOfStack--;
#else /* ifdef PRELOAD_REGISTER_VALUES */
#else
pxTopOfStack -= 3;
*pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack -= 9;
#endif /* ifdef PRELOAD_REGISTER_VALUES */
#endif
/* 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 is
* initially set to zero. */
This variable has to be stored as part of the task context and is
initially set to zero. */
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack we have generated so this can
* be stored in the task control block for the task. */
be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
@ -160,7 +157,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
void vPortEndScheduler( void )
{
/* It is unlikely that the MSP430 port will get stopped. If required simply
* disable the tick interrupt here. */
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
@ -176,8 +173,10 @@ void vPortSetupTimerInterrupt( void )
#pragma vector=configTICK_VECTOR
__interrupt __raw void vTickISREntry( void )
{
extern void vPortTickISR( void );
extern void vPortTickISR( void );
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
vPortTickISR();
}

View file

@ -50,7 +50,7 @@
#define portBASE_TYPE short
/* The stack type changes depending on the data model. */
#if ( __DATA_MODEL__ == __DATA_MODEL_SMALL__ )
#if( __DATA_MODEL__ == __DATA_MODEL_SMALL__ )
#define portSTACK_TYPE uint16_t
#define portPOINTER_SIZE_TYPE uint16_t
#else
@ -61,7 +61,7 @@ typedef portSTACK_TYPE StackType_t;
typedef short BaseType_t;
typedef unsigned short UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
@ -80,8 +80,8 @@ typedef unsigned short UBaseType_t;
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
{ \
extern volatile uint16_t usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
@ -89,11 +89,11 @@ typedef unsigned short UBaseType_t;
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
}
#define portEXIT_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
{ \
extern volatile uint16_t usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
@ -107,7 +107,7 @@ typedef unsigned short UBaseType_t;
portENABLE_INTERRUPTS(); \
} \
} \
}
}
/*-----------------------------------------------------------*/
/* Task utilities. */
@ -127,15 +127,16 @@ extern void vPortYield( void );
/*-----------------------------------------------------------*/
/* 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 )
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
void vApplicationSetupTimerInterrupt( void );
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
* run time stats information is to be displayed. */
run time stats information is to be displayed. */
#define portLU_PRINTF_SPECIFIER_REQUIRED
#endif /* PORTMACRO_H */

View file

@ -58,11 +58,11 @@
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
portasmSAVE_ADDITIONAL_REGISTERS MACRO
/* No additional registers to save, so this macro does nothing. */
ENDM
/* No additional registers to save, so this macro does nothing. */
ENDM
portasmRESTORE_ADDITIONAL_REGISTERS MACRO
/* No additional registers to restore, so this macro does nothing. */
/* No additional registers to restore, so this macro does nothing. */
ENDM
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */

View file

@ -26,8 +26,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the RISC-V RV32 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the RISC-V RV32 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
@ -38,20 +38,20 @@
#include "string.h"
#ifdef configCLINT_BASE_ADDRESS
#warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
#warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
#endif
#ifndef configMTIME_BASE_ADDRESS
#warning configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
#warning configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
#endif
#ifndef configMTIMECMP_BASE_ADDRESS
#warning configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
#warning configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
#endif
/* Let the user override the pre-loading of the initial LR with the address of
* prvTaskExitError() in case it messes up unwinding of the stack in the
* debugger. */
prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */
#ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else
@ -59,19 +59,19 @@
#endif
/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS
* to use a statically allocated array as the interrupt stack. Alternative leave
* configISR_STACK_SIZE_WORDS undefined and update the linker script so that a
* linker variable names __freertos_irq_stack_top has the same value as the top
* of the stack used by main. Using the linker script method will repurpose the
* stack that was used by main before the scheduler was started for use as the
* interrupt stack after the scheduler has started. */
to use a statically allocated array as the interrupt stack. Alternative leave
configISR_STACK_SIZE_WORDS undefined and update the linker script so that a
linker variable names __freertos_irq_stack_top has the same value as the top
of the stack used by main. Using the linker script method will repurpose the
stack that was used by main before the scheduler was started for use as the
interrupt stack after the scheduler has started. */
#ifdef configISR_STACK_SIZE_WORDS
static __attribute__( ( aligned( 16 ) ) ) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 };
static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 };
const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ] );
/* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for
* the task stacks, and so will legitimately appear in many positions within
* the ISR stack. */
/* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for
the task stacks, and so will legitimately appear in many positions within
the ISR stack. */
#define portISR_STACK_FILL_BYTE 0xee
#else
extern const uint32_t __freertos_irq_stack_top[];
@ -83,42 +83,40 @@
* file is weak to allow application writers to change the timer used to
* generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void ) __attribute__( ( weak ) );
void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));
/*-----------------------------------------------------------*/
/* Used to program the machine timer compare register. */
uint64_t ullNextTime = 0ULL;
const uint64_t * pullNextTime = &ullNextTime;
const uint64_t *pullNextTime = &ullNextTime;
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
* stack checking. A problem in the ISR stack will trigger an assert, not call the
* stack overflow hook function (because the stack overflow hook is specific to a
* task stack, not the ISR stack). */
stack checking. A problem in the ISR stack will trigger an assert, not call the
stack overflow hook function (because the stack overflow hook is specific to a
task stack, not the ISR stack). */
#if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 )
#warning This path not tested, or even compiled yet.
static const uint8_t ucExpectedStackBytes[] =
{
static const uint8_t ucExpectedStackBytes[] = {
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE
}; \
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE }; \
#define portCHECK_ISR_STACK() configASSERT( ( memcmp( ( void * ) xISRStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) == 0 ) )
#else /* if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 ) */
#else
/* Define the function away. */
#define portCHECK_ISR_STACK()
#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */
/*-----------------------------------------------------------*/
#if ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
void vPortSetupTimerInterrupt( void )
{
@ -127,8 +125,7 @@ volatile uint64_t * pullMachineTimerCompareRegister = NULL;
volatile uint32_t * const pulTimeLow = ( uint32_t * ) ( configMTIME_BASE_ADDRESS );
volatile uint32_t ulHartId;
__asm volatile ( "csrr %0, 0xf14" : "=r" ( ulHartId ) ); /* 0xf14 is hartid. */
__asm volatile( "csrr %0, 0xf14" : "=r"( ulHartId ) ); /* 0xf14 is hartid. */
pullMachineTimerCompareRegister = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) );
do
@ -152,20 +149,20 @@ volatile uint64_t * pullMachineTimerCompareRegister = NULL;
BaseType_t xPortStartScheduler( void )
{
extern void xPortStartFirstTask( void );
extern void xPortStartFirstTask( void );
#if ( configASSERT_DEFINED == 1 )
#if( configASSERT_DEFINED == 1 )
{
volatile uint32_t mtvec = 0;
/* Check the least significant two bits of mtvec are 00 - indicating
* single vector mode. */
__asm volatile ( "csrr %0, 0x305" : "=r" ( mtvec ) ); /* 0x305 is mtvec. */
single vector mode. */
__asm volatile( "csrr %0, 0x305" : "=r"( mtvec ) ); /* 0x305 is mtvec. */
configASSERT( ( mtvec & 0x03UL ) == 0 );
/* Check alignment of the interrupt stack - which is the same as the
* stack that was being used by main() prior to the scheduler being
* started. */
stack that was being used by main() prior to the scheduler being
started. */
configASSERT( ( xISRStackTop & portBYTE_ALIGNMENT_MASK ) == 0 );
#ifdef configISR_STACK_SIZE_WORDS
@ -177,28 +174,28 @@ BaseType_t xPortStartScheduler( void )
#endif /* configASSERT_DEFINED */
/* If there is a CLINT then it is ok to use the default implementation
* in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
* configure whichever clock is to be used to generate the tick interrupt. */
in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
configure whichever clock is to be used to generate the tick interrupt. */
vPortSetupTimerInterrupt();
#if ( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) )
#if( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) )
{
/* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11
* for external interrupt. _RB_ What happens here when mtime is not present as
* with pulpino? */
__asm volatile ( "csrs 0x304, %0" ::"r" ( 0x880 ) ); /* 0x304 is mie. */
for external interrupt. _RB_ What happens here when mtime is not present as
with pulpino? */
__asm volatile( "csrs 0x304, %0" :: "r"(0x880) ); /* 0x304 is mie. */
}
#else
{
/* Enable external interrupts. */
__asm volatile ( "csrs 0x304, %0" ::"r" ( 0x800 ) ); /* 304 is mie. */
__asm volatile( "csrs 0x304, %0" :: "r"(0x800) ); /* 304 is mie. */
}
#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */
xPortStartFirstTask();
/* Should not get here as after calling xPortStartFirstTask() only tasks
* should be executing. */
should be executing. */
return pdFAIL;
}
/*-----------------------------------------------------------*/
@ -206,7 +203,10 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* Not implemented. */
for( ; ; )
{
}
for( ;; );
}

View file

@ -27,13 +27,13 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include "intrinsics.h"
#include "intrinsics.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -46,133 +46,132 @@
*/
/* Type definitions. */
#if __riscv_xlen == 64
#if __riscv_xlen == 64
#define portSTACK_TYPE uint64_t
#define portBASE_TYPE int64_t
#define portUBASE_TYPE uint64_t
#define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffUL
#define portPOINTER_SIZE_TYPE uint64_t
#elif __riscv_xlen == 32
#elif __riscv_xlen == 32
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE int32_t
#define portUBASE_TYPE uint32_t
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#else /* if __riscv_xlen == 64 */
#else
#error Assembler did not define __riscv_xlen
#endif /* if __riscv_xlen == 64 */
#endif
typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t;
typedef portUBASE_TYPE UBaseType_t;
typedef portUBASE_TYPE TickType_t;
typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t;
typedef portUBASE_TYPE UBaseType_t;
typedef portUBASE_TYPE TickType_t;
/* Legacy type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#ifdef __riscv64
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#ifdef __riscv64
#error This is the RV32 port that has not yet been adapted for 64.
#define portBYTE_ALIGNMENT 16
#else
#else
#define portBYTE_ALIGNMENT 16
#endif
#endif
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
extern void vTaskSwitchContext( void );
#define portYIELD() __asm volatile ( "ecall" );
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
extern void vTaskSwitchContext( void );
#define portYIELD() __asm volatile( "ecall" );
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portCRITICAL_NESTING_IN_TCB 1
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portCRITICAL_NESTING_IN_TCB 1
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#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()
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
#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()
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/*-----------------------------------------------------------*/
/* Architecture specific optimisations. */
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
#error configUSE_PORT_OPTIMISED_TASK_SELECTION cannot yet be used in the IAR RISC-V port, the CLZ instruction needs to be emulated.
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
* not necessary for to use this port. They are defined so the common demo files
* (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/*-----------------------------------------------------------*/
#define portNOP() __asm volatile ( " nop " )
#define portNOP() __asm volatile ( " nop " )
#define portINLINE __inline
#define portINLINE __inline
#ifndef portFORCE_INLINE
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
#endif
#ifndef portFORCE_INLINE
#define portFORCE_INLINE inline __attribute__(( always_inline))
#endif
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
* the source code because to do so would cause other compilers to generate
* warnings. */
#pragma diag_suppress=Pa082
the source code because to do so would cause other compilers to generate
warnings. */
#pragma diag_suppress=Pa082
/* configCLINT_BASE_ADDRESS is a legacy definition that was replaced by the
* configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For
* backward compatibility derive the newer definitions from the old if the old
* definition is found. */
#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 )
/* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate
* there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP
* addresses to 0. */
configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For
backward compatibility derive the newer definitions from the old if the old
definition is found. */
#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 )
/* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate
there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP
addresses to 0. */
#define configMTIME_BASE_ADDRESS ( 0 )
#define configMTIMECMP_BASE_ADDRESS ( 0 )
#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )
/* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of
* the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses
* from the CLINT address. */
#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )
/* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of
the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses
from the CLINT address. */
#define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL )
#define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL )
#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )
#error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
#endif /* if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 ) */
#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )
#error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
#endif
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,112 +1,83 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
#include "FreeRTOSConfig.h"
;
Variables used by scheduler
;
------------------------------------------------------------------------------
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
; Variables used by scheduler
;------------------------------------------------------------------------------
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
;
------------------------------------------------------------------------------
;
portSAVE_CONTEXT MACRO
;
Saves the context of the general purpose registers, CS and ES( only in far
;
memory mode ) registers the usCriticalNesting Value and the Stack Pointer
;
of the active Task onto the task stack
;
------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; portSAVE_CONTEXT MACRO
; Saves the context of the general purpose registers, CS and ES (only in far
; memory mode) registers the usCriticalNesting Value and the Stack Pointer
; of the active Task onto the task stack
;------------------------------------------------------------------------------
portSAVE_CONTEXT MACRO
PUSH AX;
Save AX Register to stack.
PUSH AX ; Save AX Register to stack.
PUSH HL
MOV A, CS;
Save CS register.
MOV A, CS ; Save CS register.
XCH A, X
MOV A, ES;
Save ES register.
MOV A, ES ; Save ES register.
PUSH AX
PUSH DE;
Save the remaining general purpose registers.
PUSH DE ; Save the remaining general purpose registers.
PUSH BC
MOVW AX, usCriticalNesting;
Save the usCriticalNesting value.
MOVW AX, usCriticalNesting ; Save the usCriticalNesting value.
PUSH AX
MOVW AX, pxCurrentTCB;
Save the Stack pointer.
MOVW AX, pxCurrentTCB ; Save the Stack pointer.
MOVW HL, AX
MOVW AX, SP
MOVW[ HL ], AX
MOVW AX, SP
MOVW [HL], AX
ENDM
;
------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;
------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------
; portRESTORE_CONTEXT MACRO
; Restores the task Stack Pointer then use this to restore usCriticalNesting,
; general purpose registers and the CS and ES (only in far memory mode)
; of the selected task from the task stack
;------------------------------------------------------------------------------
portRESTORE_CONTEXT MACRO
;
Restores the task Stack Pointer then use this to restore usCriticalNesting,
;
general purpose registers and the CS and ES( only in far memory mode )
;
of the selected task from the task stack
;
------------------------------------------------------------------------------
portRESTORE_CONTEXT MACRO
MOVW AX, pxCurrentTCB;
Restore the Stack pointer.
MOVW AX, pxCurrentTCB ; Restore the Stack pointer.
MOVW HL, AX
MOVW AX, [ HL ]
MOVW SP, AX
POP AX;
Restore usCriticalNesting value.
MOVW AX, [HL]
MOVW SP, AX
POP AX ; Restore usCriticalNesting value.
MOVW usCriticalNesting, AX
POP BC;
Restore the necessary general purpose registers.
POP BC ; Restore the necessary general purpose registers.
POP DE
POP AX;
Restore the ES register.
POP AX ; Restore the ES register.
MOV ES, A
XCH A, X;
Restore the CS register.
XCH A, X ; Restore the CS register.
MOV CS, A
POP HL;
Restore general purpose register HL.
POP AX;
Restore AX.
POP HL ; Restore general purpose register HL.
POP AX ; Restore AX.
ENDM
;
------------------------------------------------------------------------------
;------------------------------------------------------------------------------

View file

@ -30,7 +30,7 @@
#include "task.h"
/* The critical nesting value is initialised to a non zero value to ensure
* interrupts don't accidentally become enabled before the scheduler is started. */
interrupts don't accidentally become enabled before the scheduler is started. */
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
/* Initial PSW value allocated to a newly created task.
@ -47,18 +47,18 @@
#define portPSW ( 0xc6UL )
/* The address of the pxCurrentTCB variable, but don't know or need to know its
* type. */
type. */
typedef void TCB_t;
extern volatile TCB_t * volatile pxCurrentTCB;
/* Each task maintains a count of the critical section nesting depth. Each time
* a critical section is entered the count is incremented. Each time a critical
* section is exited the count is decremented - with interrupts only being
* re-enabled if the count is zero.
*
* usCriticalNesting will get set to zero when the scheduler starts, but must
* not be initialised to zero as that could cause problems during the startup
* sequence. */
a critical section is entered the count is incremented. Each time a critical
section is exited the count is decremented - with interrupts only being
re-enabled if the count is zero.
usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as that could cause problems during the startup
sequence. */
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/
@ -71,9 +71,8 @@ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
*/
static void prvSetupTimerInterrupt( void );
#ifndef configSETUP_TICK_INTERRUPT
/* The user has not provided their own tick interrupt configuration so use
* the definition in this file (which uses the interval timer). */
/* The user has not provided their own tick interrupt configuration so use
the definition in this file (which uses the interval timer). */
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
#endif /* configSETUP_TICK_INTERRUPT */
@ -96,20 +95,18 @@ static void prvTaskExitError( void );
*
* See the header file portable.h.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
uint32_t * pulLocal;
uint32_t *pulLocal;
/* With large code and large data sizeof( StackType_t ) == 2, and
* sizeof( StackType_t * ) == 4. With small code and small data
* sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
sizeof( StackType_t * ) == 4. With small code and small data
sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
{
/* Parameters are passed in on the stack, and written using a 32-bit value
* hence a space is left for the second two bytes. */
hence a space is left for the second two bytes. */
pxTopOfStack--;
/* Write in the parameter value. */
@ -118,15 +115,15 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* The return address, leaving space for the first two bytes of the
* 32-bit value. See the comments above the prvTaskExitError() prototype
* at the top of this file. */
32-bit value. See the comments above the prvTaskExitError() prototype
at the top of this file. */
pxTopOfStack--;
pulLocal = ( uint32_t * ) pxTopOfStack;
*pulLocal = ( uint32_t ) prvTaskExitError;
pxTopOfStack--;
/* The start address / PSW value is also written in as a 32-bit value,
* so leave a space for the second two bytes. */
so leave a space for the second two bytes. */
pxTopOfStack--;
/* Task function start address combined with the PSW. */
@ -138,18 +135,18 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) 0x1111;
pxTopOfStack--;
}
#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
#else
{
/* The return address, leaving space for the first two bytes of the
* 32-bit value. See the comments above the prvTaskExitError() prototype
* at the top of this file. */
32-bit value. See the comments above the prvTaskExitError() prototype
at the top of this file. */
pxTopOfStack--;
pulLocal = ( uint32_t * ) pxTopOfStack;
*pulLocal = ( uint32_t ) prvTaskExitError;
pxTopOfStack--;
/* Task function. Again as it is written as a 32-bit value a space is
* left on the stack for the second two bytes. */
left on the stack for the second two bytes. */
pxTopOfStack--;
/* Task function start address combined with the PSW. */
@ -161,7 +158,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack--;
}
#endif /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
#endif
/* An initial value for the HL register. */
*pxTopOfStack = ( StackType_t ) 0x2222;
@ -178,11 +175,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Finally the critical section nesting count is set to zero when the task
* first starts. */
first starts. */
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack that has been generated so it
* can be stored in the task control block for the task. */
can be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
@ -190,35 +187,32 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
static void prvTaskExitError( void )
{
/* A function that implements a task must not exit or attempt to return to
* its caller as there is nothing to return to. If a task wants to exit it
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
* defined, then stop here so application writers can catch the error. */
its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ).
Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT( usCriticalNesting == ~0U );
portDISABLE_INTERRUPTS();
for( ; ; )
{
}
for( ;; );
}
/*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void )
{
/* Setup the hardware to generate the tick. Interrupts are disabled when
* this function is called. */
this function is called. */
configSETUP_TICK_INTERRUPT();
/* Restore the context of the first task that is going to run. */
vPortStartFirstTask();
/* Execution should not reach here as the tasks are now running!
* prvSetupTimerInterrupt() is called here to prevent the compiler outputting
* a warning about a statically declared function not being referenced in the
* case that the application writer has provided their own tick interrupt
* configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
* their own routine will be called in place of prvSetupTimerInterrupt()). */
prvSetupTimerInterrupt() is called here to prevent the compiler outputting
a warning about a statically declared function not being referenced in the
case that the application writer has provided their own tick interrupt
configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
their own routine will be called in place of prvSetupTimerInterrupt()). */
prvSetupTimerInterrupt();
return pdTRUE;
}
@ -232,8 +226,8 @@ void vPortEndScheduler( void )
static void prvSetupTimerInterrupt( void )
{
const uint16_t usClockHz = 15000UL; /* Internal clock. */
const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL;
const uint16_t usClockHz = 15000UL; /* Internal clock. */
const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL;
/* Use the internal 15K clock. */
OSMC = ( uint8_t ) 0x16;
@ -258,7 +252,7 @@ static void prvSetupTimerInterrupt( void )
/* Enable INTIT interrupt. */
ITMK = ( uint8_t ) 0;
}
#endif /* ifdef RTCEN */
#endif
#ifdef TMKAEN
{
@ -280,6 +274,7 @@ static void prvSetupTimerInterrupt( void )
/* Enable INTIT interrupt. */
TMKAMK = ( uint8_t ) 0;
}
#endif /* ifdef TMKAEN */
#endif
}
/*-----------------------------------------------------------*/

View file

@ -26,11 +26,11 @@
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -42,56 +42,56 @@
*-----------------------------------------------------------
*/
#if __DATA_MODEL__ == __DATA_MODEL_FAR__ && __CODE_MODEL__ == __CODE_MODEL_NEAR__
#if __DATA_MODEL__ == __DATA_MODEL_FAR__ && __CODE_MODEL__ == __CODE_MODEL_NEAR__
#warning This port has not been tested with your selected memory model combination. If a far data model is required it is recommended to also use a far code model.
#endif
#endif
#if __DATA_MODEL__ == __DATA_MODEL_NEAR__ && __CODE_MODEL__ == __CODE_MODEL_FAR__
#if __DATA_MODEL__ == __DATA_MODEL_NEAR__ && __CODE_MODEL__ == __CODE_MODEL_FAR__
#warning This port has not been tested with your selected memory model combination. If a far code model is required it is recommended to also use a far data model.
#endif
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint16_t
#define portBASE_TYPE short
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint16_t
#define portBASE_TYPE short
typedef portSTACK_TYPE StackType_t;
typedef short BaseType_t;
typedef unsigned short UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef short BaseType_t;
typedef unsigned short UBaseType_t;
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
#define portPOINTER_SIZE_TYPE uint32_t
#else
#else
#define portPOINTER_SIZE_TYPE uint16_t
#endif
#endif
#if ( configUSE_16_BIT_TICKS == 1 )
#if ( configUSE_16_BIT_TICKS == 1 )
typedef unsigned int TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() __asm( "DI" )
#define portENABLE_INTERRUPTS() __asm( "EI" )
#define portDISABLE_INTERRUPTS() __asm ( "DI" )
#define portENABLE_INTERRUPTS() __asm ( "EI" )
/*-----------------------------------------------------------*/
/* Critical section control macros. */
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
#define portENTER_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
@ -99,11 +99,11 @@
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
}
#define portEXIT_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
#define portEXIT_CRITICAL() \
{ \
extern volatile uint16_t usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
@ -117,27 +117,28 @@
portENABLE_INTERRUPTS(); \
} \
} \
}
}
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portYIELD() __asm( "BRK" )
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
#define portNOP() __asm( "NOP" )
#define portYIELD() __asm( "BRK" )
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
#define portNOP() __asm( "NOP" )
/*-----------------------------------------------------------*/
/* Hardwware specifics. */
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -26,8 +26,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the SH2A port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the SH2A port.
*----------------------------------------------------------*/
/* Standard C includes. */
#include "limits.h"
@ -45,11 +45,11 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
/* The peripheral clock is divided by this value before being supplying the
* CMT. */
CMT. */
#if ( configUSE_TICKLESS_IDLE == 0 )
/* If tickless idle is not used then the divisor can be fixed. */
#define portCLOCK_DIVISOR 8UL
@ -65,7 +65,7 @@
/* Keys required to lock and unlock access to certain system registers
* respectively. */
respectively. */
#define portUNLOCK_KEY 0xA50B
#define portLOCK_KEY 0xA500
@ -91,9 +91,8 @@ __interrupt static void prvTickISR( void );
*/
static void prvSetupTimerInterrupt( void );
#ifndef configSETUP_TICK_INTERRUPT
/* The user has not provided their own tick interrupt configuration so use
* the definition in this file (which uses the interval timer). */
/* The user has not provided their own tick interrupt configuration so use
the definition in this file (which uses the interval timer). */
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
#endif /* configSETUP_TICK_INTERRUPT */
@ -108,7 +107,7 @@ static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
extern void * pxCurrentTCB;
extern void *pxCurrentTCB;
/*-----------------------------------------------------------*/
@ -117,35 +116,33 @@ static const uint32_t ulMatchValueForOneTick = ( ( configPERIPHERAL_CLOCK_HZ / p
#if configUSE_TICKLESS_IDLE == 1
/* Holds the maximum number of ticks that can be suppressed - which is
* basically how far into the future an interrupt can be generated. Set
* during initialisation. This is the maximum possible value that the
* compare match register can hold divided by ulMatchValueForOneTick. */
/* Holds the maximum number of ticks that can be suppressed - which is
basically how far into the future an interrupt can be generated. Set
during initialisation. This is the maximum possible value that the
compare match register can hold divided by ulMatchValueForOneTick. */
static const TickType_t xMaximumPossibleSuppressedTicks = USHRT_MAX / ( ( configPERIPHERAL_CLOCK_HZ / portCLOCK_DIVISOR ) / configTICK_RATE_HZ );
/* Flag set from the tick interrupt to allow the sleep processing to know if
* sleep mode was exited because of a tick interrupt, or an interrupt
* generated by something else. */
/* Flag set from the tick interrupt to allow the sleep processing to know if
sleep mode was exited because of a tick interrupt, or an interrupt
generated by something else. */
static volatile uint32_t ulTickFlag = pdFALSE;
/* The CMT counter is stopped temporarily each time it is re-programmed.
* The following constant offsets the CMT counter match value by the number of
* CMT counts that would typically be missed while the counter was stopped to
* compensate for the lost time. The large difference between the divided CMT
* clock and the CPU clock means it is likely ulStoppedTimerCompensation will
* equal zero - and be optimised away. */
/* The CMT counter is stopped temporarily each time it is re-programmed.
The following constant offsets the CMT counter match value by the number of
CMT counts that would typically be missed while the counter was stopped to
compensate for the lost time. The large difference between the divided CMT
clock and the CPU clock means it is likely ulStoppedTimerCompensation will
equal zero - and be optimised away. */
static const uint32_t ulStoppedTimerCompensation = 100UL / ( configCPU_CLOCK_HZ / ( configPERIPHERAL_CLOCK_HZ / portCLOCK_DIVISOR ) );
#endif /* if configUSE_TICKLESS_IDLE == 1 */
#endif
/*-----------------------------------------------------------*/
/*
* 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 )
{
/* Offset to end up on 8 byte boundary. */
pxTopOfStack--;
@ -160,8 +157,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -194,13 +191,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
/* Leave space for the registers that will get popped from the stack
* when the task first starts executing. */
when the task first starts executing. */
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
@ -218,10 +215,10 @@ BaseType_t xPortStartScheduler( void )
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate
* the tick interrupt. This way the application can decide which
* peripheral to use. If tickless mode is used then the default
* implementation defined in this file (which uses CMT0) should not be
* overridden. */
the tick interrupt. This way the application can decide which
peripheral to use. If tickless mode is used then the default
implementation defined in this file (which uses CMT0) should not be
overridden. */
configSETUP_TICK_INTERRUPT();
/* Enable the software interrupt. */
@ -238,11 +235,11 @@ BaseType_t xPortStartScheduler( void )
}
/* Execution should not reach here as the tasks are now running!
* prvSetupTimerInterrupt() is called here to prevent the compiler outputting
* a warning about a statically declared function not being referenced in the
* case that the application writer has provided their own tick interrupt
* configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
* their own routine will be called in place of prvSetupTimerInterrupt()). */
prvSetupTimerInterrupt() is called here to prevent the compiler outputting
a warning about a statically declared function not being referenced in the
case that the application writer has provided their own tick interrupt
configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
their own routine will be called in place of prvSetupTimerInterrupt()). */
prvSetupTimerInterrupt();
/* Should not get here. */
@ -257,7 +254,7 @@ __interrupt static void prvTickISR( void )
__enable_interrupt();
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
__set_interrupt_level( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -273,7 +270,7 @@ __interrupt static void prvTickISR( void )
ulTickFlag = pdTRUE;
/* If this is the first tick since exiting tickless mode then the CMT
* compare match value needs resetting. */
compare match value needs resetting. */
CMT0.CMCOR = ( uint16_t ) ulMatchValueForOneTick;
}
#endif
@ -283,7 +280,7 @@ __interrupt static void prvTickISR( void )
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
}
/*-----------------------------------------------------------*/
@ -322,11 +319,11 @@ static void prvSetupTimerInterrupt( void )
{
CMT0.CMCR.BIT.CKS = 0;
}
#else /* if portCLOCK_DIVISOR == 512 */
#else
{
#error Invalid portCLOCK_DIVISOR setting
}
#endif /* if portCLOCK_DIVISOR == 512 */
#endif
/* Enable the interrupt... */
@ -348,8 +345,8 @@ static void prvSetupTimerInterrupt( void )
configPRE_SLEEP_PROCESSING( xExpectedIdleTime );
/* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING()
* means the application defined code has already executed the WAIT
* instruction. */
means the application defined code has already executed the WAIT
instruction. */
if( xExpectedIdleTime > 0 )
{
__wait_for_interrupt();
@ -378,41 +375,38 @@ static void prvSetupTimerInterrupt( void )
}
/* Calculate the reload value required to wait xExpectedIdleTime tick
* periods. */
periods. */
ulMatchValue = ulMatchValueForOneTick * xExpectedIdleTime;
if( ulMatchValue > ulStoppedTimerCompensation )
{
/* Compensate for the fact that the CMT is going to be stopped
* momentarily. */
momentarily. */
ulMatchValue -= ulStoppedTimerCompensation;
}
/* Stop the CMT momentarily. The time the CMT is stopped for is
* accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
CMT.CMSTR0.BIT.STR0 = 0;
while( CMT.CMSTR0.BIT.STR0 == 1 )
{
/* Nothing to do here. */
}
/* Critical section using the global interrupt bit as the i bit is
* automatically reset by the WAIT instruction. */
automatically reset by the WAIT instruction. */
__disable_interrupt();
/* The tick flag is set to false before sleeping. If it is true when
* sleep mode is exited then sleep mode was probably exited because the
* tick was suppressed for the entire xExpectedIdleTime period. */
sleep mode is exited then sleep mode was probably exited because the
tick was suppressed for the entire xExpectedIdleTime period. */
ulTickFlag = pdFALSE;
/* If a context switch is pending then abandon the low power entry as
* the context switch might have been pended by an external interrupt that
* requires processing. */
the context switch might have been pended by an external interrupt that
requires processing. */
eSleepAction = eTaskConfirmSleepModeStatus();
if( eSleepAction == eAbortSleep )
{
/* Restart tick. */
@ -431,7 +425,7 @@ static void prvSetupTimerInterrupt( void )
SYSTEM.PRCR.WORD = portLOCK_KEY;
/* Sleep until something happens. Calling prvSleep() will
* automatically reset the i bit in the PSW. */
automatically reset the i bit in the PSW. */
prvSleep( xExpectedIdleTime );
/* Restart the CMT. */
@ -451,7 +445,7 @@ static void prvSetupTimerInterrupt( void )
SYSTEM.PRCR.WORD = portLOCK_KEY;
/* Adjust the match value to take into account that the current
* time slice is already partially complete. */
time slice is already partially complete. */
ulMatchValue -= ( uint32_t ) CMT0.CMCNT;
CMT0.CMCOR = ( uint16_t ) ulMatchValue;
@ -460,15 +454,14 @@ static void prvSetupTimerInterrupt( void )
CMT.CMSTR0.BIT.STR0 = 1;
/* Sleep until something happens. Calling prvSleep() will
* automatically reset the i bit in the PSW. */
automatically reset the i bit in the PSW. */
prvSleep( xExpectedIdleTime );
/* Stop CMT. Again, the time the SysTick is stopped for is
* accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
CMT.CMSTR0.BIT.STR0 = 0;
while( CMT.CMSTR0.BIT.STR0 == 1 )
{
/* Nothing to do here. */
@ -479,44 +472,45 @@ static void prvSetupTimerInterrupt( void )
if( ulTickFlag != pdFALSE )
{
/* The tick interrupt has already executed, although because
* this function is called with the scheduler suspended the actual
* tick processing will not occur until after this function has
* exited. Reset the match value with whatever remains of this
* tick period. */
this function is called with the scheduler suspended the actual
tick processing will not occur until after this function has
exited. Reset the match value with whatever remains of this
tick period. */
ulMatchValue = ulMatchValueForOneTick - ulCurrentCount;
CMT0.CMCOR = ( uint16_t ) ulMatchValue;
/* The tick interrupt handler will already have pended the tick
* processing in the kernel. As the pending tick will be
* processed as soon as this function exits, the tick value
* maintained by the tick is stepped forward by one less than the
* time spent sleeping. The actual stepping of the tick appears
* later in this function. */
processing in the kernel. As the pending tick will be
processed as soon as this function exits, the tick value
maintained by the tick is stepped forward by one less than the
time spent sleeping. The actual stepping of the tick appears
later in this function. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
}
else
{
/* Something other than the tick interrupt ended the sleep.
* How many complete tick periods passed while the processor was
* sleeping? */
How many complete tick periods passed while the processor was
sleeping? */
ulCompleteTickPeriods = ulCurrentCount / ulMatchValueForOneTick;
/* The match value is set to whatever fraction of a single tick
* period remains. */
period remains. */
ulMatchValue = ulCurrentCount - ( ulCompleteTickPeriods * ulMatchValueForOneTick );
CMT0.CMCOR = ( uint16_t ) ulMatchValue;
}
/* Restart the CMT so it runs up to the match value. The match value
* will get set to the value required to generate exactly one tick period
* the next time the CMT interrupt executes. */
will get set to the value required to generate exactly one tick period
the next time the CMT interrupt executes. */
CMT0.CMCNT = 0;
CMT.CMSTR0.BIT.STR0 = 1;
/* Wind the tick forward by the number of tick periods that the CPU
* remained in a low power state. */
remained in a low power state. */
vTaskStepTick( ulCompleteTickPeriods );
}
}
#endif /* configUSE_TICKLESS_IDLE */

View file

@ -27,16 +27,16 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Hardware specifics. */
#include "machine.h"
#include "machine.h"
/*-----------------------------------------------------------
* Port specific definitions.
@ -49,101 +49,102 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() __no_operation()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() __no_operation()
#define portYIELD() \
#define portYIELD() \
__asm volatile \
( \
"MOV.L #0x872E0, R15 \n"\
"MOV.B #1, [R15] \n"\
"MOV.L [R15], R15 \n"\
"MOV.L #0x872E0, R15 \n" \
"MOV.B #1, [R15] \n" \
"MOV.L [R15], R15 \n" \
::: "R15" \
)
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) { portYIELD(); }
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) { portYIELD(); }
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 )
#ifdef configASSERT
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#else
#define portDISABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_level(); portDISABLE_INTERRUPTS()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) __set_interrupt_level( ( uint8_t ) ( uxSavedInterruptStatus ) )
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_level(); portDISABLE_INTERRUPTS()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) __set_interrupt_level( ( uint8_t ) ( uxSavedInterruptStatus ) )
/* Tickless idle/low power functionality. */
#if configUSE_TICKLESS_IDLE == 1
#if configUSE_TICKLESS_IDLE == 1
#ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif
#endif
#endif
/*-----------------------------------------------------------*/
/* 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 )
/* Prevent warnings of undefined behaviour: the order of volatile accesses is
* undefined - all warnings have been manually checked and are not an issue, and
* the warnings cannot be prevent by code changes without undesirable effects. */
#pragma diag_suppress=Pa082
undefined - all warnings have been manually checked and are not an issue, and
the warnings cannot be prevent by code changes without undesirable effects. */
#pragma diag_suppress=Pa082
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -26,8 +26,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the SH2A port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the SH2A port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
@ -42,7 +42,7 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
@ -62,16 +62,14 @@ __interrupt void vTickISR( void );
/*-----------------------------------------------------------*/
extern void * pxCurrentTCB;
extern void *pxCurrentTCB;
/*-----------------------------------------------------------*/
/*
* 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 )
{
/* R0 is not included as it is the stack pointer. */
@ -82,8 +80,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -116,11 +114,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
@ -136,14 +134,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vApplicationSetupTimerInterrupt( void );
extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */
tick interrupt. This way the application can decide which peripheral to
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */
@ -171,7 +169,7 @@ __interrupt void vTickISR( void )
__enable_interrupt();
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
__set_interrupt_level( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -186,7 +184,10 @@ __interrupt void vTickISR( void )
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
}
/*-----------------------------------------------------------*/

View file

@ -27,13 +27,13 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -46,93 +46,94 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() __no_operation()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() __no_operation()
/* Yield equivalent to "*portITU_SWINTR = 0x01; ( void ) *portITU_SWINTR;"
* where portITU_SWINTR is the location of the software interrupt register
* (0x000872E0). Don't rely on the assembler to select a register, so instead
* save and restore clobbered registers manually. */
#define portYIELD() \
where portITU_SWINTR is the location of the software interrupt register
(0x000872E0). Don't rely on the assembler to select a register, so instead
save and restore clobbered registers manually. */
#define portYIELD() \
__asm volatile \
( \
"PUSH.L R10 \n"\
"MOV.L #0x872E0, R10 \n"\
"MOV.B #0x1, [R10] \n"\
"MOV.L [R10], R10 \n"\
"POP R10 \n"\
"PUSH.L R10 \n" \
"MOV.L #0x872E0, R10 \n" \
"MOV.B #0x1, [R10] \n" \
"MOV.L [R10], R10 \n" \
"POP R10 \n" \
)
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) portYIELD()
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) portYIELD()
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 )
#ifdef configASSERT
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#else
#define portDISABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_level(); portDISABLE_INTERRUPTS()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) __set_interrupt_level( ( uint8_t ) ( uxSavedInterruptStatus ) )
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_level(); portDISABLE_INTERRUPTS()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) __set_interrupt_level( ( uint8_t ) ( uxSavedInterruptStatus ) )
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -26,8 +26,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the SH2A port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the SH2A port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
@ -42,7 +42,7 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
@ -62,16 +62,14 @@ __interrupt void vTickISR( void );
/*-----------------------------------------------------------*/
extern void * pxCurrentTCB;
extern void *pxCurrentTCB;
/*-----------------------------------------------------------*/
/*
* 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 )
{
/* R0 is not included as it is the stack pointer. */
@ -82,8 +80,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -116,11 +114,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
@ -144,14 +142,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vApplicationSetupTimerInterrupt( void );
extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */
tick interrupt. This way the application can decide which peripheral to
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */
@ -179,7 +177,7 @@ __interrupt void vTickISR( void )
__enable_interrupt();
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
__set_interrupt_level( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -194,7 +192,10 @@ __interrupt void vTickISR( void )
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
}
/*-----------------------------------------------------------*/

View file

@ -27,13 +27,13 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -46,98 +46,99 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() __no_operation()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() __no_operation()
/* Yield equivalent to "*portITU_SWINTR = 0x01; ( void ) *portITU_SWINTR;"
* where portITU_SWINTR is the location of the software interrupt register
* (0x000872E0). Don't rely on the assembler to select a register, so instead
* save and restore clobbered registers manually. */
#define portYIELD() \
where portITU_SWINTR is the location of the software interrupt register
(0x000872E0). Don't rely on the assembler to select a register, so instead
save and restore clobbered registers manually. */
#define portYIELD() \
__asm volatile \
( \
"PUSH.L R10 \n"\
"MOV.L #0x872E0, R10 \n"\
"MOV.B #0x1, [R10] \n"\
"MOV.L [R10], R10 \n"\
"POP R10 \n"\
"PUSH.L R10 \n" \
"MOV.L #0x872E0, R10 \n" \
"MOV.B #0x1, [R10] \n" \
"MOV.L [R10], R10 \n" \
"POP R10 \n" \
)
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) portYIELD()
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) portYIELD()
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 )
#ifdef configASSERT
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( __get_interrupt_level() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( __get_interrupt_level() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#else
#define portDISABLE_INTERRUPTS() __set_interrupt_level( ( uint8_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_level(); portDISABLE_INTERRUPTS()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) __set_interrupt_level( ( uint8_t ) ( uxSavedInterruptStatus ) )
#define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_level(); portDISABLE_INTERRUPTS()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) __set_interrupt_level( ( uint8_t ) ( uxSavedInterruptStatus ) )
/*-----------------------------------------------------------*/
/* 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 )
/* Prevent warnings of undefined behaviour: the order of volatile accesses is
* undefined - all warnings have been manually checked and are not an issue, and
* the warnings cannot be prevent by code changes without undesirable effects. */
#pragma diag_suppress=Pa082
undefined - all warnings have been manually checked and are not an issue, and
the warnings cannot be prevent by code changes without undesirable effects. */
#pragma diag_suppress=Pa082
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,123 +1,105 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
;
Push R0 as we are going to use the register.
STMDB SP !, { R0 }
; Push R0 as we are going to use the register.
STMDB SP!, {R0}
;
Set R0 to point to the task stack pointer.
STMDB SP, { SP } ^
NOP
SUB SP, SP, # 4
LDMIA SP !, { R0 }
; Set R0 to point to the task stack pointer.
STMDB SP, {SP}^
NOP
SUB SP, SP, #4
LDMIA SP!, {R0}
;
Push the return address onto the stack.
STMDB R0 !, { LR }
; Push the return address onto the stack.
STMDB R0!, {LR}
;
Now we have saved LR we can use it instead of R0.
; Now we have saved LR we can use it instead of R0.
MOV LR, R0
;
Pop R0 so we can save it onto the system mode stack.
LDMIA SP !, { R0 }
; Pop R0 so we can save it onto the system mode stack.
LDMIA SP!, {R0}
;
Push all the system mode registers onto the task stack.
STMDB LR, { R0 - LR } ^
NOP
SUB LR, LR, # 60
; Push all the system mode registers onto the task stack.
STMDB LR, {R0-LR}^
NOP
SUB LR, LR, #60
;
Push the SPSR onto the task stack.
; Push the SPSR onto the task stack.
MRS R0, SPSR
STMDB LR !, { R0 }
STMDB LR!, {R0}
LDR R0, = ulCriticalNesting
LDR R0, [ R0 ]
STMDB LR !, { R0 }
LDR R0, =ulCriticalNesting
LDR R0, [R0]
STMDB LR!, {R0}
;
Store the new top of stack for the task.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
STR LR, [ R0 ]
; Store the new top of stack for the task.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
STR LR, [R0]
ENDM
ENDM
portRESTORE_CONTEXT MACRO
;
Set the LR to the task stack.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
LDR LR, [ R0 ]
; Set the LR to the task stack.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
LDR LR, [R0]
;
The critical nesting depth is the first item on the stack.
;
Load it into the ulCriticalNesting variable.
LDR R0, = ulCriticalNesting
LDMFD LR !, { R1 }
STR R1, [ R0 ]
; The critical nesting depth is the first item on the stack.
; Load it into the ulCriticalNesting variable.
LDR R0, =ulCriticalNesting
LDMFD LR!, {R1}
STR R1, [R0]
;
Get the SPSR from the stack.
LDMFD LR !, { R0 }
MSR SPSR_cxsf, R0
; Get the SPSR from the stack.
LDMFD LR!, {R0}
MSR SPSR_cxsf, R0
;
Restore all system mode registers for the task.
LDMFD LR, { R0 - R14 } ^
NOP
; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^
NOP
;
Restore the return address.
LDR LR, [ LR, # + 60 ]
; Restore the return address.
LDR LR, [LR, #+60]
;
; And return - correcting the offset in the LR to obtain the
; correct address.
SUBS PC, LR, #4
And return -correcting the offset in the LR to obtain the
;
ENDM
correct address.
SUBS PC, LR, # 4
ENDM

View file

@ -26,9 +26,9 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ST STR71x ARM7
* port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the ST STR71x ARM7
* port.
*----------------------------------------------------------*/
/* Library includes. */
#include "wdg.h"
@ -57,13 +57,13 @@
static void prvSetupTimerInterrupt( void );
/* ulCriticalNesting will get set to zero when the first task starts. It
* cannot be initialised to 0 as this will cause interrupts to be enabled
* during the kernel initialisation process. */
cannot be initialised to 0 as this will cause interrupts to be enabled
during the kernel initialisation process. */
uint32_t ulCriticalNesting = ( uint32_t ) 9999;
/* Tick interrupt routines for cooperative and preemptive operation
* respectively. The preemptive version is not defined as __irq as it is called
* from an asm wrapper function. */
respectively. The preemptive version is not defined as __irq as it is called
from an asm wrapper function. */
__arm __irq void vPortNonPreemptiveTick( void );
void vPortPreemptiveTick( void );
@ -75,24 +75,22 @@ void vPortPreemptiveTick( 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 * pxOriginalTOS;
StackType_t *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert
* is not really required. */
is not really required. */
pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
* start of the task. The offset is added to make the return address appear
* as it would within an IRQ ISR. */
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
@ -126,7 +124,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R0. */
R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--;
@ -142,8 +140,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
* instead be stored in a variable, which is then saved as part of the
* tasks context. */
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
@ -152,10 +150,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void vPortStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -169,17 +167,17 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/* The cooperative scheduler requires a normal IRQ service routine to
* simply increment the system tick. */
simply increment the system tick. */
__arm __irq void vPortNonPreemptiveTick( void )
{
/* Increment the tick count - which may wake some tasks but as the
* preemptive scheduler is not being used any woken task is not given
* processor time no matter what its priority. */
preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */
xTaskIncrementTick();
/* Clear the interrupt in the watchdog and EIC. */
@ -189,7 +187,7 @@ __arm __irq void vPortNonPreemptiveTick( void )
/*-----------------------------------------------------------*/
/* This function is called from an asm wrapper, so does not require the __irq
* keyword. */
keyword. */
void vPortPreemptiveTick( void )
{
/* Increment the tick counter. */
@ -219,7 +217,7 @@ static void prvSetupTimerInterrupt( void )
WDG_ECITConfig( ENABLE );
/* Start the timer - interrupts are actually disabled at this point so
* it is safe to do this here. */
it is safe to do this here. */
WDG_CntOnOffConfig( ENABLE );
}
/*-----------------------------------------------------------*/
@ -230,8 +228,8 @@ __arm __interwork void vPortEnterCritical( void )
__disable_interrupt();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -244,7 +242,7 @@ __arm __interwork void vPortExitCritical( void )
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
* re-enabled. */
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
__enable_interrupt();
@ -252,3 +250,9 @@ __arm __interwork void vPortExitCritical( void )
}
}
/*-----------------------------------------------------------*/

View file

@ -27,7 +27,7 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/*-----------------------------------------------------------
* Port specific definitions.
@ -39,81 +39,83 @@
*-----------------------------------------------------------
*/
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
__arm __interwork void vPortDisableInterruptsFromThumb( void );
__arm __interwork void vPortEnableInterruptsFromThumb( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
}
/*-----------------------------------------------------------*/
/* EIC utilities. */
#define portEIC_CICR_ADDR *( ( uint32_t * ) 0xFFFFF804 )
#define portEIC_IPR_ADDR *( ( uint32_t * ) 0xFFFFF840 )
#define portCLEAR_EIC() portEIC_IPR_ADDR = 0x01 << portEIC_CICR_ADDR
#define portEIC_CICR_ADDR *( ( uint32_t * ) 0xFFFFF804 )
#define portEIC_IPR_ADDR *( ( uint32_t * ) 0xFFFFF840 )
#define portCLEAR_EIC() portEIC_IPR_ADDR = 0x01 << portEIC_CICR_ADDR
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,123 +1,105 @@
; /*
* ; * FreeRTOS Kernel V10.3.1
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* ; *
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
* ; * this software and associated documentation files (the "Software"), to deal in
* ; * the Software without restriction, including without limitation the rights to
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
* ; * subject to the following conditions:
* ; *
* ; * The above copyright notice and this permission notice shall be included in all
* ; * copies or substantial portions of the Software.
* ; *
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ; *
* ; * http://www.FreeRTOS.org
* ; * http://aws.amazon.com/freertos
* ; *
* ; * 1 tab == 4 spaces!
* ; */
;/*
; * FreeRTOS Kernel V10.3.1
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * http://www.FreeRTOS.org
; * http://aws.amazon.com/freertos
; *
; * 1 tab == 4 spaces!
; */
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
;
Push R0 as we are going to use the register.
STMDB SP !, { R0 }
; Push R0 as we are going to use the register.
STMDB SP!, {R0}
;
Set R0 to point to the task stack pointer.
STMDB SP, { SP } ^
NOP
SUB SP, SP, # 4
LDMIA SP !, { R0 }
; Set R0 to point to the task stack pointer.
STMDB SP, {SP}^
NOP
SUB SP, SP, #4
LDMIA SP!, {R0}
;
Push the return address onto the stack.
STMDB R0 !, { LR }
; Push the return address onto the stack.
STMDB R0!, {LR}
;
Now we have saved LR we can use it instead of R0.
; Now we have saved LR we can use it instead of R0.
MOV LR, R0
;
Pop R0 so we can save it onto the system mode stack.
LDMIA SP !, { R0 }
; Pop R0 so we can save it onto the system mode stack.
LDMIA SP!, {R0}
;
Push all the system mode registers onto the task stack.
STMDB LR, { R0 - LR } ^
NOP
SUB LR, LR, # 60
; Push all the system mode registers onto the task stack.
STMDB LR, {R0-LR}^
NOP
SUB LR, LR, #60
;
Push the SPSR onto the task stack.
; Push the SPSR onto the task stack.
MRS R0, SPSR
STMDB LR !, { R0 }
STMDB LR!, {R0}
LDR R0, = ulCriticalNesting
LDR R0, [ R0 ]
STMDB LR !, { R0 }
LDR R0, =ulCriticalNesting
LDR R0, [R0]
STMDB LR!, {R0}
;
Store the new top of stack for the task.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
STR LR, [ R0 ]
; Store the new top of stack for the task.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
STR LR, [R0]
ENDM
ENDM
portRESTORE_CONTEXT MACRO
;
Set the LR to the task stack.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
LDR LR, [ R0 ]
; Set the LR to the task stack.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
LDR LR, [R0]
;
The critical nesting depth is the first item on the stack.
;
Load it into the ulCriticalNesting variable.
LDR R0, = ulCriticalNesting
LDMFD LR !, { R1 }
STR R1, [ R0 ]
; The critical nesting depth is the first item on the stack.
; Load it into the ulCriticalNesting variable.
LDR R0, =ulCriticalNesting
LDMFD LR!, {R1}
STR R1, [R0]
;
Get the SPSR from the stack.
LDMFD LR !, { R0 }
MSR SPSR_cxsf, R0
; Get the SPSR from the stack.
LDMFD LR!, {R0}
MSR SPSR_cxsf, R0
;
Restore all system mode registers for the task.
LDMFD LR, { R0 - R14 } ^
NOP
; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^
NOP
;
Restore the return address.
LDR LR, [ LR, # + 60 ]
; Restore the return address.
LDR LR, [LR, #+60]
;
; And return - correcting the offset in the LR to obtain the
; correct address.
SUBS PC, LR, #4
And return -correcting the offset in the LR to obtain the
;
ENDM
correct address.
SUBS PC, LR, # 4
ENDM

View file

@ -26,9 +26,9 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ST STR75x ARM7
* port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the ST STR75x ARM7
* port.
*----------------------------------------------------------*/
/* Library includes. */
#include "75x_tb.h"
@ -55,8 +55,8 @@
static void prvSetupTimerInterrupt( void );
/* ulCriticalNesting will get set to zero when the first task starts. It
* cannot be initialised to 0 as this will cause interrupts to be enabled
* during the kernel initialisation process. */
cannot be initialised to 0 as this will cause interrupts to be enabled
during the kernel initialisation process. */
uint32_t ulCriticalNesting = ( uint32_t ) 9999;
/* Tick interrupt routines for preemptive operation. */
@ -70,24 +70,22 @@ __arm void vPortPreemptiveTick( 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 * pxOriginalTOS;
StackType_t *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert
* is not really required. */
is not really required. */
pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
* start of the task. The offset is added to make the return address appear
* as it would within an IRQ ISR. */
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
@ -121,7 +119,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R0. */
R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--;
@ -130,8 +128,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
* instead be stored in a variable, which is then saved as part of the
* tasks context. */
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
@ -140,10 +138,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void vPortStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -157,7 +155,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
@ -176,30 +174,30 @@ __arm void vPortPreemptiveTick( void )
static void prvSetupTimerInterrupt( void )
{
EIC_IRQInitTypeDef EIC_IRQInitStructure;
TB_InitTypeDef TB_InitStructure;
EIC_IRQInitTypeDef EIC_IRQInitStructure;
TB_InitTypeDef TB_InitStructure;
/* Setup the EIC for the TB. */
EIC_IRQInitStructure.EIC_IRQChannelCmd = ENABLE;
EIC_IRQInitStructure.EIC_IRQChannel = TB_IRQChannel;
EIC_IRQInitStructure.EIC_IRQChannelPriority = 1;
EIC_IRQInit( &EIC_IRQInitStructure );
EIC_IRQInit(&EIC_IRQInitStructure);
/* Setup the TB for the generation of the tick interrupt. */
TB_InitStructure.TB_Mode = TB_Mode_Timing;
TB_InitStructure.TB_CounterMode = TB_CounterMode_Down;
TB_InitStructure.TB_Prescaler = portPRESCALE - 1;
TB_InitStructure.TB_AutoReload = ( ( configCPU_CLOCK_HZ / portPRESCALE ) / configTICK_RATE_HZ );
TB_Init( &TB_InitStructure );
TB_Init(&TB_InitStructure);
/* Enable TB Update interrupt */
TB_ITConfig( TB_IT_Update, ENABLE );
TB_ITConfig(TB_IT_Update, ENABLE);
/* Clear TB Update interrupt pending bit */
TB_ClearITPendingBit( TB_IT_Update );
TB_ClearITPendingBit(TB_IT_Update);
/* Enable TB */
TB_Cmd( ENABLE );
TB_Cmd(ENABLE);
}
/*-----------------------------------------------------------*/
@ -209,8 +207,8 @@ __arm __interwork void vPortEnterCritical( void )
__disable_interrupt();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -223,7 +221,7 @@ __arm __interwork void vPortExitCritical( void )
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
* re-enabled. */
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
__enable_interrupt();
@ -231,3 +229,9 @@ __arm __interwork void vPortExitCritical( void )
}
}
/*-----------------------------------------------------------*/

View file

@ -27,7 +27,7 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/*-----------------------------------------------------------
* Port specific definitions.
@ -39,72 +39,74 @@
*-----------------------------------------------------------
*/
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
}
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -25,99 +25,81 @@
* 1 tab == 4 spaces!
*/
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
EXTERN pxCurrentTCB
EXTERN ulCriticalNesting
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
;
Push R0 as we are going to use the register.
STMDB SP !, { R0 }
; Push R0 as we are going to use the register.
STMDB SP!, {R0}
;
Set R0 to point to the task stack pointer.
STMDB SP, { SP } ^
NOP
SUB SP, SP, # 4
LDMIA SP !, { R0 }
; Set R0 to point to the task stack pointer.
STMDB SP, {SP}^
NOP
SUB SP, SP, #4
LDMIA SP!, {R0}
;
Push the return address onto the stack.
STMDB R0 !, { LR }
; Push the return address onto the stack.
STMDB R0!, {LR}
;
Now we have saved LR we can use it instead of R0.
; Now we have saved LR we can use it instead of R0.
MOV LR, R0
;
Pop R0 so we can save it onto the system mode stack.
LDMIA SP !, { R0 }
; Pop R0 so we can save it onto the system mode stack.
LDMIA SP!, {R0}
;
Push all the system mode registers onto the task stack.
STMDB LR, { R0 - LR } ^
NOP
SUB LR, LR, # 60
; Push all the system mode registers onto the task stack.
STMDB LR, {R0-LR}^
NOP
SUB LR, LR, #60
;
Push the SPSR onto the task stack.
; Push the SPSR onto the task stack.
MRS R0, SPSR
STMDB LR !, { R0 }
STMDB LR!, {R0}
LDR R0, = ulCriticalNesting
LDR R0, [ R0 ]
STMDB LR !, { R0 }
LDR R0, =ulCriticalNesting
LDR R0, [R0]
STMDB LR!, {R0}
;
Store the new top of stack for the task.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
STR LR, [ R0 ]
; Store the new top of stack for the task.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
STR LR, [R0]
ENDM
ENDM
portRESTORE_CONTEXT MACRO
;
Set the LR to the task stack.
LDR R1, = pxCurrentTCB
LDR R0, [ R1 ]
LDR LR, [ R0 ]
; Set the LR to the task stack.
LDR R1, =pxCurrentTCB
LDR R0, [R1]
LDR LR, [R0]
;
The critical nesting depth is the first item on the stack.
;
Load it into the ulCriticalNesting variable.
LDR R0, = ulCriticalNesting
LDMFD LR !, { R1 }
STR R1, [ R0 ]
; The critical nesting depth is the first item on the stack.
; Load it into the ulCriticalNesting variable.
LDR R0, =ulCriticalNesting
LDMFD LR!, {R1}
STR R1, [R0]
;
Get the SPSR from the stack.
LDMFD LR !, { R0 }
MSR SPSR_cxsf, R0
; Get the SPSR from the stack.
LDMFD LR!, {R0}
MSR SPSR_cxsf, R0
;
Restore all system mode registers for the task.
LDMFD LR, { R0 - R14 } ^
NOP
; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^
NOP
;
Restore the return address.
LDR LR, [ LR, # + 60 ]
; Restore the return address.
LDR LR, [LR, #+60]
;
; And return - correcting the offset in the LR to obtain the
; correct address.
SUBS PC, LR, #4
And return -correcting the offset in the LR to obtain the
;
ENDM
correct address.
SUBS PC, LR, # 4
ENDM

View file

@ -26,9 +26,9 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ST STR91x ARM9
* port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the ST STR91x ARM9
* port.
*----------------------------------------------------------*/
/* Library includes. */
#include "91x_lib.h"
@ -58,7 +58,7 @@
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
#ifndef abs
#define abs( x ) ( ( x ) > 0 ? ( x ) : -( x ) )
#define abs(x) ((x)>0 ? (x) : -(x))
#endif
/**
@ -73,14 +73,14 @@
* }
*
*/
#define TOGGLE_LED( port, pin ) \
if( ( ( ( ( port )->DR[ ( pin ) << 2 ] ) ) & ( pin ) ) != Bit_RESET ) \
#define TOGGLE_LED(port,pin) \
if ( ((((port)->DR[(pin)<<2])) & (pin)) != Bit_RESET ) \
{ \
( port )->DR[ ( pin ) << 2 ] = 0x00; \
(port)->DR[(pin) <<2] = 0x00; \
} \
else \
{ \
( port )->DR[ ( pin ) << 2 ] = ( pin ); \
(port)->DR[(pin) <<2] = (pin); \
}
@ -90,13 +90,13 @@
static void prvSetupTimerInterrupt( void );
/* ulCriticalNesting will get set to zero when the first task starts. It
* cannot be initialised to 0 as this will cause interrupts to be enabled
* during the kernel initialisation process. */
cannot be initialised to 0 as this will cause interrupts to be enabled
during the kernel initialisation process. */
uint32_t ulCriticalNesting = ( uint32_t ) 9999;
/* Tick interrupt routines for cooperative and preemptive operation
* respectively. The preemptive version is not defined as __irq as it is called
* from an asm wrapper function. */
respectively. The preemptive version is not defined as __irq as it is called
from an asm wrapper function. */
void WDG_IRQHandler( void );
/* VIC interrupt default handler. */
@ -115,24 +115,22 @@ static void prvDefaultHandler( 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 * pxOriginalTOS;
StackType_t *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert
* is not really required. */
is not really required. */
pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
* start of the task. The offset is added to make the return address appear
* as it would within an IRQ ISR. */
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
@ -166,7 +164,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
* R0. */
R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--;
@ -175,8 +173,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
* instead be stored in a variable, which is then saved as part of the
* tasks context. */
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
@ -185,10 +183,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void vPortStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
* here already. */
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
@ -202,49 +200,41 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
* is nothing to return to. */
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/* This function is called from an asm wrapper, so does not require the __irq
* keyword. */
keyword. */
#if configUSE_WATCHDOG_TICK == 1
static void prvFindFactors( u32 n,
u16 * a,
u32 * b )
static void prvFindFactors(u32 n, u16 *a, u32 *b)
{
/* This function is copied from the ST STR7 library and is
* copyright STMicroelectronics. Reproduced with permission. */
copyright STMicroelectronics. Reproduced with permission. */
u32 b0;
u16 a0;
int32_t err, err_min = n;
int32_t err, err_min=n;
*a = a0 = ( ( n - 1 ) / 65536ul ) + 1;
*a = a0 = ((n-1)/65536ul) + 1;
*b = b0 = n / *a;
for( ; *a <= 256; ( *a )++ )
for (; *a <= 256; (*a)++)
{
*b = n / *a;
err = ( int32_t ) *a * ( int32_t ) *b - ( int32_t ) n;
if( abs( err ) > ( *a / 2 ) )
err = (int32_t)*a * (int32_t)*b - (int32_t)n;
if (abs(err) > (*a / 2))
{
( *b )++;
err = ( int32_t ) *a * ( int32_t ) *b - ( int32_t ) n;
(*b)++;
err = (int32_t)*a * (int32_t)*b - (int32_t)n;
}
if( abs( err ) < abs( err_min ) )
if (abs(err) < abs(err_min))
{
err_min = err;
a0 = *a;
b0 = *b;
if( err == 0 )
{
break;
}
if (err == 0) break;
}
}
@ -260,16 +250,16 @@ void vPortEndScheduler( void )
uint32_t n = configCPU_PERIPH_HZ / configTICK_RATE_HZ, b;
/* Configure the watchdog as a free running timer that generates a
* periodic interrupt. */
periodic interrupt. */
SCU_APBPeriphClockConfig( __WDG, ENABLE );
WDG_DeInit();
WDG_StructInit( &xWdg );
WDG_StructInit(&xWdg);
prvFindFactors( n, &a, &b );
xWdg.WDG_Prescaler = a - 1;
xWdg.WDG_Preload = b - 1;
WDG_Init( &xWdg );
WDG_ITConfig( ENABLE );
WDG_ITConfig(ENABLE);
/* Configure the VIC for the WDG interrupt. */
VIC_Config( WDG_ITLine, VIC_IRQ, 10 );
@ -279,7 +269,7 @@ void vPortEndScheduler( void )
VIC0->DVAR = ( uint32_t ) prvDefaultHandler;
VIC1->DVAR = ( uint32_t ) prvDefaultHandler;
WDG_Cmd( ENABLE );
WDG_Cmd(ENABLE);
}
/*-----------------------------------------------------------*/
@ -298,44 +288,36 @@ void vPortEndScheduler( void )
}
}
#else /* if configUSE_WATCHDOG_TICK == 1 */
#else
static void prvFindFactors( u32 n,
u8 * a,
u16 * b )
static void prvFindFactors(u32 n, u8 *a, u16 *b)
{
/* This function is copied from the ST STR7 library and is
* copyright STMicroelectronics. Reproduced with permission. */
copyright STMicroelectronics. Reproduced with permission. */
u16 b0;
u8 a0;
int32_t err, err_min = n;
int32_t err, err_min=n;
*a = a0 = ( ( n - 1 ) / 256 ) + 1;
*a = a0 = ((n-1)/256) + 1;
*b = b0 = n / *a;
for( ; *a <= 256; ( *a )++ )
for (; *a <= 256; (*a)++)
{
*b = n / *a;
err = ( int32_t ) *a * ( int32_t ) *b - ( int32_t ) n;
if( abs( err ) > ( *a / 2 ) )
err = (int32_t)*a * (int32_t)*b - (int32_t)n;
if (abs(err) > (*a / 2))
{
( *b )++;
err = ( int32_t ) *a * ( int32_t ) *b - ( int32_t ) n;
(*b)++;
err = (int32_t)*a * (int32_t)*b - (int32_t)n;
}
if( abs( err ) < abs( err_min ) )
if (abs(err) < abs(err_min))
{
err_min = err;
a0 = *a;
b0 = *b;
if( err == 0 )
{
break;
}
if (err == 0) break;
}
}
@ -353,20 +335,20 @@ void vPortEndScheduler( void )
TIM_InitTypeDef timer;
SCU_APBPeriphClockConfig( __TIM23, ENABLE );
TIM_DeInit( TIM2 );
TIM_StructInit( &timer );
TIM_DeInit(TIM2);
TIM_StructInit(&timer);
prvFindFactors( n, &a, &b );
timer.TIM_Mode = TIM_OCM_CHANNEL_1;
timer.TIM_OC1_Modes = TIM_TIMING;
timer.TIM_Clock_Source = TIM_CLK_APB;
timer.TIM_Clock_Edge = TIM_CLK_EDGE_RISING;
timer.TIM_Prescaler = a - 1;
timer.TIM_Prescaler = a-1;
timer.TIM_Pulse_Level_1 = TIM_HIGH;
timer.TIM_Pulse_Length_1 = s_nPulseLength = b - 1;
timer.TIM_Pulse_Length_1 = s_nPulseLength = b-1;
TIM_Init( TIM2, &timer );
TIM_ITConfig( TIM2, TIM_IT_OC1, ENABLE );
TIM_Init (TIM2, &timer);
TIM_ITConfig(TIM2, TIM_IT_OC1, ENABLE);
/* Configure the VIC for the WDG interrupt. */
VIC_Config( TIM2_ITLine, VIC_IRQ, 10 );
VIC_ITCmd( TIM2_ITLine, ENABLE );
@ -375,8 +357,8 @@ void vPortEndScheduler( void )
VIC0->DVAR = ( uint32_t ) prvDefaultHandler;
VIC1->DVAR = ( uint32_t ) prvDefaultHandler;
TIM_CounterCmd( TIM2, TIM_CLEAR );
TIM_CounterCmd( TIM2, TIM_START );
TIM_CounterCmd(TIM2, TIM_CLEAR);
TIM_CounterCmd(TIM2, TIM_START);
}
/*-----------------------------------------------------------*/
@ -406,8 +388,8 @@ __arm __interwork void vPortEnterCritical( void )
portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
@ -420,7 +402,7 @@ __arm __interwork void vPortExitCritical( void )
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
* re-enabled. */
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
portENABLE_INTERRUPTS();
@ -432,3 +414,8 @@ __arm __interwork void vPortExitCritical( void )
static void prvDefaultHandler( void )
{
}

View file

@ -27,7 +27,7 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/*-----------------------------------------------------------
* Port specific definitions.
@ -39,74 +39,76 @@
*-----------------------------------------------------------
*/
#include <intrinsics.h>
#include <intrinsics.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm ( "SWI 0" )
#define portNOP() asm ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
__arm __interwork void vPortEnterCritical( void );
__arm __interwork void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
#define portDISABLE_INTERRUPTS() __disable_interrupt()
#define portENABLE_INTERRUPTS() __enable_interrupt()
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
}
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -25,142 +25,125 @@
* 1 tab == 4 spaces!
*/
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
#include "FreeRTOSConfig.h"
;
Context save and restore macro definitions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Context save and restore macro definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
portSAVE_CONTEXT MACRO
add - 0x0C, sp;
prepare stack to save necessary values
st.w lp, 8[ sp ];
store LP to stack
stsr 0, r31
st.w lp, 4[ sp ];
store EIPC to stack
stsr 1, lp
st.w lp, 0[ sp ];
store EIPSW to stack
#if configDATA_MODE == 1; Using the Tiny data model
prepare { r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30 }, 76, sp;
save general purpose registers
sst.w r19, 72[ ep ]
sst.w r18, 68[ ep ]
sst.w r17, 64[ ep ]
sst.w r16, 60[ ep ]
sst.w r15, 56[ ep ]
sst.w r14, 52[ ep ]
sst.w r13, 48[ ep ]
sst.w r12, 44[ ep ]
sst.w r11, 40[ ep ]
sst.w r10, 36[ ep ]
sst.w r9, 32[ ep ]
sst.w r8, 28[ ep ]
sst.w r7, 24[ ep ]
sst.w r6, 20[ ep ]
sst.w r5, 16[ ep ]
sst.w r4, 12[ ep ]
#else; Using the Small / Large data model
prepare { r20, r21, r22, r23, r24, r26, r27, r28, r29, r30 }, 72, sp;
save general purpose registers
sst.w r19, 68[ ep ]
sst.w r18, 64[ ep ]
sst.w r17, 60[ ep ]
sst.w r16, 56[ ep ]
sst.w r15, 52[ ep ]
sst.w r14, 48[ ep ]
sst.w r13, 44[ ep ]
sst.w r12, 40[ ep ]
sst.w r11, 36[ ep ]
sst.w r10, 32[ ep ]
sst.w r9, 28[ ep ]
sst.w r8, 24[ ep ]
sst.w r7, 20[ ep ]
sst.w r6, 16[ ep ]
sst.w r5, 12[ ep ]
add -0x0C,sp ; prepare stack to save necessary values
st.w lp,8[sp] ; store LP to stack
stsr 0,r31
st.w lp,4[sp] ; store EIPC to stack
stsr 1,lp
st.w lp,0[sp] ; store EIPSW to stack
#if configDATA_MODE == 1 ; Using the Tiny data model
prepare {r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30},76,sp ; save general purpose registers
sst.w r19,72[ep]
sst.w r18,68[ep]
sst.w r17,64[ep]
sst.w r16,60[ep]
sst.w r15,56[ep]
sst.w r14,52[ep]
sst.w r13,48[ep]
sst.w r12,44[ep]
sst.w r11,40[ep]
sst.w r10,36[ep]
sst.w r9,32[ep]
sst.w r8,28[ep]
sst.w r7,24[ep]
sst.w r6,20[ep]
sst.w r5,16[ep]
sst.w r4,12[ep]
#else ; Using the Small/Large data model
prepare {r20,r21,r22,r23,r24,r26,r27,r28,r29,r30},72,sp ; save general purpose registers
sst.w r19,68[ep]
sst.w r18,64[ep]
sst.w r17,60[ep]
sst.w r16,56[ep]
sst.w r15,52[ep]
sst.w r14,48[ep]
sst.w r13,44[ep]
sst.w r12,40[ep]
sst.w r11,36[ep]
sst.w r10,32[ep]
sst.w r9,28[ep]
sst.w r8,24[ep]
sst.w r7,20[ep]
sst.w r6,16[ep]
sst.w r5,12[ep]
#endif /* configDATA_MODE */
sst.w r2, 8[ ep ]
sst.w r1, 4[ ep ]
MOVHI hi1( usCriticalNesting ), r0, r1;
save usCriticalNesting value to stack
ld.w lw1( usCriticalNesting )[ r1 ], r2
sst.w r2, 0[ ep ]
MOVHI hi1( pxCurrentTCB ), r0, r1;
save SP to top of current TCB
ld.w lw1( pxCurrentTCB )[ r1 ], r2
st.w sp, 0[ r2 ]
ENDM
sst.w r2,8[ep]
sst.w r1,4[ep]
MOVHI hi1(usCriticalNesting),r0,r1 ; save usCriticalNesting value to stack
ld.w lw1(usCriticalNesting)[r1],r2
sst.w r2,0[ep]
MOVHI hi1(pxCurrentTCB),r0,r1 ; save SP to top of current TCB
ld.w lw1(pxCurrentTCB)[r1],r2
st.w sp,0[r2]
ENDM
portRESTORE_CONTEXT MACRO
MOVHI hi1( pxCurrentTCB ), r0, r1;
get Stackpointer address
ld.w lw1( pxCurrentTCB )[ r1 ], sp
MOV sp, r1
ld.w 0[ r1 ], sp;
load stackpointer
MOV sp, ep;
set stack pointer to element pointer
sld.w 0[ ep ], r1;
load usCriticalNesting value from stack
MOVHI hi1( usCriticalNesting ), r0, r2
st.w r1, lw1( usCriticalNesting )[ r2 ]
sld.w 4[ ep ], r1;
restore general purpose registers
sld.w 8[ ep ], r2
#if configDATA_MODE == 1; Using Tiny data model
sld.w 12[ ep ], r4
sld.w 16[ ep ], r5
sld.w 20[ ep ], r6
sld.w 24[ ep ], r7
sld.w 28[ ep ], r8
sld.w 32[ ep ], r9
sld.w 36[ ep ], r10
sld.w 40[ ep ], r11
sld.w 44[ ep ], r12
sld.w 48[ ep ], r13
sld.w 52[ ep ], r14
sld.w 56[ ep ], r15
sld.w 60[ ep ], r16
sld.w 64[ ep ], r17
sld.w 68[ ep ], r18
sld.w 72[ ep ], r19
dispose 76, { r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30 }
#else; Using Small / Large data model
sld.w 12[ ep ], r5
sld.w 16[ ep ], r6
sld.w 20[ ep ], r7
sld.w 24[ ep ], r8
sld.w 28[ ep ], r9
sld.w 32[ ep ], r10
sld.w 36[ ep ], r11
sld.w 40[ ep ], r12
sld.w 44[ ep ], r13
sld.w 48[ ep ], r14
sld.w 52[ ep ], r15
sld.w 56[ ep ], r16
sld.w 60[ ep ], r17
sld.w 64[ ep ], r18
sld.w 68[ ep ], r19
dispose 72, { r20, r21, r22, r23, r24, r26, r27, r28, r29, r30 }
MOVHI hi1(pxCurrentTCB),r0,r1 ; get Stackpointer address
ld.w lw1(pxCurrentTCB)[r1],sp
MOV sp,r1
ld.w 0[r1],sp ; load stackpointer
MOV sp,ep ; set stack pointer to element pointer
sld.w 0[ep],r1 ; load usCriticalNesting value from stack
MOVHI hi1(usCriticalNesting),r0,r2
st.w r1,lw1(usCriticalNesting)[r2]
sld.w 4[ep],r1 ; restore general purpose registers
sld.w 8[ep],r2
#if configDATA_MODE == 1 ; Using Tiny data model
sld.w 12[ep],r4
sld.w 16[ep],r5
sld.w 20[ep],r6
sld.w 24[ep],r7
sld.w 28[ep],r8
sld.w 32[ep],r9
sld.w 36[ep],r10
sld.w 40[ep],r11
sld.w 44[ep],r12
sld.w 48[ep],r13
sld.w 52[ep],r14
sld.w 56[ep],r15
sld.w 60[ep],r16
sld.w 64[ep],r17
sld.w 68[ep],r18
sld.w 72[ep],r19
dispose 76,{r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30}
#else ; Using Small/Large data model
sld.w 12[ep],r5
sld.w 16[ep],r6
sld.w 20[ep],r7
sld.w 24[ep],r8
sld.w 28[ep],r9
sld.w 32[ep],r10
sld.w 36[ep],r11
sld.w 40[ep],r12
sld.w 44[ep],r13
sld.w 48[ep],r14
sld.w 52[ep],r15
sld.w 56[ep],r16
sld.w 60[ep],r17
sld.w 64[ep],r18
sld.w 68[ep],r19
dispose 72,{r20,r21,r22,r23,r24,r26,r27,r28,r29,r30}
#endif /* configDATA_MODE */
ld.w 0[ sp ], lp;
restore EIPSW from stack
ldsr lp, 1
ld.w 4[ sp ], lp;
restore EIPC from stack
ldsr lp, 0
ld.w 8[ sp ], lp;
restore LP from stack
add 0x0C, sp;
set SP to right position
ld.w 0[sp],lp ; restore EIPSW from stack
ldsr lp,1
ld.w 4[sp],lp ; restore EIPC from stack
ldsr lp,0
ld.w 8[sp],lp ; restore LP from stack
add 0x0C,sp ; set SP to right position
RETI
RETI
ENDM
ENDM

View file

@ -33,14 +33,14 @@
#include "task.h"
/* Critical nesting should be initialised to a non zero value so interrupts don't
* accidentally get enabled before the scheduler is started. */
#define portINITIAL_CRITICAL_NESTING ( ( StackType_t ) 10 )
accidentally get enabled before the scheduler is started. */
#define portINITIAL_CRITICAL_NESTING (( StackType_t ) 10)
/* The PSW value assigned to tasks when they start to run for the first time. */
#define portPSW ( ( StackType_t ) 0x00000000 )
#define portPSW (( StackType_t ) 0x00000000)
/* 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;
@ -52,9 +52,7 @@ volatile StackType_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
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 ) pxCode; /* Task function start address */
pxTopOfStack--;
@ -72,10 +70,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x24242424; /* Initial Value of R24 */
pxTopOfStack--;
#if ( __DATA_MODEL__ == 0 ) || ( __DATA_MODEL__ == 1 )
#if (__DATA_MODEL__ == 0) || (__DATA_MODEL__ == 1)
*pxTopOfStack = ( StackType_t ) 0x25252525; /* Initial Value of R25 */
pxTopOfStack--;
#endif /* configDATA_MODE */
#endif /* configDATA_MODE */
*pxTopOfStack = ( StackType_t ) 0x26262626; /* Initial Value of R26 */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x27272727; /* Initial Value of R27 */
@ -116,10 +114,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x55555555; /* Initial Value of R05 */
pxTopOfStack--;
#if __DATA_MODEL__ == 0 || __DATA_MODEL__ == 1
#if __DATA_MODEL__ == 0 || __DATA_MODEL__ == 1
*pxTopOfStack = ( StackType_t ) 0x44444444; /* Initial Value of R04 */
pxTopOfStack--;
#endif /* configDATA_MODE */
#endif /* configDATA_MODE */
*pxTopOfStack = ( StackType_t ) 0x22222222; /* Initial Value of R02 */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 is expected to hold the function parameter*/
@ -137,7 +135,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
/* Setup the hardware to generate the tick. Interrupts are disabled when
* this function is called. */
this function is called. */
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run. */
@ -151,7 +149,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void )
{
/* It is unlikely that the V850ES/Fx3 port will get stopped. If required simply
* disable the tick interrupt here. */
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
@ -166,11 +164,11 @@ static void prvSetupTimerInterrupt( void )
#ifdef __IAR_V850ES_Fx3__
{
TM0CMP0 = ( ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) / 2 ) - 1 ); /* divided by 2 because peripherals only run at CPU_CLOCK/2 */
TM0CMP0 = (((configCPU_CLOCK_HZ / configTICK_RATE_HZ) / 2)-1); /* divided by 2 because peripherals only run at CPU_CLOCK/2 */
}
#else
{
TM0CMP0 = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
TM0CMP0 = (configCPU_CLOCK_HZ / configTICK_RATE_HZ);
}
#endif
@ -181,3 +179,5 @@ static void prvSetupTimerInterrupt( void )
TM0CE = 1; /* TMM0 operation enable */
}
/*-----------------------------------------------------------*/

View file

@ -26,11 +26,11 @@
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Port specific definitions.
@ -43,39 +43,39 @@
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned int
#define portBASE_TYPE int
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned int
#define portBASE_TYPE int
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configUSE_16_BIT_TICKS == 1 )
#if (configUSE_16_BIT_TICKS==1)
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
#endif
/*-----------------------------------------------------------*/
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() __asm( "DI" )
#define portENABLE_INTERRUPTS() __asm( "EI" )
#define portDISABLE_INTERRUPTS() __asm ( "DI" )
#define portENABLE_INTERRUPTS() __asm ( "EI" )
/*-----------------------------------------------------------*/
/* Critical section control macros. */
#define portNO_CRITICAL_SECTION_NESTING ( ( UBaseType_t ) 0 )
#define portNO_CRITICAL_SECTION_NESTING ( ( UBaseType_t ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile /*uint16_t*/ portSTACK_TYPE usCriticalNesting; \
#define portENTER_CRITICAL() \
{ \
extern volatile /*uint16_t*/ portSTACK_TYPE usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
@ -83,11 +83,11 @@
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
}
#define portEXIT_CRITICAL() \
{ \
extern volatile /*uint16_t*/ portSTACK_TYPE usCriticalNesting; \
#define portEXIT_CRITICAL() \
{ \
extern volatile /*uint16_t*/ portSTACK_TYPE usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
@ -101,34 +101,35 @@
portENABLE_INTERRUPTS(); \
} \
} \
}
}
/*-----------------------------------------------------------*/
/* Task utilities. */
extern void vPortYield( void );
extern void vPortStart( void );
extern void portSAVE_CONTEXT( void );
extern void portRESTORE_CONTEXT( void );
#define portYIELD() __asm( "trap 0" )
#define portNOP() __asm( "NOP" )
extern void vTaskSwitchContext( void );
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
extern void vPortYield( void );
extern void vPortStart( void );
extern void portSAVE_CONTEXT( void );
extern void portRESTORE_CONTEXT( void );
#define portYIELD() __asm ( "trap 0" )
#define portNOP() __asm ( "NOP" )
extern void vTaskSwitchContext( void );
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
/*-----------------------------------------------------------*/
/* Hardwware specifics. */
#define portBYTE_ALIGNMENT 4
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* 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 )
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */