mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -04:00
Normalize line endings and whitespace in source files
This commit is contained in:
parent
151fb04ad1
commit
01820d3ed9
574 changed files with 162626 additions and 172362 deletions
|
@ -1,340 +1,338 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the AVR/IAR port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Start tasks with interrupts enables. */
|
||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
|
||||
|
||||
/* Hardware constants for timer 1. */
|
||||
#define portCLEAR_COUNTER_ON_MATCH ( ( uint8_t ) 0x08 )
|
||||
#define portPRESCALE_64 ( ( uint8_t ) 0x03 )
|
||||
#define portCLOCK_PRESCALER ( ( uint32_t ) 64 )
|
||||
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( uint8_t ) 0x10 )
|
||||
|
||||
/* The number of bytes used on the hardware stack by the task start address. */
|
||||
#define portBYTES_USED_BY_RETURN_ADDRESS ( 2 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Stores the critical section nesting. This must not be initialised to 0.
|
||||
It will be initialised when a task starts. */
|
||||
#define portNO_CRITICAL_NESTING ( ( UBaseType_t ) 0 )
|
||||
UBaseType_t uxCriticalNesting = 0x50;
|
||||
|
||||
|
||||
/*
|
||||
* Perform hardware setup to enable ticks from timer 1, compare match A.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The IAR compiler does not have full support for inline assembler, so
|
||||
* these are defined in the portmacro assembler file.
|
||||
*/
|
||||
extern void vPortYieldFromTick( void );
|
||||
extern void vPortStart( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
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. */
|
||||
|
||||
*pxTopOfStack = 0x11;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x22;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x33;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Remember where the top of the hardware stack is - this is required
|
||||
below. */
|
||||
pxTopOfHardwareStack = pxTopOfStack;
|
||||
|
||||
|
||||
/* Simulate how the stack would look after a call to vPortYield(). */
|
||||
|
||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||
|
||||
|
||||
|
||||
/* 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. */
|
||||
usAddress = ( uint16_t ) pxCode;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
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. */
|
||||
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. */
|
||||
*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. */
|
||||
pxTopOfHardwareStack -= portBYTES_USED_BY_RETURN_ADDRESS;
|
||||
usAddress = ( uint16_t ) pxTopOfHardwareStack;
|
||||
|
||||
/* SPL */
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* SPH */
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Now the remaining registers. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x13; /* R13 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x14; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x15; /* R15 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Place the parameter on the stack in the expected location. */
|
||||
usAddress = ( uint16_t ) pvParameters;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x18; /* R18 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x19; /* R19 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x20; /* R20 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x21; /* R21 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x22; /* R22 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x23; /* R23 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x24; /* R24 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x25; /* R25 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x26; /* R26 X */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x27; /* R27 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The Y register is not stored as it is used as the software stack and
|
||||
gets saved into the task control block. */
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x30; /* R30 Z */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x031; /* R31 */
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING; /* Critical nesting is zero when the task starts. */
|
||||
|
||||
/*lint +e950 +e611 +e923 */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Setup the hardware to generate the tick. */
|
||||
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.*/
|
||||
vPortStart();
|
||||
|
||||
/* Should not get here! */
|
||||
return pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the AVR port will get stopped. If required simply
|
||||
disable the tick interrupt here. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup timer 1 compare match A to generate a tick interrupt.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
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. */
|
||||
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* We only have 16 bits so have to scale to get our required tick rate. */
|
||||
ulCompareMatch /= portCLOCK_PRESCALER;
|
||||
|
||||
/* Adjust for correct value. */
|
||||
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. */
|
||||
ucLowByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
||||
ulCompareMatch >>= 8;
|
||||
ucHighByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
||||
OCR1AH = ucHighByte;
|
||||
OCR1AL = ucLowByte;
|
||||
|
||||
/* Setup clock source and compare match behaviour. */
|
||||
ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;
|
||||
TCCR1B = ucLowByte;
|
||||
|
||||
/* Enable the interrupt - this is okay as interrupt are currently globally
|
||||
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.
|
||||
*/
|
||||
__task void SIG_OUTPUT_COMPARE1A( void )
|
||||
{
|
||||
vPortYieldFromTick();
|
||||
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();
|
||||
*
|
||||
* THE INTERRUPT VECTOR IS POPULATED IN portmacro.s90. DO NOT INSTALL
|
||||
* IT HERE USING THE USUAL PRAGMA.
|
||||
*/
|
||||
__interrupt void SIG_OUTPUT_COMPARE1A( void )
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the AVR/IAR port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Start tasks with interrupts enables. */
|
||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
|
||||
|
||||
/* Hardware constants for timer 1. */
|
||||
#define portCLEAR_COUNTER_ON_MATCH ( ( uint8_t ) 0x08 )
|
||||
#define portPRESCALE_64 ( ( uint8_t ) 0x03 )
|
||||
#define portCLOCK_PRESCALER ( ( uint32_t ) 64 )
|
||||
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( uint8_t ) 0x10 )
|
||||
|
||||
/* The number of bytes used on the hardware stack by the task start address. */
|
||||
#define portBYTES_USED_BY_RETURN_ADDRESS ( 2 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Stores the critical section nesting. This must not be initialised to 0.
|
||||
It will be initialised when a task starts. */
|
||||
#define portNO_CRITICAL_NESTING ( ( UBaseType_t ) 0 )
|
||||
UBaseType_t uxCriticalNesting = 0x50;
|
||||
|
||||
|
||||
/*
|
||||
* Perform hardware setup to enable ticks from timer 1, compare match A.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The IAR compiler does not have full support for inline assembler, so
|
||||
* these are defined in the portmacro assembler file.
|
||||
*/
|
||||
extern void vPortYieldFromTick( void );
|
||||
extern void vPortStart( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
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. */
|
||||
|
||||
*pxTopOfStack = 0x11;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x22;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x33;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Remember where the top of the hardware stack is - this is required
|
||||
below. */
|
||||
pxTopOfHardwareStack = pxTopOfStack;
|
||||
|
||||
|
||||
/* Simulate how the stack would look after a call to vPortYield(). */
|
||||
|
||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||
|
||||
|
||||
|
||||
/* 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. */
|
||||
usAddress = ( uint16_t ) pxCode;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
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. */
|
||||
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. */
|
||||
*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. */
|
||||
pxTopOfHardwareStack -= portBYTES_USED_BY_RETURN_ADDRESS;
|
||||
usAddress = ( uint16_t ) pxTopOfHardwareStack;
|
||||
|
||||
/* SPL */
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* SPH */
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Now the remaining registers. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x01; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x13; /* R13 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x14; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x15; /* R15 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Place the parameter on the stack in the expected location. */
|
||||
usAddress = ( uint16_t ) pvParameters;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x18; /* R18 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x19; /* R19 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x20; /* R20 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x21; /* R21 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x22; /* R22 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x23; /* R23 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x24; /* R24 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x25; /* R25 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x26; /* R26 X */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x27; /* R27 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The Y register is not stored as it is used as the software stack and
|
||||
gets saved into the task control block. */
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x30; /* R30 Z */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x031; /* R31 */
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING; /* Critical nesting is zero when the task starts. */
|
||||
|
||||
/*lint +e950 +e611 +e923 */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Setup the hardware to generate the tick. */
|
||||
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.*/
|
||||
vPortStart();
|
||||
|
||||
/* Should not get here! */
|
||||
return pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the AVR port will get stopped. If required simply
|
||||
disable the tick interrupt here. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup timer 1 compare match A to generate a tick interrupt.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
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. */
|
||||
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* We only have 16 bits so have to scale to get our required tick rate. */
|
||||
ulCompareMatch /= portCLOCK_PRESCALER;
|
||||
|
||||
/* Adjust for correct value. */
|
||||
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. */
|
||||
ucLowByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
||||
ulCompareMatch >>= 8;
|
||||
ucHighByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
||||
OCR1AH = ucHighByte;
|
||||
OCR1AL = ucLowByte;
|
||||
|
||||
/* Setup clock source and compare match behaviour. */
|
||||
ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;
|
||||
TCCR1B = ucLowByte;
|
||||
|
||||
/* Enable the interrupt - this is okay as interrupt are currently globally
|
||||
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.
|
||||
*/
|
||||
__task void SIG_OUTPUT_COMPARE1A( void )
|
||||
{
|
||||
vPortYieldFromTick();
|
||||
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();
|
||||
*
|
||||
* THE INTERRUPT VECTOR IS POPULATED IN portmacro.s90. DO NOT INSTALL
|
||||
* IT HERE USING THE USUAL PRAGMA.
|
||||
*/
|
||||
__interrupt void SIG_OUTPUT_COMPARE1A( void )
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,113 +1,111 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.2.3
|
||||
|
||||
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
|
||||
base 16.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* 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
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef signed char BaseType_t;
|
||||
typedef unsigned char UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
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" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#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()
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#define outb( PORT, VALUE ) PORT = VALUE
|
||||
#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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.2.3
|
||||
|
||||
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
|
||||
base 16.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* 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
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef signed char BaseType_t;
|
||||
typedef unsigned char UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
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" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#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()
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#define outb( PORT, VALUE ) PORT = VALUE
|
||||
#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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
|
|
@ -1,246 +1,245 @@
|
|||
;/*
|
||||
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * https://www.FreeRTOS.org
|
||||
; * https://github.com/FreeRTOS
|
||||
; *
|
||||
; */
|
||||
|
||||
#include <iom323.h>
|
||||
|
||||
; Declare all extern symbols here - including any ISRs that are referenced in
|
||||
; the vector table.
|
||||
|
||||
; ISR functions
|
||||
; -------------
|
||||
EXTERN SIG_OUTPUT_COMPARE1A
|
||||
EXTERN SIG_UART_RECV
|
||||
EXTERN SIG_UART_DATA
|
||||
|
||||
|
||||
; Functions used by scheduler
|
||||
; ---------------------------
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN xTaskIncrementTick
|
||||
EXTERN uxCriticalNesting
|
||||
|
||||
; Functions implemented in this file
|
||||
; ----------------------------------
|
||||
PUBLIC vPortYield
|
||||
PUBLIC vPortYieldFromTick
|
||||
PUBLIC vPortStart
|
||||
|
||||
|
||||
; Interrupt vector table.
|
||||
; -----------------------
|
||||
;
|
||||
; For simplicity the RTOS tick interrupt routine uses the __task keyword.
|
||||
; As the IAR compiler does not permit a function to be declared using both
|
||||
; __task and __interrupt, the use of __task necessitates that the interrupt
|
||||
; vector table be setup manually.
|
||||
;
|
||||
; To write an ISR, implement the ISR function using the __interrupt keyword
|
||||
; but do not install the interrupt using the "#pragma vector=ABC" method.
|
||||
; Instead manually place the name of the ISR in the vector table using an
|
||||
; ORG and jmp instruction as demonstrated below.
|
||||
; You will also have to add an EXTERN statement at the top of the file.
|
||||
|
||||
ASEG
|
||||
|
||||
|
||||
ORG TIMER1_COMPA_vect ; Vector address
|
||||
jmp SIG_OUTPUT_COMPARE1A ; ISR
|
||||
|
||||
ORG USART_RXC_vect ; Vector address
|
||||
jmp SIG_UART_RECV ; ISR
|
||||
|
||||
ORG USART_UDRE_vect ; Vector address
|
||||
jmp SIG_UART_DATA ; ISR
|
||||
|
||||
|
||||
RSEG CODE
|
||||
|
||||
|
||||
|
||||
; Saving and Restoring a Task Context and Task Switching
|
||||
; ------------------------------------------------------
|
||||
;
|
||||
; The IAR compiler does not fully support inline assembler, so saving and
|
||||
; restoring a task context has to be written in an asm file.
|
||||
;
|
||||
; vPortYield() and vPortYieldFromTick() are usually written in C. Doing
|
||||
; so in this case would required calls to be made to portSAVE_CONTEXT() and
|
||||
; portRESTORE_CONTEXT(). This is dis-advantageous as the context switch
|
||||
; function would require two extra jump and return instructions over the
|
||||
; WinAVR equivalent.
|
||||
;
|
||||
; To avoid this I have opted to implement both vPortYield() and
|
||||
; vPortYieldFromTick() in this assembly file. For convenience
|
||||
; portSAVE_CONTEXT and portRESTORE_CONTEXT are implemented as macros.
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
st -y, r0 ; First save the r0 register - we need to use this.
|
||||
in r0, SREG ; Obtain the SREG value so we can disable interrupts...
|
||||
cli ; ... as soon as possible.
|
||||
st -y, r0 ; Store the SREG as it was before we disabled interrupts.
|
||||
|
||||
in r0, SPL ; Next store the hardware stack pointer. The IAR...
|
||||
st -y, r0 ; ... compiler uses the hardware stack as a call stack ...
|
||||
in r0, SPH ; ... only.
|
||||
st -y, r0
|
||||
|
||||
st -y, r1 ; Now store the rest of the registers. Dont store the ...
|
||||
st -y, r2 ; ... the Y register here as it is used as the software
|
||||
st -y, r3 ; stack pointer and will get saved into the TCB.
|
||||
st -y, r4
|
||||
st -y, r5
|
||||
st -y, r6
|
||||
st -y, r7
|
||||
st -y, r8
|
||||
st -y, r9
|
||||
st -y, r10
|
||||
st -y, r11
|
||||
st -y, r12
|
||||
st -y, r13
|
||||
st -y, r14
|
||||
st -y, r15
|
||||
st -y, r16
|
||||
st -y, r17
|
||||
st -y, r18
|
||||
st -y, r19
|
||||
st -y, r20
|
||||
st -y, r21
|
||||
st -y, r22
|
||||
st -y, r23
|
||||
st -y, r24
|
||||
st -y, r25
|
||||
st -y, r26
|
||||
st -y, r27
|
||||
st -y, r30
|
||||
st -y, r31
|
||||
lds r0, uxCriticalNesting
|
||||
st -y, r0 ; Store the critical nesting counter.
|
||||
|
||||
lds r26, pxCurrentTCB ; Finally save the software stack pointer (Y ...
|
||||
lds r27, pxCurrentTCB + 1 ; ... register) into the TCB.
|
||||
st x+, r28
|
||||
st x+, r29
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
lds r26, pxCurrentTCB
|
||||
lds r27, pxCurrentTCB + 1 ; Restore the software stack pointer from ...
|
||||
ld r28, x+ ; the TCB into the software stack pointer (...
|
||||
ld r29, x+ ; ... the Y register).
|
||||
|
||||
ld r0, y+
|
||||
sts uxCriticalNesting, r0
|
||||
ld r31, y+ ; Restore the registers down to R0. The Y
|
||||
ld r30, y+ ; register is missing from this list as it
|
||||
ld r27, y+ ; has already been restored.
|
||||
ld r26, y+
|
||||
ld r25, y+
|
||||
ld r24, y+
|
||||
ld r23, y+
|
||||
ld r22, y+
|
||||
ld r21, y+
|
||||
ld r20, y+
|
||||
ld r19, y+
|
||||
ld r18, y+
|
||||
ld r17, y+
|
||||
ld r16, y+
|
||||
ld r15, y+
|
||||
ld r14, y+
|
||||
ld r13, y+
|
||||
ld r12, y+
|
||||
ld r11, y+
|
||||
ld r10, y+
|
||||
ld r9, y+
|
||||
ld r8, y+
|
||||
ld r7, y+
|
||||
ld r6, y+
|
||||
ld r5, y+
|
||||
ld r4, y+
|
||||
ld r3, y+
|
||||
ld r2, y+
|
||||
ld r1, y+
|
||||
|
||||
ld r0, y+ ; The next thing on the stack is the ...
|
||||
out SPH, r0 ; ... hardware stack pointer.
|
||||
ld r0, y+
|
||||
out SPL, r0
|
||||
|
||||
ld r0, y+ ; Next there is the SREG register.
|
||||
out SREG, r0
|
||||
|
||||
ld r0, y+ ; Finally we have finished with r0, so restore r0.
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
; vPortYield() and vPortYieldFromTick()
|
||||
; -------------------------------------
|
||||
;
|
||||
; Manual and preemptive context switch functions respectively.
|
||||
; The IAR compiler does not fully support inline assembler,
|
||||
; so these are implemented here rather than the more usually
|
||||
; place of within port.c.
|
||||
|
||||
vPortYield:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
call vTaskSwitchContext ; Call the scheduler.
|
||||
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
|
||||
ret ; ... scheduler decided should run.
|
||||
|
||||
vPortYieldFromTick:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
call xTaskIncrementTick ; Call the timer tick function.
|
||||
tst r16
|
||||
breq SkipTaskSwitch
|
||||
call vTaskSwitchContext ; Call the scheduler.
|
||||
SkipTaskSwitch:
|
||||
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
|
||||
ret ; ... scheduler decided should run.
|
||||
|
||||
; vPortStart()
|
||||
; ------------
|
||||
;
|
||||
; Again due to the lack of inline assembler, this is required
|
||||
; to get access to the portRESTORE_CONTEXT macro.
|
||||
|
||||
vPortStart:
|
||||
portRESTORE_CONTEXT
|
||||
ret
|
||||
|
||||
|
||||
; Just a filler for unused interrupt vectors.
|
||||
vNoISR:
|
||||
reti
|
||||
|
||||
|
||||
END
|
||||
|
||||
;/*
|
||||
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * SPDX-License-Identifier: MIT
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * https://www.FreeRTOS.org
|
||||
; * https://github.com/FreeRTOS
|
||||
; *
|
||||
; */
|
||||
|
||||
#include <iom323.h>
|
||||
|
||||
; Declare all extern symbols here - including any ISRs that are referenced in
|
||||
; the vector table.
|
||||
|
||||
; ISR functions
|
||||
; -------------
|
||||
EXTERN SIG_OUTPUT_COMPARE1A
|
||||
EXTERN SIG_UART_RECV
|
||||
EXTERN SIG_UART_DATA
|
||||
|
||||
|
||||
; Functions used by scheduler
|
||||
; ---------------------------
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN xTaskIncrementTick
|
||||
EXTERN uxCriticalNesting
|
||||
|
||||
; Functions implemented in this file
|
||||
; ----------------------------------
|
||||
PUBLIC vPortYield
|
||||
PUBLIC vPortYieldFromTick
|
||||
PUBLIC vPortStart
|
||||
|
||||
|
||||
; Interrupt vector table.
|
||||
; -----------------------
|
||||
;
|
||||
; For simplicity the RTOS tick interrupt routine uses the __task keyword.
|
||||
; As the IAR compiler does not permit a function to be declared using both
|
||||
; __task and __interrupt, the use of __task necessitates that the interrupt
|
||||
; vector table be setup manually.
|
||||
;
|
||||
; To write an ISR, implement the ISR function using the __interrupt keyword
|
||||
; but do not install the interrupt using the "#pragma vector=ABC" method.
|
||||
; Instead manually place the name of the ISR in the vector table using an
|
||||
; ORG and jmp instruction as demonstrated below.
|
||||
; You will also have to add an EXTERN statement at the top of the file.
|
||||
|
||||
ASEG
|
||||
|
||||
|
||||
ORG TIMER1_COMPA_vect ; Vector address
|
||||
jmp SIG_OUTPUT_COMPARE1A ; ISR
|
||||
|
||||
ORG USART_RXC_vect ; Vector address
|
||||
jmp SIG_UART_RECV ; ISR
|
||||
|
||||
ORG USART_UDRE_vect ; Vector address
|
||||
jmp SIG_UART_DATA ; ISR
|
||||
|
||||
|
||||
RSEG CODE
|
||||
|
||||
|
||||
|
||||
; Saving and Restoring a Task Context and Task Switching
|
||||
; ------------------------------------------------------
|
||||
;
|
||||
; The IAR compiler does not fully support inline assembler, so saving and
|
||||
; restoring a task context has to be written in an asm file.
|
||||
;
|
||||
; vPortYield() and vPortYieldFromTick() are usually written in C. Doing
|
||||
; so in this case would required calls to be made to portSAVE_CONTEXT() and
|
||||
; portRESTORE_CONTEXT(). This is dis-advantageous as the context switch
|
||||
; function would require two extra jump and return instructions over the
|
||||
; WinAVR equivalent.
|
||||
;
|
||||
; To avoid this I have opted to implement both vPortYield() and
|
||||
; vPortYieldFromTick() in this assembly file. For convenience
|
||||
; portSAVE_CONTEXT and portRESTORE_CONTEXT are implemented as macros.
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
st -y, r0 ; First save the r0 register - we need to use this.
|
||||
in r0, SREG ; Obtain the SREG value so we can disable interrupts...
|
||||
cli ; ... as soon as possible.
|
||||
st -y, r0 ; Store the SREG as it was before we disabled interrupts.
|
||||
|
||||
in r0, SPL ; Next store the hardware stack pointer. The IAR...
|
||||
st -y, r0 ; ... compiler uses the hardware stack as a call stack ...
|
||||
in r0, SPH ; ... only.
|
||||
st -y, r0
|
||||
|
||||
st -y, r1 ; Now store the rest of the registers. Dont store the ...
|
||||
st -y, r2 ; ... the Y register here as it is used as the software
|
||||
st -y, r3 ; stack pointer and will get saved into the TCB.
|
||||
st -y, r4
|
||||
st -y, r5
|
||||
st -y, r6
|
||||
st -y, r7
|
||||
st -y, r8
|
||||
st -y, r9
|
||||
st -y, r10
|
||||
st -y, r11
|
||||
st -y, r12
|
||||
st -y, r13
|
||||
st -y, r14
|
||||
st -y, r15
|
||||
st -y, r16
|
||||
st -y, r17
|
||||
st -y, r18
|
||||
st -y, r19
|
||||
st -y, r20
|
||||
st -y, r21
|
||||
st -y, r22
|
||||
st -y, r23
|
||||
st -y, r24
|
||||
st -y, r25
|
||||
st -y, r26
|
||||
st -y, r27
|
||||
st -y, r30
|
||||
st -y, r31
|
||||
lds r0, uxCriticalNesting
|
||||
st -y, r0 ; Store the critical nesting counter.
|
||||
|
||||
lds r26, pxCurrentTCB ; Finally save the software stack pointer (Y ...
|
||||
lds r27, pxCurrentTCB + 1 ; ... register) into the TCB.
|
||||
st x+, r28
|
||||
st x+, r29
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
lds r26, pxCurrentTCB
|
||||
lds r27, pxCurrentTCB + 1 ; Restore the software stack pointer from ...
|
||||
ld r28, x+ ; the TCB into the software stack pointer (...
|
||||
ld r29, x+ ; ... the Y register).
|
||||
|
||||
ld r0, y+
|
||||
sts uxCriticalNesting, r0
|
||||
ld r31, y+ ; Restore the registers down to R0. The Y
|
||||
ld r30, y+ ; register is missing from this list as it
|
||||
ld r27, y+ ; has already been restored.
|
||||
ld r26, y+
|
||||
ld r25, y+
|
||||
ld r24, y+
|
||||
ld r23, y+
|
||||
ld r22, y+
|
||||
ld r21, y+
|
||||
ld r20, y+
|
||||
ld r19, y+
|
||||
ld r18, y+
|
||||
ld r17, y+
|
||||
ld r16, y+
|
||||
ld r15, y+
|
||||
ld r14, y+
|
||||
ld r13, y+
|
||||
ld r12, y+
|
||||
ld r11, y+
|
||||
ld r10, y+
|
||||
ld r9, y+
|
||||
ld r8, y+
|
||||
ld r7, y+
|
||||
ld r6, y+
|
||||
ld r5, y+
|
||||
ld r4, y+
|
||||
ld r3, y+
|
||||
ld r2, y+
|
||||
ld r1, y+
|
||||
|
||||
ld r0, y+ ; The next thing on the stack is the ...
|
||||
out SPH, r0 ; ... hardware stack pointer.
|
||||
ld r0, y+
|
||||
out SPL, r0
|
||||
|
||||
ld r0, y+ ; Next there is the SREG register.
|
||||
out SREG, r0
|
||||
|
||||
ld r0, y+ ; Finally we have finished with r0, so restore r0.
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
; vPortYield() and vPortYieldFromTick()
|
||||
; -------------------------------------
|
||||
;
|
||||
; Manual and preemptive context switch functions respectively.
|
||||
; The IAR compiler does not fully support inline assembler,
|
||||
; so these are implemented here rather than the more usually
|
||||
; place of within port.c.
|
||||
|
||||
vPortYield:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
call vTaskSwitchContext ; Call the scheduler.
|
||||
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
|
||||
ret ; ... scheduler decided should run.
|
||||
|
||||
vPortYieldFromTick:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
call xTaskIncrementTick ; Call the timer tick function.
|
||||
tst r16
|
||||
breq SkipTaskSwitch
|
||||
call vTaskSwitchContext ; Call the scheduler.
|
||||
SkipTaskSwitch:
|
||||
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
|
||||
ret ; ... scheduler decided should run.
|
||||
|
||||
; vPortStart()
|
||||
; ------------
|
||||
;
|
||||
; Again due to the lack of inline assembler, this is required
|
||||
; to get access to the portRESTORE_CONTEXT macro.
|
||||
|
||||
vPortStart:
|
||||
portRESTORE_CONTEXT
|
||||
ret
|
||||
|
||||
|
||||
; Just a filler for unused interrupt vectors.
|
||||
vNoISR:
|
||||
reti
|
||||
|
||||
|
||||
END
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue