Add FreeRTOS-Plus directory.

This commit is contained in:
Richard Barry 2012-08-11 21:34:11 +00:00
parent 7bd5f21ad5
commit f508a5f653
6798 changed files with 134949 additions and 19 deletions

View file

@ -0,0 +1,657 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/*
Changes between V1.2.4 and V1.2.5
+ Introduced portGLOBAL_INTERRUPT_FLAG definition to test the global
interrupt flag setting. Using the two bits defined within
portINITAL_INTERRUPT_STATE was causing the w register to get clobbered
before the test was performed.
Changes from V1.2.5
+ Set the interrupt vector address to 0x08. Previously it was at the
incorrect address for compatibility mode of 0x18.
Changes from V2.1.1
+ PCLATU and PCLATH are now saved as part of the context. This allows
function pointers to be used within tasks. Thanks to Javier Espeche
for the enhancement.
Changes from V2.3.1
+ TABLAT is now saved as part of the task context.
Changes from V3.2.0
+ TBLPTRU is now initialised to zero as the MPLAB compiler expects this
value and does not write to the register.
*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
/* MPLAB library include file. */
#include "timers.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the PIC port.
*----------------------------------------------------------*/
/* Hardware setup for tick. */
#define portTIMER_FOSC_SCALE ( ( unsigned long ) 4 )
/* Initial interrupt enable state for newly created tasks. This value is
copied into INTCON when a task switches in for the first time. */
#define portINITAL_INTERRUPT_STATE 0xc0
/* Just the bit within INTCON for the global interrupt flag. */
#define portGLOBAL_INTERRUPT_FLAG 0x80
/* Constant used for context switch macro when we require the interrupt
enable state to be unchanged when the interrupted task is switched back in. */
#define portINTERRUPTS_UNCHANGED 0x00
/* Some memory areas get saved as part of the task context. These memory
area's get used by the compiler for temporary storage, especially when
performing mathematical operations, or when using 32bit data types. This
constant defines the size of memory area which must be saved. */
#define portCOMPILER_MANAGED_MEMORY_SIZE ( ( unsigned char ) 0x13 )
/* We require the address of the pxCurrentTCB variable, but don't want to know
any details of its type. */
typedef void tskTCB;
extern volatile tskTCB * volatile pxCurrentTCB;
/* IO port constants. */
#define portBIT_SET ( ( unsigned char ) 1 )
#define portBIT_CLEAR ( ( unsigned char ) 0 )
/*
* The serial port ISR's are defined in serial.c, but are called from portable
* as they use the same vector as the tick ISR.
*/
void vSerialTxISR( void );
void vSerialRxISR( void );
/*
* Perform hardware setup to enable ticks.
*/
static void prvSetupTimerInterrupt( void );
/*
* ISR to maintain the tick, and perform tick context switches if the
* preemptive scheduler is being used.
*/
static void prvTickISR( void );
/*
* ISR placed on the low priority vector. This calls the appropriate ISR for
* the actual interrupt.
*/
static void prvLowInterrupt( void );
/*
* Macro that pushes all the registers that make up the context of a task onto
* the stack, then saves the new top of stack into the TCB.
*
* If this is called from an ISR then the interrupt enable bits must have been
* set for the ISR to ever get called. Therefore we want to save the INTCON
* register with the enable bits forced to be set - and ucForcedInterruptFlags
* must contain these bit settings. This means the interrupts will again be
* enabled when the interrupted task is switched back in.
*
* If this is called from a manual context switch (i.e. from a call to yield),
* then we want to save the INTCON so it is restored with its current state,
* and ucForcedInterruptFlags must be 0. This allows a yield from within
* a critical section.
*
* The compiler uses some locations at the bottom of the memory for temporary
* storage during math and other computations. This is especially true if
* 32bit data types are utilised (as they are by the scheduler). The .tmpdata
* and MATH_DATA sections have to be stored in there entirety as part of a task
* context. This macro stores from data address 0x00 to
* portCOMPILER_MANAGED_MEMORY_SIZE. This is sufficient for the demo
* applications but you should check the map file for your project to ensure
* this is sufficient for your needs. It is not clear whether this size is
* fixed for all compilations or has the potential to be program specific.
*/
#define portSAVE_CONTEXT( ucForcedInterruptFlags ) \
{ \
_asm \
/* Save the status and WREG registers first, as these will get modified \
by the operations below. */ \
MOVFF WREG, PREINC1 \
MOVFF STATUS, PREINC1 \
/* Save the INTCON register with the appropriate bits forced if \
necessary - as described above. */ \
MOVFF INTCON, WREG \
IORLW ucForcedInterruptFlags \
MOVFF WREG, PREINC1 \
_endasm \
\
portDISABLE_INTERRUPTS(); \
\
_asm \
/* Store the necessary registers to the stack. */ \
MOVFF BSR, PREINC1 \
MOVFF FSR2L, PREINC1 \
MOVFF FSR2H, PREINC1 \
MOVFF FSR0L, PREINC1 \
MOVFF FSR0H, PREINC1 \
MOVFF TABLAT, PREINC1 \
MOVFF TBLPTRU, PREINC1 \
MOVFF TBLPTRH, PREINC1 \
MOVFF TBLPTRL, PREINC1 \
MOVFF PRODH, PREINC1 \
MOVFF PRODL, PREINC1 \
MOVFF PCLATU, PREINC1 \
MOVFF PCLATH, PREINC1 \
/* Store the .tempdata and MATH_DATA areas as described above. */ \
CLRF FSR0L, 0 \
CLRF FSR0H, 0 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF POSTINC0, PREINC1 \
MOVFF INDF0, PREINC1 \
MOVFF FSR0L, PREINC1 \
MOVFF FSR0H, PREINC1 \
/* Store the hardware stack pointer in a temp register before we \
modify it. */ \
MOVFF STKPTR, FSR0L \
_endasm \
\
/* Store each address from the hardware stack. */ \
while( STKPTR > ( unsigned char ) 0 ) \
{ \
_asm \
MOVFF TOSL, PREINC1 \
MOVFF TOSH, PREINC1 \
MOVFF TOSU, PREINC1 \
POP \
_endasm \
} \
\
_asm \
/* Store the number of addresses on the hardware stack (from the \
temporary register). */ \
MOVFF FSR0L, PREINC1 \
MOVF PREINC1, 1, 0 \
_endasm \
\
/* Save the new top of the software stack in the TCB. */ \
_asm \
MOVFF pxCurrentTCB, FSR0L \
MOVFF pxCurrentTCB + 1, FSR0H \
MOVFF FSR1L, POSTINC0 \
MOVFF FSR1H, POSTINC0 \
_endasm \
}
/*-----------------------------------------------------------*/
/*
* This is the reverse of portSAVE_CONTEXT. See portSAVE_CONTEXT for more
* details.
*/
#define portRESTORE_CONTEXT() \
{ \
_asm \
/* Set FSR0 to point to pxCurrentTCB->pxTopOfStack. */ \
MOVFF pxCurrentTCB, FSR0L \
MOVFF pxCurrentTCB + 1, FSR0H \
\
/* De-reference FSR0 to set the address it holds into FSR1. \
(i.e. *( pxCurrentTCB->pxTopOfStack ) ). */ \
MOVFF POSTINC0, FSR1L \
MOVFF POSTINC0, FSR1H \
\
/* How many return addresses are there on the hardware stack? Discard \
the first byte as we are pointing to the next free space. */ \
MOVFF POSTDEC1, FSR0L \
MOVFF POSTDEC1, FSR0L \
_endasm \
\
/* Fill the hardware stack from our software stack. */ \
STKPTR = 0; \
\
while( STKPTR < FSR0L ) \
{ \
_asm \
PUSH \
MOVF POSTDEC1, 0, 0 \
MOVWF TOSU, 0 \
MOVF POSTDEC1, 0, 0 \
MOVWF TOSH, 0 \
MOVF POSTDEC1, 0, 0 \
MOVWF TOSL, 0 \
_endasm \
} \
\
_asm \
/* Restore the .tmpdata and MATH_DATA memory. */ \
MOVFF POSTDEC1, FSR0H \
MOVFF POSTDEC1, FSR0L \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, POSTDEC0 \
MOVFF POSTDEC1, INDF0 \
/* Restore the other registers forming the tasks context. */ \
MOVFF POSTDEC1, PCLATH \
MOVFF POSTDEC1, PCLATU \
MOVFF POSTDEC1, PRODL \
MOVFF POSTDEC1, PRODH \
MOVFF POSTDEC1, TBLPTRL \
MOVFF POSTDEC1, TBLPTRH \
MOVFF POSTDEC1, TBLPTRU \
MOVFF POSTDEC1, TABLAT \
MOVFF POSTDEC1, FSR0H \
MOVFF POSTDEC1, FSR0L \
MOVFF POSTDEC1, FSR2H \
MOVFF POSTDEC1, FSR2L \
MOVFF POSTDEC1, BSR \
/* The next byte is the INTCON register. Read this into WREG as some \
manipulation is required. */ \
MOVFF POSTDEC1, WREG \
_endasm \
\
/* From the INTCON register, only the interrupt enable bits form part \
of the tasks context. It is perfectly legitimate for another task to \
have modified any other bits. We therefore only restore the top two bits. \
*/ \
if( WREG & portGLOBAL_INTERRUPT_FLAG ) \
{ \
_asm \
MOVFF POSTDEC1, STATUS \
MOVFF POSTDEC1, WREG \
/* Return enabling interrupts. */ \
RETFIE 0 \
_endasm \
} \
else \
{ \
_asm \
MOVFF POSTDEC1, STATUS \
MOVFF POSTDEC1, WREG \
/* Return without effecting interrupts. The context may have \
been saved from a critical region. */ \
RETURN 0 \
_endasm \
} \
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned long ulAddress;
unsigned char ucBlock;
/* 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++;
/* Simulate how the stack would look after a call to vPortYield() generated
by the compiler.
First store the function parameters. This is where the task will expect to
find them when it starts running. */
ulAddress = ( unsigned long ) pvParameters;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulAddress & ( unsigned long ) 0x00ff );
pxTopOfStack++;
ulAddress >>= 8;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulAddress & ( unsigned long ) 0x00ff );
pxTopOfStack++;
/* Next we just leave a space. When a context is saved the stack pointer
is incremented before it is used so as not to corrupt whatever the stack
pointer is actually pointing to. This is especially necessary during
function epilogue code generated by the compiler. */
*pxTopOfStack = 0x44;
pxTopOfStack++;
/* Next are all the registers that form part of the task context. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x66; /* WREG. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0xcc; /* Status. */
pxTopOfStack++;
/* INTCON is saved with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITAL_INTERRUPT_STATE; /* INTCON */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* BSR. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* FSR2L. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x33; /* FSR2H. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x44; /* FSR0L. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x55; /* FSR0H. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x66; /* TABLAT. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* TBLPTRU. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x88; /* TBLPTRUH. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x99; /* TBLPTRUL. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaa; /* PRODH. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0xbb; /* PRODL. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* PCLATU. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* PCLATH. */
pxTopOfStack++;
/* Next the .tmpdata and MATH_DATA sections. */
for( ucBlock = 0; ucBlock <= portCOMPILER_MANAGED_MEMORY_SIZE; ucBlock++ )
{
*pxTopOfStack = ( portSTACK_TYPE ) ucBlock;
*pxTopOfStack++;
}
/* Store the top of the global data section. */
*pxTopOfStack = ( portSTACK_TYPE ) portCOMPILER_MANAGED_MEMORY_SIZE; /* Low. */
pxTopOfStack++;
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* High. */
pxTopOfStack++;
/* The only function return address so far is the address of the
task. */
ulAddress = ( unsigned long ) pxCode;
/* TOS low. */
*pxTopOfStack = ( portSTACK_TYPE ) ( ulAddress & ( unsigned long ) 0x00ff );
pxTopOfStack++;
ulAddress >>= 8;
/* TOS high. */
*pxTopOfStack = ( portSTACK_TYPE ) ( ulAddress & ( unsigned long ) 0x00ff );
pxTopOfStack++;
ulAddress >>= 8;
/* TOS even higher. */
*pxTopOfStack = ( portSTACK_TYPE ) ( ulAddress & ( unsigned long ) 0x00ff );
pxTopOfStack++;
/* Store the number of return addresses on the hardware stack - so far only
the address of the task entry point. */
*pxTopOfStack = ( portSTACK_TYPE ) 1;
pxTopOfStack++;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Setup a timer for the tick ISR is using the preemptive scheduler. */
prvSetupTimerInterrupt();
/* Restore the context of the first task to run. */
portRESTORE_CONTEXT();
/* Should not get here. Use the function name to stop compiler warnings. */
( void ) prvLowInterrupt;
( void ) prvTickISR;
return pdTRUE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the scheduler for the PIC port will get stopped
once running. If required disable the tick interrupt here, then return
to xPortStartScheduler(). */
}
/*-----------------------------------------------------------*/
/*
* Manual context switch. This is similar to the tick context switch,
* but does not increment the tick count. It must be identical to the
* tick context switch in how it stores the stack of a task.
*/
void vPortYield( void )
{
/* This can get called with interrupts either enabled or disabled. We
will save the INTCON register with the interrupt enable bits unmodified. */
portSAVE_CONTEXT( portINTERRUPTS_UNCHANGED );
/* Switch to the highest priority task that is ready to run. */
vTaskSwitchContext();
/* Start executing the task we have just switched to. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Vector for ISR. Nothing here must alter any registers!
*/
#pragma code high_vector=0x08
static void prvLowInterrupt( void )
{
/* Was the interrupt the tick? */
if( PIR1bits.CCP1IF )
{
_asm
goto prvTickISR
_endasm
}
/* Was the interrupt a byte being received? */
if( PIR1bits.RCIF )
{
_asm
goto vSerialRxISR
_endasm
}
/* Was the interrupt the Tx register becoming empty? */
if( PIR1bits.TXIF )
{
if( PIE1bits.TXIE )
{
_asm
goto vSerialTxISR
_endasm
}
}
}
#pragma code
/*-----------------------------------------------------------*/
/*
* ISR for the tick.
* This increments the tick count and, if using the preemptive scheduler,
* performs a context switch. This must be identical to the manual
* context switch in how it stores the context of a task.
*/
static void prvTickISR( void )
{
/* Interrupts must have been enabled for the ISR to fire, so we have to
save the context with interrupts enabled. */
portSAVE_CONTEXT( portGLOBAL_INTERRUPT_FLAG );
PIR1bits.CCP1IF = 0;
/* Maintain the tick count. */
vTaskIncrementTick();
#if configUSE_PREEMPTION == 1
{
/* Switch to the highest priority task that is ready to run. */
vTaskSwitchContext();
}
#endif
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Setup a timer for a regular tick.
*/
static void prvSetupTimerInterrupt( void )
{
const unsigned long ulConstCompareValue = ( ( configCPU_CLOCK_HZ / portTIMER_FOSC_SCALE ) / configTICK_RATE_HZ );
unsigned long ulCompareValue;
unsigned char ucByte;
/* Interrupts are disabled when this function is called.
Setup CCP1 to provide the tick interrupt using a compare match on timer
1.
Clear the time count then setup timer. */
TMR1H = ( unsigned char ) 0x00;
TMR1L = ( unsigned char ) 0x00;
/* Set the compare match value. */
ulCompareValue = ulConstCompareValue;
CCPR1L = ( unsigned char ) ( ulCompareValue & ( unsigned long ) 0xff );
ulCompareValue >>= ( unsigned long ) 8;
CCPR1H = ( unsigned char ) ( ulCompareValue & ( unsigned long ) 0xff );
CCP1CONbits.CCP1M0 = portBIT_SET; /*< Compare match mode. */
CCP1CONbits.CCP1M1 = portBIT_SET; /*< Compare match mode. */
CCP1CONbits.CCP1M2 = portBIT_CLEAR; /*< Compare match mode. */
CCP1CONbits.CCP1M3 = portBIT_SET; /*< Compare match mode. */
PIE1bits.CCP1IE = portBIT_SET; /*< Interrupt enable. */
/* We are only going to use the global interrupt bit, so set the peripheral
bit to true. */
INTCONbits.GIEL = portBIT_SET;
/* Provided library function for setting up the timer that will produce the
tick. */
OpenTimer1( T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_1 & T1_CCP1_T3_CCP2 );
}

View file

@ -0,0 +1,147 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
/*-----------------------------------------------------------
* 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 unsigned char
#define portBASE_TYPE char
#if( configUSE_16_BIT_TICKS == 1 )
typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff
#else
typedef unsigned portLONG portTickType;
#define portMAX_DELAY ( portTickType ) 0xffffffff
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 1
#define portGLOBAL_INT_ENABLE_BIT 0x80
#define portSTACK_GROWTH 1
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portDISABLE_INTERRUPTS() INTCONbits.GIEH = 0;
#define portENABLE_INTERRUPTS() INTCONbits.GIEH = 1;
/* Push the INTCON register onto the stack, then disable interrupts. */
#define portENTER_CRITICAL() POSTINC1 = INTCON; \
INTCONbits.GIEH = 0;
/* Retrieve the INTCON register from the stack, and enable interrupts
if they were saved as being enabled. Don't modify any other bits
within the INTCON register as these may have lagitimately have been
modified within the critical region. */
#define portEXIT_CRITICAL() _asm \
MOVF POSTDEC1, 1, 0 \
_endasm \
if( INDF1 & portGLOBAL_INT_ENABLE_BIT ) \
{ \
portENABLE_INTERRUPTS(); \
}
/*-----------------------------------------------------------*/
/* Task utilities. */
extern void vPortYield( void );
#define portYIELD() vPortYield()
/*-----------------------------------------------------------*/
/* 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 )
/*-----------------------------------------------------------*/
/* Required by the kernel aware debugger. */
#ifdef __DEBUG
#define portREMOVE_STATIC_QUALIFIER
#endif
#define portNOP() _asm \
NOP \
_endasm
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,329 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/*
Changes from V4.2.1
+ Introduced the configKERNEL_INTERRUPT_PRIORITY definition.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the PIC24 port.
*----------------------------------------------------------*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
/* Hardware specifics. */
#define portBIT_SET 1
#define portTIMER_PRESCALE 8
#define portINITIAL_SR 0
/* Defined for backward compatability with project created prior to
FreeRTOS.org V4.3.0. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 1
#endif
/* The program counter is only 23 bits. */
#define portUNUSED_PR_BITS 0x7f
/* Records the nesting depth of calls to portENTER_CRITICAL(). */
unsigned portBASE_TYPE uxCriticalNesting = 0xef;
#if configKERNEL_INTERRUPT_PRIORITY != 1
#error If configKERNEL_INTERRUPT_PRIORITY is not 1 then the #32 in the following macros needs changing to equal the portINTERRUPT_BITS value, which is ( configKERNEL_INTERRUPT_PRIORITY << 5 )
#endif
#ifdef MPLAB_PIC24_PORT
#define portRESTORE_CONTEXT() \
asm volatile( "MOV _pxCurrentTCB, W0 \n" /* Restore the stack pointer for the task. */ \
"MOV [W0], W15 \n" \
"POP W0 \n" /* Restore the critical nesting counter for the task. */ \
"MOV W0, _uxCriticalNesting \n" \
"POP PSVPAG \n" \
"POP CORCON \n" \
"POP TBLPAG \n" \
"POP RCOUNT \n" /* Restore the registers from the stack. */ \
"POP W14 \n" \
"POP.D W12 \n" \
"POP.D W10 \n" \
"POP.D W8 \n" \
"POP.D W6 \n" \
"POP.D W4 \n" \
"POP.D W2 \n" \
"POP.D W0 \n" \
"POP SR " );
#endif /* MPLAB_PIC24_PORT */
#ifdef MPLAB_DSPIC_PORT
#define portRESTORE_CONTEXT() \
asm volatile( "MOV _pxCurrentTCB, W0 \n" /* Restore the stack pointer for the task. */ \
"MOV [W0], W15 \n" \
"POP W0 \n" /* Restore the critical nesting counter for the task. */ \
"MOV W0, _uxCriticalNesting \n" \
"POP PSVPAG \n" \
"POP CORCON \n" \
"POP DOENDH \n" \
"POP DOENDL \n" \
"POP DOSTARTH \n" \
"POP DOSTARTL \n" \
"POP DCOUNT \n" \
"POP ACCBU \n" \
"POP ACCBH \n" \
"POP ACCBL \n" \
"POP ACCAU \n" \
"POP ACCAH \n" \
"POP ACCAL \n" \
"POP TBLPAG \n" \
"POP RCOUNT \n" /* Restore the registers from the stack. */ \
"POP W14 \n" \
"POP.D W12 \n" \
"POP.D W10 \n" \
"POP.D W8 \n" \
"POP.D W6 \n" \
"POP.D W4 \n" \
"POP.D W2 \n" \
"POP.D W0 \n" \
"POP SR " );
#endif /* MPLAB_DSPIC_PORT */
/*
* Setup the timer used to generate the tick interrupt.
*/
static void prvSetupTimerInterrupt( void );
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned short usCode;
portBASE_TYPE i;
const portSTACK_TYPE xInitialStack[] =
{
0x1111, /* W1 */
0x2222, /* W2 */
0x3333, /* W3 */
0x4444, /* W4 */
0x5555, /* W5 */
0x6666, /* W6 */
0x7777, /* W7 */
0x8888, /* W8 */
0x9999, /* W9 */
0xaaaa, /* W10 */
0xbbbb, /* W11 */
0xcccc, /* W12 */
0xdddd, /* W13 */
0xeeee, /* W14 */
0xcdce, /* RCOUNT */
0xabac, /* TBLPAG */
/* dsPIC specific registers. */
#ifdef MPLAB_DSPIC_PORT
0x0202, /* ACCAL */
0x0303, /* ACCAH */
0x0404, /* ACCAU */
0x0505, /* ACCBL */
0x0606, /* ACCBH */
0x0707, /* ACCBU */
0x0808, /* DCOUNT */
0x090a, /* DOSTARTL */
0x1010, /* DOSTARTH */
0x1110, /* DOENDL */
0x1212, /* DOENDH */
#endif
};
/* Setup the stack as if a yield had occurred.
Save the low bytes of the program counter. */
usCode = ( unsigned short ) pxCode;
*pxTopOfStack = ( portSTACK_TYPE ) usCode;
pxTopOfStack++;
/* Save the high byte of the program counter. This will always be zero
here as it is passed in a 16bit pointer. If the address is greater than
16 bits then the pointer will point to a jump table. */
*pxTopOfStack = ( portSTACK_TYPE ) 0;
pxTopOfStack++;
/* Status register with interrupts enabled. */
*pxTopOfStack = portINITIAL_SR;
pxTopOfStack++;
/* Parameters are passed in W0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack++;
for( i = 0; i < ( sizeof( xInitialStack ) / sizeof( portSTACK_TYPE ) ); i++ )
{
*pxTopOfStack = xInitialStack[ i ];
pxTopOfStack++;
}
*pxTopOfStack = CORCON;
pxTopOfStack++;
*pxTopOfStack = PSVPAG;
pxTopOfStack++;
/* Finally the critical nesting depth. */
*pxTopOfStack = 0x00;
pxTopOfStack++;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Setup a timer for the tick ISR. */
prvSetupTimerInterrupt();
/* Restore the context of the first task to run. */
portRESTORE_CONTEXT();
/* Simulate the end of the yield function. */
asm volatile ( "return" );
/* Should not reach here. */
return pdTRUE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the scheduler for the PIC port will get stopped
once running. If required disable the tick interrupt here, then return
to xPortStartScheduler(). */
}
/*-----------------------------------------------------------*/
/*
* Setup a timer for a regular tick.
*/
static void prvSetupTimerInterrupt( void )
{
const unsigned long ulCompareMatch = ( ( configCPU_CLOCK_HZ / portTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1;
/* Prescale of 8. */
T1CON = 0;
TMR1 = 0;
PR1 = ( unsigned short ) ulCompareMatch;
/* Setup timer 1 interrupt priority. */
IPC0bits.T1IP = configKERNEL_INTERRUPT_PRIORITY;
/* Clear the interrupt as a starting condition. */
IFS0bits.T1IF = 0;
/* Enable the interrupt. */
IEC0bits.T1IE = 1;
/* Setup the prescale value. */
T1CONbits.TCKPS0 = 1;
T1CONbits.TCKPS1 = 0;
/* Start the timer. */
T1CONbits.TON = 1;
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
void __attribute__((__interrupt__, auto_psv)) _T1Interrupt( void )
{
/* Clear the timer interrupt. */
IFS0bits.T1IF = 0;
vTaskIncrementTick();
#if configUSE_PREEMPTION == 1
portYIELD();
#endif
}

View file

@ -0,0 +1,117 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
.global _vPortYield
.extern _vTaskSwitchContext
.extern uxCriticalNesting
_vPortYield:
PUSH SR /* Save the SR used by the task.... */
PUSH W0 /* ....then disable interrupts. */
MOV #32, W0
MOV W0, SR
PUSH W1 /* Save registers to the stack. */
PUSH.D W2
PUSH.D W4
PUSH.D W6
PUSH.D W8
PUSH.D W10
PUSH.D W12
PUSH W14
PUSH RCOUNT
PUSH TBLPAG
PUSH CORCON
PUSH PSVPAG
MOV _uxCriticalNesting, W0 /* Save the critical nesting counter for the task. */
PUSH W0
MOV _pxCurrentTCB, W0 /* Save the new top of stack into the TCB. */
MOV W15, [W0]
call _vTaskSwitchContext
MOV _pxCurrentTCB, W0 /* Restore the stack pointer for the task. */
MOV [W0], W15
POP W0 /* Restore the critical nesting counter for the task. */
MOV W0, _uxCriticalNesting
POP PSVPAG
POP CORCON
POP TBLPAG
POP RCOUNT /* Restore the registers from the stack. */
POP W14
POP.D W12
POP.D W10
POP.D W8
POP.D W6
POP.D W4
POP.D W2
POP.D W0
POP SR
return
.end

View file

@ -0,0 +1,140 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
.global _vPortYield
.extern _vTaskSwitchContext
.extern uxCriticalNesting
_vPortYield:
PUSH SR /* Save the SR used by the task.... */
PUSH W0 /* ....then disable interrupts. */
MOV #32, W0
MOV W0, SR
PUSH W1 /* Save registers to the stack. */
PUSH.D W2
PUSH.D W4
PUSH.D W6
PUSH.D W8
PUSH.D W10
PUSH.D W12
PUSH W14
PUSH RCOUNT
PUSH TBLPAG
PUSH ACCAL
PUSH ACCAH
PUSH ACCAU
PUSH ACCBL
PUSH ACCBH
PUSH ACCBU
PUSH DCOUNT
PUSH DOSTARTL
PUSH DOSTARTH
PUSH DOENDL
PUSH DOENDH
PUSH CORCON
PUSH PSVPAG
MOV _uxCriticalNesting, W0 /* Save the critical nesting counter for the task. */
PUSH W0
MOV _pxCurrentTCB, W0 /* Save the new top of stack into the TCB. */
MOV W15, [W0]
call _vTaskSwitchContext
MOV _pxCurrentTCB, W0 /* Restore the stack pointer for the task. */
MOV [W0], W15
POP W0 /* Restore the critical nesting counter for the task. */
MOV W0, _uxCriticalNesting
POP PSVPAG
POP CORCON
POP DOENDH
POP DOENDL
POP DOSTARTH
POP DOSTARTL
POP DCOUNT
POP ACCBU
POP ACCBH
POP ACCBL
POP ACCAU
POP ACCAH
POP ACCAL
POP TBLPAG
POP RCOUNT /* Restore the registers from the stack. */
POP W14
POP.D W12
POP.D W10
POP.D W8
POP.D W6
POP.D W4
POP.D W2
POP.D W0
POP SR
return
.end

View file

@ -0,0 +1,145 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#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 short
#define portSTACK_TYPE unsigned short
#define portBASE_TYPE short
#if( configUSE_16_BIT_TICKS == 1 )
typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff
#else
typedef unsigned portLONG portTickType;
#define portMAX_DELAY ( portTickType ) 0xffffffff
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH 1
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portINTERRUPT_BITS ( ( unsigned portSHORT ) configKERNEL_INTERRUPT_PRIORITY << ( unsigned portSHORT ) 5 )
#define portDISABLE_INTERRUPTS() SR |= portINTERRUPT_BITS
#define portENABLE_INTERRUPTS() SR &= ~portINTERRUPT_BITS
/* Note that exiting a critical sectino will set the IPL bits to 0, nomatter
what their value was prior to entering the critical section. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
extern void vPortYield( void );
#define portYIELD() asm volatile ( "CALL _vPortYield \n" \
"NOP " );
/*-----------------------------------------------------------*/
/* 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 )
/*-----------------------------------------------------------*/
/* Required by the kernel aware debugger. */
#ifdef __DEBUG
#define portREMOVE_STATIC_QUALIFIER
#endif
#define portNOP() asm volatile ( "NOP" )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,230 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#include "FreeRTOSConfig.h"
#define portCONTEXT_SIZE 132
#define portEPC_STACK_LOCATION 124
#define portSTATUS_STACK_LOCATION 128
/******************************************************************/
.macro portSAVE_CONTEXT
/* Make room for the context. First save the current status so we can
manipulate it, and the cause and EPC registers so we capture their
original values in case of interrupt nesting. */
mfc0 k0, _CP0_CAUSE
addiu sp, sp, -portCONTEXT_SIZE
mfc0 k1, _CP0_STATUS
/* Also save s6 and s5 so we can use them during this interrupt. Any
nesting interrupts should maintain the values of these registers
across the ISR. */
sw s6, 44(sp)
sw s5, 40(sp)
sw k1, portSTATUS_STACK_LOCATION(sp)
/* Enable interrupts above the current priority. */
srl k0, k0, 0xa
ins k1, k0, 10, 6
ins k1, zero, 1, 4
/* s5 is used as the frame pointer. */
add s5, zero, sp
/* Check the nesting count value. */
la k0, uxInterruptNesting
lw s6, (k0)
/* If the nesting count is 0 then swap to the the system stack, otherwise
the system stack is already being used. */
bne s6, zero, .+20
nop
/* Swap to the system stack. */
la sp, xISRStackTop
lw sp, (sp)
/* Increment and save the nesting count. */
addiu s6, s6, 1
sw s6, 0(k0)
/* s6 holds the EPC value, this is saved after interrupts are re-enabled. */
mfc0 s6, _CP0_EPC
/* Re-enable interrupts. */
mtc0 k1, _CP0_STATUS
/* Save the context into the space just created. s6 is saved again
here as it now contains the EPC value. No other s registers need be
saved. */
sw ra, 120(s5)
sw s8, 116(s5)
sw t9, 112(s5)
sw t8, 108(s5)
sw t7, 104(s5)
sw t6, 100(s5)
sw t5, 96(s5)
sw t4, 92(s5)
sw t3, 88(s5)
sw t2, 84(s5)
sw t1, 80(s5)
sw t0, 76(s5)
sw a3, 72(s5)
sw a2, 68(s5)
sw a1, 64(s5)
sw a0, 60(s5)
sw v1, 56(s5)
sw v0, 52(s5)
sw s6, portEPC_STACK_LOCATION(s5)
sw $1, 16(s5)
/* s6 is used as a scratch register. */
mfhi s6
sw s6, 12(s5)
mflo s6
sw s6, 8(s5)
/* Update the task stack pointer value if nesting is zero. */
la s6, uxInterruptNesting
lw s6, (s6)
addiu s6, s6, -1
bne s6, zero, .+20
nop
/* Save the stack pointer. */
la s6, uxSavedTaskStackPointer
sw s5, (s6)
.endm
/******************************************************************/
.macro portRESTORE_CONTEXT
/* Restore the stack pointer from the TCB. This is only done if the
nesting count is 1. */
la s6, uxInterruptNesting
lw s6, (s6)
addiu s6, s6, -1
bne s6, zero, .+20
nop
la s6, uxSavedTaskStackPointer
lw s5, (s6)
/* Restore the context. */
lw s6, 8(s5)
mtlo s6
lw s6, 12(s5)
mthi s6
lw $1, 16(s5)
/* s6 is loaded as it was used as a scratch register and therefore saved
as part of the interrupt context. */
lw s6, 44(s5)
lw v0, 52(s5)
lw v1, 56(s5)
lw a0, 60(s5)
lw a1, 64(s5)
lw a2, 68(s5)
lw a3, 72(s5)
lw t0, 76(s5)
lw t1, 80(s5)
lw t2, 84(s5)
lw t3, 88(s5)
lw t4, 92(s5)
lw t5, 96(s5)
lw t6, 100(s5)
lw t7, 104(s5)
lw t8, 108(s5)
lw t9, 112(s5)
lw s8, 116(s5)
lw ra, 120(s5)
/* Protect access to the k registers, and others. */
di
/* Decrement the nesting count. */
la k0, uxInterruptNesting
lw k1, (k0)
addiu k1, k1, -1
sw k1, 0(k0)
lw k0, portSTATUS_STACK_LOCATION(s5)
lw k1, portEPC_STACK_LOCATION(s5)
/* Leave the stack how we found it. First load sp from s5, then restore
s5 from the stack. */
add sp, zero, s5
lw s5, 40(sp)
addiu sp, sp, portCONTEXT_SIZE
mtc0 k0, _CP0_STATUS
mtc0 k1, _CP0_EPC
ehb
eret
nop
.endm

View file

@ -0,0 +1,243 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the PIC32MX port.
*----------------------------------------------------------*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
/* Hardware specifics. */
#define portTIMER_PRESCALE 8
/* Bits within various registers. */
#define portIE_BIT ( 0x00000001 )
#define portEXL_BIT ( 0x00000002 )
/* The EXL bit is set to ensure interrupts do not occur while the context of
the first task is being restored. */
#define portINITIAL_SR ( portIE_BIT | portEXL_BIT )
/* Records the interrupt nesting depth. This starts at one as it will be
decremented to 0 when the first task starts. */
volatile unsigned portBASE_TYPE uxInterruptNesting = 0x01;
/* Stores the task stack pointer when a switch is made to use the system stack. */
unsigned portBASE_TYPE uxSavedTaskStackPointer = 0;
/* The stack used by interrupt service routines that cause a context switch. */
portSTACK_TYPE xISRStack[ configISR_STACK_SIZE ] = { 0 };
/* The top of stack value ensures there is enough space to store 6 registers on
the callers stack, as some functions seem to want to do this. */
const portSTACK_TYPE * const xISRStackTop = &( xISRStack[ configISR_STACK_SIZE - 7 ] );
/*
* Place the prototype here to ensure the interrupt vector is correctly installed.
* Note that because the interrupt is written in assembly, the IPL setting in the
* following line of code has no effect. The interrupt priority is set by the
* call to ConfigIntTimer1() in prvSetupTimerInterrupt().
*/
extern void __attribute__( (interrupt(ipl1), vector(_TIMER_1_VECTOR))) vT1InterruptHandler( void );
/*
* The software interrupt handler that performs the yield. Note that, because
* the interrupt is written in assembly, the IPL setting in the following line of
* code has no effect. The interrupt priority is set by the call to
* mConfigIntCoreSW0() in xPortStartScheduler().
*/
void __attribute__( (interrupt(ipl1), vector(_CORE_SOFTWARE_0_VECTOR))) vPortYieldISR( void );
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Ensure byte alignment is maintained when leaving this function. */
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) 0x12345678; /* Word to which the stack pointer will be left pointing after context restore. */
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) _CP0_GET_CAUSE();
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) portINITIAL_SR; /* CP0_STATUS */
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) pxCode; /* CP0_EPC */
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) NULL; /* ra */
pxTopOfStack -= 15;
*pxTopOfStack = (portSTACK_TYPE) pvParameters; /* Parameters to pass in */
pxTopOfStack -= 14;
*pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level - no longer used. */
pxTopOfStack--;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
/*
* Setup a timer for a regular tick.
*/
void prvSetupTimerInterrupt( void )
{
const unsigned long ulCompareMatch = ( (configPERIPHERAL_CLOCK_HZ / portTIMER_PRESCALE) / configTICK_RATE_HZ ) - 1;
OpenTimer1( ( T1_ON | T1_PS_1_8 | T1_SOURCE_INT ), ulCompareMatch );
ConfigIntTimer1( T1_INT_ON | configKERNEL_INTERRUPT_PRIORITY );
}
/*-----------------------------------------------------------*/
void vPortEndScheduler(void)
{
/* It is unlikely that the scheduler for the PIC port will get stopped
once running. If required disable the tick interrupt here, then return
to xPortStartScheduler(). */
for( ;; );
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
extern void *pxCurrentTCB;
/* Setup the software interrupt. */
mConfigIntCoreSW0( CSW_INT_ON | configKERNEL_INTERRUPT_PRIORITY | CSW_INT_SUB_PRIOR_0 );
/* Setup the timer to generate the tick. Interrupts will have been
disabled by the time we get here. */
prvSetupTimerInterrupt();
/* Kick off the highest priority task that has been created so far.
Its stack location is loaded into uxSavedTaskStackPointer. */
uxSavedTaskStackPointer = *( unsigned portBASE_TYPE * ) pxCurrentTCB;
vPortStartFirstTask();
/* Should never get here as the tasks will now be executing. */
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vPortIncrementTick( void )
{
unsigned portBASE_TYPE uxSavedStatus;
uxSavedStatus = uxPortSetInterruptMaskFromISR();
vTaskIncrementTick();
vPortClearInterruptMaskFromISR( uxSavedStatus );
/* If we are using the preemptive scheduler then we might want to select
a different task to execute. */
#if configUSE_PREEMPTION == 1
SetCoreSW0();
#endif /* configUSE_PREEMPTION */
/* Clear timer 0 interrupt. */
mT1ClearIntFlag();
}
/*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void )
{
unsigned portBASE_TYPE uxSavedStatusRegister;
asm volatile ( "di" );
uxSavedStatusRegister = _CP0_GET_STATUS() | 0x01;
/* This clears the IPL bits, then sets them to
configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called
from an interrupt that has a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY so, when used correctly, the action
can only result in the IPL being unchanged or raised, and therefore never
lowered. */
_CP0_SET_STATUS( ( ( uxSavedStatusRegister & ( ~portALL_IPL_BITS ) ) ) | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) );
return uxSavedStatusRegister;
}
/*-----------------------------------------------------------*/
void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE uxSavedStatusRegister )
{
_CP0_SET_STATUS( uxSavedStatusRegister );
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,306 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#include <p32xxxx.h>
#include <sys/asm.h>
#include "ISR_Support.h"
.set nomips16
.set noreorder
.extern pxCurrentTCB
.extern vTaskSwitchContext
.extern vPortIncrementTick
.extern xISRStackTop
.global vPortStartFirstTask
.global vPortYieldISR
.global vT1InterruptHandler
/******************************************************************/
.set noreorder
.set noat
.ent vT1InterruptHandler
vT1InterruptHandler:
portSAVE_CONTEXT
jal vPortIncrementTick
nop
portRESTORE_CONTEXT
.end vT1InterruptHandler
/******************************************************************/
.set noreorder
.set noat
.ent xPortStartScheduler
vPortStartFirstTask:
/* Simply restore the context of the highest priority task that has been
created so far. */
portRESTORE_CONTEXT
.end xPortStartScheduler
/*******************************************************************/
.set noreorder
.set noat
.ent vPortYieldISR
vPortYieldISR:
/* Make room for the context. First save the current status so we can
manipulate it, and the cause and EPC registers so we capture their
original values in case of interrupt nesting. */
mfc0 k0, _CP0_CAUSE
addiu sp, sp, -portCONTEXT_SIZE
mfc0 k1, _CP0_STATUS
/* Also save s6 and s5 so we can use them during this interrupt. Any
nesting interrupts should maintain the values of these registers
across the ISR. */
sw s6, 44(sp)
sw s5, 40(sp)
sw k1, portSTATUS_STACK_LOCATION(sp)
/* Enable interrupts above the current priority. */
srl k0, k0, 0xa
ins k1, k0, 10, 6
ins k1, zero, 1, 4
/* s5 is used as the frame pointer. */
add s5, zero, sp
/* Swap to the system stack. This is not conditional on the nesting
count as this interrupt is always the lowest priority and therefore
the nesting is always 0. */
la sp, xISRStackTop
lw sp, (sp)
/* Set the nesting count. */
la k0, uxInterruptNesting
addiu s6, zero, 1
sw s6, 0(k0)
/* s6 holds the EPC value, this is saved with the rest of the context
after interrupts are enabled. */
mfc0 s6, _CP0_EPC
/* Re-enable interrupts. */
mtc0 k1, _CP0_STATUS
/* Save the context into the space just created. s6 is saved again
here as it now contains the EPC value. */
sw ra, 120(s5)
sw s8, 116(s5)
sw t9, 112(s5)
sw t8, 108(s5)
sw t7, 104(s5)
sw t6, 100(s5)
sw t5, 96(s5)
sw t4, 92(s5)
sw t3, 88(s5)
sw t2, 84(s5)
sw t1, 80(s5)
sw t0, 76(s5)
sw a3, 72(s5)
sw a2, 68(s5)
sw a1, 64(s5)
sw a0, 60(s5)
sw v1, 56(s5)
sw v0, 52(s5)
sw s7, 48(s5)
sw s6, portEPC_STACK_LOCATION(s5)
/* s5 and s6 has already been saved. */
sw s4, 36(s5)
sw s3, 32(s5)
sw s2, 28(s5)
sw s1, 24(s5)
sw s0, 20(s5)
sw $1, 16(s5)
/* s7 is used as a scratch register as this should always be saved across
nesting interrupts. */
mfhi s7
sw s7, 12(s5)
mflo s7
sw s7, 8(s5)
/* Save the stack pointer to the task. */
la s7, pxCurrentTCB
lw s7, (s7)
sw s5, (s7)
/* Set the interrupt mask to the max priority that can use the API. The
yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which
is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever
raise the IPL value and never lower it. */
di
mfc0 s7, _CP0_STATUS
ins s7, $0, 10, 6
ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1
/* This mtc0 re-enables interrupts, but only above
configMAX_SYSCALL_INTERRUPT_PRIORITY. */
mtc0 s6, _CP0_STATUS
/* Clear the software interrupt in the core. */
mfc0 s6, _CP0_CAUSE
addiu s4,zero,-257
and s6, s6, s4
mtc0 s6, _CP0_CAUSE
/* Clear the interrupt in the interrupt controller. */
la s6, IFS0CLR
addiu s4, zero, 2
sw s4, (s6)
jal vTaskSwitchContext
nop
/* Clear the interrupt mask again. The saved status value is still in s7. */
mtc0 s7, _CP0_STATUS
/* Restore the stack pointer from the TCB. */
la s0, pxCurrentTCB
lw s0, (s0)
lw s5, (s0)
/* Restore the rest of the context. */
lw s0, 8(s5)
mtlo s0
lw s0, 12(s5)
mthi s0
lw $1, 16(s5)
lw s0, 20(s5)
lw s1, 24(s5)
lw s2, 28(s5)
lw s3, 32(s5)
lw s4, 36(s5)
/* s5 is loaded later. */
lw s6, 44(s5)
lw s7, 48(s5)
lw v0, 52(s5)
lw v1, 56(s5)
lw a0, 60(s5)
lw a1, 64(s5)
lw a2, 68(s5)
lw a3, 72(s5)
lw t0, 76(s5)
lw t1, 80(s5)
lw t2, 84(s5)
lw t3, 88(s5)
lw t4, 92(s5)
lw t5, 96(s5)
lw t6, 100(s5)
lw t7, 104(s5)
lw t8, 108(s5)
lw t9, 112(s5)
lw s8, 116(s5)
lw ra, 120(s5)
/* Protect access to the k registers, and others. */
di
/* Set nesting back to zero. As the lowest priority interrupt this
interrupt cannot have nested. */
la k0, uxInterruptNesting
sw zero, 0(k0)
/* Switch back to use the real stack pointer. */
add sp, zero, s5
/* Restore the real s5 value. */
lw s5, 40(sp)
/* Pop the status and epc values. */
lw k1, portSTATUS_STACK_LOCATION(sp)
lw k0, portEPC_STACK_LOCATION(sp)
/* Remove stack frame. */
addiu sp, sp, portCONTEXT_SIZE
mtc0 k1, _CP0_STATUS
mtc0 k0, _CP0_EPC
ehb
eret
nop
.end vPortYieldISR

View file

@ -0,0 +1,193 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
/* System include files */
#include <plib.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 short
#define portSTACK_TYPE unsigned long
#define portBASE_TYPE long
#if( configUSE_16_BIT_TICKS == 1 )
typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff
#else
typedef unsigned long portTickType;
#define portMAX_DELAY ( portTickType ) 0xffffffff
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8
#define portSTACK_GROWTH -1
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portIPL_SHIFT ( 10UL )
#define portALL_IPL_BITS ( 0x3fUL << portIPL_SHIFT )
#define portSW0_BIT ( 0x01 << 8 )
/* This clears the IPL bits, then sets them to
configMAX_SYSCALL_INTERRUPT_PRIORITY. This function should not be called
from an interrupt, so therefore will not be called with an IPL setting
above configMAX_SYSCALL_INTERRUPT_PRIORITY. Therefore, when used correctly, the
instructions in this macro can only result in the IPL being raised, and
therefore never lowered. */
#define portDISABLE_INTERRUPTS() \
{ \
unsigned long ulStatus; \
\
/* Mask interrupts at and below the kernel interrupt priority. */ \
ulStatus = _CP0_GET_STATUS(); \
ulStatus &= ~portALL_IPL_BITS; \
_CP0_SET_STATUS( ( ulStatus | ( configMAX_SYSCALL_INTERRUPT_PRIORITY << portIPL_SHIFT ) ) ); \
}
#define portENABLE_INTERRUPTS() \
{ \
unsigned long ulStatus; \
\
/* Unmask all interrupts. */ \
ulStatus = _CP0_GET_STATUS(); \
ulStatus &= ~portALL_IPL_BITS; \
_CP0_SET_STATUS( ulStatus ); \
}
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portCRITICAL_NESTING_IN_TCB 1
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR();
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMaskFromISR()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) vPortClearInterruptMaskFromISR( uxSavedStatusRegister )
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portYIELD() \
{ \
unsigned long ulStatus; \
\
/* Trigger software interrupt. */ \
ulStatus = _CP0_GET_CAUSE(); \
ulStatus |= portSW0_BIT; \
_CP0_SET_CAUSE( ulStatus ); \
}
#define portNOP() asm volatile ( "nop" )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) \
{ \
portYIELD(); \
}
/* Required by the kernel aware debugger. */
#ifdef __DEBUG
#define portREMOVE_STATIC_QUALIFIER
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */