2006-10-09 19:40:24 +08:00
/*
2017-01-22 13:28:13 +08:00
FreeRTOS V9 .0 .1 - Copyright ( C ) 2017 Real Time Engineers Ltd .
2013-10-15 03:56:47 +08:00
All rights reserved
2012-10-16 20:17:47 +08:00
2013-07-18 02:32:57 +08:00
VISIT http : //www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
2006-10-09 19:40:24 +08:00
2009-10-05 17:46:11 +08:00
This file is part of the FreeRTOS distribution .
2006-10-09 19:40:24 +08:00
2009-10-13 18:54:32 +08:00
FreeRTOS is free software ; you can redistribute it and / or modify it under
2009-10-05 17:46:11 +08:00
the terms of the GNU General Public License ( version 2 ) as published by the
2015-10-16 22:57:00 +08:00
Free Software Foundation > > > > AND MODIFIED BY < < < < the FreeRTOS exception .
2013-02-20 02:36:58 +08:00
2015-03-22 05:03:42 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2014-04-24 22:26:36 +08:00
> > ! 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 . ! < <
2015-03-22 05:03:42 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2013-02-20 02:36:58 +08:00
FreeRTOS is distributed in the hope that it will be useful , but WITHOUT ANY
WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
2014-12-22 03:09:18 +08:00
FOR A PARTICULAR PURPOSE . Full license text is available on the following
2013-07-18 02:32:57 +08:00
link : http : //www.freertos.org/a00114.html
2009-03-15 03:20:12 +08:00
2014-12-22 03:09:18 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* FreeRTOS provides completely free yet professionally developed , *
* robust , strictly quality controlled , supported , and cross *
* platform software that is more than just the market leader , it *
* is the industry ' s de facto standard . *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book , reference manual , or both : *
* http : //www.FreeRTOS.org/Documentation *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2015-01-16 21:20:28 +08:00
http : //www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
2015-03-22 05:03:42 +08:00
the FAQ page " My application does not run, what could be wrong? " . Have you
defined configASSERT ( ) ?
2014-12-22 03:09:18 +08:00
2015-03-22 05:03:42 +08:00
http : //www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum .
2014-12-22 03:09:18 +08:00
2015-03-22 05:03:42 +08:00
http : //www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible . Now you can receive
FreeRTOS training directly from Richard Barry , CEO of Real Time Engineers
Ltd , and the world ' s leading authority on the world ' s leading RTOS .
2013-01-24 00:06:45 +08:00
2012-05-09 00:36:52 +08:00
http : //www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
2013-07-18 02:32:57 +08:00
including FreeRTOS + Trace - an indispensable productivity tool , a DOS
compatible FAT file system , and our tiny thread aware UDP / IP stack .
2013-02-20 02:36:58 +08:00
2014-12-22 03:09:18 +08:00
http : //www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS + TCP , our new open source TCP / IP stack for FreeRTOS .
2015-01-16 21:20:28 +08:00
http : //www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
2014-12-22 03:09:18 +08:00
Integrity Systems ltd . to sell under the OpenRTOS brand . Low cost OpenRTOS
licenses offer ticketed support , indemnification and commercial middleware .
2013-06-09 02:36:25 +08:00
http : //www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
2013-02-20 02:36:58 +08:00
mission critical applications that require provable dependability .
2013-07-18 02:32:57 +08:00
1 tab = = 4 spaces !
2006-10-09 19:40:24 +08:00
*/
2007-06-05 17:56:16 +08:00
/*
Changes from V4 .2 .1
+ Introduced the configKERNEL_INTERRUPT_PRIORITY definition .
*/
2006-10-09 19:40:24 +08:00
/*-----------------------------------------------------------
* 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
2013-01-24 00:06:45 +08:00
/* Defined for backward compatability with project created prior to
2007-06-05 17:56:16 +08:00
FreeRTOS . org V4 .3 .0 . */
# ifndef configKERNEL_INTERRUPT_PRIORITY
# define configKERNEL_INTERRUPT_PRIORITY 1
# endif
2013-06-09 02:36:25 +08:00
/* Use _T1Interrupt as the interrupt handler name if the application writer has
not provided their own . */
# ifndef configTICK_INTERRUPT_HANDLER
# define configTICK_INTERRUPT_HANDLER _T1Interrupt
# endif /* configTICK_INTERRUPT_HANDLER */
2006-10-09 19:40:24 +08:00
/* The program counter is only 23 bits. */
# define portUNUSED_PR_BITS 0x7f
/* Records the nesting depth of calls to portENTER_CRITICAL(). */
2013-12-29 22:06:04 +08:00
UBaseType_t uxCriticalNesting = 0xef ;
2006-10-09 19:40:24 +08:00
2007-06-05 17:56:16 +08:00
# 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
2013-06-09 02:36:25 +08:00
# if defined( __PIC24E__ ) || defined ( __PIC24F__ ) || defined( __PIC24FK__ ) || defined( __PIC24H__ )
2006-10-09 19:40:24 +08:00
2013-01-24 00:06:45 +08:00
# ifdef __HAS_EDS__
2013-02-20 02:36:58 +08:00
# define portRESTORE_CONTEXT() \
asm volatile ( " MOV _pxCurrentTCB, W0 \n " /* Restore the stack pointer for the task. */ \
2013-01-24 00:06:45 +08:00
" MOV [W0], W15 \n " \
" POP W0 \n " /* Restore the critical nesting counter for the task. */ \
" MOV W0, _uxCriticalNesting \n " \
" POP DSWPAG \n " \
2013-02-20 02:36:58 +08:00
" POP DSRPAG \n " \
2013-01-24 00:06:45 +08:00
" 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 " ) ;
# else /* __HAS_EDS__ */
# 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 /* __HAS_EDS__ */
2006-10-09 19:40:24 +08:00
# endif /* MPLAB_PIC24_PORT */
2013-06-12 04:15:15 +08:00
# if defined( __dsPIC30F__ ) || defined( __dsPIC33F__ )
2006-10-09 19:40:24 +08:00
# 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 */
2013-06-09 02:36:25 +08:00
# ifndef portRESTORE_CONTEXT
# error Unrecognised device selected
2014-04-23 23:23:54 +08:00
/* Note: dsPIC parts with EDS are not supported as there is no easy way to
recover the hardware stacked copies for DOCOUNT , DOHIGH , DOLOW . */
2013-06-09 02:36:25 +08:00
# endif
2006-10-09 19:40:24 +08:00
/*
* Setup the timer used to generate the tick interrupt .
*/
2013-06-09 02:36:25 +08:00
void vApplicationSetupTickTimerInterrupt ( void ) ;
2006-10-09 19:40:24 +08:00
2013-01-24 00:06:45 +08:00
/*
* See header file for description .
2006-10-09 19:40:24 +08:00
*/
2014-01-01 00:45:49 +08:00
StackType_t * pxPortInitialiseStack ( StackType_t * pxTopOfStack , TaskFunction_t pxCode , void * pvParameters )
2006-10-09 19:40:24 +08:00
{
2013-12-29 22:06:04 +08:00
uint16_t usCode ;
UBaseType_t i ;
2006-10-09 19:40:24 +08:00
2013-12-29 22:06:04 +08:00
const StackType_t xInitialStack [ ] =
2006-10-09 19:40:24 +08:00
{
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 . */
2013-12-29 22:06:04 +08:00
usCode = ( uint16_t ) pxCode ;
* pxTopOfStack = ( StackType_t ) usCode ;
2006-10-09 19:40:24 +08:00
pxTopOfStack + + ;
/* Save the high byte of the program counter. This will always be zero
here as it is passed in a 16 bit pointer . If the address is greater than
16 bits then the pointer will point to a jump table . */
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0 ;
2006-10-09 19:40:24 +08:00
pxTopOfStack + + ;
/* Status register with interrupts enabled. */
* pxTopOfStack = portINITIAL_SR ;
pxTopOfStack + + ;
/* Parameters are passed in W0. */
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) pvParameters ;
2006-10-09 19:40:24 +08:00
pxTopOfStack + + ;
2013-12-29 22:06:04 +08:00
for ( i = 0 ; i < ( sizeof ( xInitialStack ) / sizeof ( StackType_t ) ) ; i + + )
2006-10-09 19:40:24 +08:00
{
* pxTopOfStack = xInitialStack [ i ] ;
pxTopOfStack + + ;
}
* pxTopOfStack = CORCON ;
pxTopOfStack + + ;
2013-01-24 00:06:45 +08:00
# if defined(__HAS_EDS__)
* pxTopOfStack = DSRPAG ;
pxTopOfStack + + ;
* pxTopOfStack = DSWPAG ;
pxTopOfStack + + ;
# else /* __HAS_EDS__ */
* pxTopOfStack = PSVPAG ;
pxTopOfStack + + ;
# endif /* __HAS_EDS__ */
2006-10-09 19:40:24 +08:00
/* Finally the critical nesting depth. */
* pxTopOfStack = 0x00 ;
pxTopOfStack + + ;
return pxTopOfStack ;
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
BaseType_t xPortStartScheduler ( void )
2006-10-09 19:40:24 +08:00
{
/* Setup a timer for the tick ISR. */
2013-06-09 02:36:25 +08:00
vApplicationSetupTickTimerInterrupt ( ) ;
2006-10-09 19:40:24 +08:00
/* 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 )
{
2013-11-28 18:48:33 +08:00
/* Not implemented in ports where there is nothing to return to.
Artificially force an assert . */
configASSERT ( uxCriticalNesting = = 1000UL ) ;
2006-10-09 19:40:24 +08:00
}
/*-----------------------------------------------------------*/
/*
* Setup a timer for a regular tick .
*/
2013-06-09 02:36:25 +08:00
__attribute__ ( ( weak ) ) void vApplicationSetupTickTimerInterrupt ( void )
2006-10-09 19:40:24 +08:00
{
2013-12-29 22:06:04 +08:00
const uint32_t ulCompareMatch = ( ( configCPU_CLOCK_HZ / portTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1 ;
2006-10-09 19:40:24 +08:00
/* Prescale of 8. */
T1CON = 0 ;
TMR1 = 0 ;
2013-12-29 22:06:04 +08:00
PR1 = ( uint16_t ) ulCompareMatch ;
2006-10-09 19:40:24 +08:00
/* Setup timer 1 interrupt priority. */
2007-06-05 17:56:16 +08:00
IPC0bits . T1IP = configKERNEL_INTERRUPT_PRIORITY ;
2006-10-09 19:40:24 +08:00
/* 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 )
{
2013-11-28 18:48:33 +08:00
configASSERT ( uxCriticalNesting ) ;
2006-10-09 19:40:24 +08:00
uxCriticalNesting - - ;
if ( uxCriticalNesting = = 0 )
{
portENABLE_INTERRUPTS ( ) ;
}
}
/*-----------------------------------------------------------*/
2013-06-09 02:36:25 +08:00
void __attribute__ ( ( __interrupt__ , auto_psv ) ) configTICK_INTERRUPT_HANDLER ( void )
2006-10-09 19:40:24 +08:00
{
/* Clear the timer interrupt. */
IFS0bits . T1IF = 0 ;
2013-06-07 20:16:58 +08:00
if ( xTaskIncrementTick ( ) ! = pdFALSE )
{
2006-10-09 19:40:24 +08:00
portYIELD ( ) ;
2013-06-07 20:16:58 +08:00
}
2006-10-09 19:40:24 +08:00
}
2013-06-07 20:16:58 +08:00