Before changing headers to V6 and changing portLONG, portSHORt and portCHAR to their standard C types.

This commit is contained in:
Richard Barry 2009-10-05 08:33:08 +00:00
parent 3dfbb349ca
commit 5c64e1fad9
4417 changed files with 1261274 additions and 0 deletions

365
20091005/Source/croutine.c Normal file
View file

@ -0,0 +1,365 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
/*
* Some kernel aware debuggers require data to be viewed to be global, rather
* than file scope.
*/
#ifdef portREMOVE_STATIC_QUALIFIER
#define static
#endif
/* Lists for ready and blocked co-routines. --------------------*/
static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */
static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
/* Other file private variables. --------------------------------*/
corCRCB * pxCurrentCoRoutine = NULL;
static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;
static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
/* The initial state of the co-routine when it is created. */
#define corINITIAL_STATE ( 0 )
/*
* Place the co-routine represented by pxCRCB into the appropriate ready queue
* for the priority. It is inserted at the end of the list.
*
* This macro accesses the co-routine ready lists and therefore must not be
* used from within an ISR.
*/
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
{ \
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
{ \
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
} \
vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
}
/*
* Utility to ready all the lists used by the scheduler. This is called
* automatically upon the creation of the first co-routine.
*/
static void prvInitialiseCoRoutineLists( void );
/*
* Co-routines that are readied by an interrupt cannot be placed directly into
* the ready lists (there is no mutual exclusion). Instead they are placed in
* in the pending ready list in order that they can later be moved to the ready
* list by the co-routine scheduler.
*/
static void prvCheckPendingReadyList( void );
/*
* Macro that looks at the list of co-routines that are currently delayed to
* see if any require waking.
*
* Co-routines are stored in the queue in the order of their wake time -
* meaning once one co-routine has been found whose timer has not expired
* we need not look any further down the list.
*/
static void prvCheckDelayedList( void );
/*-----------------------------------------------------------*/
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )
{
signed portBASE_TYPE xReturn;
corCRCB *pxCoRoutine;
/* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );
if( pxCoRoutine )
{
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
be created and the co-routine data structures need initialising. */
if( pxCurrentCoRoutine == NULL )
{
pxCurrentCoRoutine = pxCoRoutine;
prvInitialiseCoRoutineLists();
}
/* Check the priority is within limits. */
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
{
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
}
/* Fill out the co-routine control block from the function parameters. */
pxCoRoutine->uxState = corINITIAL_STATE;
pxCoRoutine->uxPriority = uxPriority;
pxCoRoutine->uxIndex = uxIndex;
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
/* Initialise all the other co-routine control block parameters. */
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
/* Set the co-routine control block as a link back from the xListItem.
This is so we can get back to the containing CRCB from a generic item
in a list. */
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
/* Event lists are always in priority order. */
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
/* Now the co-routine has been initialised it can be added to the ready
list at the correct priority. */
prvAddCoRoutineToReadyQueue( pxCoRoutine );
xReturn = pdPASS;
}
else
{
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn;
}
/*-----------------------------------------------------------*/
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )
{
portTickType xTimeToWake;
/* Calculate the time to wake - this may overflow but this is
not a problem. */
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
/* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for
both lists. */
vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
/* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xCoRoutineTickCount )
{
/* Wake time has overflowed. Place this item in the
overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the
current block list. */
vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
}
if( pxEventList )
{
/* Also add the co-routine to an event list. If this is done then the
function must be called with interrupts disabled. */
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
}
}
/*-----------------------------------------------------------*/
static void prvCheckPendingReadyList( void )
{
/* Are there any co-routines waiting to get moved to the ready list? These
are co-routines that have been readied by an ISR. The ISR cannot access
the ready lists itself. */
while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) )
{
corCRCB *pxUnblockedCRCB;
/* The pending ready list can be accessed by an ISR. */
portDISABLE_INTERRUPTS();
{
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
}
portENABLE_INTERRUPTS();
vListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
}
}
/*-----------------------------------------------------------*/
static void prvCheckDelayedList( void )
{
corCRCB *pxCRCB;
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
while( xPassedTicks )
{
xCoRoutineTickCount++;
xPassedTicks--;
/* If the tick count has overflowed we need to swap the ready lists. */
if( xCoRoutineTickCount == 0 )
{
xList * pxTemp;
/* Tick count has overflowed so we need to swap the delay lists. If there are
any items in pxDelayedCoRoutineList here then there is an error! */
pxTemp = pxDelayedCoRoutineList;
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
pxOverflowDelayedCoRoutineList = pxTemp;
}
/* See if this tick has made a timeout expire. */
while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL )
{
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
{
/* Timeout not yet expired. */
break;
}
portDISABLE_INTERRUPTS();
{
/* The event could have occurred just before this critical
section. If this is the case then the generic list item will
have been moved to the pending ready list and the following
line is still valid. Also the pvContainer parameter will have
been set to NULL so the following lines are also valid. */
vListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */
if( pxCRCB->xEventListItem.pvContainer )
{
vListRemove( &( pxCRCB->xEventListItem ) );
}
}
portENABLE_INTERRUPTS();
prvAddCoRoutineToReadyQueue( pxCRCB );
}
}
xLastTickCount = xCoRoutineTickCount;
}
/*-----------------------------------------------------------*/
void vCoRoutineSchedule( void )
{
/* See if any co-routines readied by events need moving to the ready lists. */
prvCheckPendingReadyList();
/* See if any delayed co-routines have timed out. */
prvCheckDelayedList();
/* Find the highest priority queue that contains ready co-routines. */
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
{
if( uxTopCoRoutineReadyPriority == 0 )
{
/* No more co-routines to check. */
return;
}
--uxTopCoRoutineReadyPriority;
}
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
of the same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
/* Call the co-routine. */
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
return;
}
/*-----------------------------------------------------------*/
static void prvInitialiseCoRoutineLists( void )
{
unsigned portBASE_TYPE uxPriority;
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
{
vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
}
vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );
vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );
vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );
/* Start with pxDelayedCoRoutineList using list1 and the
pxOverflowDelayedCoRoutineList using list2. */
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )
{
corCRCB *pxUnblockedCRCB;
signed portBASE_TYPE xReturn;
/* This function is called from within an interrupt. It can only access
event lists and the pending ready list. */
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
}

View file

@ -0,0 +1,414 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef INC_FREERTOS_H
#define INC_FREERTOS_H
/*
* Include the generic headers required for the FreeRTOS port being used.
*/
#include <stddef.h>
/* Basic FreeRTOS definitions. */
#include "projdefs.h"
/* Application specific configuration options. */
#include "FreeRTOSConfig.h"
/* Definitions specific to the port being used. */
#include "portable.h"
/* Defines the prototype to which the application task hook function must
conform. */
typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
/*
* Check all the required application specific macros have been defined.
* These macros are application specific and (as downloaded) are defined
* within FreeRTOSConfig.h.
*/
#ifndef configUSE_PREEMPTION
#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_IDLE_HOOK
#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_TICK_HOOK
#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_CO_ROUTINES
#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskPrioritySet
#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_uxTaskPriorityGet
#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskDelete
#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskCleanUpResources
#error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskSuspend
#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskDelayUntil
#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskDelay
#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_16_BIT_TICKS
#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_APPLICATION_TASK_TAG
#define configUSE_APPLICATION_TASK_TAG 0
#endif
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#endif
#ifndef configUSE_RECURSIVE_MUTEXES
#define configUSE_RECURSIVE_MUTEXES 0
#endif
#ifndef configUSE_MUTEXES
#define configUSE_MUTEXES 0
#endif
#ifndef configUSE_COUNTING_SEMAPHORES
#define configUSE_COUNTING_SEMAPHORES 0
#endif
#ifndef configUSE_ALTERNATIVE_API
#define configUSE_ALTERNATIVE_API 0
#endif
#ifndef portCRITICAL_NESTING_IN_TCB
#define portCRITICAL_NESTING_IN_TCB 0
#endif
#ifndef configMAX_TASK_NAME_LEN
#define configMAX_TASK_NAME_LEN 16
#endif
#ifndef configIDLE_SHOULD_YIELD
#define configIDLE_SHOULD_YIELD 1
#endif
#if configMAX_TASK_NAME_LEN < 1
#undef configMAX_TASK_NAME_LEN
#define configMAX_TASK_NAME_LEN 1
#endif
#ifndef INCLUDE_xTaskResumeFromISR
#define INCLUDE_xTaskResumeFromISR 1
#endif
#ifndef INCLUDE_xTaskGetSchedulerState
#define INCLUDE_xTaskGetSchedulerState 0
#endif
#if ( configUSE_MUTEXES == 1 )
/* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
within the mutex implementation so must be available if mutexes are used. */
#undef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#else
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 0
#endif
#endif
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
#endif
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
#endif
#ifndef configQUEUE_REGISTRY_SIZE
#define configQUEUE_REGISTRY_SIZE 0
#endif
#if configQUEUE_REGISTRY_SIZE < 1
#define configQUEUE_REGISTRY_SIZE 0
#define vQueueAddToRegistry( xQueue, pcName )
#define vQueueUnregisterQueue( xQueue )
#endif
/* Remove any unused trace macros. */
#ifndef traceSTART
/* Used to perform any necessary initialisation - for example, open a file
into which trace is to be written. */
#define traceSTART()
#endif
#ifndef traceEND
/* Use to close a trace, for example close a file into which trace has been
written. */
#define traceEND()
#endif
#ifndef traceTASK_SWITCHED_IN
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the selected task. */
#define traceTASK_SWITCHED_IN()
#endif
#ifndef traceTASK_SWITCHED_OUT
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the task being switched out. */
#define traceTASK_SWITCHED_OUT()
#endif
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
/* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
#endif
#ifndef traceBLOCKING_ON_QUEUE_SEND
/* Task is about to block because it cannot write to a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the write was attempted. pxCurrentTCB points to the TCB of the
task that attempted the write. */
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
#endif
#ifndef configCHECK_FOR_STACK_OVERFLOW
#define configCHECK_FOR_STACK_OVERFLOW 0
#endif
/* The following event macros are embedded in the kernel API calls. */
#ifndef traceQUEUE_CREATE
#define traceQUEUE_CREATE( pxNewQueue )
#endif
#ifndef traceQUEUE_CREATE_FAILED
#define traceQUEUE_CREATE_FAILED()
#endif
#ifndef traceCREATE_MUTEX
#define traceCREATE_MUTEX( pxNewQueue )
#endif
#ifndef traceCREATE_MUTEX_FAILED
#define traceCREATE_MUTEX_FAILED()
#endif
#ifndef traceGIVE_MUTEX_RECURSIVE
#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
#endif
#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
#endif
#ifndef traceTAKE_MUTEX_RECURSIVE
#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
#endif
#ifndef traceCREATE_COUNTING_SEMAPHORE
#define traceCREATE_COUNTING_SEMAPHORE()
#endif
#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
#endif
#ifndef traceQUEUE_SEND
#define traceQUEUE_SEND( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FAILED
#define traceQUEUE_SEND_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE
#define traceQUEUE_RECEIVE( pxQueue )
#endif
#ifndef traceQUEUE_PEEK
#define traceQUEUE_PEEK( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FAILED
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FROM_ISR
#define traceQUEUE_SEND_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FROM_ISR
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_DELETE
#define traceQUEUE_DELETE( pxQueue )
#endif
#ifndef traceTASK_CREATE
#define traceTASK_CREATE( pxNewTCB )
#endif
#ifndef traceTASK_CREATE_FAILED
#define traceTASK_CREATE_FAILED( pxNewTCB )
#endif
#ifndef traceTASK_DELETE
#define traceTASK_DELETE( pxTaskToDelete )
#endif
#ifndef traceTASK_DELAY_UNTIL
#define traceTASK_DELAY_UNTIL()
#endif
#ifndef traceTASK_DELAY
#define traceTASK_DELAY()
#endif
#ifndef traceTASK_PRIORITY_SET
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
#endif
#ifndef traceTASK_SUSPEND
#define traceTASK_SUSPEND( pxTaskToSuspend )
#endif
#ifndef traceTASK_RESUME
#define traceTASK_RESUME( pxTaskToResume )
#endif
#ifndef traceTASK_RESUME_FROM_ISR
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
#endif
#ifndef traceTASK_INCREMENT_TICK
#define traceTASK_INCREMENT_TICK( xTickCount )
#endif
#ifndef configGENERATE_RUN_TIME_STATS
#define configGENERATE_RUN_TIME_STATS 0
#endif
#if ( configGENERATE_RUN_TIME_STATS == 1 )
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
#ifndef portGET_RUN_TIME_COUNTER_VALUE
#error If configGENERATE_RUN_TIME_STATS is defined then portGET_RUN_TIME_COUNTER_VALUE must also be defined. portGET_RUN_TIME_COUNTER_VALUE should evaluate to the counter value of the timer/counter peripheral used as the run time counter time base.
#endif /* portGET_RUN_TIME_COUNTER_VALUE */
#endif /* configGENERATE_RUN_TIME_STATS */
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#endif
#ifndef configUSE_MALLOC_FAILED_HOOK
#define configUSE_MALLOC_FAILED_HOOK 0
#endif
#ifndef portPRIVILEGE_BIT
#define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
#endif
#ifndef portYIELD_WITHIN_API
#define portYIELD_WITHIN_API portYIELD
#endif
#ifndef pvPortMallocAligned
#define pvPortMallocAligned( xSize, pvBuffer ) pvPortMalloc( xSize ); ( void ) pvBuffer
#endif
#ifndef vPortFreeAligned
#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
#endif
#endif /* INC_FREERTOS_H */

View file

@ -0,0 +1,167 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef STACK_MACROS_H
#define STACK_MACROS_H
/*
* Call the stack overflow hook function if the stack of the task being swapped
* out is currently overflowed, or looks like it might have overflowed in the
* past.
*
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
* the current stack state only - comparing the current top of stack value to
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
* will also cause the last few stack bytes to be checked to ensure the value
* to which the bytes were set when the task was created have not been
* overwritten. Note this second test does not guarantee that an overflowed
* stack will always be recognised.
*/
/*-----------------------------------------------------------*/
#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
/* FreeRTOSConfig.h is not set to check for stack overflows. */
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */
/*-----------------------------------------------------------*/
#if( configCHECK_FOR_STACK_OVERFLOW == 1 )
/* FreeRTOSConfig.h is only set to use the first method of
overflow checking. */
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
#endif
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )
/* Only the current stack state is to be checked. */
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
/* Only the current stack state is to be checked. */
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
\
/* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
{ \
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
\
\
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\
/* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \
}
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/
#endif /* STACK_MACROS_H */

View file

@ -0,0 +1,743 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef INC_FREERTOS_H
#error "#include FreeRTOS.h" must appear in source files before "#include croutine.h"
#endif
#ifndef CO_ROUTINE_H
#define CO_ROUTINE_H
#include "list.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Used to hide the implementation of the co-routine control block. The
control block structure however has to be included in the header due to
the macro implementation of the co-routine functionality. */
typedef void * xCoRoutineHandle;
/* Defines the prototype to which co-routine functions must conform. */
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
typedef struct corCoRoutineControlBlock
{
crCOROUTINE_CODE pxCoRoutineFunction;
xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
unsigned short uxState; /*< Used internally by the co-routine implementation. */
} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
/**
* croutine. h
*<pre>
portBASE_TYPE xCoRoutineCreate(
crCOROUTINE_CODE pxCoRoutineCode,
unsigned portBASE_TYPE uxPriority,
unsigned portBASE_TYPE uxIndex
);</pre>
*
* Create a new co-routine and add it to the list of co-routines that are
* ready to run.
*
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
* functions require special syntax - see the co-routine section of the WEB
* documentation for more information.
*
* @param uxPriority The priority with respect to other co-routines at which
* the co-routine will run.
*
* @param uxIndex Used to distinguish between different co-routines that
* execute the same function. See the example below and the co-routine section
* of the WEB documentation for further information.
*
* @return pdPASS if the co-routine was successfully created and added to a ready
* list, otherwise an error code defined with ProjDefs.h.
*
* Example usage:
<pre>
// Co-routine to be created.
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables.
static const char cLedToFlash[ 2 ] = { 5, 6 };
static const portTickType xTimeToDelay[ 2 ] = { 200, 400 };
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// This co-routine just delays for a fixed period, then toggles
// an LED. Two co-routines are created using this function, so
// the uxIndex parameter is used to tell the co-routine which
// LED to flash and how long to delay. This assumes xQueue has
// already been created.
vParTestToggleLED( cLedToFlash[ uxIndex ] );
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
}
// Must end every co-routine with a call to crEND();
crEND();
}
// Function that creates two co-routines.
void vOtherFunction( void )
{
unsigned char ucParameterToPass;
xTaskHandle xHandle;
// Create two co-routines at priority 0. The first is given index 0
// so (from the code above) toggles LED 5 every 200 ticks. The second
// is given index 1 so toggles LED 6 every 400 ticks.
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
{
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
}
}
</pre>
* \defgroup xCoRoutineCreate xCoRoutineCreate
* \ingroup Tasks
*/
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
/**
* croutine. h
*<pre>
void vCoRoutineSchedule( void );</pre>
*
* Run a co-routine.
*
* vCoRoutineSchedule() executes the highest priority co-routine that is able
* to run. The co-routine will execute until it either blocks, yields or is
* preempted by a task. Co-routines execute cooperatively so one
* co-routine cannot be preempted by another, but can be preempted by a task.
*
* If an application comprises of both tasks and co-routines then
* vCoRoutineSchedule should be called from the idle task (in an idle task
* hook).
*
* Example usage:
<pre>
// This idle task hook will schedule a co-routine each time it is called.
// The rest of the idle task will execute between co-routine calls.
void vApplicationIdleHook( void )
{
vCoRoutineSchedule();
}
// Alternatively, if you do not require any other part of the idle task to
// execute, the idle task hook can call vCoRoutineScheduler() within an
// infinite loop.
void vApplicationIdleHook( void )
{
for( ;; )
{
vCoRoutineSchedule();
}
}
</pre>
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
* \ingroup Tasks
*/
void vCoRoutineSchedule( void );
/**
* croutine. h
* <pre>
crSTART( xCoRoutineHandle xHandle );</pre>
*
* This macro MUST always be called at the start of a co-routine function.
*
* Example usage:
<pre>
// Co-routine to be created.
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static long ulAVariable;
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// Co-routine functionality goes here.
}
// Must end every co-routine with a call to crEND();
crEND();
}</pre>
* \defgroup crSTART crSTART
* \ingroup Tasks
*/
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
/**
* croutine. h
* <pre>
crEND();</pre>
*
* This macro MUST always be called at the end of a co-routine function.
*
* Example usage:
<pre>
// Co-routine to be created.
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static long ulAVariable;
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// Co-routine functionality goes here.
}
// Must end every co-routine with a call to crEND();
crEND();
}</pre>
* \defgroup crSTART crSTART
* \ingroup Tasks
*/
#define crEND() }
/*
* These macros are intended for internal use by the co-routine implementation
* only. The macros should not be used directly by application writers.
*/
#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
/**
* croutine. h
*<pre>
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
*
* Delay a co-routine for a fixed period of time.
*
* crDELAY can only be called from the co-routine function itself - not
* from within a function called by the co-routine function. This is because
* co-routines do not maintain their own stack.
*
* @param xHandle The handle of the co-routine to delay. This is the xHandle
* parameter of the co-routine function.
*
* @param xTickToDelay The number of ticks that the co-routine should delay
* for. The actual amount of time this equates to is defined by
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
* can be used to convert ticks to milliseconds.
*
* Example usage:
<pre>
// Co-routine to be created.
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables.
// We are to delay for 200ms.
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// Delay for 200ms.
crDELAY( xHandle, xDelayTime );
// Do something here.
}
// Must end every co-routine with a call to crEND();
crEND();
}</pre>
* \defgroup crDELAY crDELAY
* \ingroup Tasks
*/
#define crDELAY( xHandle, xTicksToDelay ) \
if( xTicksToDelay > 0 ) \
{ \
vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
} \
crSET_STATE0( xHandle );
/**
* <pre>
crQUEUE_SEND(
xCoRoutineHandle xHandle,
xQueueHandle pxQueue,
void *pvItemToQueue,
portTickType xTicksToWait,
portBASE_TYPE *pxResult
)</pre>
*
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
*
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
* xQueueSend() and xQueueReceive() can only be used from tasks.
*
* crQUEUE_SEND can only be called from the co-routine function itself - not
* from within a function called by the co-routine function. This is because
* co-routines do not maintain their own stack.
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xHandle The handle of the calling co-routine. This is the xHandle
* parameter of the co-routine function.
*
* @param pxQueue The handle of the queue on which the data will be posted.
* The handle is obtained as the return value when the queue is created using
* the xQueueCreate() API function.
*
* @param pvItemToQueue A pointer to the data being posted onto the queue.
* The number of bytes of each queued item is specified when the queue is
* created. This number of bytes is copied from pvItemToQueue into the queue
* itself.
*
* @param xTickToDelay The number of ticks that the co-routine should block
* to wait for space to become available on the queue, should space not be
* available immediately. The actual amount of time this equates to is defined
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
* below).
*
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
* data was successfully posted onto the queue, otherwise it will be set to an
* error defined within ProjDefs.h.
*
* Example usage:
<pre>
// Co-routine function that blocks for a fixed period then posts a number onto
// a queue.
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static portBASE_TYPE xNumberToPost = 0;
static portBASE_TYPE xResult;
// Co-routines must begin with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// This assumes the queue has already been created.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
if( xResult != pdPASS )
{
// The message was not posted!
}
// Increment the number to be posted onto the queue.
xNumberToPost++;
// Delay for 100 ticks.
crDELAY( xHandle, 100 );
}
// Co-routines must end with a call to crEND().
crEND();
}</pre>
* \defgroup crQUEUE_SEND crQUEUE_SEND
* \ingroup Tasks
*/
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
{ \
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \
if( *pxResult == errQUEUE_BLOCKED ) \
{ \
crSET_STATE0( xHandle ); \
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \
} \
if( *pxResult == errQUEUE_YIELD ) \
{ \
crSET_STATE1( xHandle ); \
*pxResult = pdPASS; \
} \
}
/**
* croutine. h
* <pre>
crQUEUE_RECEIVE(
xCoRoutineHandle xHandle,
xQueueHandle pxQueue,
void *pvBuffer,
portTickType xTicksToWait,
portBASE_TYPE *pxResult
)</pre>
*
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
*
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
* xQueueSend() and xQueueReceive() can only be used from tasks.
*
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
* from within a function called by the co-routine function. This is because
* co-routines do not maintain their own stack.
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xHandle The handle of the calling co-routine. This is the xHandle
* parameter of the co-routine function.
*
* @param pxQueue The handle of the queue from which the data will be received.
* The handle is obtained as the return value when the queue is created using
* the xQueueCreate() API function.
*
* @param pvBuffer The buffer into which the received item is to be copied.
* The number of bytes of each queued item is specified when the queue is
* created. This number of bytes is copied into pvBuffer.
*
* @param xTickToDelay The number of ticks that the co-routine should block
* to wait for data to become available from the queue, should data not be
* available immediately. The actual amount of time this equates to is defined
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
* crQUEUE_SEND example).
*
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
* data was successfully retrieved from the queue, otherwise it will be set to
* an error code as defined within ProjDefs.h.
*
* Example usage:
<pre>
// A co-routine receives the number of an LED to flash from a queue. It
// blocks on the queue until the number is received.
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static portBASE_TYPE xResult;
static unsigned portBASE_TYPE uxLEDToFlash;
// All co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// Wait for data to become available on the queue.
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
if( xResult == pdPASS )
{
// We received the LED to flash - flash it!
vParTestToggleLED( uxLEDToFlash );
}
}
crEND();
}</pre>
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
* \ingroup Tasks
*/
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
{ \
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \
if( *pxResult == errQUEUE_BLOCKED ) \
{ \
crSET_STATE0( xHandle ); \
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \
} \
if( *pxResult == errQUEUE_YIELD ) \
{ \
crSET_STATE1( xHandle ); \
*pxResult = pdPASS; \
} \
}
/**
* croutine. h
* <pre>
crQUEUE_SEND_FROM_ISR(
xQueueHandle pxQueue,
void *pvItemToQueue,
portBASE_TYPE xCoRoutinePreviouslyWoken
)</pre>
*
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
* functions used by tasks.
*
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
* xQueueReceiveFromISR() can only be used to pass data between a task and and
* ISR.
*
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
* that is being used from within a co-routine.
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xQueue The handle to the queue on which the item is to be posted.
*
* @param pvItemToQueue A pointer to the item that is to be placed on the
* queue. The size of the items the queue will hold was defined when the
* queue was created, so this many bytes will be copied from pvItemToQueue
* into the queue storage area.
*
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
* the same queue multiple times from a single interrupt. The first call
* should always pass in pdFALSE. Subsequent calls should pass in
* the value returned from the previous call.
*
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
* used by the ISR to determine if a context switch may be required following
* the ISR.
*
* Example usage:
<pre>
// A co-routine that blocks on a queue waiting for characters to be received.
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
char cRxedChar;
portBASE_TYPE xResult;
// All co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// Wait for data to become available on the queue. This assumes the
// queue xCommsRxQueue has already been created!
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
// Was a character received?
if( xResult == pdPASS )
{
// Process the character here.
}
}
// All co-routines must end with a call to crEND().
crEND();
}
// An ISR that uses a queue to send characters received on a serial port to
// a co-routine.
void vUART_ISR( void )
{
char cRxedChar;
portBASE_TYPE xCRWokenByPost = pdFALSE;
// We loop around reading characters until there are none left in the UART.
while( UART_RX_REG_NOT_EMPTY() )
{
// Obtain the character from the UART.
cRxedChar = UART_RX_REG;
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
// the first time around the loop. If the post causes a co-routine
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
// In this manner we can ensure that if more than one co-routine is
// blocked on the queue only one is woken by this ISR no matter how
// many characters are posted to the queue.
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
}
}</pre>
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
* \ingroup Tasks
*/
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
/**
* croutine. h
* <pre>
crQUEUE_SEND_FROM_ISR(
xQueueHandle pxQueue,
void *pvBuffer,
portBASE_TYPE * pxCoRoutineWoken
)</pre>
*
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
* functions used by tasks.
*
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
* xQueueReceiveFromISR() can only be used to pass data between a task and and
* ISR.
*
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
* from a queue that is being used from within a co-routine (a co-routine
* posted to the queue).
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xQueue The handle to the queue on which the item is to be posted.
*
* @param pvBuffer A pointer to a buffer into which the received item will be
* placed. The size of the items the queue will hold was defined when the
* queue was created, so this many bytes will be copied from the queue into
* pvBuffer.
*
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
* *pxCoRoutineWoken will remain unchanged.
*
* @return pdTRUE an item was successfully received from the queue, otherwise
* pdFALSE.
*
* Example usage:
<pre>
// A co-routine that posts a character to a queue then blocks for a fixed
// period. The character is incremented each time.
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// cChar holds its value while this co-routine is blocked and must therefore
// be declared static.
static char cCharToTx = 'a';
portBASE_TYPE xResult;
// All co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// Send the next character to the queue.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
if( xResult == pdPASS )
{
// The character was successfully posted to the queue.
}
else
{
// Could not post the character to the queue.
}
// Enable the UART Tx interrupt to cause an interrupt in this
// hypothetical UART. The interrupt will obtain the character
// from the queue and send it.
ENABLE_RX_INTERRUPT();
// Increment to the next character then block for a fixed period.
// cCharToTx will maintain its value across the delay as it is
// declared static.
cCharToTx++;
if( cCharToTx > 'x' )
{
cCharToTx = 'a';
}
crDELAY( 100 );
}
// All co-routines must end with a call to crEND().
crEND();
}
// An ISR that uses a queue to receive characters to send on a UART.
void vUART_ISR( void )
{
char cCharToTx;
portBASE_TYPE xCRWokenByPost = pdFALSE;
while( UART_TX_REG_EMPTY() )
{
// Are there any characters in the queue waiting to be sent?
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
// is woken by the post - ensuring that only a single co-routine is
// woken no matter how many times we go around this loop.
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
{
SEND_CHARACTER( cCharToTx );
}
}
}</pre>
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
* \ingroup Tasks
*/
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
/*
* This function is intended for internal use by the co-routine macros only.
* The macro nature of the co-routine implementation requires that the
* prototype appears here. The function should not be used by application
* writers.
*
* Removes the current co-routine from its ready list and places it in the
* appropriate delayed list.
*/
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
/*
* This function is intended for internal use by the queue implementation only.
* The function should not be used by application writers.
*
* Removes the highest priority co-routine from the event list and places it in
* the pending ready list.
*/
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
#ifdef __cplusplus
}
#endif
#endif /* CO_ROUTINE_H */

View file

@ -0,0 +1,299 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
* This is the list implementation used by the scheduler. While it is tailored
* heavily for the schedulers needs, it is also available for use by
* application code.
*
* xLists can only store pointers to xListItems. Each xListItem contains a
* numeric value (xItemValue). Most of the time the lists are sorted in
* descending item value order.
*
* Lists are created already containing one list item. The value of this
* item is the maximum possible that can be stored, it is therefore always at
* the end of the list and acts as a marker. The list member pxHead always
* points to this marker - even though it is at the tail of the list. This
* is because the tail contains a wrap back pointer to the true head of
* the list.
*
* In addition to it's value, each list item contains a pointer to the next
* item in the list (pxNext), a pointer to the list it is in (pxContainer)
* and a pointer to back to the object that contains it. These later two
* pointers are included for efficiency of list manipulation. There is
* effectively a two way link between the object containing the list item and
* the list item itself.
*
*
* \page ListIntroduction List Implementation
* \ingroup FreeRTOSIntro
*/
/*
Changes from V4.3.1
+ Included local const within listGET_OWNER_OF_NEXT_ENTRY() to assist
compiler with optimisation. Thanks B.R.
*/
#ifndef LIST_H
#define LIST_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Definition of the only type of object that a list can contain.
*/
struct xLIST_ITEM
{
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
};
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
struct xMINI_LIST_ITEM
{
portTickType xItemValue;
volatile struct xLIST_ITEM *pxNext;
volatile struct xLIST_ITEM *pxPrevious;
};
typedef struct xMINI_LIST_ITEM xMiniListItem;
/*
* Definition of the type of queue used by the scheduler.
*/
typedef struct xLIST
{
volatile unsigned portBASE_TYPE uxNumberOfItems;
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
} xList;
/*
* Access macro to set the owner of a list item. The owner of a list item
* is the object (usually a TCB) that contains the list item.
*
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
* \ingroup LinkedList
*/
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner
/*
* Access macro to set the value of the list item. In most cases the value is
* used to sort the list in descending order.
*
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
* \ingroup LinkedList
*/
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue
/*
* Access macro the retrieve the value of the list item. The value can
* represent anything - for example a the priority of a task, or the time at
* which a task should be unblocked.
*
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
* \ingroup LinkedList
*/
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
/*
* Access macro to determine if a list contains any items. The macro will
* only have the value true if the list is empty.
*
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
* \ingroup LinkedList
*/
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
/*
* Access macro to return the number of items in the list.
*/
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
/*
* Access function to obtain the owner of the next entry in a list.
*
* The list member pxIndex is used to walk through a list. Calling
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
* and returns that entries pxOwner parameter. Using multiple calls to this
* function it is therefore possible to move through every item contained in
* a list.
*
* The pxOwner parameter of a list item is a pointer to the object that owns
* the list item. In the scheduler this is normally a task control block.
* The pxOwner parameter effectively creates a two way link between the list
* item and its owner.
*
* @param pxList The list from which the next item owner is to be returned.
*
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
* \ingroup LinkedList
*/
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
{ \
xList * const pxConstList = pxList; \
/* Increment the index to the next item and return the item, ensuring */ \
/* we don't return the marker used at the end of the list. */ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \
{ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \
pxTCB = ( pxConstList )->pxIndex->pvOwner; \
}
/*
* Access function to obtain the owner of the first entry in a list. Lists
* are normally sorted in ascending item value order.
*
* This function returns the pxOwner member of the first item in the list.
* The pxOwner parameter of a list item is a pointer to the object that owns
* the list item. In the scheduler this is normally a task control block.
* The pxOwner parameter effectively creates a two way link between the list
* item and its owner.
*
* @param pxList The list from which the owner of the head item is to be
* returned.
*
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
* \ingroup LinkedList
*/
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
/*
* Check to see if a list item is within a list. The list item maintains a
* "container" pointer that points to the list it is in. All this macro does
* is check to see if the container and the list match.
*
* @param pxList The list we want to know if the list item is within.
* @param pxListItem The list item we want to know if is in the list.
* @return pdTRUE is the list item is in the list, otherwise pdFALSE.
* pointer against
*/
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )
/*
* Must be called before a list is used! This initialises all the members
* of the list structure and inserts the xListEnd item into the list as a
* marker to the back of the list.
*
* @param pxList Pointer to the list being initialised.
*
* \page vListInitialise vListInitialise
* \ingroup LinkedList
*/
void vListInitialise( xList *pxList );
/*
* Must be called before a list item is used. This sets the list container to
* null so the item does not think that it is already contained in a list.
*
* @param pxItem Pointer to the list item being initialised.
*
* \page vListInitialiseItem vListInitialiseItem
* \ingroup LinkedList
*/
void vListInitialiseItem( xListItem *pxItem );
/*
* Insert a list item into a list. The item will be inserted into the list in
* a position determined by its item value (descending item value order).
*
* @param pxList The list into which the item is to be inserted.
*
* @param pxNewListItem The item to that is to be placed in the list.
*
* \page vListInsert vListInsert
* \ingroup LinkedList
*/
void vListInsert( xList *pxList, xListItem *pxNewListItem );
/*
* Insert a list item into a list. The item will be inserted in a position
* such that it will be the last item within the list returned by multiple
* calls to listGET_OWNER_OF_NEXT_ENTRY.
*
* The list member pvIndex is used to walk through a list. Calling
* listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
* Placing an item in a list using vListInsertEnd effectively places the item
* in the list position pointed to by pvIndex. This means that every other
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
* the pvIndex parameter again points to the item being inserted.
*
* @param pxList The list into which the item is to be inserted.
*
* @param pxNewListItem The list item to be inserted into the list.
*
* \page vListInsertEnd vListInsertEnd
* \ingroup LinkedList
*/
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
/*
* Remove an item from a list. The list item has a pointer to the list that
* it is in, so only the list item need be passed into the function.
*
* @param vListRemove The item to be removed. The item will remove itself from
* the list pointed to by it's pxContainer parameter.
*
* \page vListRemove vListRemove
* \ingroup LinkedList
*/
void vListRemove( xListItem *pxItemToRemove );
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,124 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef MPU_WRAPPERS_H
#define MPU_WRAPPERS_H
/* This file redefines API functions to be called through a wrapper macro, but
only for ports that are using the MPU. */
#ifdef portUSING_MPU_WRAPPERS
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
included from queue.c or task.c to prevent it from having an effict within
those files. */
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#define xTaskGenericCreate MPU_xTaskGenericCreate
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
#define vTaskDelete MPU_vTaskDelete
#define vTaskDelayUntil MPU_vTaskDelayUntil
#define vTaskDelay MPU_vTaskDelay
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
#define vTaskPrioritySet MPU_vTaskPrioritySet
#define vTaskSuspend MPU_vTaskSuspend
#define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended
#define vTaskResume MPU_vTaskResume
#define vTaskSuspendAll MPU_vTaskSuspendAll
#define xTaskResumeAll MPU_xTaskResumeAll
#define xTaskGetTickCount MPU_xTaskGetTickCount
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
#define vTaskList MPU_vTaskList
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define vTaskStartTrace MPU_vTaskStartTrace
#define ulTaskEndTrace MPU_ulTaskEndTrace
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
#define xQueueCreate MPU_xQueueCreate
#define xQueueCreateMutex MPU_xQueueCreateMutex
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
#define xQueueGenericSend MPU_xQueueGenericSend
#define xQueueAltGenericSend MPU_xQueueAltGenericSend
#define xQueueAltGenericReceive MPU_xQueueAltGenericReceive
#define xQueueGenericReceive MPU_xQueueGenericReceive
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define vQueueDelete MPU_vQueueDelete
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
#define pvPortMalloc MPU_pvPortMalloc
#define vPortFree MPU_vPortFree
/* Remove the privileged function macro. */
#define PRIVILEGED_FUNCTION
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Ensure API functions go in the privileged execution section. */
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
//#define PRIVILEGED_DATA
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
#else /* portUSING_MPU_WRAPPERS */
#define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA
#define portUSING_MPU_WRAPPERS 0
#endif /* portUSING_MPU_WRAPPERS */
#endif /* MPU_WRAPPERS_H */

View file

@ -0,0 +1,383 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Portable layer API. Each function must be defined for each port.
*----------------------------------------------------------*/
#ifndef PORTABLE_H
#define PORTABLE_H
/* Include the macro file relevant to the port being used. */
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
typedef void ( __interrupt __far *pxISR )();
#endif
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
typedef void ( __interrupt __far *pxISR )();
#endif
#ifdef GCC_MEGA_AVR
#include "../portable/GCC/ATMega323/portmacro.h"
#endif
#ifdef IAR_MEGA_AVR
#include "../portable/IAR/ATMega323/portmacro.h"
#endif
#ifdef MPLAB_PIC24_PORT
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
#endif
#ifdef MPLAB_DSPIC_PORT
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
#endif
#ifdef MPLAB_PIC18F_PORT
#include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
#endif
#ifdef MPLAB_PIC32MX_PORT
#include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"
#endif
#ifdef _FEDPICC
#include "libFreeRTOS/Include/portmacro.h"
#endif
#ifdef SDCC_CYGNAL
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
#endif
#ifdef GCC_ARM7
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
#endif
#ifdef GCC_ARM7_ECLIPSE
#include "portmacro.h"
#endif
#ifdef ROWLEY_LPC23xx
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
#endif
#ifdef IAR_MSP430
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
#endif
#ifdef GCC_MSP430
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
#endif
#ifdef ROWLEY_MSP430
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
#endif
#ifdef ARM7_LPC21xx_KEIL_RVDS
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
#endif
#ifdef SAM7_GCC
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
#endif
#ifdef SAM7_IAR
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
#endif
#ifdef SAM9XE_IAR
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
#endif
#ifdef LPC2000_IAR
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
#endif
#ifdef STR71X_IAR
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
#endif
#ifdef STR75X_IAR
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
#endif
#ifdef STR75X_GCC
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
#endif
#ifdef STR91X_IAR
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
#endif
#ifdef GCC_H8S
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
#endif
#ifdef GCC_AT91FR40008
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
#endif
#ifdef RVDS_ARMCM3_LM3S102
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
#endif
#ifdef GCC_ARMCM3_LM3S102
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif
#ifdef GCC_ARMCM3
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif
#ifdef IAR_ARM_CM3
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif
#ifdef IAR_ARMCM3_LM
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif
#ifdef HCS12_CODE_WARRIOR
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
#endif
#ifdef MICROBLAZE_GCC
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
#endif
#ifdef TERN_EE
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
#endif
#ifdef GCC_HCS12
#include "../../Source/portable/GCC/HCS12/portmacro.h"
#endif
#ifdef GCC_MCF5235
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
#endif
#ifdef COLDFIRE_V2_GCC
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
#endif
#ifdef COLDFIRE_V2_CODEWARRIOR
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
#endif
#ifdef GCC_PPC405
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
#endif
#ifdef GCC_PPC440
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
#endif
#ifdef _16FX_SOFTUNE
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
#endif
#ifdef BCC_INDUSTRIAL_PC_PORT
/* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */
#include "frconfig.h"
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
typedef void ( __interrupt __far *pxISR )();
#endif
#ifdef BCC_FLASH_LITE_186_PORT
/* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */
#include "frconfig.h"
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
typedef void ( __interrupt __far *pxISR )();
#endif
#ifdef __GNUC__
#ifdef __AVR32_AVR32A__
#include "portmacro.h"
#endif
#endif
#ifdef __ICCAVR32__
#ifdef __CORE__
#if __CORE__ == __AVR32A__
#include "portmacro.h"
#endif
#endif
#endif
#ifdef __91467D
#include "portmacro.h"
#endif
#ifdef __96340
#include "portmacro.h"
#endif
#ifdef __IAR_V850ES_Fx3__
#include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif
#ifdef __IAR_V850ES_Jx3__
#include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif
#ifdef __IAR_V850ES_Jx3_L__
#include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif
#ifdef __IAR_V850ES_Jx2__
#include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif
#ifdef __IAR_V850ES_Hx2__
#include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif
#ifdef __IAR_78K0R_Kx3__
#include "../../Source/portable/IAR/78K0R/portmacro.h"
#endif
#ifdef __IAR_78K0R_Kx3L__
#include "../../Source/portable/IAR/78K0R/portmacro.h"
#endif
/* Catch all to ensure portmacro.h is included in the build. Newer demos
have the path as part of the project options, rather than as relative from
the project location. If portENTER_CRITICAL() has not been defined then
portmacro.h has not yet been included - as every portmacro.h provides a
portENTER_CRITICAL() definition. Check the demo application for your demo
to find the path to the correct portmacro.h file. */
#ifndef portENTER_CRITICAL
#include "portmacro.h"
#endif
#if portBYTE_ALIGNMENT == 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
#endif
#if portBYTE_ALIGNMENT == 4
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
#endif
#if portBYTE_ALIGNMENT == 2
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
#endif
#if portBYTE_ALIGNMENT == 1
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
#endif
#ifndef portBYTE_ALIGNMENT_MASK
#error "Invalid portBYTE_ALIGNMENT definition"
#endif
#ifndef portNUM_CONFIGURABLE_REGIONS
#define portNUM_CONFIGURABLE_REGIONS 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "mpu_wrappers.h"
/*
* Setup the stack of a new task so it is ready to be placed under the
* scheduler control. The registers have to be placed on the stack in
* the order that the port expects to find them.
*
*/
#if( portUSING_MPU_WRAPPERS == 1 )
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;
#else
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );
#endif
/*
* Map to the memory management routines required for the port.
*/
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
/*
* Setup the hardware ready for the scheduler to take control. This generally
* sets up a tick interrupt and sets timers for the correct tick frequency.
*/
portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
/*
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
* the hardware is left in its original condition after the scheduler stops
* executing.
*/
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
/*
* The structures and methods of manipulating the MPU are contained within the
* port layer.
*
* Fills the xMPUSettings structure with the memory region information
* contained in xRegions.
*/
#if( portUSING_MPU_WRAPPERS == 1 )
struct xMEMORY_REGION;
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned portSHORT usStackDepth ) PRIVILEGED_FUNCTION;
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTABLE_H */

View file

@ -0,0 +1,71 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef PROJDEFS_H
#define PROJDEFS_H
/* Defines the prototype to which task functions must conform. */
typedef void (*pdTASK_CODE)( void * );
#define pdTRUE ( 1 )
#define pdFALSE ( 0 )
#define pdPASS ( 1 )
#define pdFAIL ( 0 )
#define errQUEUE_EMPTY ( 0 )
#define errQUEUE_FULL ( 0 )
/* Error definitions. */
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
#define errNO_TASK_TO_RUN ( -2 )
#define errQUEUE_BLOCKED ( -4 )
#define errQUEUE_YIELD ( -5 )
#endif /* PROJDEFS_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,705 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef INC_FREERTOS_H
#error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
#endif
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include "queue.h"
typedef xQueueHandle xSemaphoreHandle;
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 )
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 )
/**
* semphr. h
* <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
*
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
* The queue length is 1 as this is a binary semaphore. The data size is 0
* as we don't want to actually store any data - we just want to know if the
* queue is empty or full.
*
* This type of semaphore can be used for pure synchronisation between tasks or
* between an interrupt and a task. The semaphore need not be given back once
* obtained, so one task/interrupt can continuously 'give' the semaphore while
* another continuously 'takes' the semaphore. For this reason this type of
* semaphore does not use a priority inheritance mechanism. For an alternative
* that does use priority inheritance see xSemaphoreCreateMutex().
*
* @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
// This is a macro so pass the variable in directly.
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
#define vSemaphoreCreateBinary( xSemaphore ) { \
xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( xSemaphore != NULL ) \
{ \
xSemaphoreGive( xSemaphore ); \
} \
}
/**
* semphr. h
* xSemaphoreTake(
* xSemaphoreHandle xSemaphore,
* portTickType xBlockTime
* )</pre>
*
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting().
*
* @param xSemaphore A handle to the semaphore being taken - obtained when
* the semaphore was created.
*
* @param xBlockTime The time in ticks to wait for the semaphore to become
* available. The macro portTICK_RATE_MS can be used to convert this to a
* real time. A block time of zero can be used to poll the semaphore. A block
* time of portMAX_DELAY can be used to block indefinitely (provided
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
*
* @return pdTRUE if the semaphore was obtained. pdFALSE
* if xBlockTime expired without the semaphore becoming available.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore = NULL;
// A task that creates a semaphore.
void vATask( void * pvParameters )
{
// Create the semaphore to guard a shared resource.
vSemaphoreCreateBinary( xSemaphore );
}
// A task that uses the semaphore.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xSemaphore != NULL )
{
// See if we can obtain the semaphore. If the semaphore is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the semaphore and can now access the
// shared resource.
// ...
// We have finished accessing the shared resource. Release the
// semaphore.
xSemaphoreGive( xSemaphore );
}
else
{
// We could not obtain the semaphore and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreTake xSemaphoreTake
* \ingroup Semaphores
*/
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
/**
* semphr. h
* xSemaphoreTakeRecursive(
* xSemaphoreHandle xMutex,
* portTickType xBlockTime
* )
*
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
* The mutex must have previously been created using a call to
* xSemaphoreCreateRecursiveMutex();
*
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
* macro to be available.
*
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being obtained. This is the
* handle returned by xSemaphoreCreateRecursiveMutex();
*
* @param xBlockTime The time in ticks to wait for the semaphore to become
* available. The macro portTICK_RATE_MS can be used to convert this to a
* real time. A block time of zero can be used to poll the semaphore. If
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
* return immediately no matter what the value of xBlockTime.
*
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
* expired without the semaphore becoming available.
*
* Example usage:
<pre>
xSemaphoreHandle xMutex = NULL;
// A task that creates a mutex.
void vATask( void * pvParameters )
{
// Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex();
}
// A task that uses the mutex.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xMutex != NULL )
{
// See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the mutex and can now access the
// shared resource.
// ...
// For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside
// a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
// The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, but instead buried in a more complex
// call structure. This is just for illustrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks.
}
else
{
// We could not obtain the mutex and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
* \ingroup Semaphores
*/
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime )
/*
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
*
* The source code that implements the alternative (Alt) API is much
* simpler because it executes everything from within a critical section.
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
* preferred fully featured API too. The fully featured API has more
* complex code that takes longer to execute, but makes much less use of
* critical sections. Therefore the alternative API sacrifices interrupt
* responsiveness to gain execution speed, whereas the fully featured API
* sacrifices execution speed to ensure better interrupt responsiveness.
*/
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
/**
* semphr. h
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
*
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
* an alternative which can be used from an ISR.
*
* This macro must also not be used on semaphores created using
* xSemaphoreCreateRecursiveMutex().
*
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
* Semaphores are implemented using queues. An error can occur if there is
* no space on the queue to post a message - indicating that the
* semaphore was not first obtained correctly.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore = NULL;
void vATask( void * pvParameters )
{
// Create the semaphore to guard a shared resource.
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore != NULL )
{
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{
// We would expect this call to fail because we cannot give
// a semaphore without first "taking" it!
}
// Obtain the semaphore - don't block if the semaphore is not
// immediately available.
if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
{
// We now have the semaphore and can access the shared resource.
// ...
// We have finished accessing the shared resource so can free the
// semaphore.
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{
// We would not expect this call to fail because we must have
// obtained the semaphore to get here.
}
}
}
}
</pre>
* \defgroup xSemaphoreGive xSemaphoreGive
* \ingroup Semaphores
*/
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
*
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
* The mutex must have previously been created using a call to
* xSemaphoreCreateRecursiveMutex();
*
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
* macro to be available.
*
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being released, or 'given'. This is the
* handle returned by xSemaphoreCreateMutex();
*
* @return pdTRUE if the semaphore was given.
*
* Example usage:
<pre>
xSemaphoreHandle xMutex = NULL;
// A task that creates a mutex.
void vATask( void * pvParameters )
{
// Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex();
}
// A task that uses the mutex.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xMutex != NULL )
{
// See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the mutex and can now access the
// shared resource.
// ...
// For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside
// a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
// The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, it would be more likely that the calls
// to xSemaphoreGiveRecursive() would be called as a call stack
// unwound. This is just for demonstrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks.
}
else
{
// We could not obtain the mutex and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
* \ingroup Semaphores
*/
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex )
/*
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
*
* The source code that implements the alternative (Alt) API is much
* simpler because it executes everything from within a critical section.
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
* preferred fully featured API too. The fully featured API has more
* complex code that takes longer to execute, but makes much less use of
* critical sections. Therefore the alternative API sacrifices interrupt
* responsiveness to gain execution speed, whereas the fully featured API
* sacrifices execution speed to ensure better interrupt responsiveness.
*/
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>
xSemaphoreGiveFromISR(
xSemaphoreHandle xSemaphore,
portBASE_TYPE *pxHigherPriorityTaskWoken
)</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
*
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
* must not be used with this macro.
*
* This macro can be used from an ISR.
*
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
* @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
* *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
* to unblock, and the unblocked task has a priority higher than the currently
* running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
* a context switch should be requested before the interrupt is exited.
*
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
*
* Example usage:
<pre>
#define LONG_TIME 0xffff
#define TICKS_TO_WAIT 10
xSemaphoreHandle xSemaphore = NULL;
// Repetitive task.
void vATask( void * pvParameters )
{
for( ;; )
{
// We want this task to run every 10 ticks of a timer. The semaphore
// was created before this task was started.
// Block waiting for the semaphore to become available.
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
{
// It is time to execute.
// ...
// We have finished our task. Return to the top of the loop where
// we will block on the semaphore until it is time to execute
// again. Note when using the semaphore for synchronisation with an
// ISR in this manner there is no need to 'give' the semaphore back.
}
}
}
// Timer ISR
void vTimerISR( void * pvParameters )
{
static unsigned char ucLocalTickCount = 0;
static portBASE_TYPE xHigherPriorityTaskWoken;
// A timer tick has occurred.
// ... Do other time functions.
// Is it time for vATask () to run?
xHigherPriorityTaskWoken = pdFALSE;
ucLocalTickCount++;
if( ucLocalTickCount >= TICKS_TO_WAIT )
{
// Unblock the task by releasing the semaphore.
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
// Reset the count so we release the semaphore again in 10 ticks time.
ucLocalTickCount = 0;
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
// We can force a context switch here. Context switching from an
// ISR uses port specific syntax. Check the demo task for your port
// to find the syntax required.
}
}
</pre>
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
* \ingroup Semaphores
*/
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
*
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
* mechanism.
*
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
* xSemaphoreGiveRecursive() macros should not be used.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
* semaphore it is no longer required.
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
* See vSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
* xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateMutex();
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
* \ingroup Semaphores
*/
#define xSemaphoreCreateMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
*
* <i>Macro</i> that implements a recursive mutex by using the existing queue
* mechanism.
*
* Mutexes created using this macro can be accessed using the
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
* semaphore it is no longer required.
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
* See vSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
* xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateRecursiveMutex();
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
* \ingroup Semaphores
*/
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
*
* <i>Macro</i> that creates a counting semaphore by using the existing
* queue mechanism.
*
* Counting semaphores are typically used for two things:
*
* 1) Counting events.
*
* In this usage scenario an event handler will 'give' a semaphore each time
* an event occurs (incrementing the semaphore count value), and a handler
* task will 'take' a semaphore each time it processes an event
* (decrementing the semaphore count value). The count value is therefore
* the difference between the number of events that have occurred and the
* number that have been processed. In this case it is desirable for the
* initial count value to be zero.
*
* 2) Resource management.
*
* In this usage scenario the count value indicates the number of resources
* available. To obtain control of a resource a task must first obtain a
* semaphore - decrementing the semaphore count value. When the count value
* reaches zero there are no free resources. When a task finishes with the
* resource it 'gives' the semaphore back - incrementing the semaphore count
* value. In this case it is desirable for the initial count value to be
* equal to the maximum count value, indicating that all resources are free.
*
* @param uxMaxCount The maximum count value that can be reached. When the
* semaphore reaches this value it can no longer be 'given'.
*
* @param uxInitialCount The count value assigned to the semaphore when it is
* created.
*
* @return Handle to the created semaphore. Null if the semaphore could not be
* created.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
xSemaphoreHandle xSemaphore = NULL;
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
// The max value to which the semaphore can count should be 10, and the
// initial value assigned to the count should be 0.
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores
*/
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
#endif /* SEMAPHORE_H */

File diff suppressed because it is too large Load diff

185
20091005/Source/list.c Normal file
View file

@ -0,0 +1,185 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include <stdlib.h>
#include "FreeRTOS.h"
#include "list.h"
/*-----------------------------------------------------------
* PUBLIC LIST API documented in list.h
*----------------------------------------------------------*/
void vListInitialise( xList *pxList )
{
/* The list structure contains a list item which is used to mark the
end of the list. To initialise the list the list end is inserted
as the only list entry. */
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );
/* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */
pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know
when the list is empty. */
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
pxList->uxNumberOfItems = 0;
}
/*-----------------------------------------------------------*/
void vListInitialiseItem( xListItem *pxItem )
{
/* Make sure the list item is not recorded as being on a list. */
pxItem->pvContainer = NULL;
}
/*-----------------------------------------------------------*/
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
{
volatile xListItem * pxIndex;
/* Insert a new list item into pxList, but rather than sort the list,
makes the new list item the last item to be removed by a call to
pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
the pxIndex member. */
pxIndex = pxList->pxIndex;
pxNewListItem->pxNext = pxIndex->pxNext;
pxNewListItem->pxPrevious = pxList->pxIndex;
pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;
pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/
void vListInsert( xList *pxList, xListItem *pxNewListItem )
{
volatile xListItem *pxIterator;
portTickType xValueOfInsertion;
/* Insert the new list item into the list, sorted in ulListItem order. */
xValueOfInsertion = pxNewListItem->xItemValue;
/* If the list already contains a list item with the same item value then
the new list item should be placed after it. This ensures that TCB's which
are stored in ready lists (all of which have the same ulListItem value)
get an equal share of the CPU. However, if the xItemValue is the same as
the back marker the iteration loop below will not end. This means we need
to guard against this by checking the value first and modifying the
algorithm slightly if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
/* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are:
1) Stack overflow -
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex M3
parts where numerically high priority values denote low actual
interrupt priories, which can seem counter intuitive. See
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when
the scheduler is suspended.
4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?).
See http://www.freertos.org/FAQHelp.html for more tips.
**********************************************************************/
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/
void vListRemove( xListItem *pxItemToRemove )
{
xList * pxList;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
/* The list item knows which list it is in. Obtain the list from the list
item. */
pxList = ( xList * ) pxItemToRemove->pvContainer;
/* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
pxItemToRemove->pvContainer = NULL;
( pxList->uxNumberOfItems )--;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,268 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V1.00:
+ Call to taskYIELD() from within tick ISR has been replaced by the more
efficient portSWITCH_CONTEXT().
+ ISR function definitions renamed to include the prv prefix.
Changes from V2.6.1
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
macro to be consistent with the later ports.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Flashlite 186
* port.
*----------------------------------------------------------*/
#include <dos.h>
#include <stdlib.h>
#include <setjmp.h>
#include "FreeRTOS.h"
#include "task.h"
#include "portasm.h"
/*lint -e950 Non ANSI reserved words okay in this file only. */
#define portTIMER_EOI_TYPE ( 8 )
#define portRESET_PIC() portOUTPUT_WORD( ( unsigned portSHORT ) 0xff22, portTIMER_EOI_TYPE )
#define portTIMER_INT_NUMBER 0x12
#define portTIMER_1_CONTROL_REGISTER ( ( unsigned portSHORT ) 0xff5e )
#define portTIMER_0_CONTROL_REGISTER ( ( unsigned portSHORT ) 0xff56 )
#define portTIMER_INTERRUPT_ENABLE ( ( unsigned portSHORT ) 0x2000 )
/* Setup the hardware to generate the required tick frequency. */
static void prvSetTickFrequency( unsigned portLONG ulTickRateHz );
/* Set the hardware back to the state as per before the scheduler started. */
static void prvExitFunction( void );
/* The ISR used depends on whether the preemptive or cooperative scheduler
is being used. */
#if( configUSE_PREEMPTION == 1 )
/* Tick service routine used by the scheduler when preemptive scheduling is
being used. */
static void __interrupt __far prvPreemptiveTick( void );
#else
/* Tick service routine used by the scheduler when cooperative scheduling is
being used. */
static void __interrupt __far prvNonPreemptiveTick( void );
#endif
/* Trap routine used by taskYIELD() to manually cause a context switch. */
static void __interrupt __far prvYieldProcessor( void );
/*lint -e956 File scopes necessary here. */
/* Set true when the vectors are set so the scheduler will service the tick. */
static portBASE_TYPE xSchedulerRunning = pdFALSE;
/* Points to the original routine installed on the vector we use for manual
context switches. This is then used to restore the original routine during
prvExitFunction(). */
static void ( __interrupt __far *pxOldSwitchISR )();
/* Used to restore the original DOS context when the scheduler is ended. */
static jmp_buf xJumpBuf;
/*lint +e956 */
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* This is called with interrupts already disabled. */
/* Remember what was on the interrupts we are going to use
so we can put them back later if required. */
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
/* Put our manual switch (yield) function on a known
vector. */
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
#if( configUSE_PREEMPTION == 1 )
{
/* Put our tick switch function on the timer interrupt. */
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
}
#else
{
/* We want the timer interrupt to just increment the tick count. */
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
}
#endif
prvSetTickFrequency( configTICK_RATE_HZ );
/* Clean up function if we want to return to DOS. */
if( setjmp( xJumpBuf ) != 0 )
{
prvExitFunction();
xSchedulerRunning = pdFALSE;
}
else
{
xSchedulerRunning = pdTRUE;
/* Kick off the scheduler by setting up the context of the first task. */
portFIRST_CONTEXT();
}
return xSchedulerRunning;
}
/*-----------------------------------------------------------*/
/* The ISR used depends on whether the preemptive or cooperative scheduler
is being used. */
#if( configUSE_PREEMPTION == 1 )
static void __interrupt __far prvPreemptiveTick( void )
{
/* Get the scheduler to update the task states following the tick. */
vTaskIncrementTick();
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
/* Reset the PIC ready for the next time. */
portRESET_PIC();
}
#else
static void __interrupt __far prvNonPreemptiveTick( void )
{
/* Same as preemptive tick, but the cooperative scheduler is being used
so we don't have to switch in the context of the next task. */
vTaskIncrementTick();
portRESET_PIC();
}
#endif
/*-----------------------------------------------------------*/
static void __interrupt __far prvYieldProcessor( void )
{
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Jump back to the processor state prior to starting the
scheduler. This means we are not going to be using a
task stack frame so the task can be deleted. */
longjmp( xJumpBuf, 1 );
}
/*-----------------------------------------------------------*/
static void prvExitFunction( void )
{
const unsigned portSHORT usTimerDisable = 0x0000;
unsigned portSHORT usTimer0Control;
/* Interrupts should be disabled here anyway - but no
harm in making sure. */
portDISABLE_INTERRUPTS();
if( xSchedulerRunning == pdTRUE )
{
/* Put back the switch interrupt routines that was in place
before the scheduler started. */
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
}
/* Disable the timer used for the tick to ensure the scheduler is
not called before restoring interrupts. There was previously nothing
on this timer so there is no old ISR to restore. */
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
/* Restart the DOS tick. */
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
usTimer0Control |= portTIMER_INTERRUPT_ENABLE;
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
portENABLE_INTERRUPTS();
/* This will free up all the memory used by the scheduler.
exiting back to dos with INT21 AH=4CH will do this anyway so
it is not necessary to call this. */
vTaskCleanUpResources();
}
/*-----------------------------------------------------------*/
static void prvSetTickFrequency( unsigned portLONG ulTickRateHz )
{
const unsigned portSHORT usMaxCountRegister = 0xff5a;
const unsigned portSHORT usTimerPriorityRegister = 0xff32;
const unsigned portSHORT usTimerEnable = 0xC000;
const unsigned portSHORT usRetrigger = 0x0001;
const unsigned portSHORT usTimerHighPriority = 0x0000;
unsigned portSHORT usTimer0Control;
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
const unsigned portLONG ulClockFrequency = ( unsigned portLONG ) 0x7f31a0UL;
unsigned portLONG ulTimerCount = ulClockFrequency / ulTickRateHz;
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
portOUTPUT_WORD( usMaxCountRegister, ( unsigned portSHORT ) ulTimerCount );
portOUTPUT_WORD( usTimerPriorityRegister, usTimerHighPriority );
/* Stop the DOS tick - don't do this if you want to maintain a TOD clock. */
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
usTimer0Control &= ~portTIMER_INTERRUPT_ENABLE;
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
}
/*lint +e950 */

View file

@ -0,0 +1,113 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 long
#define portLONG long
#define portSHORT int
#define portSTACK_TYPE unsigned portSHORT
#define portBASE_TYPE portSHORT
#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
/*-----------------------------------------------------------*/
/* Critical section handling. */
#define portENTER_CRITICAL() __asm{ pushf } \
__asm{ cli } \
#define portEXIT_CRITICAL() __asm{ popf }
#define portDISABLE_INTERRUPTS() __asm{ cli }
#define portENABLE_INTERRUPTS() __asm{ sti }
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portNOP() __asm{ nop }
#define portSTACK_GROWTH ( -1 )
#define portSWITCH_INT_NUMBER 0x80
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 2
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
/*-----------------------------------------------------------*/
/* Compiler specifics. */
#define portINPUT_BYTE( xAddr ) inp( xAddr )
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
#define portINPUT_WORD( xAddr ) inpw( xAddr )
#define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,312 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V2.6.1
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
macro to be consistent with the later ports.
Changes from V4.0.1
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
its proper value when the scheduler exits.
*/
#include <stdlib.h>
#include <dos.h>
#include <setjmp.h>
#include "FreeRTOS.h"
#include "task.h"
#include "portasm.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the industrial
* PC port.
*----------------------------------------------------------*/
/*lint -e950 Non ANSI reserved words okay in this file only. */
#define portTIMER_INT_NUMBER 0x08
/* Setup hardware for required tick interrupt rate. */
static void prvSetTickFrequency( unsigned portLONG ulTickRateHz );
/* Restore hardware to as it was prior to starting the scheduler. */
static void prvExitFunction( void );
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
directly. We chain to the DOS tick as close as possible to the standard DOS
tick rate. */
static void prvPortResetPIC( void );
/* The ISR used depends on whether the preemptive or cooperative
scheduler is being used. */
#if( configUSE_PREEMPTION == 1 )
/* Tick service routine used by the scheduler when preemptive scheduling is
being used. */
static void __interrupt __far prvPreemptiveTick( void );
#else
/* Tick service routine used by the scheduler when cooperative scheduling is
being used. */
static void __interrupt __far prvNonPreemptiveTick( void );
#endif
/* Trap routine used by taskYIELD() to manually cause a context switch. */
static void __interrupt __far prvYieldProcessor( void );
/* Set the tick frequency back so the floppy drive works correctly when the
scheduler exits. */
static void prvSetTickFrequencyDefault( void );
/*lint -e956 File scopes necessary here. */
/* Used to signal when to chain to the DOS tick, and when to just clear the PIC ourselves. */
static portSHORT sDOSTickCounter;
/* Set true when the vectors are set so the scheduler will service the tick. */
static portBASE_TYPE xSchedulerRunning = pdFALSE;
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
static void ( __interrupt __far *pxOldSwitchISR )();
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
/* Used to restore the original DOS context when the scheduler is ended. */
static jmp_buf xJumpBuf;
/*lint +e956 */
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
pxISR pxOriginalTickISR;
/* This is called with interrupts already disabled. */
/* Remember what was on the interrupts we are going to use
so we can put them back later if required. */
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
prvSetTickFrequency( configTICK_RATE_HZ );
/* Put our manual switch (yield) function on a known
vector. */
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
/* Put the old tick on a different interrupt number so we can
call it when we want. */
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
/* The ISR used depends on whether the preemptive or cooperative
scheduler is being used. */
#if( configUSE_PREEMPTION == 1 )
{
/* Put our tick switch function on the timer interrupt. */
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
}
#else
{
/* We want the timer interrupt to just increment the tick count. */
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
}
#endif
/* Setup a counter that is used to call the DOS interrupt as close
to it's original frequency as can be achieved given our chosen tick
frequency. */
sDOSTickCounter = portTICKS_PER_DOS_TICK;
/* Clean up function if we want to return to DOS. */
if( setjmp( xJumpBuf ) != 0 )
{
prvExitFunction();
xSchedulerRunning = pdFALSE;
}
else
{
xSchedulerRunning = pdTRUE;
/* Kick off the scheduler by setting up the context of the first task. */
portFIRST_CONTEXT();
}
return xSchedulerRunning;
}
/*-----------------------------------------------------------*/
/* The ISR used depends on whether the preemptive or cooperative
scheduler is being used. */
#if( configUSE_PREEMPTION == 1 )
static void __interrupt __far prvPreemptiveTick( void )
{
/* Get the scheduler to update the task states following the tick. */
vTaskIncrementTick();
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
/* Reset the PIC ready for the next time. */
prvPortResetPIC();
}
#else
static void __interrupt __far prvNonPreemptiveTick( void )
{
/* Same as preemptive tick, but the cooperative scheduler is being used
so we don't have to switch in the context of the next task. */
vTaskIncrementTick();
prvPortResetPIC();
}
#endif
/*-----------------------------------------------------------*/
static void __interrupt __far prvYieldProcessor( void )
{
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
}
/*-----------------------------------------------------------*/
static void prvPortResetPIC( void )
{
/* We are going to call the DOS tick interrupt at as close a
frequency to the normal DOS tick as possible. */
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
--sDOSTickCounter;
if( sDOSTickCounter <= 0 )
{
sDOSTickCounter = ( portSHORT ) portTICKS_PER_DOS_TICK;
__asm{ int portSWITCH_INT_NUMBER + 1 };
}
else
{
/* Reset the PIC as the DOS tick is not being called to
do it. */
__asm
{
mov al, 20H
out 20H, al
};
}
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Jump back to the processor state prior to starting the
scheduler. This means we are not going to be using a
task stack frame so the task can be deleted. */
longjmp( xJumpBuf, 1 );
}
/*-----------------------------------------------------------*/
static void prvExitFunction( void )
{
void ( __interrupt __far *pxOriginalTickISR )();
/* Interrupts should be disabled here anyway - but no
harm in making sure. */
portDISABLE_INTERRUPTS();
if( xSchedulerRunning == pdTRUE )
{
/* Set the DOS tick back onto the timer ticker. */
pxOriginalTickISR = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
_dos_setvect( portTIMER_INT_NUMBER, pxOriginalTickISR );
prvSetTickFrequencyDefault();
/* Put back the switch interrupt routines that was in place
before the scheduler started. */
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
}
/* The tick timer is back how DOS wants it. We can re-enable
interrupts without the scheduler being called. */
portENABLE_INTERRUPTS();
/* This will free up all the memory used by the scheduler.
exiting back to dos with INT21 AH=4CH will do this anyway so
it is not necessary to call this. */
vTaskCleanUpResources();
}
/*-----------------------------------------------------------*/
static void prvSetTickFrequency( unsigned portLONG ulTickRateHz )
{
const unsigned portSHORT usPIT_MODE = ( unsigned portSHORT ) 0x43;
const unsigned portSHORT usPIT0 = ( unsigned portSHORT ) 0x40;
const unsigned portLONG ulPIT_CONST = ( unsigned portLONG ) 1193180UL;
const unsigned portSHORT us8254_CTR0_MODE3 = ( unsigned portSHORT ) 0x36;
unsigned portLONG ulOutput;
/* Setup the 8245 to tick at the wanted frequency. */
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
ulOutput = ulPIT_CONST / ulTickRateHz;
portOUTPUT_BYTE( usPIT0, ( unsigned portSHORT )( ulOutput & ( unsigned portLONG ) 0xff ) );
ulOutput >>= 8;
portOUTPUT_BYTE( usPIT0, ( unsigned portSHORT ) ( ulOutput & ( unsigned portLONG ) 0xff ) );
}
/*-----------------------------------------------------------*/
static void prvSetTickFrequencyDefault( void )
{
const unsigned portSHORT usPIT_MODE = ( unsigned portSHORT ) 0x43;
const unsigned portSHORT usPIT0 = ( unsigned portSHORT ) 0x40;
const unsigned portSHORT us8254_CTR0_MODE3 = ( unsigned portSHORT ) 0x36;
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
portOUTPUT_BYTE( usPIT0,0 );
portOUTPUT_BYTE( usPIT0,0 );
}
/*lint +e950 */

View file

@ -0,0 +1,112 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 long
#define portDOUBLE long
#define portLONG long
#define portSHORT int
#define portSTACK_TYPE unsigned portSHORT
#define portBASE_TYPE portSHORT
#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
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portENTER_CRITICAL() __asm{ pushf } \
__asm{ cli } \
#define portEXIT_CRITICAL() __asm{ popf }
#define portDISABLE_INTERRUPTS() __asm{ cli }
#define portENABLE_INTERRUPTS() __asm{ sti }
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portNOP() __asm{ nop }
#define portSTACK_GROWTH ( -1 )
#define portSWITCH_INT_NUMBER 0x80
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
#define portDOS_TICK_RATE ( 18.20648 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portTICKS_PER_DOS_TICK ( ( unsigned portSHORT ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) )
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
/*-----------------------------------------------------------*/
/* Compiler specifics. */
#define portINPUT_BYTE( xAddr ) inp( xAddr )
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,107 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef PORT_ASM_H
#define PORT_ASM_H
typedef void tskTCB;
extern volatile tskTCB * volatile pxCurrentTCB;
extern void vTaskSwitchContext( void );
/*
* Saves the stack pointer for one task into its TCB, calls
* vTaskSwitchContext() to update the TCB being used, then restores the stack
* from the new TCB read to run the task.
*/
void portSWITCH_CONTEXT( void );
/*
* Load the stack pointer from the TCB of the task which is going to be first
* to execute. Then force an IRET so the registers and IP are popped off the
* stack.
*/
void portFIRST_CONTEXT( void );
/* There are slightly different versions depending on whether you are building
to include debugger information. If debugger information is used then there
are a couple of extra bytes left of the ISR stack (presumably for use by the
debugger). The true stack pointer is then stored in the bp register. We add
2 to the stack pointer to remove the extra bytes before we restore our context. */
#define portSWITCH_CONTEXT() \
asm { mov ax, seg pxCurrentTCB } \
asm { mov ds, ax } \
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
asm { mov es:0x2[ bx ], ss } \
asm { mov es:[ bx ], sp } \
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
asm { mov ds, ax } \
asm { les bx, dword ptr pxCurrentTCB } \
asm { mov ss, es:[ bx + 2 ] } \
asm { mov sp, es:[ bx ] }
#define portFIRST_CONTEXT() \
__asm { mov ax, seg pxCurrentTCB } \
__asm { mov ds, ax } \
__asm { les bx, dword ptr pxCurrentTCB } \
__asm { mov ss, es:[ bx + 2 ] } \
__asm { mov sp, es:[ bx ] } \
__asm { pop bp } \
__asm { pop di } \
__asm { pop si } \
__asm { pop ds } \
__asm { pop es } \
__asm { pop dx } \
__asm { pop cx } \
__asm { pop bx } \
__asm { pop ax } \
__asm { iret }
#endif

View file

@ -0,0 +1,140 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V1.00:
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
same format used by the compiler. This allows the compiler generated
interrupt mechanism to be used for context switches.
Changes from V2.6.1
+ Move usPortCheckFreeStackSpace() to tasks.c.
*/
#include <dos.h>
#include <stdlib.h>
#include "FreeRTOS.h"
/*-----------------------------------------------------------*/
/* See header file for description. */
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE DS_Reg = 0;
/* Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging. */
*pxTopOfStack = 0x1111;
pxTopOfStack--;
*pxTopOfStack = 0x2222;
pxTopOfStack--;
*pxTopOfStack = 0x3333;
pxTopOfStack--;
*pxTopOfStack = 0x4444;
pxTopOfStack--;
*pxTopOfStack = 0x5555;
pxTopOfStack--;
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
/* We are going to start the scheduler using a return from interrupt
instruction to load the program counter, so first there would be the
function call with parameters preamble. */
*pxTopOfStack = FP_SEG( pvParameters );
pxTopOfStack--;
*pxTopOfStack = FP_OFF( pvParameters );
pxTopOfStack--;
*pxTopOfStack = FP_SEG( pxCode );
pxTopOfStack--;
*pxTopOfStack = FP_OFF( pxCode );
pxTopOfStack--;
/* Next the status register and interrupt return address. */
*pxTopOfStack = portINITIAL_SW;
pxTopOfStack--;
*pxTopOfStack = FP_SEG( pxCode );
pxTopOfStack--;
*pxTopOfStack = FP_OFF( pxCode );
pxTopOfStack--;
/* The remaining registers would be pushed on the stack by our context
switch function. These are loaded with values simply to make debugging
easier. */
*pxTopOfStack = ( portSTACK_TYPE ) 0xAAAA; /* AX */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xBBBB; /* BX */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xCCCC; /* CX */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xDDDD; /* DX */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xEEEE; /* ES */
pxTopOfStack--;
/* We need the true data segment. */
__asm{ MOV DS_Reg, DS };
*pxTopOfStack = DS_Reg; /* DS */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0123; /* SI */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xDDDD; /* DI */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xBBBB; /* BP */
/*lint +e950 +e611 +e923 */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,208 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#define portINITIAL_FORMAT_VECTOR ( ( portSTACK_TYPE ) 0x4000 )
/* Supervisor mode set. */
#define portINITIAL_STATUS_REGISTER ( ( portSTACK_TYPE ) 0x2000)
/* The clock prescale into the timer peripheral. */
#define portPRESCALE_VALUE ( ( unsigned portCHAR ) 10 )
/* The clock frequency into the RTC. */
#define portRTC_CLOCK_HZ ( ( unsigned portLONG ) 1000 )
asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
static void prvSetupTimerInterrupt( void );
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
will be set to 0 prior to the first task being started. */
static unsigned portLONG ulCriticalNesting = 0x9999UL;
/*-----------------------------------------------------------*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned portLONG ulOriginalA5;
__asm{ MOVE.L A5, ulOriginalA5 };
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
pxTopOfStack--;
/* Exception stack frame starts with the return address. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
pxTopOfStack -= 14; /* A5 to D0. */
/* Parameter in A0. */
*( pxTopOfStack + 8 ) = ( portSTACK_TYPE ) pvParameters;
/* A5 must be maintained as it is resurved by the compiler. */
*( pxTopOfStack + 13 ) = ulOriginalA5;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
ulCriticalNesting = 0UL;
/* Configure a timer to generate the tick interrupt. */
prvSetupTimerInterrupt();
/* Start the first task executing. */
vPortStartFirstTask();
return pdFALSE;
}
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
/* Prescale by 1 - ie no prescale. */
RTCSC |= 8;
/* Compare match value. */
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
/* Enable the RTC to generate interrupts - interrupts are already disabled
when this code executes. */
RTCSC_RTIE = 1;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented as there is nothing to return to. */
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
if( ulCriticalNesting == 0UL )
{
/* Guard against context switches being pended simultaneously with a
critical section being entered. */
do
{
portDISABLE_INTERRUPTS();
if( INTC_FRC == 0UL )
{
break;
}
portENABLE_INTERRUPTS();
} while( 1 );
}
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
ulCriticalNesting--;
if( ulCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
void vPortYieldHandler( void )
{
unsigned portLONG ulSavedInterruptMask;
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Note this will clear all forced interrupts - this is done for speed. */
INTC_CFRC = 0x3E;
vTaskSwitchContext();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
}
/*-----------------------------------------------------------*/
void interrupt VectorNumber_Vrtc vPortTickISR( void )
{
unsigned portLONG ulSavedInterruptMask;
/* Clear the interrupt. */
RTCSC |= RTCSC_RTIF_MASK;
/* Increment the RTOS tick. */
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
/* If we are using the pre-emptive scheduler then also request a
context switch as incrementing the tick could have unblocked a task. */
#if configUSE_PREEMPTION == 1
{
taskYIELD();
}
#endif
}

View file

@ -0,0 +1,150 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
* Purpose: Lowest level routines for all ColdFire processors.
*
* Notes:
*
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
* supplied source files.
*/
.global ulPortSetIPL
.global _ulPortSetIPL
.global mcf5xxx_wr_cacrx
.global _mcf5xxx_wr_cacrx
.global vPortYieldISR
.global _vPortYieldISR
.global vPortStartFirstTask
.global _vPortStartFirstTask
.extern _pxCurrentTCB
.extern _vPortYieldHandler
.text
.macro portSAVE_CONTEXT
lea.l (-60, sp), sp
movem.l d0-a6, (sp)
move.l _pxCurrentTCB, a0
move.l sp, (a0)
.endm
.macro portRESTORE_CONTEXT
move.l _pxCurrentTCB, a0
move.l (a0), sp
movem.l (sp), d0-a6
lea.l (60, sp), sp
rte
.endm
/********************************************************************/
/*
* This routines changes the IPL to the value passed into the routine.
* It also returns the old IPL value back.
* Calling convention from C:
* old_ipl = asm_set_ipl(new_ipl);
* For the Diab Data C compiler, it passes return value thru D0.
* Note that only the least significant three bits of the passed
* value are used.
*/
ulPortSetIPL:
_ulPortSetIPL:
link A6,#-8
movem.l D6-D7,(SP)
move.w SR,D7 /* current sr */
move.l D7,D6 /* prepare return value */
andi.l #0x0700,D6 /* mask out IPL */
lsr.l #8,D6 /* IPL */
andi.l #0x07,D0 /* least significant three bits */
lsl.l #8,D0 /* move over to make mask */
andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D0,D7 /* place new IPL in sr */
move.w D7,SR
move.l D6, D0 /* Return value in D0. */
movem.l (SP),D6-D7
lea 8(SP),SP
unlk A6
rts
/********************************************************************/
mcf5xxx_wr_cacrx:
_mcf5xxx_wr_cacrx:
move.l 4(sp),d0
.long 0x4e7b0002 /* movec d0,cacr */
nop
rts
/********************************************************************/
/* Yield interrupt. */
_vPortYieldISR:
vPortYieldISR:
portSAVE_CONTEXT
jsr _vPortYieldHandler
portRESTORE_CONTEXT
/********************************************************************/
vPortStartFirstTask:
_vPortStartFirstTask:
portRESTORE_CONTEXT
.end

View file

@ -0,0 +1,130 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 long
#define portBASE_TYPE long
#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 4
#define portSTACK_GROWTH -1
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
unsigned portLONG ulPortSetIPL( unsigned portLONG );
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portNOP() asm volatile ( "nop" )
/* Context switches are requested using the force register. */
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
/*-----------------------------------------------------------*/
/* 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 != pdFALSE ) \
{ \
portYIELD(); \
}
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,167 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#define portINITIAL_FORMAT_VECTOR ( ( portSTACK_TYPE ) 0x4000 )
/* Supervisor mode set. */
#define portINITIAL_STATUS_REGISTER ( ( portSTACK_TYPE ) 0x2000)
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
will be set to 0 prior to the first task being started. */
static unsigned portLONG ulCriticalNesting = 0x9999UL;
#define portSAVE_CONTEXT() \
lea.l (-60, %sp), %sp; \
movem.l %d0-%fp, (%sp); \
move.l pxCurrentTCB, %a0; \
move.l %sp, (%a0);
#define portRESTORE_CONTEXT() \
move.l pxCurrentTCB, %a0; \
move.l (%a0), %sp; \
movem.l (%sp), %d0-%fp; \
lea.l %sp@(60), %sp; \
rte
/*-----------------------------------------------------------*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
pxTopOfStack--;
/* Exception stack frame starts with the return address. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
pxTopOfStack -= 14; /* A5 to D0. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
ulCriticalNesting = 0UL;
/* Configure the interrupts used by this port. */
vApplicationSetupInterrupts();
/* Start the first task executing. */
vPortStartFirstTask();
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented as there is nothing to return to. */
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
if( ulCriticalNesting == 0UL )
{
/* Guard against context switches being pended simultaneously with a
critical section being entered. */
do
{
portDISABLE_INTERRUPTS();
if( MCF_INTC0_INTFRCH == 0UL )
{
break;
}
portENABLE_INTERRUPTS();
} while( 1 );
}
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
ulCriticalNesting--;
if( ulCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
void vPortYieldHandler( void )
{
unsigned portLONG ulSavedInterruptMask;
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
/* Note this will clear all forced interrupts - this is done for speed. */
MCF_INTC0_INTFRCL = 0;
vTaskSwitchContext();
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,150 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
* Purpose: Lowest level routines for all ColdFire processors.
*
* Notes:
*
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
* supplied source files.
*/
.global ulPortSetIPL
.global _ulPortSetIPL
.global mcf5xxx_wr_cacrx
.global _mcf5xxx_wr_cacrx
.global vPortYieldISR
.global _vPortYieldISR
.global vPortStartFirstTask
.global _vPortStartFirstTask
.extern _pxCurrentTCB
.extern _vPortYieldHandler
.text
.macro portSAVE_CONTEXT
lea.l (-60, sp), sp
movem.l d0-a6, (sp)
move.l _pxCurrentTCB, a0
move.l sp, (a0)
.endm
.macro portRESTORE_CONTEXT
move.l _pxCurrentTCB, a0
move.l (a0), sp
movem.l (sp), d0-a6
lea.l (60, sp), sp
rte
.endm
/********************************************************************/
/*
* This routines changes the IPL to the value passed into the routine.
* It also returns the old IPL value back.
* Calling convention from C:
* old_ipl = asm_set_ipl(new_ipl);
* For the Diab Data C compiler, it passes return value thru D0.
* Note that only the least significant three bits of the passed
* value are used.
*/
ulPortSetIPL:
_ulPortSetIPL:
link A6,#-8
movem.l D6-D7,(SP)
move.w SR,D7 /* current sr */
move.l D7,D0 /* prepare return value */
andi.l #0x0700,D0 /* mask out IPL */
lsr.l #8,D0 /* IPL */
move.l 8(A6),D6 /* get argument */
andi.l #0x07,D6 /* least significant three bits */
lsl.l #8,D6 /* move over to make mask */
andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D6,D7 /* place new IPL in sr */
move.w D7,SR
movem.l (SP),D6-D7
lea 8(SP),SP
unlk A6
rts
/********************************************************************/
mcf5xxx_wr_cacrx:
_mcf5xxx_wr_cacrx:
move.l 4(sp),d0
.long 0x4e7b0002 /* movec d0,cacr */
nop
rts
/********************************************************************/
/* Yield interrupt. */
_vPortYieldISR:
vPortYieldISR:
portSAVE_CONTEXT
jsr _vPortYieldHandler
portRESTORE_CONTEXT
/********************************************************************/
vPortStartFirstTask:
_vPortStartFirstTask:
portRESTORE_CONTEXT
.end

View file

@ -0,0 +1,130 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 long
#define portBASE_TYPE long
#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 4
#define portSTACK_GROWTH -1
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
unsigned portLONG ulPortSetIPL( unsigned portLONG );
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portNOP() asm volatile ( "nop" )
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
/*-----------------------------------------------------------*/
/* 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 != pdFALSE ) \
{ \
portYIELD(); \
}
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,258 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the HCS12 port.
*----------------------------------------------------------*/
/*
* Configure a timer to generate the RTOS tick at the frequency specified
* within FreeRTOSConfig.h.
*/
static void prvSetupTimerInterrupt( void );
/* Interrupt service routines have to be in non-banked memory - as does the
scheduler startup function. */
#pragma CODE_SEG __NEAR_SEG NON_BANKED
/* Manual context switch function. This is the SWI ISR. */
void interrupt vPortYield( void );
/* Tick context switch function. This is the timer ISR. */
void interrupt vPortTickInterrupt( void );
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
start the scheduler directly because the header file containing the
xPortStartScheduler() prototype is part of the common kernel code, and
therefore cannot use the CODE_SEG pragma. */
static portBASE_TYPE xBankedStartScheduler( void );
#pragma CODE_SEG DEFAULT
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
critical section should not be left (i.e. interrupts should not be re-enabled)
until the nesting depth reaches 0. This variable simply tracks the nesting
depth. Each task maintains it's own critical nesting depth variable so
uxCriticalNesting is saved and restored from the task stack during a context
switch. */
volatile unsigned portBASE_TYPE uxCriticalNesting = 0xff;
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/*
Place a few bytes of known values on the bottom of the stack.
This can be uncommented to provide useful stack markers when debugging.
*pxTopOfStack = ( portSTACK_TYPE ) 0x11;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x22;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x33;
pxTopOfStack--;
*/
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
expected by the HCS12 RTI instruction. */
/* The address of the task function is placed in the stack byte at a time. */
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 1 );
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 0 );
pxTopOfStack--;
/* Next are all the registers that form part of the task context. */
/* Y register */
*pxTopOfStack = ( portSTACK_TYPE ) 0xff;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xee;
pxTopOfStack--;
/* X register */
*pxTopOfStack = ( portSTACK_TYPE ) 0xdd;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xcc;
pxTopOfStack--;
/* A register contains parameter high byte. */
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 0 );
pxTopOfStack--;
/* B register contains parameter low byte. */
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 1 );
pxTopOfStack--;
/* CCR: Note that when the task starts interrupts will be enabled since
"I" bit of CCR is cleared */
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
pxTopOfStack--;
#ifdef BANKED_MODEL
/* The page of the task. */
*pxTopOfStack = ( portSTACK_TYPE ) ( ( int ) pxCode );
pxTopOfStack--;
#endif
/* Finally the critical nesting depth is initialised with 0 (not within
a critical section). */
*pxTopOfStack = ( portSTACK_TYPE ) 0x00;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the HCS12 port will get stopped. */
}
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
TickTimer_SetFreqHz( configTICK_RATE_HZ );
TickTimer_Enable();
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* xPortStartScheduler() does not start the scheduler directly because
the header file containing the xPortStartScheduler() prototype is part
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
Instead it simply calls the locally defined xBankedStartScheduler() -
which does use the CODE_SEG pragma. */
return xBankedStartScheduler();
}
/*-----------------------------------------------------------*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
static portBASE_TYPE xBankedStartScheduler( void )
{
/* Configure the timer that will generate the RTOS tick. Interrupts are
disabled when this function is called. */
prvSetupTimerInterrupt();
/* Restore the context of the first task. */
portRESTORE_CONTEXT();
/* Simulate the end of an interrupt to start the scheduler off. */
__asm( "rti" );
/* Should not get here! */
return pdFALSE;
}
/*-----------------------------------------------------------*/
/*
* Context switch functions. These are both interrupt service routines.
*/
/*
* Manual context switch forced by calling portYIELD(). This is the SWI
* handler.
*/
void interrupt vPortYield( void )
{
portSAVE_CONTEXT();
vTaskSwitchContext();
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* RTOS tick interrupt service routine. If the cooperative scheduler is
* being used then this simply increments the tick count. If the
* preemptive scheduler is being used a context switch can occur.
*/
void interrupt vPortTickInterrupt( void )
{
#if configUSE_PREEMPTION == 1
{
/* A context switch might happen so save the context. */
portSAVE_CONTEXT();
/* Increment the tick ... */
vTaskIncrementTick();
/* ... then see if the new tick value has necessitated a
context switch. */
vTaskSwitchContext();
TFLG1 = 1;
/* Restore the context of a task - which may be a different task
to that interrupted. */
portRESTORE_CONTEXT();
}
#else
{
vTaskIncrementTick();
TFLG1 = 1;
}
#endif
}
#pragma CODE_SEG DEFAULT

View file

@ -0,0 +1,218 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 short
#define portSTACK_TYPE unsigned portCHAR
#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 portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portYIELD() __asm( "swi" );
#define portNOP() __asm( "nop" );
/*-----------------------------------------------------------*/
/* Critical section handling. */
#define portENABLE_INTERRUPTS() __asm( "cli" )
#define portDISABLE_INTERRUPTS() __asm( "sei" )
/*
* Disable interrupts before incrementing the count of critical section nesting.
* The nesting count is maintained so we know when interrupts should be
* re-enabled. Once interrupts are disabled the nesting count can be accessed
* directly. Each task maintains its own nesting count.
*/
#define portENTER_CRITICAL() \
{ \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
uxCriticalNesting++; \
}
/*
* Interrupts are disabled so we can access the nesting count directly. If the
* nesting is found to be 0 (no nesting) then we are leaving the critical
* section and interrupts can be re-enabled.
*/
#define portEXIT_CRITICAL() \
{ \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
uxCriticalNesting--; \
if( uxCriticalNesting == 0 ) \
{ \
portENABLE_INTERRUPTS(); \
} \
}
/*-----------------------------------------------------------*/
/* Task utilities. */
/*
* These macros are very simple as the processor automatically saves and
* restores its registers as interrupts are entered and exited. In
* addition to the (automatically stacked) registers we also stack the
* critical nesting count. Each task maintains its own critical nesting
* count as it is legitimate for a task to yield from within a critical
* section. If the banked memory model is being used then the PPAGE
* register is also stored as part of the tasks context.
*/
#ifdef BANKED_MODEL
/*
* Load the stack pointer for the task, then pull the critical nesting
* count and PPAGE register from the stack. The remains of the
* context are restored by the RTI instruction.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile void * pxCurrentTCB; \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
__asm( "ldx pxCurrentTCB" ); \
__asm( "lds 0, x" ); \
__asm( "pula" ); \
__asm( "staa uxCriticalNesting" ); \
__asm( "pula" ); \
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
}
/*
* By the time this macro is called the processor has already stacked the
* registers. Simply stack the nesting count and PPAGE value, then save
* the task stack pointer.
*/
#define portSAVE_CONTEXT() \
{ \
extern volatile void * pxCurrentTCB; \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
__asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \
__asm( "psha" ); \
__asm( "ldaa uxCriticalNesting" ); \
__asm( "psha" ); \
__asm( "ldx pxCurrentTCB" ); \
__asm( "sts 0, x" ); \
}
#else
/*
* These macros are as per the BANKED versions above, but without saving
* and restoring the PPAGE register.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile void * pxCurrentTCB; \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
__asm( "ldx pxCurrentTCB" ); \
__asm( "lds 0, x" ); \
__asm( "pula" ); \
__asm( "staa uxCriticalNesting" ); \
}
#define portSAVE_CONTEXT() \
{ \
extern volatile void * pxCurrentTCB; \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
__asm( "ldaa uxCriticalNesting" ); \
__asm( "psha" ); \
__asm( "ldx pxCurrentTCB" ); \
__asm( "sts 0, x" ); \
}
#endif
/*
* Utility macro to call macros above in correct order in order to perform a
* task switch from within a standard ISR. This macro can only be used if
* the ISR does not use any local (stack) variables. If the ISR uses stack
* variables portYIELD() should be used in it's place.
*/
#define portTASK_SWITCH_FROM_ISR() \
portSAVE_CONTEXT(); \
vTaskSwitchContext(); \
portRESTORE_CONTEXT();
/* 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 )
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,254 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Atmel AT91R40008
* port.
*
* Components that can be compiled to either ARM or THUMB mode are
* contained in this file. The ISR routines, which can only be compiled
* to ARM mode are contained in portISR.c.
*----------------------------------------------------------*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Hardware specific definitions. */
#include "AT91R40008.h"
#include "pio.h"
#include "aic.h"
#include "tc.h"
/* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
#define portTICK_PRIORITY_6 ( 6 )
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*
* The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c.
*/
extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
#ifdef THUMB_INTERWORK
{
/* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
#endif
pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
vPortISRStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/*
* Setup the tick timer to generate the tick interrupts at the required frequency.
*/
static void prvSetupTimerInterrupt( void )
{
volatile unsigned portLONG ulDummy;
/* Enable clock to the tick timer... */
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
/* Stop the tick timer... */
portTIMER_REG_BASE_PTR->TC_CCR = TC_CLKDIS;
/* Start with tick timer interrupts disabled... */
portTIMER_REG_BASE_PTR->TC_IDR = 0xFFFFFFFF;
/* Clear any pending tick timer interrupts... */
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
/* Store interrupt handler function address in tick timer vector register...
The ISR installed depends on whether the preemptive or cooperative
scheduler is being used. */
#if configUSE_PREEMPTION == 1
{
extern void ( vPreemptiveTick )( void );
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( unsigned portLONG ) vPreemptiveTick;
}
#else // else use cooperative scheduler
{
extern void ( vNonPreemptiveTick )( void );
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( unsigned portLONG ) vNonPreemptiveTick;
}
#endif
/* Tick timer interrupt level-sensitive, priority 6... */
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
/* Enable the tick timer interrupt...
First at timer level */
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
/* Then at the AIC level. */
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
/* Calculate timer compare value to achieve the desired tick rate... */
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
{
/* The tick rate is fast enough for us to use the faster timer input
clock (main clock / 2). */
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
}
else
{
/* We must use a slower timer input clock (main clock / 8) because the
tick rate is too slow for the faster input clock. */
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
}
/* Start tick timer... */
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,251 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Components that can be compiled to either ARM or THUMB mode are
* contained in port.c The ISR routines, which can only be compiled
* to ARM mode, are contained in this file.
*----------------------------------------------------------*/
/*
Changes from V3.2.4
+ The assembler statements are now included in a single asm block rather
than each line having its own asm block.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to handle interrupts. */
#define portCLEAR_AIC_INTERRUPT ( ( unsigned portLONG ) 0 )
/* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
/*-----------------------------------------------------------*/
/* ISR to handle manual context switches (from a call to taskYIELD()). */
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
/*
* The scheduler can only be started from ARM mode, hence the inclusion of this
* function here.
*/
void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
void vPortISRStartFirstTask( void )
{
/* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Called by portYIELD() or taskYIELD() to manually force a context switch.
*
* When a context switch is performed from the task level the saved task
* context is made to look as if it occurred from within the tick ISR. This
* way the same restore context function can be used when restoring the context
* saved from the ISR or that saved from a call to vPortYieldProcessor.
*/
void vPortYieldProcessor( void )
{
/* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */
asm volatile ( "ADD LR, LR, #4" );
/* Perform the context switch. First save the context of the current task. */
portSAVE_CONTEXT();
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext();
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
void vNonPreemptiveTick( void )
{
static volatile unsigned portLONG ulDummy;
/* Clear tick timer interrupt indication. */
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
vTaskIncrementTick();
/* Acknowledge the interrupt at AIC level... */
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
}
#else /* else preemption is turned on */
/* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__((naked));
void vPreemptiveTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* WARNING - Do not use local (stack) variables here. Use globals
if you must! */
static volatile unsigned portLONG ulDummy;
/* Clear tick timer interrupt indication. */
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
vTaskIncrementTick();
vTaskSwitchContext();
/* Acknowledge the interrupt at AIC level... */
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
#endif
/*-----------------------------------------------------------*/
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
* the utilities are defined as macros in portmacro.h - as per other ports.
*/
#ifdef THUMB_INTERWORK
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortDisableInterruptsFromThumb( void )
{
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
void vPortEnableInterruptsFromThumb( void )
{
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
#endif /* THUMB_INTERWORK */
/* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void )
{
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as we are leaving a critical section. */
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable interrupts as per portEXIT_CRITICAL(). */
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
}
}
}

View file

@ -0,0 +1,271 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V3.2.3
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
Changes from V3.2.4
+ Removed the use of the %0 parameter within the assembler macros and
replaced them with hard coded registers. This will ensure the
assembler does not select the link register as the temp register as
was occasionally happening previously.
+ The assembler statements are now included in a single asm block rather
than each line having its own asm block.
Changes from V4.5.0
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
and replaced them with portYIELD_FROM_ISR() macro. Application code
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
macros as per the V4.5.1 demo code.
*/
#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 portLONG
#define portBASE_TYPE long
#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 portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm volatile ( "SWI" )
#define portNOP() asm volatile ( "NOP" )
/*
* These define the timer to use for generating the tick interrupt.
* They are put in this file so they can be shared between "port.c"
* and "portisr.c".
*/
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
#define portTIMER_AIC_CHANNEL ( ( unsigned portLONG ) 4 )
/*-----------------------------------------------------------*/
/* Task utilities. */
/*
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
* are included here for efficiency. An attempt to call one from
* THUMB mode code will result in a compile time error.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Set the LR to the task stack. */ \
asm volatile ( \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"LDR LR, [R0] \n\t" \
\
/* The critical nesting depth is the first item on the stack. */ \
/* Load it into the ulCriticalNesting variable. */ \
"LDR R0, =ulCriticalNesting \n\t" \
"LDMFD LR!, {R1} \n\t" \
"STR R1, [R0] \n\t" \
\
/* Get the SPSR from the stack. */ \
"LDMFD LR!, {R0} \n\t" \
"MSR SPSR, R0 \n\t" \
\
/* Restore all system mode registers for the task. */ \
"LDMFD LR, {R0-R14}^ \n\t" \
"NOP \n\t" \
\
/* Restore the return address. */ \
"LDR LR, [LR, #+60] \n\t" \
\
/* And return - correcting the offset in the LR to obtain the */ \
/* correct address. */ \
"SUBS PC, LR, #4 \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
/*-----------------------------------------------------------*/
#define portSAVE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Push R0 as we are going to use the register. */ \
asm volatile ( \
"STMDB SP!, {R0} \n\t" \
\
/* Set R0 to point to the task stack pointer. */ \
"STMDB SP,{SP}^ \n\t" \
"NOP \n\t" \
"SUB SP, SP, #4 \n\t" \
"LDMIA SP!,{R0} \n\t" \
\
/* Push the return address onto the stack. */ \
"STMDB R0!, {LR} \n\t" \
\
/* Now we have saved LR we can use it instead of R0. */ \
"MOV LR, R0 \n\t" \
\
/* Pop R0 so we can save it onto the system mode stack. */ \
"LDMIA SP!, {R0} \n\t" \
\
/* Push all the system mode registers onto the task stack. */ \
"STMDB LR,{R0-LR}^ \n\t" \
"NOP \n\t" \
"SUB LR, LR, #60 \n\t" \
\
/* Push the SPSR onto the task stack. */ \
"MRS R0, SPSR \n\t" \
"STMDB LR!, {R0} \n\t" \
\
"LDR R0, =ulCriticalNesting \n\t" \
"LDR R0, [R0] \n\t" \
"STMDB LR!, {R0} \n\t" \
\
/* Store the new top of stack for the task. */ \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"STR LR, [R0] \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
#define portYIELD_FROM_ISR() vTaskSwitchContext()
/* Critical section handling. */
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* defined then the utilities are defined as macros here - as per other ports.
*/
#ifdef THUMB_INTERWORK
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
#else
#define portDISABLE_INTERRUPTS() \
asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#define portENABLE_INTERRUPTS() \
asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#endif /* THUMB_INTERWORK */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/*-----------------------------------------------------------*/
/* 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 */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
//* ----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//* ----------------------------------------------------------------------------
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//* ----------------------------------------------------------------------------
//* File Name : lib_AT91SAM7X256.h
//* Object : AT91SAM7X256 inlined functions
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29)
//*
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003//
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005//
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003//
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005//
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005//
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005//
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005//
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004//
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003//
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
//* ----------------------------------------------------------------------------
#include "AT91SAM7X256.h"
//*----------------------------------------------------------------------------
//* \fn AT91F_AIC_ConfigureIt
//* \brief Interrupt Handler Initialization
//*----------------------------------------------------------------------------

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,237 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ARM7 port.
*
* Components that can be compiled to either ARM or THUMB mode are
* contained in this file. The ISR routines, which can only be compiled
* to ARM mode are contained in portISR.c.
*----------------------------------------------------------*/
/*
Changes from V2.5.2
+ ulCriticalNesting is now saved as part of the task context, as is
therefore added to the initial task stack during pxPortInitialiseStack.
*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Processor constants. */
#include "AT91SAM7X256.h"
/* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
/* Constants required to setup the tick ISR. */
#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
#define portPRESCALE_VALUE 0x00
#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
/* Constants required to setup the PIT. */
#define portPIT_CLOCK_DIVISOR ( ( unsigned portLONG ) 16 )
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
#define portINT_LEVEL_SENSITIVE 0
#define portPIT_ENABLE ( ( unsigned portSHORT ) 0x1 << 24 )
#define portPIT_INT_ENABLE ( ( unsigned portSHORT ) 0x1 << 25 )
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*
* The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c.
*/
extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
#ifdef THUMB_INTERWORK
{
/* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
#endif
pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
vPortISRStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/*
* Setup the timer 0 to generate the tick interrupts at the required frequency.
*/
static void prvSetupTimerInterrupt( void )
{
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
on whether the preemptive or cooperative scheduler is being used. */
#if configUSE_PREEMPTION == 0
extern void ( vNonPreemptiveTick ) ( void );
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
#else
extern void ( vPreemptiveTick )( void );
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
#endif
/* Configure the PIT period. */
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
/* Enable the interrupt. Global interrupts are disables at this point so
this is safe. */
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,246 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Components that can be compiled to either ARM or THUMB mode are
* contained in port.c The ISR routines, which can only be compiled
* to ARM mode, are contained in this file.
*----------------------------------------------------------*/
/*
Changes from V3.2.4
+ The assembler statements are now included in a single asm block rather
than each line having its own asm block.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "AT91SAM7X256.h"
/* Constants required to handle interrupts. */
#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
/* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
/*-----------------------------------------------------------*/
/* ISR to handle manual context switches (from a call to taskYIELD()). */
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
/*
* The scheduler can only be started from ARM mode, hence the inclusion of this
* function here.
*/
void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
void vPortISRStartFirstTask( void )
{
/* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Called by portYIELD() or taskYIELD() to manually force a context switch.
*
* When a context switch is performed from the task level the saved task
* context is made to look as if it occurred from within the tick ISR. This
* way the same restore context function can be used when restoring the context
* saved from the ISR or that saved from a call to vPortYieldProcessor.
*/
void vPortYieldProcessor( void )
{
/* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */
asm volatile ( "ADD LR, LR, #4" );
/* Perform the context switch. First save the context of the current task. */
portSAVE_CONTEXT();
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext();
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
void vNonPreemptiveTick( void )
{
unsigned portLONG ulDummy;
/* Increment the tick count - which may wake some tasks but as the
preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */
vTaskIncrementTick();
/* Clear the PIT interrupt. */
ulDummy = AT91C_BASE_PITC->PITC_PIVR;
/* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
}
#else
/* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__((naked));
void vPreemptiveTick( void )
{
/* Save the context of the current task. */
portSAVE_CONTEXT();
/* Increment the tick count - this may wake a task. */
vTaskIncrementTick();
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext();
/* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;;
portRESTORE_CONTEXT();
}
#endif
/*-----------------------------------------------------------*/
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
* the utilities are defined as macros in portmacro.h - as per other ports.
*/
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortDisableInterruptsFromThumb( void )
{
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
void vPortEnableInterruptsFromThumb( void )
{
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
/* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void )
{
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as we are leaving a critical section. */
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable interrupts as per portEXIT_CRITICAL(). */
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
}
}
}

View file

@ -0,0 +1,265 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V3.2.3
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
Changes from V3.2.4
+ Removed the use of the %0 parameter within the assembler macros and
replaced them with hard coded registers. This will ensure the
assembler does not select the link register as the temp register as
was occasionally happening previously.
+ The assembler statements are now included in a single asm block rather
than each line having its own asm block.
Changes from V4.5.0
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
and replaced them with portYIELD_FROM_ISR() macro. Application code
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
macros as per the V4.5.1 demo code.
*/
#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 portLONG
#define portBASE_TYPE portLONG
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portNOP() asm volatile ( "NOP" );
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
/*
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
* are included here for efficiency. An attempt to call one from
* THUMB mode code will result in a compile time error.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Set the LR to the task stack. */ \
asm volatile ( \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"LDR LR, [R0] \n\t" \
\
/* The critical nesting depth is the first item on the stack. */ \
/* Load it into the ulCriticalNesting variable. */ \
"LDR R0, =ulCriticalNesting \n\t" \
"LDMFD LR!, {R1} \n\t" \
"STR R1, [R0] \n\t" \
\
/* Get the SPSR from the stack. */ \
"LDMFD LR!, {R0} \n\t" \
"MSR SPSR, R0 \n\t" \
\
/* Restore all system mode registers for the task. */ \
"LDMFD LR, {R0-R14}^ \n\t" \
"NOP \n\t" \
\
/* Restore the return address. */ \
"LDR LR, [LR, #+60] \n\t" \
\
/* And return - correcting the offset in the LR to obtain the */ \
/* correct address. */ \
"SUBS PC, LR, #4 \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
/*-----------------------------------------------------------*/
#define portSAVE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Push R0 as we are going to use the register. */ \
asm volatile ( \
"STMDB SP!, {R0} \n\t" \
\
/* Set R0 to point to the task stack pointer. */ \
"STMDB SP,{SP}^ \n\t" \
"NOP \n\t" \
"SUB SP, SP, #4 \n\t" \
"LDMIA SP!,{R0} \n\t" \
\
/* Push the return address onto the stack. */ \
"STMDB R0!, {LR} \n\t" \
\
/* Now we have saved LR we can use it instead of R0. */ \
"MOV LR, R0 \n\t" \
\
/* Pop R0 so we can save it onto the system mode stack. */ \
"LDMIA SP!, {R0} \n\t" \
\
/* Push all the system mode registers onto the task stack. */ \
"STMDB LR,{R0-LR}^ \n\t" \
"NOP \n\t" \
"SUB LR, LR, #60 \n\t" \
\
/* Push the SPSR onto the task stack. */ \
"MRS R0, SPSR \n\t" \
"STMDB LR!, {R0} \n\t" \
\
"LDR R0, =ulCriticalNesting \n\t" \
"LDR R0, [R0] \n\t" \
"STMDB LR!, {R0} \n\t" \
\
/* Store the new top of stack for the task. */ \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"STR LR, [R0] \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
#define portYIELD_FROM_ISR() vTaskSwitchContext()
#define portYIELD() asm volatile ( "SWI" )
/*-----------------------------------------------------------*/
/* Critical section management. */
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* defined then the utilities are defined as macros here - as per other ports.
*/
#ifdef THUMB_INTERWORK
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
#else
#define portDISABLE_INTERRUPTS() \
asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#define portENABLE_INTERRUPTS() \
asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#endif /* THUMB_INTERWORK */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/*-----------------------------------------------------------*/
/* 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 */

View file

@ -0,0 +1,237 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ARM7 port.
*
* Components that can be compiled to either ARM or THUMB mode are
* contained in this file. The ISR routines, which can only be compiled
* to ARM mode are contained in portISR.c.
*----------------------------------------------------------*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
/* Constants required to setup the tick ISR. */
#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
#define portPRESCALE_VALUE 0x00
#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
/* Constants required to setup the VIC for the tick ISR. */
#define portTIMER_VIC_CHANNEL ( ( unsigned portLONG ) 0x0004 )
#define portTIMER_VIC_CHANNEL_BIT ( ( unsigned portLONG ) 0x0010 )
#define portTIMER_VIC_ENABLE ( ( unsigned portLONG ) 0x0020 )
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*
* The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c.
*/
extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )
{
/* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
vPortISRStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/*
* Setup the timer 0 to generate the tick interrupts at the required frequency.
*/
static void prvSetupTimerInterrupt( void )
{
unsigned portLONG ulCompareMatch;
extern void ( vTickISR )( void );
/* A 1ms tick does not require the use of the timer prescale. This is
defaulted to zero but can be used if necessary. */
T0_PR = portPRESCALE_VALUE;
/* Calculate the match value required for our wanted tick rate. */
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
/* Protect against divide by zero. Using an if() statement still results
in a warning - hence the #if. */
#if portPRESCALE_VALUE != 0
{
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
}
#endif
T0_MR0 = ulCompareMatch;
/* Generate tick with timer 0 compare match. */
T0_MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH;
/* Setup the VIC for the timer. */
VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT );
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
/* The ISR installed depends on whether the preemptive or cooperative
scheduler is being used. */
VICVectAddr0 = ( portLONG ) vTickISR;
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
/* Start the timer - interrupts are disabled when this function is called
so it is okay to do this here. */
T0_TCR = portENABLE_TIMER;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,232 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Components that can be compiled to either ARM or THUMB mode are
* contained in port.c The ISR routines, which can only be compiled
* to ARM mode, are contained in this file.
*----------------------------------------------------------*/
/*
Changes from V2.5.2
+ The critical section management functions have been changed. These no
longer modify the stack and are safe to use at all optimisation levels.
The functions are now also the same for both ARM and THUMB modes.
Changes from V2.6.0
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
allow the demo to link when using the cooperative scheduler.
Changes from V3.2.4
+ The assembler statements are now included in a single asm block rather
than each line having its own asm block.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
/* Constants required to handle interrupts. */
#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
/* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
/*-----------------------------------------------------------*/
/* ISR to handle manual context switches (from a call to taskYIELD()). */
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
/*
* The scheduler can only be started from ARM mode, hence the inclusion of this
* function here.
*/
void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
void vPortISRStartFirstTask( void )
{
/* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Called by portYIELD() or taskYIELD() to manually force a context switch.
*
* When a context switch is performed from the task level the saved task
* context is made to look as if it occurred from within the tick ISR. This
* way the same restore context function can be used when restoring the context
* saved from the ISR or that saved from a call to vPortYieldProcessor.
*/
void vPortYieldProcessor( void )
{
/* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */
__asm volatile ( "ADD LR, LR, #4" );
/* Perform the context switch. First save the context of the current task. */
portSAVE_CONTEXT();
/* Find the highest priority task that is ready to run. */
__asm volatile ( "bl vTaskSwitchContext" );
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* The ISR used for the scheduler tick.
*/
void vTickISR( void ) __attribute__((naked));
void vTickISR( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
__asm volatile( "bl vTaskIncrementTick" );
#if configUSE_PREEMPTION == 1
__asm volatile( "bl vTaskSwitchContext" );
#endif
/* Ready for the next interrupt. */
T0_IR = portTIMER_MATCH_ISR_BIT;
VICVectAddr = portCLEAR_VIC_INTERRUPT;
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
* the utilities are defined as macros in portmacro.h - as per other ports.
*/
#ifdef THUMB_INTERWORK
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortDisableInterruptsFromThumb( void )
{
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
void vPortEnableInterruptsFromThumb( void )
{
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
#endif /* THUMB_INTERWORK */
/* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void )
{
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as we are leaving a critical section. */
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable interrupts as per portEXIT_CRITICAL(). */
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
}
}
}

View file

@ -0,0 +1,242 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portLONG
#define portBASE_TYPE portLONG
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portNOP() __asm volatile ( "NOP" );
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
/*
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
* are included here for efficiency. An attempt to call one from
* THUMB mode code will result in a compile time error.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Set the LR to the task stack. */ \
__asm volatile ( \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"LDR LR, [R0] \n\t" \
\
/* The critical nesting depth is the first item on the stack. */ \
/* Load it into the ulCriticalNesting variable. */ \
"LDR R0, =ulCriticalNesting \n\t" \
"LDMFD LR!, {R1} \n\t" \
"STR R1, [R0] \n\t" \
\
/* Get the SPSR from the stack. */ \
"LDMFD LR!, {R0} \n\t" \
"MSR SPSR, R0 \n\t" \
\
/* Restore all system mode registers for the task. */ \
"LDMFD LR, {R0-R14}^ \n\t" \
"NOP \n\t" \
\
/* Restore the return address. */ \
"LDR LR, [LR, #+60] \n\t" \
\
/* And return - correcting the offset in the LR to obtain the */ \
/* correct address. */ \
"SUBS PC, LR, #4 \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
/*-----------------------------------------------------------*/
#define portSAVE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Push R0 as we are going to use the register. */ \
__asm volatile ( \
"STMDB SP!, {R0} \n\t" \
\
/* Set R0 to point to the task stack pointer. */ \
"STMDB SP,{SP}^ \n\t" \
"NOP \n\t" \
"SUB SP, SP, #4 \n\t" \
"LDMIA SP!,{R0} \n\t" \
\
/* Push the return address onto the stack. */ \
"STMDB R0!, {LR} \n\t" \
\
/* Now we have saved LR we can use it instead of R0. */ \
"MOV LR, R0 \n\t" \
\
/* Pop R0 so we can save it onto the system mode stack. */ \
"LDMIA SP!, {R0} \n\t" \
\
/* Push all the system mode registers onto the task stack. */ \
"STMDB LR,{R0-LR}^ \n\t" \
"NOP \n\t" \
"SUB LR, LR, #60 \n\t" \
\
/* Push the SPSR onto the task stack. */ \
"MRS R0, SPSR \n\t" \
"STMDB LR!, {R0} \n\t" \
\
"LDR R0, =ulCriticalNesting \n\t" \
"LDR R0, [R0] \n\t" \
"STMDB LR!, {R0} \n\t" \
\
/* Store the new top of stack for the task. */ \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"STR LR, [R0] \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
extern void vTaskSwitchContext( void );
#define portYIELD_FROM_ISR() vTaskSwitchContext()
#define portYIELD() __asm volatile ( "SWI" )
/*-----------------------------------------------------------*/
/* Critical section management. */
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* defined then the utilities are defined as macros here - as per other ports.
*/
#ifdef THUMB_INTERWORK
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
#else
#define portDISABLE_INTERRUPTS() \
__asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#define portENABLE_INTERRUPTS() \
__asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#endif /* THUMB_INTERWORK */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/*-----------------------------------------------------------*/
/* 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 */

View file

@ -0,0 +1,249 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ARM7 port.
*
* Components that can be compiled to either ARM or THUMB mode are
* contained in this file. The ISR routines, which can only be compiled
* to ARM mode are contained in portISR.c.
*----------------------------------------------------------*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
/* Constants required to setup the tick ISR. */
#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
#define portPRESCALE_VALUE 0x00
#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
/* Constants required to setup the VIC for the tick ISR. */
#define portTIMER_VIC_CHANNEL ( ( unsigned portLONG ) 0x0004 )
#define portTIMER_VIC_CHANNEL_BIT ( ( unsigned portLONG ) 0x0010 )
#define portTIMER_VIC_ENABLE ( ( unsigned portLONG ) 0x0020 )
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*
* The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c.
*/
extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )
{
/* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
vPortISRStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/*
* Setup the timer 0 to generate the tick interrupts at the required frequency.
*/
static void prvSetupTimerInterrupt( void )
{
unsigned portLONG ulCompareMatch;
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
T0TCR = 2; /* Stop and reset the timer */
T0CTCR = 0; /* Timer mode */
/* A 1ms tick does not require the use of the timer prescale. This is
defaulted to zero but can be used if necessary. */
T0PR = portPRESCALE_VALUE;
/* Calculate the match value required for our wanted tick rate. */
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
/* Protect against divide by zero. Using an if() statement still results
in a warning - hence the #if. */
#if portPRESCALE_VALUE != 0
{
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
}
#endif
T0MR1 = ulCompareMatch;
/* Generate tick with timer 0 compare match. */
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
/* Setup the VIC for the timer. */
VICIntEnable = 0x00000010;
/* The ISR installed depends on whether the preemptive or cooperative
scheduler is being used. */
#if configUSE_PREEMPTION == 1
{
extern void ( vPreemptiveTick )( void );
VICVectAddr4 = ( portLONG ) vPreemptiveTick;
}
#else
{
extern void ( vNonPreemptiveTick )( void );
VICVectAddr4 = ( portLONG ) vNonPreemptiveTick;
}
#endif
VICVectCntl4 = 1;
/* Start the timer - interrupts are disabled when this function is called
so it is okay to do this here. */
T0TCR = portENABLE_TIMER;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,232 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Components that can be compiled to either ARM or THUMB mode are
* contained in port.c The ISR routines, which can only be compiled
* to ARM mode, are contained in this file.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to handle interrupts. */
#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
/* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
/*-----------------------------------------------------------*/
/* ISR to handle manual context switches (from a call to taskYIELD()). */
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
/*
* The scheduler can only be started from ARM mode, hence the inclusion of this
* function here.
*/
void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
void vPortISRStartFirstTask( void )
{
/* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Called by portYIELD() or taskYIELD() to manually force a context switch.
*
* When a context switch is performed from the task level the saved task
* context is made to look as if it occurred from within the tick ISR. This
* way the same restore context function can be used when restoring the context
* saved from the ISR or that saved from a call to vPortYieldProcessor.
*/
void vPortYieldProcessor( void )
{
/* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */
__asm volatile ( "ADD LR, LR, #4" );
/* Perform the context switch. First save the context of the current task. */
portSAVE_CONTEXT();
/* Find the highest priority task that is ready to run. */
__asm volatile( "bl vTaskSwitchContext" );
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
void vNonPreemptiveTick( void )
{
vTaskIncrementTick();
T0IR = 2;
VICVectAddr = portCLEAR_VIC_INTERRUPT;
}
#else
/* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__((naked));
void vPreemptiveTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
__asm volatile( "bl vTaskIncrementTick" );
__asm volatile( "bl vTaskSwitchContext" );
/* Ready for the next interrupt. */
T0IR = 2;
VICVectAddr = portCLEAR_VIC_INTERRUPT;
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
#endif
/*-----------------------------------------------------------*/
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
* the utilities are defined as macros in portmacro.h - as per other ports.
*/
#ifdef THUMB_INTERWORK
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortDisableInterruptsFromThumb( void )
{
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
void vPortEnableInterruptsFromThumb( void )
{
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
#endif /* THUMB_INTERWORK */
/* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void )
{
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as we are leaving a critical section. */
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable interrupts as per portEXIT_CRITICAL(). */
__asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
}
}
}

View file

@ -0,0 +1,265 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V3.2.3
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
Changes from V3.2.4
+ Removed the use of the %0 parameter within the assembler macros and
replaced them with hard coded registers. This will ensure the
assembler does not select the link register as the temp register as
was occasionally happening previously.
+ The assembler statements are now included in a single asm block rather
than each line having its own asm block.
Changes from V4.5.0
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
and replaced them with portYIELD_FROM_ISR() macro. Application code
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
macros as per the V4.5.1 demo code.
*/
#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 portLONG
#define portBASE_TYPE portLONG
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portNOP() __asm volatile ( "NOP" );
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
/*
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
* are included here for efficiency. An attempt to call one from
* THUMB mode code will result in a compile time error.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Set the LR to the task stack. */ \
__asm volatile ( \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"LDR LR, [R0] \n\t" \
\
/* The critical nesting depth is the first item on the stack. */ \
/* Load it into the ulCriticalNesting variable. */ \
"LDR R0, =ulCriticalNesting \n\t" \
"LDMFD LR!, {R1} \n\t" \
"STR R1, [R0] \n\t" \
\
/* Get the SPSR from the stack. */ \
"LDMFD LR!, {R0} \n\t" \
"MSR SPSR, R0 \n\t" \
\
/* Restore all system mode registers for the task. */ \
"LDMFD LR, {R0-R14}^ \n\t" \
"NOP \n\t" \
\
/* Restore the return address. */ \
"LDR LR, [LR, #+60] \n\t" \
\
/* And return - correcting the offset in the LR to obtain the */ \
/* correct address. */ \
"SUBS PC, LR, #4 \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
/*-----------------------------------------------------------*/
#define portSAVE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Push R0 as we are going to use the register. */ \
__asm volatile ( \
"STMDB SP!, {R0} \n\t" \
\
/* Set R0 to point to the task stack pointer. */ \
"STMDB SP,{SP}^ \n\t" \
"NOP \n\t" \
"SUB SP, SP, #4 \n\t" \
"LDMIA SP!,{R0} \n\t" \
\
/* Push the return address onto the stack. */ \
"STMDB R0!, {LR} \n\t" \
\
/* Now we have saved LR we can use it instead of R0. */ \
"MOV LR, R0 \n\t" \
\
/* Pop R0 so we can save it onto the system mode stack. */ \
"LDMIA SP!, {R0} \n\t" \
\
/* Push all the system mode registers onto the task stack. */ \
"STMDB LR,{R0-LR}^ \n\t" \
"NOP \n\t" \
"SUB LR, LR, #60 \n\t" \
\
/* Push the SPSR onto the task stack. */ \
"MRS R0, SPSR \n\t" \
"STMDB LR!, {R0} \n\t" \
\
"LDR R0, =ulCriticalNesting \n\t" \
"LDR R0, [R0] \n\t" \
"STMDB LR!, {R0} \n\t" \
\
/* Store the new top of stack for the task. */ \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"STR LR, [R0] \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
#define portYIELD_FROM_ISR() vTaskSwitchContext()
#define portYIELD() __asm volatile ( "SWI" )
/*-----------------------------------------------------------*/
/* Critical section management. */
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* defined then the utilities are defined as macros here - as per other ports.
*/
#ifdef THUMB_INTERWORK
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
#else
#define portDISABLE_INTERRUPTS() \
__asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#define portENABLE_INTERRUPTS() \
__asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#endif /* THUMB_INTERWORK */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/*-----------------------------------------------------------*/
/* 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 */

View file

@ -0,0 +1,274 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ARM CM3 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
defined. The value should also ensure backward compatibility.
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 255
#endif
/* Constants required to manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned portLONG *) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned portLONG *) 0xe000e014 )
#define portNVIC_INT_CTRL ( ( volatile unsigned portLONG *) 0xe000ed04 )
#define portNVIC_SYSPRI2 ( ( volatile unsigned portLONG *) 0xe000ed20 )
#define portNVIC_SYSTICK_CLK 0x00000004
#define portNVIC_SYSTICK_INT 0x00000002
#define portNVIC_SYSTICK_ENABLE 0x00000001
#define portNVIC_PENDSVSET 0x10000000
#define portNVIC_PENDSV_PRI ( ( ( unsigned portLONG ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned portLONG ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
/* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 )
/* The priority used by the kernel is assigned to a variable to make access
from inline assembler easier. */
const unsigned portLONG ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
/* Each task maintains its own interrupt status in the critical nesting
variable. */
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
/*
* Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void );
/*
* Exception handlers.
*/
void xPortPendSVHandler( void ) __attribute__ (( naked ));
void xPortSysTickHandler( void );
void vPortSVCHandler( void ) __attribute__ (( naked ));
/*
* Start first task is a separate function so it can be tested in isolation.
*/
void vPortStartFirstTask( void ) __attribute__ (( naked ));
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Simulate the stack frame as it would be created by a context switch
interrupt. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
pxTopOfStack--;
*pxTopOfStack = 0; /* LR */
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
void vPortSVCHandler( void )
{
__asm volatile (
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
" msr psp, r0 \n" /* Restore the task stack pointer. */
" mov r0, #0 \n"
" msr basepri, r0 \n"
" orr r14, #0xd \n"
" bx r14 \n"
" \n"
" .align 2 \n"
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
);
}
/*-----------------------------------------------------------*/
void vPortStartFirstTask( void )
{
__asm volatile(
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n"
" ldr r0, [r0] \n"
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
" svc 0 \n" /* System call to start first task. */
);
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0;
/* Start the first task. */
vPortStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the CM3 port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
void vPortYieldFromISR( void )
{
/* Set a PendSV to request a context switch. */
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
void xPortPendSVHandler( void )
{
/* This is a naked function. */
__asm volatile
(
" mrs r0, psp \n"
" \n"
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
" ldr r2, [r3] \n"
" \n"
" stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
" \n"
" stmdb sp!, {r3, r14} \n"
" mov r0, %0 \n"
" msr basepri, r0 \n"
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
" ldmia sp!, {r3, r14} \n"
" \n" /* Restore the context, including the critical nesting count. */
" ldr r1, [r3] \n"
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
" msr psp, r0 \n"
" bx r14 \n"
" \n"
" .align 2 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n"
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
);
}
/*-----------------------------------------------------------*/
void xPortSysTickHandler( void )
{
unsigned portLONG ulDummy;
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
#endif
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}
/*-----------------------------------------------------------*/
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency.
*/
void prvSetupTimerInterrupt( void )
{
/* Configure SysTick to interrupt at the requested rate. */
*(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,150 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portLONG
#define portBASE_TYPE long
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
extern void vPortYieldFromISR( void );
#define portYIELD() vPortYieldFromISR()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
/*-----------------------------------------------------------*/
/* Critical section management. */
/*
* Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
* registers. r0 is clobbered.
*/
#define portSET_INTERRUPT_MASK() \
__asm volatile \
( \
" mov r0, %0 \n" \
" msr basepri, r0 \n" \
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \
)
/*
* Set basepri back to 0 without effective other registers.
* r0 is clobbered.
*/
#define portCLEAR_INTERRUPT_MASK() \
__asm volatile \
( \
" mov r0, #0 \n" \
" msr basepri, r0 \n" \
:::"r0" \
)
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portNOP()
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,193 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portLONG
#define portBASE_TYPE long
#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
/*-----------------------------------------------------------*/
/* MPU specific constants. */
#define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL )
#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL )
#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL )
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
#define portUNPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_FLASH_REGION ( 1UL )
#define portPRIVILEGED_RAM_REGION ( 2UL )
#define portGENERAL_PERIPHERALS_REGION ( 3UL )
#define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " )
typedef struct MPU_REGION_REGISTERS
{
unsigned portLONG ulRegionBaseAddress;
unsigned portLONG ulRegionAttribute;
} xMPU_REGION_REGISTERS;
/* Plus 1 to create space for the stack region. */
typedef struct MPU_SETTINGS
{
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ];
} xMPU_SETTINGS;
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* SVC numbers for various services. */
#define portSVC_START_SCHEDULER 0
#define portSVC_YIELD 1
#define portSVC_prvRaisePrivilege 2
/* Scheduler utilities. */
#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) )
#define portYIELD_WITHIN_API() *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET
#define portNVIC_INT_CTRL ( ( volatile unsigned portLONG *) 0xe000ed04 )
#define portNVIC_PENDSVSET 0x10000000
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET
/*-----------------------------------------------------------*/
/* Critical section management. */
/*
* Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
* registers. r0 is clobbered.
*/
#define portSET_INTERRUPT_MASK() \
__asm volatile \
( \
" mov r0, %0 \n" \
" msr basepri, r0 \n" \
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \
)
/*
* Set basepri back to 0 without effective other registers.
* r0 is clobbered.
*/
#define portCLEAR_INTERRUPT_MASK() \
__asm volatile \
( \
" mov r0, #0 \n" \
" msr basepri, r0 \n" \
:::"r0" \
)
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portNOP()
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,444 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V2.6.0
+ AVR port - Replaced the inb() and outb() functions with direct memory
access. This allows the port to be built with the 20050414 build of
WinAVR.
*/
#include <stdlib.h>
#include <avr/interrupt.h>
#include "FreeRTOS.h"
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the AVR port.
*----------------------------------------------------------*/
/* Start tasks with interrupts enables. */
#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 )
/* Hardware constants for timer 1. */
#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned portCHAR ) 0x08 )
#define portPRESCALE_64 ( ( unsigned portCHAR ) 0x03 )
#define portCLOCK_PRESCALER ( ( unsigned portLONG ) 64 )
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 0x10 )
/*-----------------------------------------------------------*/
/* 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;
/*-----------------------------------------------------------*/
/*
* Macro to save all the general purpose registers, the save the stack pointer
* into the TCB.
*
* The first thing we do is save the flags then disable interrupts. This is to
* guard our stack against having a context switch interrupt after we have already
* pushed the registers onto the stack - causing the 32 registers to be on the
* stack twice.
*
* r1 is set to zero as the compiler expects it to be thus, however some
* of the math routines make use of R1.
*
* The interrupts will have been disabled during the call to portSAVE_CONTEXT()
* so we need not worry about reading/writing to the stack pointer.
*/
#define portSAVE_CONTEXT() \
asm volatile ( "push r0 \n\t" \
"in r0, __SREG__ \n\t" \
"cli \n\t" \
"push r0 \n\t" \
"push r1 \n\t" \
"clr r1 \n\t" \
"push r2 \n\t" \
"push r3 \n\t" \
"push r4 \n\t" \
"push r5 \n\t" \
"push r6 \n\t" \
"push r7 \n\t" \
"push r8 \n\t" \
"push r9 \n\t" \
"push r10 \n\t" \
"push r11 \n\t" \
"push r12 \n\t" \
"push r13 \n\t" \
"push r14 \n\t" \
"push r15 \n\t" \
"push r16 \n\t" \
"push r17 \n\t" \
"push r18 \n\t" \
"push r19 \n\t" \
"push r20 \n\t" \
"push r21 \n\t" \
"push r22 \n\t" \
"push r23 \n\t" \
"push r24 \n\t" \
"push r25 \n\t" \
"push r26 \n\t" \
"push r27 \n\t" \
"push r28 \n\t" \
"push r29 \n\t" \
"push r30 \n\t" \
"push r31 \n\t" \
"lds r26, pxCurrentTCB \n\t" \
"lds r27, pxCurrentTCB + 1 \n\t" \
"in r0, 0x3d \n\t" \
"st x+, r0 \n\t" \
"in r0, 0x3e \n\t" \
"st x+, r0 \n\t" \
);
/*
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
* the context save so we can write to the stack pointer.
*/
#define portRESTORE_CONTEXT() \
asm volatile ( "lds r26, pxCurrentTCB \n\t" \
"lds r27, pxCurrentTCB + 1 \n\t" \
"ld r28, x+ \n\t" \
"out __SP_L__, r28 \n\t" \
"ld r29, x+ \n\t" \
"out __SP_H__, r29 \n\t" \
"pop r31 \n\t" \
"pop r30 \n\t" \
"pop r29 \n\t" \
"pop r28 \n\t" \
"pop r27 \n\t" \
"pop r26 \n\t" \
"pop r25 \n\t" \
"pop r24 \n\t" \
"pop r23 \n\t" \
"pop r22 \n\t" \
"pop r21 \n\t" \
"pop r20 \n\t" \
"pop r19 \n\t" \
"pop r18 \n\t" \
"pop r17 \n\t" \
"pop r16 \n\t" \
"pop r15 \n\t" \
"pop r14 \n\t" \
"pop r13 \n\t" \
"pop r12 \n\t" \
"pop r11 \n\t" \
"pop r10 \n\t" \
"pop r9 \n\t" \
"pop r8 \n\t" \
"pop r7 \n\t" \
"pop r6 \n\t" \
"pop r5 \n\t" \
"pop r4 \n\t" \
"pop r3 \n\t" \
"pop r2 \n\t" \
"pop r1 \n\t" \
"pop r0 \n\t" \
"out __SREG__, r0 \n\t" \
"pop r0 \n\t" \
);
/*-----------------------------------------------------------*/
/*
* Perform hardware setup to enable ticks from timer 1, compare match A.
*/
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned portSHORT usAddress;
/* 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. */
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
/* The start of the task code will be popped off the stack last, so place
it on first. */
usAddress = ( unsigned portSHORT ) pxCode;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
usAddress >>= 8;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
/* 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 = ( portSTACK_TYPE ) 0x00; /* R0 */
pxTopOfStack--;
*pxTopOfStack = portFLAGS_INT_ENABLED;
pxTopOfStack--;
/* Now the remaining registers. The compiler expects R1 to be 0. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R1 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R16 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R17 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */
pxTopOfStack--;
/* Place the parameter on the stack in the expected location. */
usAddress = ( unsigned portSHORT ) pvParameters;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
usAddress >>= 8;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x28; /* R28 Y */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x29; /* R29 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */
pxTopOfStack--;
/*lint +e950 +e611 +e923 */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Setup the hardware to generate the tick. */
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run. */
portRESTORE_CONTEXT();
/* Simulate a function call end as generated by the compiler. We will now
jump to the start of the task the context of which we have just restored. */
asm volatile ( "ret" );
/* 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. */
}
/*-----------------------------------------------------------*/
/*
* Manual context switch. The first thing we do is save the registers so we
* can use a naked attribute.
*/
void vPortYield( void ) __attribute__ ( ( naked ) );
void vPortYield( void )
{
portSAVE_CONTEXT();
vTaskSwitchContext();
portRESTORE_CONTEXT();
asm volatile ( "ret" );
}
/*-----------------------------------------------------------*/
/*
* Context switch function used by the tick. This must be identical to
* vPortYield() from the call to vTaskSwitchContext() onwards. The only
* difference from vPortYield() is the tick count is incremented as the
* call comes from the tick ISR.
*/
void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
void vPortYieldFromTick( void )
{
portSAVE_CONTEXT();
vTaskIncrementTick();
vTaskSwitchContext();
portRESTORE_CONTEXT();
asm volatile ( "ret" );
}
/*-----------------------------------------------------------*/
/*
* Setup timer 1 compare match A to generate a tick interrupt.
*/
static void prvSetupTimerInterrupt( void )
{
unsigned portLONG ulCompareMatch;
unsigned portCHAR 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 -= ( unsigned portLONG ) 1;
/* Setup compare match value for compare match A. Interrupts are disabled
before this is called so we need not worry here. */
ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );
ulCompareMatch >>= 8;
ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 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. */
ucLowByte = TIMSK;
ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
TIMSK = ucLowByte;
}
/*-----------------------------------------------------------*/
#if configUSE_PREEMPTION == 1
/*
* Tick ISR for preemptive scheduler. We can use a naked attribute as
* the context is saved at the start of vPortYieldFromTick(). The tick
* count is incremented after the context is saved.
*/
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
void SIG_OUTPUT_COMPARE1A( void )
{
vPortYieldFromTick();
asm volatile ( "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();
*/
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );
void SIG_OUTPUT_COMPARE1A( void )
{
vTaskIncrementTick();
}
#endif

View file

@ -0,0 +1,123 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
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 unsigned portCHAR
#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
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portENTER_CRITICAL() asm volatile ( "in __tmp_reg__, __SREG__" :: ); \
asm volatile ( "cli" :: ); \
asm volatile ( "push __tmp_reg__" :: )
#define portEXIT_CRITICAL() asm volatile ( "pop __tmp_reg__" :: ); \
asm volatile ( "out __SREG__, __tmp_reg__" :: )
#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: );
#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: );
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 1
#define portNOP() asm volatile ( "nop" );
/*-----------------------------------------------------------*/
/* Kernel utilities. */
extern void vPortYield( void ) __attribute__ ( ( naked ) );
#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 )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,297 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Exception and interrupt vectors.
*
* This file maps all events supported by an AVR32UC.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32UC devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <avr32/io.h>
#include "intc.h"
//! @{
//! \verbatim
.section .exception, "ax", @progbits
// Start of Exception Vector Table.
// EVBA must be aligned with a power of two strictly greater than the EVBA-
// relative offset of the last vector.
.balign 0x200
// Export symbol.
.global _evba
.type _evba, @function
_evba:
.org 0x000
// Unrecoverable Exception.
_handle_Unrecoverable_Exception:
rjmp $
.org 0x004
// TLB Multiple Hit: UNUSED IN AVR32UC.
_handle_TLB_Multiple_Hit:
rjmp $
.org 0x008
// Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
rjmp $
.org 0x00C
// Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
rjmp $
.org 0x010
// NMI.
_handle_NMI:
rjmp $
.org 0x014
// Instruction Address.
_handle_Instruction_Address:
rjmp $
.org 0x018
// ITLB Protection.
_handle_ITLB_Protection:
rjmp $
.org 0x01C
// Breakpoint.
_handle_Breakpoint:
rjmp $
.org 0x020
// Illegal Opcode.
_handle_Illegal_Opcode:
rjmp $
.org 0x024
// Unimplemented Instruction.
_handle_Unimplemented_Instruction:
rjmp $
.org 0x028
// Privilege Violation.
_handle_Privilege_Violation:
rjmp $
.org 0x02C
// Floating-Point: UNUSED IN AVR32UC.
_handle_Floating_Point:
rjmp $
.org 0x030
// Coprocessor Absent: UNUSED IN AVR32UC.
_handle_Coprocessor_Absent:
rjmp $
.org 0x034
// Data Address (Read).
_handle_Data_Address_Read:
rjmp $
.org 0x038
// Data Address (Write).
_handle_Data_Address_Write:
rjmp $
.org 0x03C
// DTLB Protection (Read).
_handle_DTLB_Protection_Read:
rjmp $
.org 0x040
// DTLB Protection (Write).
_handle_DTLB_Protection_Write:
rjmp $
.org 0x044
// DTLB Modified: UNUSED IN AVR32UC.
_handle_DTLB_Modified:
rjmp $
.org 0x050
// ITLB Miss: UNUSED IN AVR32UC.
_handle_ITLB_Miss:
rjmp $
.org 0x060
// DTLB Miss (Read): UNUSED IN AVR32UC.
_handle_DTLB_Miss_Read:
rjmp $
.org 0x070
// DTLB Miss (Write): UNUSED IN AVR32UC.
_handle_DTLB_Miss_Write:
rjmp $
.org 0x100
// Supervisor Call.
_handle_Supervisor_Call:
lda.w pc, SCALLYield
// Interrupt support.
// The interrupt controller must provide the offset address relative to EVBA.
// Important note:
// All interrupts call a C function named _get_interrupt_handler.
// This function will read group and interrupt line number to then return in
// R12 a pointer to a user-provided interrupt handler.
.balign 4
_int0:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int0_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int0_normal:
#endif
mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int1:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int1_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int1_normal:
#endif
mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int2:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int2_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int2_normal:
#endif
mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int3:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int3_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int3_normal:
#endif
mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
// Constant data area.
.balign 4
// Values to store in the interrupt priority registers for the various interrupt priority levels.
// The interrupt priority registers contain the interrupt priority level and
// the EVBA-relative interrupt vector offset.
.global ipr_val
.type ipr_val, @object
ipr_val:
.word (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\
(INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\
(INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\
(INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)
//! \endverbatim
//! @}

View file

@ -0,0 +1,455 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port source for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Standard includes. */
#include <sys/cpu.h>
#include <sys/usart.h>
#include <malloc.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* AVR32 UC3 includes. */
#include <avr32/io.h>
#include "gpio.h"
#if( configTICK_USE_TC==1 )
#include "tc.h"
#endif
/* Constants required to setup the task context. */
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )
/* Each task maintains its own critical nesting variable. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
#if( configTICK_USE_TC==0 )
static void prvScheduleNextTick( void );
#else
static void prvClearTcInt( void );
#endif
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Low-level initialization routine called during startup, before the main
* function.
* This version comes in replacement to the default one provided by Newlib.
* Newlib's _init_startup only calls init_exceptions, but Newlib's exception
* vectors are not compatible with the SCALL management in the current FreeRTOS
* port. More low-level initializations are besides added here.
*/
void _init_startup(void)
{
/* Import the Exception Vector Base Address. */
extern void _evba;
#if configHEAP_INIT
extern void __heap_start__;
extern void __heap_end__;
portBASE_TYPE *pxMem;
#endif
/* Load the Exception Vector Base Address in the corresponding system register. */
Set_system_register( AVR32_EVBA, ( int ) &_evba );
/* Enable exceptions. */
ENABLE_ALL_EXCEPTIONS();
/* Initialize interrupt handling. */
INTC_init_interrupts();
#if configHEAP_INIT
/* Initialize the heap used by malloc. */
for( pxMem = &__heap_start__; pxMem < ( portBASE_TYPE * )&__heap_end__; )
{
*pxMem++ = 0xA5A5A5A5;
}
#endif
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
set_cpu_hz( configCPU_CLOCK_HZ );
/* Code section present if and only if the debug trace is activated. */
#if configDBG
{
static const gpio_map_t DBG_USART_GPIO_MAP =
{
{ configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
{ configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
};
/* Initialize the USART used for the debug trace with the configured parameters. */
set_usart_base( ( void * ) configDBG_USART );
gpio_enable_module( DBG_USART_GPIO_MAP,
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
usart_init( configDBG_USART_BAUDRATE );
}
#endif
}
/*-----------------------------------------------------------*/
/*
* malloc, realloc and free are meant to be called through respectively
* pvPortMalloc, pvPortRealloc and vPortFree.
* The latter functions call the former ones from within sections where tasks
* are suspended, so the latter functions are task-safe. __malloc_lock and
* __malloc_unlock use the same mechanism to also keep the former functions
* task-safe as they may be called directly from Newlib's functions.
* However, all these functions are interrupt-unsafe and SHALL THEREFORE NOT BE
* CALLED FROM WITHIN AN INTERRUPT, because __malloc_lock and __malloc_unlock do
* not call portENTER_CRITICAL and portEXIT_CRITICAL in order not to disable
* interrupts during memory allocation management as this may be a very time-
* consuming process.
*/
/*
* Lock routine called by Newlib on malloc / realloc / free entry to guarantee a
* safe section as memory allocation management uses global data.
* See the aforementioned details.
*/
void __malloc_lock(struct _reent *ptr)
{
vTaskSuspendAll();
}
/*
* Unlock routine called by Newlib on malloc / realloc / free exit to guarantee
* a safe section as memory allocation management uses global data.
* See the aforementioned details.
*/
void __malloc_unlock(struct _reent *ptr)
{
xTaskResumeAll();
}
/*-----------------------------------------------------------*/
/* Added as there is no such function in FreeRTOS. */
void *pvPortRealloc( void *pv, size_t xWantedSize )
{
void *pvReturn;
vTaskSuspendAll();
{
pvReturn = realloc( pv, xWantedSize );
}
xTaskResumeAll();
return pvReturn;
}
/*-----------------------------------------------------------*/
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
/* The preemptive scheduler is defined as "naked" as the full context is saved
on entry as part of the context switch. */
__attribute__((__naked__)) static void vTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT_OS_INT();
#if( configTICK_USE_TC==1 )
/* Clear the interrupt flag. */
prvClearTcInt();
#else
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
prvScheduleNextTick();
#endif
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
calls in a critical section . */
portENTER_CRITICAL();
vTaskIncrementTick();
portEXIT_CRITICAL();
/* Restore the context of the "elected task". */
portRESTORE_CONTEXT_OS_INT();
}
/*-----------------------------------------------------------*/
__attribute__((__naked__)) void SCALLYield( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT_SCALL();
vTaskSwitchContext();
portRESTORE_CONTEXT_SCALL();
}
/*-----------------------------------------------------------*/
/* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
__attribute__((__noinline__)) void vPortEnterCritical( void )
{
/* Disable interrupts */
portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
__attribute__((__noinline__)) void vPortExitCritical( void )
{
if(ulCriticalNesting > portNO_CRITICAL_NESTING)
{
ulCriticalNesting--;
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable all interrupt/exception. */
portENABLE_INTERRUPTS();
}
}
}
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* When the task starts, it will expect to find the function parameter in R12. */
pxTopOfStack--;
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808; /* R8 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909; /* R9 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A; /* R10 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B; /* R11 */
*pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters; /* R12 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF; /* R14/LR */
*pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; /* R15/PC */
*pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR; /* SR */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF; /* R0 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101; /* R1 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202; /* R2 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303; /* R3 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
portRESTORE_CONTEXT();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the AVR32 port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
#if( configTICK_USE_TC==0 )
static void prvScheduleFirstTick(void)
{
unsigned long lCycles;
lCycles = Get_system_register(AVR32_COUNT);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
Set_system_register(AVR32_COMPARE, lCycles);
}
__attribute__((__noinline__)) static void prvScheduleNextTick(void)
{
unsigned long lCycles, lCount;
lCycles = Get_system_register(AVR32_COMPARE);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
lCount = Get_system_register(AVR32_COUNT);
if( lCycles < lCount )
{ // We missed a tick, recover for the next.
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
}
Set_system_register(AVR32_COMPARE, lCycles);
}
#else
__attribute__((__noinline__)) static void prvClearTcInt(void)
{
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
}
#endif
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt(void)
{
#if( configTICK_USE_TC==1 )
volatile avr32_tc_t *tc = &AVR32_TC;
// Options for waveform genration.
tc_waveform_opt_t waveform_opt =
{
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
.bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */
.beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */
.bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */
.bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */
.aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */
.aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
.enetrg = FALSE, /* External event trigger enable. */
.eevt = 0, /* External event selection. */
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
.cpcdis = FALSE, /* Counter disable when RC compare. */
.cpcstop = FALSE, /* Counter clock stopped with RC compare. */
.burst = FALSE, /* Burst signal selection. */
.clki = FALSE, /* Clock inversion. */
.tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */
};
tc_interrupt_t tc_interrupt =
{
.etrgs=0,
.ldrbs=0,
.ldras=0,
.cpcs =1,
.cpbs =0,
.cpas =0,
.lovrs=0,
.covfs=0,
};
#endif
/* Disable all interrupt/exception. */
portDISABLE_INTERRUPTS();
/* Register the compare interrupt handler to the interrupt controller and
enable the compare interrupt. */
#if( configTICK_USE_TC==1 )
{
INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0);
/* Initialize the timer/counter. */
tc_init_waveform(tc, &waveform_opt);
/* Set the compare triggers.
Remember TC counter is 16-bits, so counting second is not possible!
That's why we configure it to count ms. */
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
/* Start the timer/counter. */
tc_start(tc, configTICK_TC_CHANNEL);
}
#else
{
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
prvScheduleFirstTick();
}
#endif
}

View file

@ -0,0 +1,683 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port source for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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.
*-----------------------------------------------------------
*/
#include <avr32/io.h>
#include "intc.h"
#include "compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned portLONG
#define portBASE_TYPE portLONG
#define TASK_DELAY_MS(x) ( (x) /portTICK_RATE_MS )
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portNOP() {__asm__ __volatile__ ("nop");}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* INTC-specific. */
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
/*
* Debug trace.
* Activated if and only if configDBG is nonzero.
* Prints a formatted string to stdout.
* The current source file name and line number are output with a colon before
* the formatted string.
* A carriage return and a linefeed are appended to the output.
* stdout is redirected to the USART configured by configDBG_USART.
* The parameters are the same as for the standard printf function.
* There is no return value.
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
*/
#if configDBG
#define portDBG_TRACE(...) \
{\
fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout);\
printf(__VA_ARGS__);\
fputs("\r\n", stdout);\
}
#else
#define portDBG_TRACE(...)
#endif
/* Critical section management. */
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/* Added as there is no such function in FreeRTOS. */
extern void *pvPortRealloc( void *pv, size_t xSize );
/*-----------------------------------------------------------*/
/*=============================================================================================*/
/*
* Restore Context for cases other than INTi.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
/* R0-R7 should not be used below this line */ \
/* Skip PC and SR (will do it at the end) */ \
"sub sp, -2*4 \n\t"\
/* Restore R8..R12 and LR */ \
"ldm sp++, r8-r12, lr \n\t"\
/* Restore SR */ \
"ld.w r0, sp[-8*4]\n\t" /* R0 is modified, is restored later. */ \
"mtsr %[SR], r0 \n\t"\
/* Restore r0 */ \
"ld.w r0, sp[-9*4] \n\t"\
/* Restore PC */ \
"ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
[pxCurrentTCB] "i" (&pxCurrentTCB), \
[SR] "i" (AVR32_SR) \
); \
}
/*
* portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.
* portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.
*
* Had to make different versions because registers saved on the system stack
* are not the same between INT0..3 exceptions and the scall exception.
*/
// Task context stack layout:
// R8 (*)
// R9 (*)
// R10 (*)
// R11 (*)
// R12 (*)
// R14/LR (*)
// R15/PC (*)
// SR (*)
// R0
// R1
// R2
// R3
// R4
// R5
// R6
// R7
// ulCriticalNesting
// (*) automatically done for INT0..INT3, but not for SCALL
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/*
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
*/
#define portSAVE_CONTEXT_OS_INT() \
{ \
/* Save R0..R7 */ \
__asm__ __volatile__ ("stm --sp, r0-r7"); \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context save. */ \
}
/*
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
*/
#define portRESTORE_CONTEXT_OS_INT() \
{ \
__asm__ __volatile__ ( \
/* Restore R0..R7 */ \
"ldm sp++, r0-r7\n\t" \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context restore. */ \
"rete" \
); \
}
#else
/*
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
*/
#define portSAVE_CONTEXT_OS_INT() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* When we come here */ \
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
\
__asm__ __volatile__ ( \
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t"\
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LO(%[ulCriticalNesting])\n\t" \
"orh r8, HI(%[ulCriticalNesting])\n\t" \
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0 \n\t"\
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
"brhi LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
/* NOTE: we don't enter a critical section here because all interrupt handlers */ \
/* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \
/* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \
/* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \
"mov r8, LO(%[pxCurrentTCB])\n\t" \
"orh r8, HI(%[pxCurrentTCB])\n\t" \
"ld.w r0, r8[0]\n\t" \
"st.w r0[0], sp\n" \
\
"LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:" \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
[pxCurrentTCB] "i" (&pxCurrentTCB), \
[LINE] "i" (__LINE__) \
); \
}
/*
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
*/
#define portRESTORE_CONTEXT_OS_INT() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
__asm__ __volatile__ ( \
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]" \
: \
: [LINE] "i" (__LINE__) \
); \
\
/* Else */ \
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
\
/* Restore all registers */ \
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n"\
\
"LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t" \
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* Now, the stack should be R8..R12, LR, PC and SR */ \
"rete" \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
[pxCurrentTCB] "i" (&pxCurrentTCB), \
[LINE] "i" (__LINE__) \
); \
}
#endif
/*
* portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.
*
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
*
*/
#define portSAVE_CONTEXT_SCALL() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
/* If SR[M2:M0] == 001 */ \
/* PC and SR are on the stack. */ \
/* Else (other modes) */ \
/* Nothing on the stack. */ \
\
/* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \
/* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \
/* in an interrupt|exception handler. */ \
\
__asm__ __volatile__ ( \
/* in order to save R0-R7 */ \
"sub sp, 6*4 \n\t"\
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t"\
\
/* in order to save R8-R12 and LR */ \
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
"sub r7, sp,-16*4 \n\t"\
/* Copy PC and SR in other places in the stack. */ \
"ld.w r0, r7[-2*4] \n\t" /* Read SR */\
"st.w r7[-8*4], r0 \n\t" /* Copy SR */\
"ld.w r0, r7[-1*4] \n\t" /* Read PC */\
"st.w r7[-7*4], r0 \n\t" /* Copy PC */\
\
/* Save R8..R12 and LR on the stack. */ \
"stm --r7, r8-r12, lr \n\t"\
\
/* Arriving here we have the following stack organizations: */ \
/* R8..R12, LR, PC, SR, R0..R7. */ \
\
/* Now we can finalize the save. */ \
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0" \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting) \
); \
\
/* Disable the its which may cause a context switch (i.e. cause a change of */ \
/* pxCurrentTCB). */ \
/* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \
/* critical section because it is a global structure. */ \
portENTER_CRITICAL(); \
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
__asm__ __volatile__ ( \
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp" \
: \
: [pxCurrentTCB] "i" (&pxCurrentTCB) \
); \
}
/*
* portRESTORE_CONTEXT() for SupervisorCALL exception.
*/
#define portRESTORE_CONTEXT_SCALL() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Restore all registers */ \
\
/* Set SP to point to new stack */ \
__asm__ __volatile__ ( \
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0]" \
: \
: [pxCurrentTCB] "i" (&pxCurrentTCB) \
); \
\
/* Leave pxCurrentTCB variable access critical section */ \
portEXIT_CRITICAL(); \
\
__asm__ __volatile__ ( \
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* skip PC and SR */ \
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
"sub r7, sp, -10*4 \n\t"\
/* Restore r8-r12 and LR */ \
"ldm r7++, r8-r12, lr \n\t"\
\
/* RETS will take care of the extra PC and SR restore. */ \
/* So, we have to prepare the stack for this. */ \
"ld.w r0, r7[-8*4] \n\t" /* Read SR */\
"st.w r7[-2*4], r0 \n\t" /* Copy SR */\
"ld.w r0, r7[-7*4] \n\t" /* Read PC */\
"st.w r7[-1*4], r0 \n\t" /* Copy PC */\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
"sub sp, -6*4 \n\t"\
\
"rets" \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting) \
); \
}
/*
* The ISR used depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/*
* ISR entry and exit macros. These are only required if a task switch
* is required from the ISR.
*/
#define portENTER_SWITCHING_ISR() \
{ \
/* Save R0..R7 */ \
__asm__ __volatile__ ("stm --sp, r0-r7"); \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context save. */ \
}
/*
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
*/
#define portEXIT_SWITCHING_ISR() \
{ \
__asm__ __volatile__ ( \
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context restore. */ \
"rete" \
); \
}
#else
/*
* ISR entry and exit macros. These are only required if a task switch
* is required from the ISR.
*/
#define portENTER_SWITCHING_ISR() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* When we come here */ \
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
\
__asm__ __volatile__ ( \
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t"\
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0 \n\t"\
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp \n"\
\
"LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:" \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
[pxCurrentTCB] "i" (&pxCurrentTCB), \
[LINE] "i" (__LINE__) \
); \
}
/*
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
*/
#define portEXIT_SWITCHING_ISR() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
__asm__ __volatile__ ( \
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
/* did not previously save SP in its TCB. */ \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE] \n\t"\
\
/* If a switch is required then we just need to call */ \
/* vTaskSwitchContext() as the context has already been */ \
/* saved. */ \
"cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
"brne LABEL_ISR_RESTORE_CONTEXT_%[LINE]" \
: \
: [LINE] "i" (__LINE__) \
); \
\
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
\
__asm__ __volatile__ ( \
"LABEL_ISR_RESTORE_CONTEXT_%[LINE]: \n\t"\
/* Restore the context of which ever task is now the highest */ \
/* priority that is ready to run. */ \
\
/* Restore all registers */ \
\
/* Set SP to point to new stack */ \
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n"\
\
"LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* Now, the stack should be R8..R12, LR, PC and SR */ \
"rete" \
: \
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
[pxCurrentTCB] "i" (&pxCurrentTCB), \
[LINE] "i" (__LINE__) \
); \
}
#endif
#define portYIELD() {__asm__ __volatile__ ("scall");}
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,154 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#define portINITIAL_FORMAT_VECTOR ( ( portSTACK_TYPE ) 0x4000 )
/* Supervisor mode set. */
#define portINITIAL_STATUS_REGISTER ( ( portSTACK_TYPE ) 0x2000)
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
will be set to 0 prior to the first task being started. */
static unsigned portLONG ulCriticalNesting = 0x9999UL;
/*-----------------------------------------------------------*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
pxTopOfStack--;
/* Exception stack frame starts with the return address. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
pxTopOfStack -= 14; /* A5 to D0. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void vPortStartFirstTask( void );
ulCriticalNesting = 0UL;
/* Configure the interrupts used by this port. */
vApplicationSetupInterrupts();
/* Start the first task executing. */
vPortStartFirstTask();
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented as there is nothing to return to. */
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
if( ulCriticalNesting == 0UL )
{
/* Guard against context switches being pended simultaneously with a
critical section being entered. */
do
{
portDISABLE_INTERRUPTS();
if( MCF_INTC0_INTFRCL == 0UL )
{
break;
}
portENABLE_INTERRUPTS();
} while( 1 );
}
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
ulCriticalNesting--;
if( ulCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
void vPortYieldHandler( void )
{
unsigned portLONG ulSavedInterruptMask;
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
/* Note this will clear all forced interrupts - this is done for speed. */
MCF_INTC0_INTFRCL = 0;
vTaskSwitchContext();
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
}

View file

@ -0,0 +1,140 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
* Purpose: Lowest level routines for all ColdFire processors.
*
* Notes:
*
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
* supplied source files.
*/
.global ulPortSetIPL
.global mcf5xxx_wr_cacr
.global __cs3_isr_interrupt_80
.global vPortStartFirstTask
.text
.macro portSAVE_CONTEXT
lea.l (-60, %sp), %sp
movem.l %d0-%fp, (%sp)
move.l pxCurrentTCB, %a0
move.l %sp, (%a0)
.endm
.macro portRESTORE_CONTEXT
move.l pxCurrentTCB, %a0
move.l (%a0), %sp
movem.l (%sp), %d0-%fp
lea.l %sp@(60), %sp
rte
.endm
/********************************************************************/
/*
* This routines changes the IPL to the value passed into the routine.
* It also returns the old IPL value back.
* Calling convention from C:
* old_ipl = asm_set_ipl(new_ipl);
* For the Diab Data C compiler, it passes return value thru D0.
* Note that only the least significant three bits of the passed
* value are used.
*/
ulPortSetIPL:
link A6,#-8
movem.l D6-D7,(SP)
move.w SR,D7 /* current sr */
move.l D7,D0 /* prepare return value */
andi.l #0x0700,D0 /* mask out IPL */
lsr.l #8,D0 /* IPL */
move.l 8(A6),D6 /* get argument */
andi.l #0x07,D6 /* least significant three bits */
lsl.l #8,D6 /* move over to make mask */
andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D6,D7 /* place new IPL in sr */
move.w D7,SR
movem.l (SP),D6-D7
lea 8(SP),SP
unlk A6
rts
/********************************************************************/
mcf5xxx_wr_cacr:
move.l 4(sp),d0
.long 0x4e7b0002 /* movec d0,cacr */
nop
rts
/********************************************************************/
/* Yield interrupt. */
__cs3_isr_interrupt_80:
portSAVE_CONTEXT
jsr vPortYieldHandler
portRESTORE_CONTEXT
/********************************************************************/
vPortStartFirstTask:
portRESTORE_CONTEXT
.end

View file

@ -0,0 +1,130 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 long
#define portBASE_TYPE long
#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 4
#define portSTACK_GROWTH -1
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
unsigned portLONG ulPortSetIPL( unsigned portLONG );
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR( void );
extern void vPortClearInterruptMaskFromISR( unsigned portBASE_TYPE );
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portNOP() asm volatile ( "nop" )
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP()
/*-----------------------------------------------------------*/
/* 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 != pdFALSE ) \
{ \
portYIELD(); \
}
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,321 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the H8S port.
*----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* When the task starts interrupts should be enabled. */
#define portINITIAL_CCR ( ( portSTACK_TYPE ) 0x00 )
/* Hardware specific constants used to generate the RTOS tick from the TPU. */
#define portCLEAR_ON_TGRA_COMPARE_MATCH ( ( unsigned portCHAR ) 0x20 )
#define portCLOCK_DIV_64 ( ( unsigned portCHAR ) 0x03 )
#define portCLOCK_DIV ( ( unsigned portLONG ) 64 )
#define portTGRA_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 0x01 )
#define portTIMER_CHANNEL ( ( unsigned portCHAR ) 0x02 )
#define portMSTP13 ( ( unsigned portSHORT ) 0x2000 )
/*
* Setup TPU channel one for the RTOS tick at the requested frequency.
*/
static void prvSetupTimerInterrupt( void );
/*
* The ISR used by portYIELD(). This is installed as a trap handler.
*/
void vPortYield( void ) __attribute__ ( ( saveall, interrupt_handler ) );
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned portLONG ulValue;
/* This requires an even address. */
ulValue = ( unsigned portLONG ) pxTopOfStack;
if( ulValue & 1UL )
{
pxTopOfStack = pxTopOfStack - 1;
}
/* Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging. */
pxTopOfStack--;
*pxTopOfStack = 0xaa;
pxTopOfStack--;
*pxTopOfStack = 0xbb;
pxTopOfStack--;
*pxTopOfStack = 0xcc;
pxTopOfStack--;
*pxTopOfStack = 0xdd;
/* The initial stack mimics an interrupt stack. First there is the program
counter (24 bits). */
ulValue = ( unsigned portLONG ) pxCode;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
pxTopOfStack--;
ulValue >>= 8UL;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
pxTopOfStack--;
ulValue >>= 8UL;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
/* Followed by the CCR. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_CCR;
/* Next all the general purpose registers - with the parameters being passed
in ER0. The parameter order must match that used by the compiler when the
"saveall" function attribute is used. */
/* ER6 */
pxTopOfStack--;
*pxTopOfStack = 0x66;
pxTopOfStack--;
*pxTopOfStack = 0x66;
pxTopOfStack--;
*pxTopOfStack = 0x66;
pxTopOfStack--;
*pxTopOfStack = 0x66;
/* ER0 */
ulValue = ( unsigned portLONG ) pvParameters;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
pxTopOfStack--;
ulValue >>= 8UL;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
pxTopOfStack--;
ulValue >>= 8UL;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
pxTopOfStack--;
ulValue >>= 8UL;
*pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );
/* ER1 */
pxTopOfStack--;
*pxTopOfStack = 0x11;
pxTopOfStack--;
*pxTopOfStack = 0x11;
pxTopOfStack--;
*pxTopOfStack = 0x11;
pxTopOfStack--;
*pxTopOfStack = 0x11;
/* ER2 */
pxTopOfStack--;
*pxTopOfStack = 0x22;
pxTopOfStack--;
*pxTopOfStack = 0x22;
pxTopOfStack--;
*pxTopOfStack = 0x22;
pxTopOfStack--;
*pxTopOfStack = 0x22;
/* ER3 */
pxTopOfStack--;
*pxTopOfStack = 0x33;
pxTopOfStack--;
*pxTopOfStack = 0x33;
pxTopOfStack--;
*pxTopOfStack = 0x33;
pxTopOfStack--;
*pxTopOfStack = 0x33;
/* ER4 */
pxTopOfStack--;
*pxTopOfStack = 0x44;
pxTopOfStack--;
*pxTopOfStack = 0x44;
pxTopOfStack--;
*pxTopOfStack = 0x44;
pxTopOfStack--;
*pxTopOfStack = 0x44;
/* ER5 */
pxTopOfStack--;
*pxTopOfStack = 0x55;
pxTopOfStack--;
*pxTopOfStack = 0x55;
pxTopOfStack--;
*pxTopOfStack = 0x55;
pxTopOfStack--;
*pxTopOfStack = 0x55;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void * pxCurrentTCB;
/* Setup the hardware to generate the tick. */
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run. This
mirrors the function epilogue code generated by the compiler when the
"saveall" function attribute is used. */
asm volatile (
"MOV.L @_pxCurrentTCB, ER6 \n\t"
"MOV.L @ER6, ER7 \n\t"
"LDM.L @SP+, (ER4-ER5) \n\t"
"LDM.L @SP+, (ER0-ER3) \n\t"
"MOV.L @ER7+, ER6 \n\t"
"RTE \n\t"
);
( void ) pxCurrentTCB;
/* Should not get here. */
return pdTRUE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the h8 port will get stopped. */
}
/*-----------------------------------------------------------*/
/*
* Manual context switch. This is a trap handler. The "saveall" function
* attribute is used so the context is saved by the compiler prologue. All
* we have to do is save the stack pointer.
*/
void vPortYield( void )
{
portSAVE_STACK_POINTER();
vTaskSwitchContext();
portRESTORE_STACK_POINTER();
}
/*-----------------------------------------------------------*/
/*
* The interrupt handler installed for the RTOS tick depends on whether the
* preemptive or cooperative scheduler is being used.
*/
#if( configUSE_PREEMPTION == 1 )
/*
* The preemptive scheduler is used so the ISR calls vTaskSwitchContext().
* The function prologue saves the context so all we have to do is save
* the stack pointer.
*/
void vTickISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
void vTickISR( void )
{
portSAVE_STACK_POINTER();
vTaskIncrementTick();
vTaskSwitchContext();
/* Clear the interrupt. */
TSR1 &= ~0x01;
portRESTORE_STACK_POINTER();
}
#else
/*
* The cooperative scheduler is being used so all we have to do is
* periodically increment the tick. This can just be a normal ISR and
* the "saveall" attribute is not required.
*/
void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );
void vTickISR( void )
{
vTaskIncrementTick();
/* Clear the interrupt. */
TSR1 &= ~0x01;
}
#endif
/*-----------------------------------------------------------*/
/*
* Setup timer 1 compare match to generate a tick interrupt.
*/
static void prvSetupTimerInterrupt( void )
{
const unsigned portLONG ulCompareMatch = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) / portCLOCK_DIV;
/* Turn the module on. */
MSTPCR &= ~portMSTP13;
/* Configure timer 1. */
TCR1 = portCLEAR_ON_TGRA_COMPARE_MATCH | portCLOCK_DIV_64;
/* Configure the compare match value for a tick of configTICK_RATE_HZ. */
TGR1A = ulCompareMatch;
/* Start the timer and enable the interrupt - we can do this here as
interrupts are globally disabled when this function is called. */
TIER1 |= portTGRA_INTERRUPT_ENABLE;
TSTR |= portTIMER_CHANNEL;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,154 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portCHAR
#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 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portYIELD() asm volatile( "TRAPA #0" )
#define portNOP() asm volatile( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
#define portENABLE_INTERRUPTS() asm volatile( "ANDC #0x7F, CCR" );
#define portDISABLE_INTERRUPTS() asm volatile( "ORC #0x80, CCR" );
/* Push the CCR then disable interrupts. */
#define portENTER_CRITICAL() asm volatile( "STC CCR, @-ER7" ); \
portDISABLE_INTERRUPTS();
/* Pop the CCR to set the interrupt masking back to its previous state. */
#define portEXIT_CRITICAL() asm volatile( "LDC @ER7+, CCR" );
/*-----------------------------------------------------------*/
/* Task utilities. */
/* Context switch macros. These macros are very simple as the context
is saved simply by selecting the saveall attribute of the context switch
interrupt service routines. These macros save and restore the stack
pointer to the TCB. */
#define portSAVE_STACK_POINTER() \
extern void* pxCurrentTCB; \
\
asm volatile( \
"MOV.L @_pxCurrentTCB, ER5 \n\t" \
"MOV.L ER7, @ER5 \n\t" \
); \
( void ) pxCurrentTCB;
#define portRESTORE_STACK_POINTER() \
extern void* pxCurrentTCB; \
\
asm volatile( \
"MOV.L @_pxCurrentTCB, ER5 \n\t" \
"MOV.L @ER5, ER7 \n\t" \
); \
( void ) pxCurrentTCB;
/*-----------------------------------------------------------*/
/* Macros to allow a context switch from within an application ISR. */
#define portENTER_SWITCHING_ISR() portSAVE_STACK_POINTER(); {
#define portEXIT_SWITCHING_ISR( x ) \
if( x ) \
{ \
extern void vTaskSwitchContext( void ); \
vTaskSwitchContext(); \
} \
} portRESTORE_STACK_POINTER();
/*-----------------------------------------------------------*/
/* 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 */

View file

@ -0,0 +1,257 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* GCC/HCS12 port by Jefferson L Smith, 2005 */
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Port includes */
#include <sys/ports_def.h>
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the HCS12 port.
*----------------------------------------------------------*/
/*
* Configure a timer to generate the RTOS tick at the frequency specified
* within FreeRTOSConfig.h.
*/
static void prvSetupTimerInterrupt( void );
/* NOTE: Interrupt service routines must be in non-banked memory - as does the
scheduler startup function. */
#define ATTR_NEAR __attribute__((near))
/* Manual context switch function. This is the SWI ISR. */
// __attribute__((interrupt))
void ATTR_NEAR vPortYield( void );
/* Tick context switch function. This is the timer ISR. */
// __attribute__((interrupt))
void ATTR_NEAR vPortTickInterrupt( void );
/* Function in non-banked memory which actually switches to first task. */
portBASE_TYPE ATTR_NEAR xStartSchedulerNear( void );
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
critical section should not be left (i.e. interrupts should not be re-enabled)
until the nesting depth reaches 0. This variable simply tracks the nesting
depth. Each task maintains it's own critical nesting depth variable so
uxCriticalNesting is saved and restored from the task stack during a context
switch. */
volatile unsigned portBASE_TYPE uxCriticalNesting = 0x80; // un-initialized
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
expected by the HCS12 RTI instruction. */
/* The address of the task function is placed in the stack byte at a time. */
*pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 1 );
*--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pxCode) ) + 0 );
/* Next are all the registers that form part of the task context. */
/* Y register */
*--pxTopOfStack = ( portSTACK_TYPE ) 0xff;
*--pxTopOfStack = ( portSTACK_TYPE ) 0xee;
/* X register */
*--pxTopOfStack = ( portSTACK_TYPE ) 0xdd;
*--pxTopOfStack = ( portSTACK_TYPE ) 0xcc;
/* A register contains parameter high byte. */
*--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 0 );
/* B register contains parameter low byte. */
*--pxTopOfStack = ( portSTACK_TYPE ) *( ((portSTACK_TYPE *) (&pvParameters) ) + 1 );
/* CCR: Note that when the task starts interrupts will be enabled since
"I" bit of CCR is cleared */
*--pxTopOfStack = ( portSTACK_TYPE ) 0x80; // keeps Stop disabled (MCU default)
/* tmp softregs used by GCC. Values right now don't matter. */
__asm("\n\
movw _.frame, 2,-%0 \n\
movw _.tmp, 2,-%0 \n\
movw _.z, 2,-%0 \n\
movw _.xy, 2,-%0 \n\
;movw _.d2, 2,-%0 \n\
;movw _.d1, 2,-%0 \n\
": "=A"(pxTopOfStack) : "0"(pxTopOfStack) );
#ifdef BANKED_MODEL
/* The page of the task. */
*--pxTopOfStack = 0x30; // can only directly start in PPAGE 0x30
#endif
/* The critical nesting depth is initialised with 0 (meaning not in
a critical section). */
*--pxTopOfStack = ( portSTACK_TYPE ) 0x00;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the HCS12 port will get stopped. */
}
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
/* Enable hardware RTI timer */
/* Ignores configTICK_RATE_HZ */
RTICTL = 0x50; // 16 MHz xtal: 976.56 Hz, 1024mS
CRGINT |= 0x80; // RTIE
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* xPortStartScheduler() does not start the scheduler directly because
the header file containing the xPortStartScheduler() prototype is part
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
Instead it simply calls the locally defined xNearStartScheduler() -
which does use the CODE_SEG pragma. */
short register d;
__asm ("jmp xStartSchedulerNear ; will never return": "=d"(d));
return d;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xStartSchedulerNear( void )
{
/* Configure the timer that will generate the RTOS tick. Interrupts are
disabled when this function is called. */
prvSetupTimerInterrupt();
/* Restore the context of the first task. */
portRESTORE_CONTEXT();
portISR_TAIL();
/* Should not get here! */
return pdFALSE;
}
/*-----------------------------------------------------------*/
/*
* Context switch functions. These are interrupt service routines.
*/
/*
* Manual context switch forced by calling portYIELD(). This is the SWI
* handler.
*/
void vPortYield( void )
{
portISR_HEAD();
/* NOTE: This is the trap routine (swi) although not defined as a trap.
It will fill the stack the same way as an ISR in order to mix preemtion
and cooperative yield. */
portSAVE_CONTEXT();
vTaskSwitchContext();
portRESTORE_CONTEXT();
portISR_TAIL();
}
/*-----------------------------------------------------------*/
/*
* RTOS tick interrupt service routine. If the cooperative scheduler is
* being used then this simply increments the tick count. If the
* preemptive scheduler is being used a context switch can occur.
*/
void vPortTickInterrupt( void )
{
portISR_HEAD();
/* Clear tick timer flag */
CRGFLG = 0x80;
#if configUSE_PREEMPTION == 1
{
/* A context switch might happen so save the context. */
portSAVE_CONTEXT();
/* Increment the tick ... */
vTaskIncrementTick();
/* ... then see if the new tick value has necessitated a
context switch. */
vTaskSwitchContext();
/* Restore the context of a task - which may be a different task
to that interrupted. */
portRESTORE_CONTEXT();
}
#else
{
vTaskIncrementTick();
}
#endif
portISR_TAIL();
}

View file

@ -0,0 +1,261 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portCHAR
#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 portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portYIELD() __asm( "swi" );
/*-----------------------------------------------------------*/
/* Critical section handling. */
#define portENABLE_INTERRUPTS() __asm( "cli" )
#define portDISABLE_INTERRUPTS() __asm( "sei" )
/*
* Disable interrupts before incrementing the count of critical section nesting.
* The nesting count is maintained so we know when interrupts should be
* re-enabled. Once interrupts are disabled the nesting count can be accessed
* directly. Each task maintains its own nesting count.
*/
#define portENTER_CRITICAL() \
{ \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
uxCriticalNesting++; \
}
/*
* Interrupts are disabled so we can access the nesting count directly. If the
* nesting is found to be 0 (no nesting) then we are leaving the critical
* section and interrupts can be re-enabled.
*/
#define portEXIT_CRITICAL() \
{ \
extern volatile unsigned portBASE_TYPE uxCriticalNesting; \
\
uxCriticalNesting--; \
if( uxCriticalNesting == 0 ) \
{ \
portENABLE_INTERRUPTS(); \
} \
}
/*-----------------------------------------------------------*/
/* Task utilities. */
/*
* These macros are very simple as the processor automatically saves and
* restores its registers as interrupts are entered and exited. In
* addition to the (automatically stacked) registers we also stack the
* critical nesting count. Each task maintains its own critical nesting
* count as it is legitimate for a task to yield from within a critical
* section. If the banked memory model is being used then the PPAGE
* register is also stored as part of the tasks context.
*/
#ifdef BANKED_MODEL
/*
* Load the stack pointer for the task, then pull the critical nesting
* count and PPAGE register from the stack. The remains of the
* context are restored by the RTI instruction.
*/
#define portRESTORE_CONTEXT() \
{ \
__asm( " \n\
.globl pxCurrentTCB ; void * \n\
.globl uxCriticalNesting ; char \n\
\n\
ldx pxCurrentTCB \n\
lds 0,x ; Stack \n\
\n\
movb 1,sp+,uxCriticalNesting \n\
movb 1,sp+,0x30 ; PPAGE \n\
" ); \
}
/*
* By the time this macro is called the processor has already stacked the
* registers. Simply stack the nesting count and PPAGE value, then save
* the task stack pointer.
*/
#define portSAVE_CONTEXT() \
{ \
__asm( " \n\
.globl pxCurrentTCB ; void * \n\
.globl uxCriticalNesting ; char \n\
\n\
movb 0x30, 1,-sp ; PPAGE \n\
movb uxCriticalNesting, 1,-sp \n\
\n\
ldx pxCurrentTCB \n\
sts 0,x ; Stack \n\
" ); \
}
#else
/*
* These macros are as per the BANKED versions above, but without saving
* and restoring the PPAGE register.
*/
#define portRESTORE_CONTEXT() \
{ \
__asm( " \n\
.globl pxCurrentTCB ; void * \n\
.globl uxCriticalNesting ; char \n\
\n\
ldx pxCurrentTCB \n\
lds 0,x ; Stack \n\
\n\
movb 1,sp+,uxCriticalNesting \n\
" ); \
}
#define portSAVE_CONTEXT() \
{ \
__asm( " \n\
.globl pxCurrentTCB ; void * \n\
.globl uxCriticalNesting ; char \n\
\n\
movb uxCriticalNesting, 1,-sp \n\
\n\
ldx pxCurrentTCB \n\
sts 0,x ; Stack \n\
" ); \
}
#endif
/*
* Utility macros to save/restore correct software registers for GCC. This is
* useful when GCC does not generate appropriate ISR head/tail code.
*/
#define portISR_HEAD() \
{ \
__asm(" \n\
movw _.frame, 2,-sp \n\
movw _.tmp, 2,-sp \n\
movw _.z, 2,-sp \n\
movw _.xy, 2,-sp \n\
;movw _.d2, 2,-sp \n\
;movw _.d1, 2,-sp \n\
"); \
}
#define portISR_TAIL() \
{ \
__asm(" \n\
movw 2,sp+, _.xy \n\
movw 2,sp+, _.z \n\
movw 2,sp+, _.tmp \n\
movw 2,sp+, _.frame \n\
;movw 2,sp+, _.d1 \n\
;movw 2,sp+, _.d2 \n\
rti \n\
"); \
}
/*
* Utility macro to call macros above in correct order in order to perform a
* task switch from within a standard ISR. This macro can only be used if
* the ISR does not use any local (stack) variables. If the ISR uses stack
* variables portYIELD() should be used in it's place.
*/
#define portTASK_SWITCH_FROM_ISR() \
portSAVE_CONTEXT(); \
vTaskSwitchContext(); \
portRESTORE_CONTEXT();
/* 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 */

View file

@ -0,0 +1,283 @@
/*
FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
MCF5235 Port - Copyright (C) 2006 Christian Walter.
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** as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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
along with FreeRTOS; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include <stdlib.h>
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "task.h"
/* ------------------------ Types ----------------------------------------- */
typedef volatile unsigned long vuint32;
typedef volatile unsigned short vuint16;
typedef volatile unsigned char vuint8;
/* ------------------------ Defines --------------------------------------- */
#define portVECTOR_TABLE __RAMVEC
#define portVECTOR_SYSCALL ( 32 + portTRAP_YIELD )
#define portVECTOR_TIMER ( 64 + 36 )
#define MCF_PIT_PRESCALER 512UL
#define MCF_PIT_TIMER_TICKS ( FSYS_2 / MCF_PIT_PRESCALER )
#define MCF_PIT_MODULUS_REGISTER(freq) ( MCF_PIT_TIMER_TICKS / ( freq ) - 1UL)
#define MCF_PIT_PMR0 ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150002 ] ) )
#define MCF_PIT_PCSR0 ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150000 ] ) )
#define MCF_PIT_PCSR_PRE(x) ( ( ( x ) & 0x000F ) << 8 )
#define MCF_PIT_PCSR_EN ( 0x0001 )
#define MCF_PIT_PCSR_RLD ( 0x0002 )
#define MCF_PIT_PCSR_PIF ( 0x0004 )
#define MCF_PIT_PCSR_PIE ( 0x0008 )
#define MCF_PIT_PCSR_OVW ( 0x0010 )
#define MCF_INTC0_ICR36 ( *( vuint8 * )( void * )( &__IPSBAR[ 0x000C64 ] ) )
#define MCF_INTC0_IMRH ( *( vuint32 * )( void * )( &__IPSBAR[ 0x000C08 ] ) )
#define MCF_INTC0_IMRH_INT_MASK36 ( 0x00000010 )
#define MCF_INTC0_IMRH_MASKALL ( 0x00000001 )
#define MCF_INTC0_ICRn_IP(x) ( ( ( x ) & 0x07 ) << 0 )
#define MCF_INTC0_ICRn_IL(x) ( ( ( x ) & 0x07 ) << 3 )
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
#define portINITIAL_CRITICAL_NESTING ( ( unsigned portLONG ) 10 )
/* ------------------------ Static variables ------------------------------ */
volatile unsigned portLONG ulCriticalNesting = portINITIAL_CRITICAL_NESTING;
/* ------------------------ Static functions ------------------------------ */
#if configUSE_PREEMPTION == 0
static void prvPortPreemptiveTick ( void ) __attribute__ ((interrupt_handler));
#else
static void prvPortPreemptiveTick ( void );
#endif
/* ------------------------ Start implementation -------------------------- */
portSTACK_TYPE *
pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode,
void *pvParameters )
{
/* Place the parameter on the stack in the expected location. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
/* Place dummy return address on stack. Tasks should never terminate so
* we can set this to anything. */
*pxTopOfStack = ( portSTACK_TYPE ) 0;
pxTopOfStack--;
/* Create a Motorola Coldfire exception stack frame. First comes the return
* address. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;
/* Format, fault-status, vector number for exception stack frame. Task
* run in supervisor mode. */
*pxTopOfStack = 0x40002000UL | ( portVECTOR_SYSCALL + 32 ) << 18;
pxTopOfStack--;
/* Set the initial critical section nesting counter to zero. This value
* is used to restore the value of ulCriticalNesting. */
*pxTopOfStack = 0;
*pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA6; /* A6 / FP */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA5; /* A5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA4; /* A4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA3; /* A3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA2; /* A2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA1; /* A1 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xA0; /* A0 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD7; /* D7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD6; /* D6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD5; /* D5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD4; /* D4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD3; /* D3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD2; /* D2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD1; /* D1 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xD0; /* D0 */
return pxTopOfStack;
}
/*
* Called by portYIELD() or taskYIELD() to manually force a context switch.
*/
static void
prvPortYield( void )
{
asm volatile ( "move.w #0x2700, %sr\n\t" );
#if _GCC_USES_FP == 1
asm volatile ( "unlk %fp\n\t" );
#endif
/* Perform the context switch. First save the context of the current task. */
portSAVE_CONTEXT( );
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext( );
/* Restore the context of the new task. */
portRESTORE_CONTEXT( );
}
#if configUSE_PREEMPTION == 0
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
static void
prvPortPreemptiveTick ( void )
{
/* The cooperative scheduler requires a normal IRQ service routine to
* simply increment the system tick.
*/
vTaskIncrementTick( );
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
}
#else
static void
prvPortPreemptiveTick( void )
{
asm volatile ( "move.w #0x2700, %sr\n\t" );
#if _GCC_USES_FP == 1
asm volatile ( "unlk %fp\n\t" );
#endif
portSAVE_CONTEXT( );
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
vTaskIncrementTick( );
vTaskSwitchContext( );
portRESTORE_CONTEXT( );
}
#endif
void
vPortEnterCritical()
{
/* FIXME: We should store the old IPL here - How are we supposed to do
* this.
*/
( void )portSET_IPL( portIPL_MAX );
/* Now interrupts are disabled ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
void
vPortExitCritical()
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as we are leaving a critical section. */
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
( void )portSET_IPL( 0 );
}
}
}
portBASE_TYPE
xPortStartScheduler( void )
{
extern void ( *portVECTOR_TABLE[ ] ) ( );
/* Add entry in vector table for yield system call. */
portVECTOR_TABLE[ portVECTOR_SYSCALL ] = prvPortYield;
/* Add entry in vector table for periodic timer. */
portVECTOR_TABLE[ portVECTOR_TIMER ] = prvPortPreemptiveTick;
/* Configure the timer for the system clock. */
if ( configTICK_RATE_HZ > 0)
{
/* Configure prescaler */
MCF_PIT_PCSR0 = MCF_PIT_PCSR_PRE( 0x9 ) | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_OVW;
/* Initialize the periodic timer interrupt. */
MCF_PIT_PMR0 = MCF_PIT_MODULUS_REGISTER( configTICK_RATE_HZ );
/* Configure interrupt priority and level and unmask interrupt. */
MCF_INTC0_ICR36 = MCF_INTC0_ICRn_IL( 0x1 ) | MCF_INTC0_ICRn_IP( 0x1 );
MCF_INTC0_IMRH &= ~( MCF_INTC0_IMRH_INT_MASK36 | MCF_INTC0_IMRH_MASKALL );
/* Enable interrupts */
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_EN | MCF_PIT_PCSR_PIF;
}
/* Restore the context of the first task that is going to run. */
portRESTORE_CONTEXT( );
/* Should not get here. */
return pdTRUE;
}
void
vPortEndScheduler( void )
{
}

View file

@ -0,0 +1,178 @@
/*
FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
MCF5235 Port - Copyright (C) 2006 Christian Walter.
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** as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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
along with FreeRTOS; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS, without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
***************************************************************************
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
/* ------------------------ Data types for Coldfire ----------------------- */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned int
#define portBASE_TYPE int
#if( USE_16_BIT_TICKS == 1 )
typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff
#else
typedef unsigned portLONG portTickType;
#define portMAX_DELAY ( portTickType ) 0xffffffff
#endif
/* ------------------------ Architecture specifics ------------------------ */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portTRAP_YIELD 0 /* Trap 0 */
#define portIPL_MAX 7 /* Only NMI interrupt 7 allowed. */
/* ------------------------ FreeRTOS macros for port ---------------------- */
/*
* This function must be called when the current state of the active task
* should be stored. It must be called immediately after exception
* processing from the CPU, i.e. there exists a Coldfire exception frame at
* the current position in the stack. The function reserves space on
* the stack for the CPU registers and other task dependent values (e.g
* ulCriticalNesting) and updates the top of the stack in the TCB.
*/
#define portSAVE_CONTEXT() \
asm volatile ( /* reserve space for task state. */ \
"lea.l (-64, %sp), %sp\n\t" \
/* push data register %d0-%d7/%a0-%a6 on stack. */ \
"movem.l %d0-%d7/%a0-%a6, (%sp)\n\t" \
/* push ulCriticalNesting counter on stack. */ \
"lea.l (60, %sp), %a0\n\t" \
"move.l ulCriticalNesting, (%a0)\n\t" \
/* set the new top of the stack in the TCB. */ \
"move.l pxCurrentTCB, %a0\n\t" \
"move.l %sp, (%a0)");
/*.
* This function restores the current active and continues its execution.
* It loads the current TCB and restores the processor registers, the
* task dependent values (e.g ulCriticalNesting). Finally execution
* is continued by executing an rte instruction.
*/
#define portRESTORE_CONTEXT() \
asm volatile ( "move.l pxCurrentTCB, %sp\n\t" \
"move.l (%sp), %sp\n\t" \
/* stack pointer now points to the saved registers. */ \
"movem.l (%sp), %d0-%d7/%a0-%a6\n\t" \
/* restore ulCriticalNesting counter from stack. */ \
"lea.l (%sp, 60), %sp\n\t" \
"move.l (%sp)+, ulCriticalNesting\n\t" \
/* stack pointer now points to exception frame. */ \
"rte\n\t" );
#define portENTER_CRITICAL() \
vPortEnterCritical();
#define portEXIT_CRITICAL() \
vPortExitCritical();
#define portSET_IPL( xIPL ) \
asm_set_ipl( xIPL )
#define portDISABLE_INTERRUPTS() \
do { ( void )portSET_IPL( portIPL_MAX ); } while( 0 )
#define portENABLE_INTERRUPTS() \
do { ( void )portSET_IPL( 0 ); } while( 0 )
#define portYIELD() \
asm volatile ( " trap %0\n\t" : : "i"(portTRAP_YIELD) )
#define portNOP() \
asm volatile ( "nop\n\t" )
#define portENTER_SWITCHING_ISR() \
asm volatile ( "move.w #0x2700, %sr" ); \
/* Save the context of the interrupted task. */ \
portSAVE_CONTEXT( ); \
{
#define portEXIT_SWITCHING_ISR( SwitchRequired ) \
/* If a switch is required we call vTaskSwitchContext(). */ \
if( SwitchRequired ) \
{ \
vTaskSwitchContext( ); \
} \
} \
portRESTORE_CONTEXT( );
/* ------------------------ Function prototypes --------------------------- */
void vPortEnterCritical( void );
void vPortExitCritical( void );
int asm_set_ipl( unsigned long int uiNewIPL );
/* ------------------------ Compiler specifics ---------------------------- */
#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 */

View file

@ -0,0 +1,346 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Changes from V2.5.2
+ usCriticalNesting now has a volatile qualifier.
*/
/* Standard includes. */
#include <stdlib.h>
#include <signal.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the MSP430 port.
*----------------------------------------------------------*/
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
not the MCLK. */
#define portACLK_FREQUENCY_HZ ( ( portTickType ) 32768 )
#define portINITIAL_CRITICAL_NESTING ( ( unsigned portSHORT ) 10 )
#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x08 )
/* 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;
/* Most ports implement critical sections by placing the interrupt flags on
the stack before disabling interrupts. Exiting the critical section is then
simply a case of popping the flags from the stack. As mspgcc does not use
a frame pointer this cannot be done as modifying the stack will clobber all
the stack variables. Instead each task maintains a count of the critical
section nesting depth. Each time a critical section is entered the count is
incremented. Each time a critical section is left the count is decremented -
with interrupts only being re-enabled if the count is zero.
usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as this will cause problems during the startup
sequence. */
volatile unsigned portSHORT usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/
/*
* Macro to save a task context to the task stack. This simply pushes all the
* general purpose msp430 registers onto the stack, followed by the
* usCriticalNesting value used by the task. Finally the resultant stack
* pointer value is saved into the task control block so it can be retrieved
* the next time the task executes.
*/
#define portSAVE_CONTEXT() \
asm volatile ( "push r4 \n\t" \
"push r5 \n\t" \
"push r6 \n\t" \
"push r7 \n\t" \
"push r8 \n\t" \
"push r9 \n\t" \
"push r10 \n\t" \
"push r11 \n\t" \
"push r12 \n\t" \
"push r13 \n\t" \
"push r14 \n\t" \
"push r15 \n\t" \
"mov.w usCriticalNesting, r14 \n\t" \
"push r14 \n\t" \
"mov.w pxCurrentTCB, r12 \n\t" \
"mov.w r1, @r12 \n\t" \
);
/*
* Macro to restore a task context from the task stack. This is effectively
* the reverse of portSAVE_CONTEXT(). First the stack pointer value is
* loaded from the task control block. Next the value for usCriticalNesting
* used by the task is retrieved from the stack - followed by the value of all
* the general purpose msp430 registers.
*
* The bic instruction ensures there are no low power bits set in the status
* register that is about to be popped from the stack.
*/
#define portRESTORE_CONTEXT() \
asm volatile ( "mov.w pxCurrentTCB, r12 \n\t" \
"mov.w @r12, r1 \n\t" \
"pop r15 \n\t" \
"mov.w r15, usCriticalNesting \n\t" \
"pop r15 \n\t" \
"pop r14 \n\t" \
"pop r13 \n\t" \
"pop r12 \n\t" \
"pop r11 \n\t" \
"pop r10 \n\t" \
"pop r9 \n\t" \
"pop r8 \n\t" \
"pop r7 \n\t" \
"pop r6 \n\t" \
"pop r5 \n\t" \
"pop r4 \n\t" \
"bic #(0xf0),0(r1) \n\t" \
"reti \n\t" \
);
/*-----------------------------------------------------------*/
/*
* Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but
* could have alternatively used the watchdog timer or timer 1.
*/
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See the header file portable.h.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/*
Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging and can be included if required.
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x2222;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x3333;
pxTopOfStack--;
*/
/* The msp430 automatically pushes the PC then SR onto the stack before
executing an ISR. We want the stack to look just as if this has happened
so place a pointer to the start of the task on the stack first - followed
by the flags we want the task to use when it starts up. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;
*pxTopOfStack = portFLAGS_INT_ENABLED;
pxTopOfStack--;
/* Next the general purpose registers. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x4444;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x5555;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x6666;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x7777;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x8888;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x9999;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaa;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xbbbb;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xcccc;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xdddd;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xeeee;
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R15. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
/* The code generated by the mspgcc compiler does not maintain separate
stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
use the stack as per other ports. Instead a variable is used to keep
track of the critical section nesting. This variable has to be stored
as part of the task context and is initially set to zero. */
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack we have generated so this can
be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Setup the hardware to generate the tick. Interrupts are disabled when
this function is called. */
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run. */
portRESTORE_CONTEXT();
/* Should not get here as the tasks are now running! */
return pdTRUE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the MSP430 port will get stopped. If required simply
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
/*
* Manual context switch called by portYIELD or taskYIELD.
*
* The first thing we do is save the registers so we can use a naked attribute.
*/
void vPortYield( void ) __attribute__ ( ( naked ) );
void vPortYield( void )
{
/* We want the stack of the task being saved to look exactly as if the task
was saved during a pre-emptive RTOS tick ISR. Before calling an ISR the
msp430 places the status register onto the stack. As this is a function
call and not an ISR we have to do this manually. */
asm volatile ( "push r2" );
_DINT();
/* Save the context of the current task. */
portSAVE_CONTEXT();
/* Switch to the highest priority task that is ready to run. */
vTaskSwitchContext();
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
/*
* Hardware initialisation to generate the RTOS tick. This uses timer 0
* but could alternatively use the watchdog timer or timer 1.
*/
static void prvSetupTimerInterrupt( void )
{
/* Ensure the timer is stopped. */
TACTL = 0;
/* Run the timer of the ACLK. */
TACTL = TASSEL_1;
/* Clear everything to start with. */
TACTL |= TACLR;
/* Set the compare match value according to the tick rate we want. */
TACCR0 = portACLK_FREQUENCY_HZ / configTICK_RATE_HZ;
/* Enable the interrupts. */
TACCTL0 = CCIE;
/* Start up clean. */
TACTL |= TACLR;
/* Up mode. */
TACTL |= MC_1;
}
/*-----------------------------------------------------------*/
/*
* The interrupt service routine used depends on whether the pre-emptive
* scheduler is being used or not.
*/
#if configUSE_PREEMPTION == 1
/*
* Tick ISR for preemptive scheduler. We can use a naked attribute as
* the context is saved at the start of vPortYieldFromTick(). The tick
* count is incremented after the context is saved.
*/
interrupt (TIMERA0_VECTOR) prvTickISR( void ) __attribute__ ( ( naked ) );
interrupt (TIMERA0_VECTOR) prvTickISR( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Increment the tick count then switch to the highest priority task
that is ready to run. */
vTaskIncrementTick();
vTaskSwitchContext();
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
#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();
*/
interrupt (TIMERA0_VECTOR) prvTickISR( void );
interrupt (TIMERA0_VECTOR) prvTickISR( void )
{
vTaskIncrementTick();
}
#endif

View file

@ -0,0 +1,143 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 unsigned portSHORT
#define portBASE_TYPE portSHORT
#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
/*-----------------------------------------------------------*/
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() asm volatile ( "DINT" )
#define portENABLE_INTERRUPTS() asm volatile ( "EINT" )
/*-----------------------------------------------------------*/
/* Critical section control macros. */
#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned portSHORT ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile unsigned portSHORT usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
/* Now interrupts are disabled ulCriticalNesting can be accessed */ \
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
#define portEXIT_CRITICAL() \
{ \
extern volatile unsigned portSHORT usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
/* Decrement the nesting count as we are leaving a critical section. */ \
usCriticalNesting--; \
\
/* If the nesting level has reached zero then interrupts should be */ \
/* re-enabled. */ \
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
{ \
portENABLE_INTERRUPTS(); \
} \
} \
}
/*-----------------------------------------------------------*/
/* Task utilities. */
extern void vPortYield( void ) __attribute__ ( ( naked ) );
#define portYIELD() vPortYield()
#define portNOP() asm volatile ( "NOP" )
/*-----------------------------------------------------------*/
/* Hardwware specifics. */
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,352 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the MicroBlaze port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Standard includes. */
#include <string.h>
/* Hardware includes. */
#include <xintc.h>
#include <xintc_i.h>
#include <xtmrctr.h>
/* Tasks are started with interrupts enabled. */
#define portINITIAL_MSR_STATE ( ( portSTACK_TYPE ) 0x02 )
/* Tasks are started with a critical section nesting of 0 - however prior
to the scheduler being commenced we don't want the critical nesting level
to reach zero, so it is initialised to a high value. */
#define portINITIAL_NESTING_VALUE ( 0xff )
/* Our hardware setup only uses one counter. */
#define portCOUNTER_0 0
/* The stack used by the ISR is filled with a known value to assist in
debugging. */
#define portISR_STACK_FILL_VALUE 0x55555555
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
maintains it's own count, so this variable is saved as part of the task
context. */
volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE;
/* To limit the amount of stack required by each task, this port uses a
separate stack for interrupts. */
unsigned portLONG *pulISRStack;
/*-----------------------------------------------------------*/
/*
* Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but
* could have alternatively used the watchdog timer or timer 1.
*/
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been made.
*
* See the header file portable.h.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
extern void *_SDA2_BASE_, *_SDA_BASE_;
const unsigned portLONG ulR2 = ( unsigned portLONG ) &_SDA2_BASE_;
const unsigned portLONG ulR13 = ( unsigned portLONG ) &_SDA_BASE_;
/* Place a few bytes of known values on the bottom of the stack.
This is essential for the Microblaze port and these lines must
not be omitted. The parameter value will overwrite the
0x22222222 value during the function prologue. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x22222222;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x33333333;
pxTopOfStack--;
/* First stack an initial value for the critical section nesting. This
is initialised to zero as tasks are started with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0. */
/* Place an initial value for all the general purpose registers. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) ulR2; /* R2 - small data area. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;/* R5 contains the function call parameters. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0a; /* R10. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0b; /* R11. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0c; /* R12. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) ulR13; /* R13 - small data read write area. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* R14. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x0f; /* R15. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R16. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R17. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R18. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R19. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R20. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R21. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x16; /* R22. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x17; /* R23. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R24. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R25. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x1a; /* R26. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x1b; /* R27. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x1c; /* R28. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x1d; /* R29. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x1e; /* R30. */
pxTopOfStack--;
/* The MSR is stacked between R30 and R31. */
*pxTopOfStack = portINITIAL_MSR_STATE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x1f; /* R31. */
pxTopOfStack--;
/* Return a pointer to the top of the stack we have generated so this can
be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void ( __FreeRTOS_interrupt_Handler )( void );
extern void ( vStartFirstTask )( void );
/* Setup the FreeRTOS interrupt handler. Code copied from crt0.s. */
asm volatile ( "la r6, r0, __FreeRTOS_interrupt_handler \n\t" \
"sw r6, r1, r0 \n\t" \
"lhu r7, r1, r0 \n\t" \
"shi r7, r0, 0x12 \n\t" \
"shi r6, r0, 0x16 " );
/* Setup the hardware to generate the tick. Interrupts are disabled when
this function is called. */
prvSetupTimerInterrupt();
/* Allocate the stack to be used by the interrupt handler. */
pulISRStack = ( unsigned portLONG * ) pvPortMalloc( configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ) );
/* Restore the context of the first task that is going to run. */
if( pulISRStack != NULL )
{
/* Fill the ISR stack with a known value to facilitate debugging. */
memset( pulISRStack, portISR_STACK_FILL_VALUE, configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ) );
pulISRStack += ( configMINIMAL_STACK_SIZE - 1 );
/* Kick off the first task. */
vStartFirstTask();
}
/* Should not get here as the tasks are now running! */
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented. */
}
/*-----------------------------------------------------------*/
/*
* Manual context switch called by portYIELD or taskYIELD.
*/
void vPortYield( void )
{
extern void VPortYieldASM( void );
/* Perform the context switch in a critical section to assure it is
not interrupted by the tick ISR. It is not a problem to do this as
each task maintains it's own interrupt status. */
portENTER_CRITICAL();
/* Jump directly to the yield function to ensure there is no
compiler generated prologue code. */
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
"or r0, r0, r0 \n\t" );
portEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
/*
* Hardware initialisation to generate the RTOS tick.
*/
static void prvSetupTimerInterrupt( void )
{
XTmrCtr xTimer;
const unsigned portLONG ulCounterValue = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
unsigned portBASE_TYPE uxMask;
/* The OPB timer1 is used to generate the tick. Use the provided library
functions to enable the timer and set the tick frequency. */
XTmrCtr_mDisable( XPAR_OPB_TIMER_1_BASEADDR, XPAR_OPB_TIMER_1_DEVICE_ID );
XTmrCtr_Initialize( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
XTmrCtr_mSetLoadReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCounterValue );
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK );
/* Set the timer interrupt enable bit while maintaining the other bit
states. */
uxMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
uxMask |= XPAR_OPB_TIMER_1_INTERRUPT_MASK;
XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( uxMask ) );
XTmrCtr_Start( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK );
XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 1 );
}
/*-----------------------------------------------------------*/
/*
* The interrupt handler placed in the interrupt vector when the scheduler is
* started. The task context has already been saved when this is called.
* This handler determines the interrupt source and calls the relevant
* peripheral handler.
*/
void vTaskISRHandler( void )
{
static unsigned portLONG ulPending;
/* Which interrupts are pending? */
ulPending = XIntc_In32( ( XPAR_INTC_SINGLE_BASEADDR + XIN_IVR_OFFSET ) );
if( ulPending < XPAR_INTC_MAX_NUM_INTR_INPUTS )
{
static XIntc_VectorTableEntry *pxTablePtr;
static XIntc_Config *pxConfig;
static unsigned portLONG ulInterruptMask;
ulInterruptMask = ( unsigned portLONG ) 1 << ulPending;
/* Get the configuration data using the device ID */
pxConfig = &XIntc_ConfigTable[ ( unsigned portLONG ) XPAR_INTC_SINGLE_DEVICE_ID ];
pxTablePtr = &( pxConfig->HandlerTable[ ulPending ] );
if( pxConfig->AckBeforeService & ( ulInterruptMask ) )
{
XIntc_mAckIntr( pxConfig->BaseAddress, ulInterruptMask );
pxTablePtr->Handler( pxTablePtr->CallBackRef );
}
else
{
pxTablePtr->Handler( pxTablePtr->CallBackRef );
XIntc_mAckIntr( pxConfig->BaseAddress, ulInterruptMask );
}
}
}
/*-----------------------------------------------------------*/
/*
* Handler for the timer interrupt.
*/
void vTickISR( void *pvBaseAddress )
{
unsigned portLONG ulCSR;
/* Increment the RTOS tick - this might cause a task to unblock. */
vTaskIncrementTick();
/* Clear the timer interrupt */
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
/* If we are using the preemptive scheduler then we also need to determine
if this tick should cause a context switch. */
#if configUSE_PREEMPTION == 1
vTaskSwitchContext();
#endif
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,171 @@
.extern pxCurrentTCB
.extern vTaskISRHandler
.extern vTaskSwitchContext
.extern uxCriticalNesting
.extern pulISRStack
.global __FreeRTOS_interrupt_handler
.global VPortYieldASM
.global vStartFirstTask
.macro portSAVE_CONTEXT
/* Make room for the context on the stack. */
addik r1, r1, -132
/* Save r31 so it can then be used. */
swi r31, r1, 4
/* Copy the msr into r31 - this is stacked later. */
mfs r31, rmsr
/* Stack general registers. */
swi r30, r1, 12
swi r29, r1, 16
swi r28, r1, 20
swi r27, r1, 24
swi r26, r1, 28
swi r25, r1, 32
swi r24, r1, 36
swi r23, r1, 40
swi r22, r1, 44
swi r21, r1, 48
swi r20, r1, 52
swi r19, r1, 56
swi r18, r1, 60
swi r17, r1, 64
swi r16, r1, 68
swi r15, r1, 72
swi r13, r1, 80
swi r12, r1, 84
swi r11, r1, 88
swi r10, r1, 92
swi r9, r1, 96
swi r8, r1, 100
swi r7, r1, 104
swi r6, r1, 108
swi r5, r1, 112
swi r4, r1, 116
swi r3, r1, 120
swi r2, r1, 124
/* Stack the critical section nesting value. */
lwi r3, r0, uxCriticalNesting
swi r3, r1, 128
/* Save the top of stack value to the TCB. */
lwi r3, r0, pxCurrentTCB
sw r1, r0, r3
.endm
.macro portRESTORE_CONTEXT
/* Load the top of stack value from the TCB. */
lwi r3, r0, pxCurrentTCB
lw r1, r0, r3
/* Restore the general registers. */
lwi r31, r1, 4
lwi r30, r1, 12
lwi r29, r1, 16
lwi r28, r1, 20
lwi r27, r1, 24
lwi r26, r1, 28
lwi r25, r1, 32
lwi r24, r1, 36
lwi r23, r1, 40
lwi r22, r1, 44
lwi r21, r1, 48
lwi r20, r1, 52
lwi r19, r1, 56
lwi r18, r1, 60
lwi r17, r1, 64
lwi r16, r1, 68
lwi r15, r1, 72
lwi r14, r1, 76
lwi r13, r1, 80
lwi r12, r1, 84
lwi r11, r1, 88
lwi r10, r1, 92
lwi r9, r1, 96
lwi r8, r1, 100
lwi r7, r1, 104
lwi r6, r1, 108
lwi r5, r1, 112
lwi r4, r1, 116
lwi r2, r1, 124
/* Load the critical nesting value. */
lwi r3, r1, 128
swi r3, r0, uxCriticalNesting
/* Obtain the MSR value from the stack. */
lwi r3, r1, 8
/* Are interrupts enabled in the MSR? If so return using an return from
interrupt instruction to ensure interrupts are enabled only once the task
is running again. */
andi r3, r3, 2
beqid r3, 36
or r0, r0, r0
/* Reload the rmsr from the stack, clear the enable interrupt bit in the
value before saving back to rmsr register, then return enabling interrupts
as we return. */
lwi r3, r1, 8
andi r3, r3, ~2
mts rmsr, r3
lwi r3, r1, 120
addik r1, r1, 132
rtid r14, 0
or r0, r0, r0
/* Reload the rmsr from the stack, place it in the rmsr register, and
return without enabling interrupts. */
lwi r3, r1, 8
mts rmsr, r3
lwi r3, r1, 120
addik r1, r1, 132
rtsd r14, 0
or r0, r0, r0
.endm
.text
.align 2
__FreeRTOS_interrupt_handler:
portSAVE_CONTEXT
/* Entered via an interrupt so interrupts must be enabled in msr. */
ori r31, r31, 2
/* Stack msr. */
swi r31, r1, 8
/* Stack the return address. As we entered via an interrupt we do
not need to modify the return address prior to stacking. */
swi r14, r1, 76
/* Now switch to use the ISR stack. */
lwi r3, r0, pulISRStack
add r1, r3, r0
bralid r15, vTaskISRHandler
or r0, r0, r0
portRESTORE_CONTEXT
VPortYieldASM:
portSAVE_CONTEXT
/* Stack msr. */
swi r31, r1, 8
/* Modify the return address so we return to the instruction after the
exception. */
addi r14, r14, 8
swi r14, r1, 76
/* Now switch to use the ISR stack. */
lwi r3, r0, pulISRStack
add r1, r3, r0
bralid r15, vTaskSwitchContext
or r0, r0, r0
portRESTORE_CONTEXT
vStartFirstTask:
portRESTORE_CONTEXT

View file

@ -0,0 +1,138 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portLONG
#define portBASE_TYPE portLONG
#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
/*-----------------------------------------------------------*/
/* Interrupt control macros. */
void microblaze_disable_interrupts( void );
void microblaze_enable_interrupts( void );
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
/*-----------------------------------------------------------*/
/* Critical section macros. */
void vPortEnterCritical( void );
void vPortExitCritical( void );
#define portENTER_CRITICAL() { \
extern unsigned portBASE_TYPE uxCriticalNesting; \
microblaze_disable_interrupts(); \
uxCriticalNesting++; \
}
#define portEXIT_CRITICAL() { \
extern unsigned portBASE_TYPE uxCriticalNesting; \
/* Interrupts are disabled, so we can */ \
/* access the variable directly. */ \
uxCriticalNesting--; \
if( uxCriticalNesting == 0 ) \
{ \
/* The nesting has unwound and we \
can enable interrupts again. */ \
portENABLE_INTERRUPTS(); \
} \
}
/*-----------------------------------------------------------*/
/* Task utilities. */
void vPortYield( void );
#define portYIELD() vPortYield()
void vTaskSwitchContext();
#define portYIELD_FROM_ISR() vTaskSwitchContext()
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 4
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#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 )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,225 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the NIOS2 port.
*----------------------------------------------------------*/
/* Standard Includes. */
#include <string.h>
#include <errno.h>
/* Altera includes. */
#include "sys/alt_irq.h"
#include "altera_avalon_timer_regs.h"
#include "priv/alt_irq_table.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Interrupts are enabled. */
#define portINITIAL_ESTATUS ( portSTACK_TYPE ) 0x01
/*-----------------------------------------------------------*/
/*
* Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void );
/*
* Call back for the alarm function.
*/
void vPortSysTickHandler( void * context, alt_u32 id );
/*-----------------------------------------------------------*/
void prvReadGp( unsigned portLONG *ulValue )
{
asm( "stw gp, (r4) " );
};
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxFramePointer = pxTopOfStack - 1;
portSTACK_TYPE xGlobalPointer;
prvReadGp( &xGlobalPointer );
/* End of stack marker. */
*pxTopOfStack = 0xdeadbeef;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxFramePointer;
pxTopOfStack--;
*pxTopOfStack = xGlobalPointer;
/* Space for R23 to R16. */
pxTopOfStack -= 9;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;
*pxTopOfStack = portINITIAL_ESTATUS;
/* Space for R15 to R5. */
pxTopOfStack -= 12;
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
/* Space for R3 to R1, muldiv and RA. */
pxTopOfStack -= 5;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
asm volatile ( " movia r2, restore_sp_from_pxCurrentTCB \n"
" jmp r2 " );
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the NIOS2 port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency.
*/
void prvSetupTimerInterrupt( void )
{
/* Try to register the interrupt handler. */
if ( -EINVAL == alt_irq_register( SYS_CLK_IRQ, 0x0, vPortSysTickHandler ) )
{
/* Failed to install the Interrupt Handler. */
asm( "break" );
}
else
{
/* Configure SysTick to interrupt at the requested rate. */
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK );
IOWR_ALTERA_AVALON_TIMER_PERIODL( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) & 0xFFFF );
IOWR_ALTERA_AVALON_TIMER_PERIODH( SYS_CLK_BASE, ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) >> 16 );
IOWR_ALTERA_AVALON_TIMER_CONTROL( SYS_CLK_BASE, ALTERA_AVALON_TIMER_CONTROL_CONT_MSK | ALTERA_AVALON_TIMER_CONTROL_START_MSK | ALTERA_AVALON_TIMER_CONTROL_ITO_MSK );
}
/* Clear any already pending interrupts generated by the Timer. */
IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );
}
/*-----------------------------------------------------------*/
void vPortSysTickHandler( void * context, alt_u32 id )
{
/* Increment the Kernel Tick. */
vTaskIncrementTick();
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
vTaskSwitchContext();
#endif
/* Clear the interrupt. */
IOWR_ALTERA_AVALON_TIMER_STATUS( SYS_CLK_BASE, ~ALTERA_AVALON_TIMER_STATUS_TO_MSK );
}
/*-----------------------------------------------------------*/
/** This function is a re-implementation of the Altera provided function.
* The function is re-implemented to prevent it from enabling an interrupt
* when it is registered. Interrupts should only be enabled after the FreeRTOS.org
* kernel has its scheduler started so that contexts are saved and switched
* correctly.
*/
int alt_irq_register( alt_u32 id, void* context, void (*handler)(void*, alt_u32) )
{
int rc = -EINVAL;
alt_irq_context status;
if (id < ALT_NIRQ)
{
/*
* interrupts are disabled while the handler tables are updated to ensure
* that an interrupt doesn't occur while the tables are in an inconsistent
* state.
*/
status = alt_irq_disable_all ();
alt_irq[id].handler = handler;
alt_irq[id].context = context;
rc = (handler) ? alt_irq_enable (id): alt_irq_disable (id);
/* alt_irq_enable_all(status); This line is removed to prevent the interrupt from being immediately enabled. */
}
return rc;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,169 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
.extern vTaskSwitchContext
.set noat
# Exported to start the first task.
.globl restore_sp_from_pxCurrentTCB
# Entry point for exceptions.
.section .exceptions.entry, "xa"
# Save the entire context of a task.
save_context:
addi ea, ea, -4 # Point to the next instruction.
addi sp, sp, -116 # Create space on the stack.
stw ra, 0(sp)
# Leave a gap for muldiv 0
stw at, 8(sp)
stw r2, 12(sp)
stw r3, 16(sp)
stw r4, 20(sp)
stw r5, 24(sp)
stw r6, 28(sp)
stw r7, 32(sp)
stw r8, 36(sp)
stw r9, 40(sp)
stw r10, 44(sp)
stw r11, 48(sp)
stw r12, 52(sp)
stw r13, 56(sp)
stw r14, 60(sp)
stw r15, 64(sp)
rdctl r5, estatus # Save the eStatus
stw r5, 68(sp)
stw ea, 72(sp) # Save the PC
stw r16, 76(sp) # Save the remaining registers
stw r17, 80(sp)
stw r18, 84(sp)
stw r19, 88(sp)
stw r20, 92(sp)
stw r21, 96(sp)
stw r22, 100(sp)
stw r23, 104(sp)
stw gp, 108(sp)
stw fp, 112(sp)
save_sp_to_pxCurrentTCB:
movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
ldw et, (et) # Load the value of the pxCurrentTCB pointer
stw sp, (et) # Store the stack pointer into the top of the TCB
.section .exceptions.irqtest, "xa"
hw_irq_test:
/*
* Test to see if the exception was a software exception or caused
* by an external interrupt, and vector accordingly.
*/
rdctl r4, ipending # Load the Pending Interrupts indication
rdctl r5, estatus # Load the eStatus (enabled interrupts).
andi r2, r5, 1 # Are interrupts enabled globally.
beq r2, zero, soft_exceptions # Interrupts are not enabled.
beq r4, zero, soft_exceptions # There are no interrupts triggered.
.section .exceptions.irqhandler, "xa"
hw_irq_handler:
call alt_irq_handler # Call the alt_irq_handler to deliver to the registered interrupt handler.
.section .exceptions.irqreturn, "xa"
restore_sp_from_pxCurrentTCB:
movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
ldw et, (et) # Load the value of the pxCurrentTCB pointer
ldw sp, (et) # Load the stack pointer with the top value of the TCB
restore_context:
ldw ra, 0(sp) # Restore the registers.
# Leave a gap for muldiv 0.
ldw at, 8(sp)
ldw r2, 12(sp)
ldw r3, 16(sp)
ldw r4, 20(sp)
ldw r5, 24(sp)
ldw r6, 28(sp)
ldw r7, 32(sp)
ldw r8, 36(sp)
ldw r9, 40(sp)
ldw r10, 44(sp)
ldw r11, 48(sp)
ldw r12, 52(sp)
ldw r13, 56(sp)
ldw r14, 60(sp)
ldw r15, 64(sp)
ldw et, 68(sp) # Load the eStatus
wrctl estatus, et # Write the eStatus
ldw ea, 72(sp) # Load the Program Counter
ldw r16, 76(sp)
ldw r17, 80(sp)
ldw r18, 84(sp)
ldw r19, 88(sp)
ldw r20, 92(sp)
ldw r21, 96(sp)
ldw r22, 100(sp)
ldw r23, 104(sp)
ldw gp, 108(sp)
ldw fp, 112(sp)
addi sp, sp, 116 # Release stack space
eret # Return to address ea, loading eStatus into Status.
.section .exceptions.soft, "xa"
soft_exceptions:
ldw et, 0(ea) # Load the instruction where the interrupt occured.
movhi at, %hi(0x003B683A) # Load the registers with the trap instruction code
ori at, at, %lo(0x003B683A)
cmpne et, et, at # Compare the trap instruction code to the last excuted instruction
beq et, r0, call_scheduler # its a trap so switchcontext
break # This is an un-implemented instruction or muldiv problem.
br restore_context # its something else
call_scheduler:
addi ea, ea, 4 # A trap was called, increment the program counter so it is not called again.
stw ea, 72(sp) # Save the new program counter to the context.
call vTaskSwitchContext # Pick the next context.
br restore_sp_from_pxCurrentTCB # Switch in the task context and restore.

View file

@ -0,0 +1,121 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C" {
#endif
#include "sys/alt_irq.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 short
#define portSTACK_TYPE unsigned portLONG
#define portBASE_TYPE long
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portNOP() asm volatile ( "NOP" )
#define portCRITICAL_NESTING_IN_TCB 1
/*-----------------------------------------------------------*/
extern void vTaskSwitchContext( void );
#define portYIELD() asm volatile ( "trap" );
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
/* Include the port_asm.S file where the Context saving/restoring is defined. */
__asm__( "\n\t.globl save_context" );
/*-----------------------------------------------------------*/
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portDISABLE_INTERRUPTS() alt_irq_disable_all()
#define portENABLE_INTERRUPTS() alt_irq_enable_all( 0x01 );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/*-----------------------------------------------------------*/
/* 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 */

View file

@ -0,0 +1,65 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* When switching out a task, if the task tag contains a buffer address then
save the flop context into the buffer. */
#define traceTASK_SWITCHED_OUT() \
if( pxCurrentTCB->pxTaskTag != NULL ) \
{ \
extern void vPortSaveFPURegisters( void * ); \
vPortSaveFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
}
/* When switching in a task, if the task tag contains a buffer address then
load the flop context from the buffer. */
#define traceTASK_SWITCHED_IN() \
if( pxCurrentTCB->pxTaskTag != NULL ) \
{ \
extern void vPortRestoreFPURegisters( void * ); \
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
}

View file

@ -0,0 +1,280 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the PPC405 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Library includes. */
#include "xtime_l.h"
#include "xintc.h"
#include "xintc_i.h"
/*-----------------------------------------------------------*/
/* Definitions to set the initial MSR of each task. */
#define portCRITICAL_INTERRUPT_ENABLE ( 1UL << 17UL )
#define portEXTERNAL_INTERRUPT_ENABLE ( 1UL << 15UL )
#define portMACHINE_CHECK_ENABLE ( 1UL << 12UL )
#if configUSE_FPU == 1
#define portAPU_PRESENT ( 1UL << 25UL )
#define portFCM_FPU_PRESENT ( 1UL << 13UL )
#else
#define portAPU_PRESENT ( 0UL )
#define portFCM_FPU_PRESENT ( 0UL )
#endif
#define portINITIAL_MSR ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE | portAPU_PRESENT | portFCM_FPU_PRESENT )
extern const unsigned _SDA_BASE_;
extern const unsigned _SDA2_BASE_;
/*-----------------------------------------------------------*/
/*
* Setup the system timer to generate the tick interrupt.
*/
static void prvSetupTimerInterrupt( void );
/*
* The handler for the tick interrupt - defined in portasm.s.
*/
extern void vPortTickISR( void );
/*
* The handler for the yield function - defined in portasm.s.
*/
extern void vPortYield( void );
/*
* Function to start the scheduler running by starting the highest
* priority task that has thus far been created.
*/
extern void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/
/* Structure used to hold the state of the interrupt controller. */
static XIntc xInterruptController;
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if the task had been
* interrupted.
*
* See the header file portable.h.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Place a known value at the bottom of the stack for debugging. */
*pxTopOfStack = 0xDEADBEEF;
pxTopOfStack--;
/* EABI stack frame. */
pxTopOfStack -= 20; /* Previous backchain and LR, R31 to R4 inclusive. */
/* Parameters in R13. */
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA_BASE_; /* address of the first small data area */
pxTopOfStack -= 10;
/* Parameters in R3. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
/* Parameters in R2. */
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA2_BASE_; /* address of the second small data area */
pxTopOfStack--;
/* R1 is the stack pointer so is omitted. */
*pxTopOfStack = 0x10000001UL;; /* R0. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* CR. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* XER. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* CTR. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler; /* LR. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_MSR;/* SRR1. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;/* Next LR. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL;/* Backchain. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
prvSetupTimerInterrupt();
XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );
vPortStartFirstTask();
/* Should not get here as the tasks are now running! */
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented. */
for( ;; );
}
/*-----------------------------------------------------------*/
/*
* Hardware initialisation to generate the RTOS tick.
*/
static void prvSetupTimerInterrupt( void )
{
const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
XTime_PITClearInterrupt();
XTime_FITClearInterrupt();
XTime_WDTClearInterrupt();
XTime_WDTDisableInterrupt();
XTime_FITDisableInterrupt();
XExc_RegisterHandler( XEXC_ID_PIT_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );
XTime_PITEnableAutoReload();
XTime_PITSetInterval( ulInterval );
XTime_PITEnableInterrupt();
}
/*-----------------------------------------------------------*/
void vPortISRHandler( void *pvNullDoNotUse )
{
unsigned portLONG ulInterruptStatus, ulInterruptMask = 1UL;
portBASE_TYPE xInterruptNumber;
XIntc_Config *pxInterruptController;
XIntc_VectorTableEntry *pxTable;
/* Just to remove compiler warning. */
( void ) pvNullDoNotUse;
/* Get the configuration by using the device ID - in this case it is
assumed that only one interrupt controller is being used. */
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
/* Which interrupts are pending? */
ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );
for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )
{
if( ulInterruptStatus & 0x01UL )
{
/* Clear the pending interrupt. */
XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );
/* Call the registered handler. */
pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );
pxTable->Handler( pxTable->CallBackRef );
}
/* Check the next interrupt. */
ulInterruptMask <<= 0x01UL;
ulInterruptStatus >>= 0x01UL;
/* Have we serviced all interrupts? */
if( ulInterruptStatus == 0UL )
{
break;
}
}
}
/*-----------------------------------------------------------*/
void vPortSetupInterruptController( void )
{
extern void vPortISRWrapper( void );
/* Perform all library calls necessary to initialise the exception table
and interrupt controller. This assumes only one interrupt controller is in
use. */
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
XExc_Init();
/* The library functions save the context - we then jump to a wrapper to
save the stack into the TCB. The wrapper then calls the handler defined
above. */
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
{
portBASE_TYPE xReturn = pdFAIL;
/* This function is defined here so the scope of xInterruptController can
remain within this file. */
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
{
XIntc_Enable( &xInterruptController, ucInterruptID );
xReturn = pdPASS;
}
return xReturn;
}

View file

@ -0,0 +1,402 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include "FreeRTOSConfig.h"
.extern pxCurrentTCB
.extern vTaskSwitchContext
.extern vTaskIncrementTick
.extern vPortISRHandler
.global vPortStartFirstTask
.global vPortYield
.global vPortTickISR
.global vPortISRWrapper
.global vPortSaveFPURegisters
.global vPortRestoreFPURegisters
.set BChainField, 0
.set NextLRField, BChainField + 4
.set MSRField, NextLRField + 4
.set PCField, MSRField + 4
.set LRField, PCField + 4
.set CTRField, LRField + 4
.set XERField, CTRField + 4
.set CRField, XERField + 4
.set USPRG0Field, CRField + 4
.set r0Field, USPRG0Field + 4
.set r2Field, r0Field + 4
.set r3r31Field, r2Field + 4
.set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4
.macro portSAVE_STACK_POINTER_AND_LR
/* Get the address of the TCB. */
xor R0, R0, R0
addis R2, R0, pxCurrentTCB@ha
lwz R2, pxCurrentTCB@l( R2 )
/* Store the stack pointer into the TCB */
stw SP, 0( R2 )
/* Save the link register */
stwu R1, -24( R1 )
mflr R0
stw R31, 20( R1 )
stw R0, 28( R1 )
mr R31, r1
.endm
.macro portRESTORE_STACK_POINTER_AND_LR
/* Restore the link register */
lwz R11, 0( R1 )
lwz R0, 4( R11 )
mtlr R0
lwz R31, -4( R11 )
mr R1, R11
/* Get the address of the TCB. */
xor R0, R0, R0
addis SP, R0, pxCurrentTCB@ha
lwz SP, pxCurrentTCB@l( R1 )
/* Get the task stack pointer from the TCB. */
lwz SP, 0( SP )
.endm
vPortStartFirstTask:
/* Get the address of the TCB. */
xor R0, R0, R0
addis SP, R0, pxCurrentTCB@ha
lwz SP, pxCurrentTCB@l( SP )
/* Get the task stack pointer from the TCB. */
lwz SP, 0( SP )
/* Restore MSR register to SRR1. */
lwz R0, MSRField(R1)
mtsrr1 R0
/* Restore current PC location to SRR0. */
lwz R0, PCField(R1)
mtsrr0 R0
/* Save USPRG0 register */
lwz R0, USPRG0Field(R1)
mtspr 0x100,R0
/* Restore Condition register */
lwz R0, CRField(R1)
mtcr R0
/* Restore Fixed Point Exception register */
lwz R0, XERField(R1)
mtxer R0
/* Restore Counter register */
lwz R0, CTRField(R1)
mtctr R0
/* Restore Link register */
lwz R0, LRField(R1)
mtlr R0
/* Restore remaining GPR registers. */
lmw R3,r3r31Field(R1)
/* Restore r0 and r2. */
lwz R0, r0Field(R1)
lwz R2, r2Field(R1)
/* Remove frame from stack */
addi R1,R1,IFrameSize
/* Return into the first task */
rfi
vPortYield:
portSAVE_STACK_POINTER_AND_LR
bl vTaskSwitchContext
portRESTORE_STACK_POINTER_AND_LR
blr
vPortTickISR:
portSAVE_STACK_POINTER_AND_LR
bl vTaskIncrementTick
#if configUSE_PREEMPTION == 1
bl vTaskSwitchContext
#endif
/* Clear the interrupt */
lis R0, 2048
mttsr R0
portRESTORE_STACK_POINTER_AND_LR
blr
vPortISRWrapper:
portSAVE_STACK_POINTER_AND_LR
bl vPortISRHandler
portRESTORE_STACK_POINTER_AND_LR
blr
#if configUSE_FPU == 1
vPortSaveFPURegisters:
/* Enable APU and mark FPU as present. */
mfmsr r0
xor r30, r30, r30
oris r30, r30, 512
ori r30, r30, 8192
or r0, r0, r30
mtmsr r0
#ifdef USE_DP_FPU
/* Buffer address is in r3. Save each flop register into an offset from
this buffer address. */
stfd f0, 0(r3)
stfd f1, 8(r3)
stfd f2, 16(r3)
stfd f3, 24(r3)
stfd f4, 32(r3)
stfd f5, 40(r3)
stfd f6, 48(r3)
stfd f7, 56(r3)
stfd f8, 64(r3)
stfd f9, 72(r3)
stfd f10, 80(r3)
stfd f11, 88(r3)
stfd f12, 96(r3)
stfd f13, 104(r3)
stfd f14, 112(r3)
stfd f15, 120(r3)
stfd f16, 128(r3)
stfd f17, 136(r3)
stfd f18, 144(r3)
stfd f19, 152(r3)
stfd f20, 160(r3)
stfd f21, 168(r3)
stfd f22, 176(r3)
stfd f23, 184(r3)
stfd f24, 192(r3)
stfd f25, 200(r3)
stfd f26, 208(r3)
stfd f27, 216(r3)
stfd f28, 224(r3)
stfd f29, 232(r3)
stfd f30, 240(r3)
stfd f31, 248(r3)
/* Also save the FPSCR. */
mffs f31
stfs f31, 256(r3)
#else
/* Buffer address is in r3. Save each flop register into an offset from
this buffer address. */
stfs f0, 0(r3)
stfs f1, 4(r3)
stfs f2, 8(r3)
stfs f3, 12(r3)
stfs f4, 16(r3)
stfs f5, 20(r3)
stfs f6, 24(r3)
stfs f7, 28(r3)
stfs f8, 32(r3)
stfs f9, 36(r3)
stfs f10, 40(r3)
stfs f11, 44(r3)
stfs f12, 48(r3)
stfs f13, 52(r3)
stfs f14, 56(r3)
stfs f15, 60(r3)
stfs f16, 64(r3)
stfs f17, 68(r3)
stfs f18, 72(r3)
stfs f19, 76(r3)
stfs f20, 80(r3)
stfs f21, 84(r3)
stfs f22, 88(r3)
stfs f23, 92(r3)
stfs f24, 96(r3)
stfs f25, 100(r3)
stfs f26, 104(r3)
stfs f27, 108(r3)
stfs f28, 112(r3)
stfs f29, 116(r3)
stfs f30, 120(r3)
stfs f31, 124(r3)
/* Also save the FPSCR. */
mffs f31
stfs f31, 128(r3)
#endif
blr
#endif /* configUSE_FPU. */
#if configUSE_FPU == 1
vPortRestoreFPURegisters:
/* Enable APU and mark FPU as present. */
mfmsr r0
xor r30, r30, r30
oris r30, r30, 512
ori r30, r30, 8192
or r0, r0, r30
mtmsr r0
#ifdef USE_DP_FPU
/* Buffer address is in r3. Restore each flop register from an offset
into this buffer.
First the FPSCR. */
lfs f31, 256(r3)
mtfsf f31, 7
lfd f0, 0(r3)
lfd f1, 8(r3)
lfd f2, 16(r3)
lfd f3, 24(r3)
lfd f4, 32(r3)
lfd f5, 40(r3)
lfd f6, 48(r3)
lfd f7, 56(r3)
lfd f8, 64(r3)
lfd f9, 72(r3)
lfd f10, 80(r3)
lfd f11, 88(r3)
lfd f12, 96(r3)
lfd f13, 104(r3)
lfd f14, 112(r3)
lfd f15, 120(r3)
lfd f16, 128(r3)
lfd f17, 136(r3)
lfd f18, 144(r3)
lfd f19, 152(r3)
lfd f20, 160(r3)
lfd f21, 168(r3)
lfd f22, 176(r3)
lfd f23, 184(r3)
lfd f24, 192(r3)
lfd f25, 200(r3)
lfd f26, 208(r3)
lfd f27, 216(r3)
lfd f28, 224(r3)
lfd f29, 232(r3)
lfd f30, 240(r3)
lfd f31, 248(r3)
#else
/* Buffer address is in r3. Restore each flop register from an offset
into this buffer.
First the FPSCR. */
lfs f31, 128(r3)
mtfsf f31, 7
lfs f0, 0(r3)
lfs f1, 4(r3)
lfs f2, 8(r3)
lfs f3, 12(r3)
lfs f4, 16(r3)
lfs f5, 20(r3)
lfs f6, 24(r3)
lfs f7, 28(r3)
lfs f8, 32(r3)
lfs f9, 36(r3)
lfs f10, 40(r3)
lfs f11, 44(r3)
lfs f12, 48(r3)
lfs f13, 52(r3)
lfs f14, 56(r3)
lfs f15, 60(r3)
lfs f16, 64(r3)
lfs f17, 68(r3)
lfs f18, 72(r3)
lfs f19, 76(r3)
lfs f20, 80(r3)
lfs f21, 84(r3)
lfs f22, 88(r3)
lfs f23, 92(r3)
lfs f24, 96(r3)
lfs f25, 100(r3)
lfs f26, 104(r3)
lfs f27, 108(r3)
lfs f28, 112(r3)
lfs f29, 116(r3)
lfs f30, 120(r3)
lfs f31, 124(r3)
#endif
blr
#endif /* configUSE_FPU. */

View file

@ -0,0 +1,134 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#include "xexception_l.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 portLONG
#define portBASE_TYPE portLONG
#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
/*-----------------------------------------------------------*/
/* This port uses the critical nesting count from the TCB rather than
maintaining a separate value and then saving this value in the task stack. */
#define portCRITICAL_NESTING_IN_TCB 1
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
/*-----------------------------------------------------------*/
/* Critical section macros. */
void vTaskEnterCritical( void );
void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
void vPortYield( void );
#define portYIELD() asm volatile ( "SC \n\t NOP" )
#define portYIELD_FROM_ISR() vTaskSwitchContext()
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portNOP() asm volatile ( "NOP" )
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
/*-----------------------------------------------------------*/
/* 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 )
/* Port specific interrupt handling functions. */
void vPortSetupInterruptController( void );
portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,65 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* When switching out a task, if the task tag contains a buffer address then
save the flop context into the buffer. */
#define traceTASK_SWITCHED_OUT() \
if( pxCurrentTCB->pxTaskTag != NULL ) \
{ \
extern void vPortSaveFPURegisters( void * ); \
vPortSaveFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
}
/* When switching in a task, if the task tag contains a buffer address then
load the flop context from the buffer. */
#define traceTASK_SWITCHED_IN() \
if( pxCurrentTCB->pxTaskTag != NULL ) \
{ \
extern void vPortRestoreFPURegisters( void * ); \
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
}

View file

@ -0,0 +1,280 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the PPC440 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Library includes. */
#include "xtime_l.h"
#include "xintc.h"
#include "xintc_i.h"
/*-----------------------------------------------------------*/
/* Definitions to set the initial MSR of each task. */
#define portCRITICAL_INTERRUPT_ENABLE ( 1UL << 17UL )
#define portEXTERNAL_INTERRUPT_ENABLE ( 1UL << 15UL )
#define portMACHINE_CHECK_ENABLE ( 1UL << 12UL )
#if configUSE_FPU == 1
#define portAPU_PRESENT ( 1UL << 25UL )
#define portFCM_FPU_PRESENT ( 1UL << 13UL )
#else
#define portAPU_PRESENT ( 0UL )
#define portFCM_FPU_PRESENT ( 0UL )
#endif
#define portINITIAL_MSR ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE | portAPU_PRESENT | portFCM_FPU_PRESENT )
extern const unsigned _SDA_BASE_;
extern const unsigned _SDA2_BASE_;
/*-----------------------------------------------------------*/
/*
* Setup the system timer to generate the tick interrupt.
*/
static void prvSetupTimerInterrupt( void );
/*
* The handler for the tick interrupt - defined in portasm.s.
*/
extern void vPortTickISR( void );
/*
* The handler for the yield function - defined in portasm.s.
*/
extern void vPortYield( void );
/*
* Function to start the scheduler running by starting the highest
* priority task that has thus far been created.
*/
extern void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/
/* Structure used to hold the state of the interrupt controller. */
static XIntc xInterruptController;
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if the task had been
* interrupted.
*
* See the header file portable.h.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Place a known value at the bottom of the stack for debugging. */
*pxTopOfStack = 0xDEADBEEF;
pxTopOfStack--;
/* EABI stack frame. */
pxTopOfStack -= 20; /* Previous backchain and LR, R31 to R4 inclusive. */
/* Parameters in R13. */
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA_BASE_; /* address of the first small data area */
pxTopOfStack -= 10;
/* Parameters in R3. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
/* Parameters in R2. */
*pxTopOfStack = ( portSTACK_TYPE ) &_SDA2_BASE_; /* address of the second small data area */
pxTopOfStack--;
/* R1 is the stack pointer so is omitted. */
*pxTopOfStack = 0x10000001UL;; /* R0. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* CR. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* XER. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL; /* CTR. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler; /* LR. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* SRR0. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_MSR;/* SRR1. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) vPortEndScheduler;/* Next LR. */
pxTopOfStack--;
*pxTopOfStack = 0x00000000UL;/* Backchain. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
prvSetupTimerInterrupt();
XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 );
vPortStartFirstTask();
/* Should not get here as the tasks are now running! */
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented. */
for( ;; );
}
/*-----------------------------------------------------------*/
/*
* Hardware initialisation to generate the RTOS tick.
*/
static void prvSetupTimerInterrupt( void )
{
const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
XTime_DECClearInterrupt();
XTime_FITClearInterrupt();
XTime_WDTClearInterrupt();
XTime_WDTDisableInterrupt();
XTime_FITDisableInterrupt();
XExc_RegisterHandler( XEXC_ID_DEC_INT, ( XExceptionHandler ) vPortTickISR, ( void * ) 0 );
XTime_DECEnableAutoReload();
XTime_DECSetInterval( ulInterval );
XTime_DECEnableInterrupt();
}
/*-----------------------------------------------------------*/
void vPortISRHandler( void *pvNullDoNotUse )
{
unsigned portLONG ulInterruptStatus, ulInterruptMask = 1UL;
portBASE_TYPE xInterruptNumber;
XIntc_Config *pxInterruptController;
XIntc_VectorTableEntry *pxTable;
/* Just to remove compiler warning. */
( void ) pvNullDoNotUse;
/* Get the configuration by using the device ID - in this case it is
assumed that only one interrupt controller is being used. */
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
/* Which interrupts are pending? */
ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress );
for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ )
{
if( ulInterruptStatus & 0x01UL )
{
/* Clear the pending interrupt. */
XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask );
/* Call the registered handler. */
pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] );
pxTable->Handler( pxTable->CallBackRef );
}
/* Check the next interrupt. */
ulInterruptMask <<= 0x01UL;
ulInterruptStatus >>= 0x01UL;
/* Have we serviced all interrupts? */
if( ulInterruptStatus == 0UL )
{
break;
}
}
}
/*-----------------------------------------------------------*/
void vPortSetupInterruptController( void )
{
extern void vPortISRWrapper( void );
/* Perform all library calls necessary to initialise the exception table
and interrupt controller. This assumes only one interrupt controller is in
use. */
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
XExc_Init();
/* The library functions save the context - we then jump to a wrapper to
save the stack into the TCB. The wrapper then calls the handler defined
above. */
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
{
portBASE_TYPE xReturn = pdFAIL;
/* This function is defined here so the scope of xInterruptController can
remain within this file. */
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
{
XIntc_Enable( &xInterruptController, ucInterruptID );
xReturn = pdPASS;
}
return xReturn;
}

View file

@ -0,0 +1,402 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include "FreeRTOSConfig.h"
.extern pxCurrentTCB
.extern vTaskSwitchContext
.extern vTaskIncrementTick
.extern vPortISRHandler
.global vPortStartFirstTask
.global vPortYield
.global vPortTickISR
.global vPortISRWrapper
.global vPortSaveFPURegisters
.global vPortRestoreFPURegisters
.set BChainField, 0
.set NextLRField, BChainField + 4
.set MSRField, NextLRField + 4
.set PCField, MSRField + 4
.set LRField, PCField + 4
.set CTRField, LRField + 4
.set XERField, CTRField + 4
.set CRField, XERField + 4
.set USPRG0Field, CRField + 4
.set r0Field, USPRG0Field + 4
.set r2Field, r0Field + 4
.set r3r31Field, r2Field + 4
.set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4
.macro portSAVE_STACK_POINTER_AND_LR
/* Get the address of the TCB. */
xor R0, R0, R0
addis R2, R0, pxCurrentTCB@ha
lwz R2, pxCurrentTCB@l( R2 )
/* Store the stack pointer into the TCB */
stw SP, 0( R2 )
/* Save the link register */
stwu R1, -24( R1 )
mflr R0
stw R31, 20( R1 )
stw R0, 28( R1 )
mr R31, r1
.endm
.macro portRESTORE_STACK_POINTER_AND_LR
/* Restore the link register */
lwz R11, 0( R1 )
lwz R0, 4( R11 )
mtlr R0
lwz R31, -4( R11 )
mr R1, R11
/* Get the address of the TCB. */
xor R0, R0, R0
addis SP, R0, pxCurrentTCB@ha
lwz SP, pxCurrentTCB@l( R1 )
/* Get the task stack pointer from the TCB. */
lwz SP, 0( SP )
.endm
vPortStartFirstTask:
/* Get the address of the TCB. */
xor R0, R0, R0
addis SP, R0, pxCurrentTCB@ha
lwz SP, pxCurrentTCB@l( SP )
/* Get the task stack pointer from the TCB. */
lwz SP, 0( SP )
/* Restore MSR register to SRR1. */
lwz R0, MSRField(R1)
mtsrr1 R0
/* Restore current PC location to SRR0. */
lwz R0, PCField(R1)
mtsrr0 R0
/* Save USPRG0 register */
lwz R0, USPRG0Field(R1)
mtspr 0x100,R0
/* Restore Condition register */
lwz R0, CRField(R1)
mtcr R0
/* Restore Fixed Point Exception register */
lwz R0, XERField(R1)
mtxer R0
/* Restore Counter register */
lwz R0, CTRField(R1)
mtctr R0
/* Restore Link register */
lwz R0, LRField(R1)
mtlr R0
/* Restore remaining GPR registers. */
lmw R3,r3r31Field(R1)
/* Restore r0 and r2. */
lwz R0, r0Field(R1)
lwz R2, r2Field(R1)
/* Remove frame from stack */
addi R1,R1,IFrameSize
/* Return into the first task */
rfi
vPortYield:
portSAVE_STACK_POINTER_AND_LR
bl vTaskSwitchContext
portRESTORE_STACK_POINTER_AND_LR
blr
vPortTickISR:
portSAVE_STACK_POINTER_AND_LR
bl vTaskIncrementTick
#if configUSE_PREEMPTION == 1
bl vTaskSwitchContext
#endif
/* Clear the interrupt */
lis R0, 2048
mttsr R0
portRESTORE_STACK_POINTER_AND_LR
blr
vPortISRWrapper:
portSAVE_STACK_POINTER_AND_LR
bl vPortISRHandler
portRESTORE_STACK_POINTER_AND_LR
blr
#if configUSE_FPU == 1
vPortSaveFPURegisters:
/* Enable APU and mark FPU as present. */
mfmsr r0
xor r30, r30, r30
oris r30, r30, 512
ori r30, r30, 8192
or r0, r0, r30
mtmsr r0
#ifdef USE_DP_FPU
/* Buffer address is in r3. Save each flop register into an offset from
this buffer address. */
stfd f0, 0(r3)
stfd f1, 8(r3)
stfd f2, 16(r3)
stfd f3, 24(r3)
stfd f4, 32(r3)
stfd f5, 40(r3)
stfd f6, 48(r3)
stfd f7, 56(r3)
stfd f8, 64(r3)
stfd f9, 72(r3)
stfd f10, 80(r3)
stfd f11, 88(r3)
stfd f12, 96(r3)
stfd f13, 104(r3)
stfd f14, 112(r3)
stfd f15, 120(r3)
stfd f16, 128(r3)
stfd f17, 136(r3)
stfd f18, 144(r3)
stfd f19, 152(r3)
stfd f20, 160(r3)
stfd f21, 168(r3)
stfd f22, 176(r3)
stfd f23, 184(r3)
stfd f24, 192(r3)
stfd f25, 200(r3)
stfd f26, 208(r3)
stfd f27, 216(r3)
stfd f28, 224(r3)
stfd f29, 232(r3)
stfd f30, 240(r3)
stfd f31, 248(r3)
/* Also save the FPSCR. */
mffs f31
stfs f31, 256(r3)
#else
/* Buffer address is in r3. Save each flop register into an offset from
this buffer address. */
stfs f0, 0(r3)
stfs f1, 4(r3)
stfs f2, 8(r3)
stfs f3, 12(r3)
stfs f4, 16(r3)
stfs f5, 20(r3)
stfs f6, 24(r3)
stfs f7, 28(r3)
stfs f8, 32(r3)
stfs f9, 36(r3)
stfs f10, 40(r3)
stfs f11, 44(r3)
stfs f12, 48(r3)
stfs f13, 52(r3)
stfs f14, 56(r3)
stfs f15, 60(r3)
stfs f16, 64(r3)
stfs f17, 68(r3)
stfs f18, 72(r3)
stfs f19, 76(r3)
stfs f20, 80(r3)
stfs f21, 84(r3)
stfs f22, 88(r3)
stfs f23, 92(r3)
stfs f24, 96(r3)
stfs f25, 100(r3)
stfs f26, 104(r3)
stfs f27, 108(r3)
stfs f28, 112(r3)
stfs f29, 116(r3)
stfs f30, 120(r3)
stfs f31, 124(r3)
/* Also save the FPSCR. */
mffs f31
stfs f31, 128(r3)
#endif
blr
#endif /* configUSE_FPU. */
#if configUSE_FPU == 1
vPortRestoreFPURegisters:
/* Enable APU and mark FPU as present. */
mfmsr r0
xor r30, r30, r30
oris r30, r30, 512
ori r30, r30, 8192
or r0, r0, r30
mtmsr r0
#ifdef USE_DP_FPU
/* Buffer address is in r3. Restore each flop register from an offset
into this buffer.
First the FPSCR. */
lfs f31, 256(r3)
mtfsf f31, 7
lfd f0, 0(r3)
lfd f1, 8(r3)
lfd f2, 16(r3)
lfd f3, 24(r3)
lfd f4, 32(r3)
lfd f5, 40(r3)
lfd f6, 48(r3)
lfd f7, 56(r3)
lfd f8, 64(r3)
lfd f9, 72(r3)
lfd f10, 80(r3)
lfd f11, 88(r3)
lfd f12, 96(r3)
lfd f13, 104(r3)
lfd f14, 112(r3)
lfd f15, 120(r3)
lfd f16, 128(r3)
lfd f17, 136(r3)
lfd f18, 144(r3)
lfd f19, 152(r3)
lfd f20, 160(r3)
lfd f21, 168(r3)
lfd f22, 176(r3)
lfd f23, 184(r3)
lfd f24, 192(r3)
lfd f25, 200(r3)
lfd f26, 208(r3)
lfd f27, 216(r3)
lfd f28, 224(r3)
lfd f29, 232(r3)
lfd f30, 240(r3)
lfd f31, 248(r3)
#else
/* Buffer address is in r3. Restore each flop register from an offset
into this buffer.
First the FPSCR. */
lfs f31, 128(r3)
mtfsf f31, 7
lfs f0, 0(r3)
lfs f1, 4(r3)
lfs f2, 8(r3)
lfs f3, 12(r3)
lfs f4, 16(r3)
lfs f5, 20(r3)
lfs f6, 24(r3)
lfs f7, 28(r3)
lfs f8, 32(r3)
lfs f9, 36(r3)
lfs f10, 40(r3)
lfs f11, 44(r3)
lfs f12, 48(r3)
lfs f13, 52(r3)
lfs f14, 56(r3)
lfs f15, 60(r3)
lfs f16, 64(r3)
lfs f17, 68(r3)
lfs f18, 72(r3)
lfs f19, 76(r3)
lfs f20, 80(r3)
lfs f21, 84(r3)
lfs f22, 88(r3)
lfs f23, 92(r3)
lfs f24, 96(r3)
lfs f25, 100(r3)
lfs f26, 104(r3)
lfs f27, 108(r3)
lfs f28, 112(r3)
lfs f29, 116(r3)
lfs f30, 120(r3)
lfs f31, 124(r3)
#endif
blr
#endif /* configUSE_FPU. */

View file

@ -0,0 +1,134 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#include "xexception_l.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 portLONG
#define portBASE_TYPE portLONG
#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
/*-----------------------------------------------------------*/
/* This port uses the critical nesting count from the TCB rather than
maintaining a separate value and then saving this value in the task stack. */
#define portCRITICAL_NESTING_IN_TCB 1
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
/*-----------------------------------------------------------*/
/* Critical section macros. */
void vTaskEnterCritical( void );
void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/*-----------------------------------------------------------*/
/* Task utilities. */
void vPortYield( void );
#define portYIELD() asm volatile ( "SC \n\t NOP" )
#define portYIELD_FROM_ISR() vTaskSwitchContext()
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portNOP() asm volatile ( "NOP" )
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
/*-----------------------------------------------------------*/
/* 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 )
/* Port specific interrupt handling functions. */
void vPortSetupInterruptController( void );
portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,213 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ST STR75x ARM7
* port.
*----------------------------------------------------------*/
/* Library includes. */
#include "75x_tb.h"
#include "75x_eic.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to setup the initial stack. */
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
/* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
/* Prescale used on the timer clock when calculating the tick period. */
#define portPRESCALE 20
/*-----------------------------------------------------------*/
/* Setup the TB to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in
R0. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
/* The status register is set for system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
#ifdef THUMB_INTERWORK
{
/* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
#endif
pxTopOfStack--;
/* Interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the
tasks context. */
*pxTopOfStack = portNO_CRITICAL_NESTING;
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
extern void vPortISRStartFirstTask( void );
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
vPortISRStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the ARM port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
EIC_IRQInitTypeDef EIC_IRQInitStructure;
TB_InitTypeDef TB_InitStructure;
/* Setup the EIC for the TB. */
EIC_IRQInitStructure.EIC_IRQChannelCmd = ENABLE;
EIC_IRQInitStructure.EIC_IRQChannel = TB_IRQChannel;
EIC_IRQInitStructure.EIC_IRQChannelPriority = 1;
EIC_IRQInit(&EIC_IRQInitStructure);
/* Setup the TB for the generation of the tick interrupt. */
TB_InitStructure.TB_Mode = TB_Mode_Timing;
TB_InitStructure.TB_CounterMode = TB_CounterMode_Down;
TB_InitStructure.TB_Prescaler = portPRESCALE - 1;
TB_InitStructure.TB_AutoReload = ( ( configCPU_CLOCK_HZ / ( portPRESCALE + 1 ) ) / configTICK_RATE_HZ ) + 1;
TB_Init(&TB_InitStructure);
/* Enable TB Update interrupt */
TB_ITConfig(TB_IT_Update, ENABLE);
/* Clear TB Update interrupt pending bit */
TB_ClearITPendingBit(TB_IT_Update);
/* Enable TB */
TB_Cmd(ENABLE);
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,203 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*-----------------------------------------------------------
* Components that can be compiled to either ARM or THUMB mode are
* contained in port.c The ISR routines, which can only be compiled
* to ARM mode, are contained in this file.
*----------------------------------------------------------*/
/*
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
/*-----------------------------------------------------------*/
/*
* The scheduler can only be started from ARM mode, hence the inclusion of this
* function here.
*/
void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/
void vPortISRStartFirstTask( void )
{
/* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */
asm volatile ( \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"LDR LR, [R0] \n\t" \
\
/* The critical nesting depth is the first item on the stack. */ \
/* Load it into the ulCriticalNesting variable. */ \
"LDR R0, =ulCriticalNesting \n\t" \
"LDMFD LR!, {R1} \n\t" \
"STR R1, [R0] \n\t" \
\
/* Get the SPSR from the stack. */ \
"LDMFD LR!, {R0} \n\t" \
"MSR SPSR, R0 \n\t" \
\
/* Restore all system mode registers for the task. */ \
"LDMFD LR, {R0-R14}^ \n\t" \
"NOP \n\t" \
\
/* Restore the return address. */ \
"LDR LR, [LR, #+60] \n\t" \
\
/* And return - correcting the offset in the LR to obtain the */ \
/* correct address. */ \
"SUBS PC, LR, #4 \n\t" \
);
}
/*-----------------------------------------------------------*/
void vPortTickISR( void )
{
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
vTaskIncrementTick();
#if configUSE_PREEMPTION == 1
vTaskSwitchContext();
#endif
/* Ready for the next interrupt. */
TB_ClearITPendingBit( TB_IT_Update );
}
/*-----------------------------------------------------------*/
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
* the utilities are defined as macros in portmacro.h - as per other ports.
*/
#ifdef THUMB_INTERWORK
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
void vPortDisableInterruptsFromThumb( void )
{
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
void vPortEnableInterruptsFromThumb( void )
{
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
"BX R14" ); /* Return back to thumb. */
}
#endif /* THUMB_INTERWORK */
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as we are leaving a critical section. */
ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be
re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable interrupts as per portEXIT_CRITICAL(). */
asm volatile (
"STMDB SP!, {R0} \n\t" /* Push R0. */
"MRS R0, CPSR \n\t" /* Get CPSR. */
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
"MSR CPSR, R0 \n\t" /* Write back modified value. */
"LDMIA SP!, {R0}" ); /* Pop R0. */
}
}
}

View file

@ -0,0 +1,157 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portLONG
#define portBASE_TYPE portLONG
#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 portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portYIELD() asm volatile ( "SWI 0" )
#define portNOP() asm volatile ( "NOP" )
/*-----------------------------------------------------------*/
/* Critical section handling. */
/*
* The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* defined then the utilities are defined as macros here - as per other ports.
*/
#ifdef THUMB_INTERWORK
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
#else
#define portDISABLE_INTERRUPTS() \
asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#define portENABLE_INTERRUPTS() \
asm volatile ( \
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
"LDMIA SP!, {R0} " ) /* Pop R0. */
#endif /* THUMB_INTERWORK */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/*-----------------------------------------------------------*/
/* Task utilities. */
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
{ \
extern void vTaskSwitchContext( void ); \
\
if( xSwitchRequired ) \
{ \
vTaskSwitchContext(); \
} \
}
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,112 @@
;/*
; FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
;
; 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 exception 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.
; Alternative commercial license and support terms are also available upon
; request. See the licensing section of http://www.FreeRTOS.org for full
; license details.
;
; 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 along
; with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
; Temple Place, Suite 330, Boston, MA 02111-1307 USA.
;
;
; ***************************************************************************
; * *
; * Looking for a quick start? Then check out the FreeRTOS eBook! *
; * See http://www.FreeRTOS.org/Documentation for details *
; * *
; ***************************************************************************
;
; 1 tab == 4 spaces!
;
; Please ensure to read the configuration and relevant port sections of the
; online documentation.
;
; http://www.FreeRTOS.org - Documentation, latest information, license and
; contact details.
;
; http://www.SafeRTOS.com - A version that is certified for use in safety
; critical systems.
;
; http://www.OpenRTOS.com - Commercial support, development, porting,
; licensing and training services.
;*/
#include "FreeRTOSConfig.h"
; Variables used by scheduler
;------------------------------------------------------------------------------
EXTERN pxCurrentTCB
EXTERN usCriticalNesting
;------------------------------------------------------------------------------
; portSAVE_CONTEXT MACRO
; Saves the context of the general purpose registers, CS and ES (only in far
; memory mode) registers the usCriticalNesting Value and the Stack Pointer
; of the active Task onto the task stack
;------------------------------------------------------------------------------
portSAVE_CONTEXT MACRO
PUSH AX ; Save AX Register to stack.
PUSH HL
#if configMEMORY_MODE == 1
MOV A, CS ; Save CS register.
XCH A, X
MOV A, ES ; Save ES register.
PUSH AX
#else
MOV A, CS ; Save CS register.
PUSH AX
#endif
PUSH DE ; Save the remaining general purpose registers.
PUSH BC
MOVW AX, usCriticalNesting ; Save the usCriticalNesting value.
PUSH AX
MOVW AX, pxCurrentTCB ; Save the Stack pointer.
MOVW HL, AX
MOVW AX, SP
MOVW [HL], AX
ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; portRESTORE_CONTEXT MACRO
; Restores the task Stack Pointer then use this to restore usCriticalNesting,
; general purpose registers and the CS and ES (only in far memory mode)
; of the selected task from the task stack
;------------------------------------------------------------------------------
portRESTORE_CONTEXT MACRO
MOVW AX, pxCurrentTCB ; Restore the Stack pointer.
MOVW HL, AX
MOVW AX, [HL]
MOVW SP, AX
POP AX ; Restore usCriticalNesting value.
MOVW usCriticalNesting, AX
POP BC ; Restore the necessary general purpose registers.
POP DE
#if configMEMORY_MODE == 1
POP AX ; Restore the ES register.
MOV ES, A
XCH A, X ; Restore the CS register.
MOV CS, A
#else
POP AX
MOV CS, A ; Restore CS register.
#endif
POP HL ; Restore general purpose register HL.
POP AX ; Restore AX.
ENDM
;------------------------------------------------------------------------------

View file

@ -0,0 +1,245 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* The critical nesting value is initialised to a non zero value to ensure
interrupts don't accidentally become enabled before the scheduler is started. */
#define portINITIAL_CRITICAL_NESTING (( unsigned portSHORT ) 10)
/* Initial PSW value allocated to a newly created task.
* 1100011000000000
* ||||||||-------------- Fill byte
* |||||||--------------- Carry Flag cleared
* |||||----------------- In-service priority Flags set to low level
* ||||------------------ Register bank Select 0 Flag cleared
* |||------------------- Auxiliary Carry Flag cleared
* ||-------------------- Register bank Select 1 Flag cleared
* |--------------------- Zero Flag set
* ---------------------- Global Interrupt Flag set (enabled)
*/
#define portPSW (0xc6UL)
/* 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;
/* Most ports implement critical sections by placing the interrupt flags on
the stack before disabling interrupts. Exiting the critical section is then
simply a case of popping the flags from the stack. As 78K0 IAR does not use
a frame pointer this cannot be done as modifying the stack will clobber all
the stack variables. Instead each task maintains a count of the critical
section nesting depth. Each time a critical section is entered the count is
incremented. Each time a critical section is left the count is decremented -
with interrupts only being re-enabled if the count is zero.
usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as this will cause problems during the startup
sequence. */
volatile unsigned portSHORT usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/
/*
* Sets up the periodic ISR used for the RTOS tick.
*/
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See the header file portable.h.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned long *pulLocal;
#if configMEMORY_MODE == 1
{
/* Parameters are passed in on the stack, and written using a 32bit value
hence a space is left for the second two bytes. */
pxTopOfStack--;
/* Write in the parameter value. */
pulLocal = ( unsigned long * ) pxTopOfStack;
*pulLocal = ( unsigned long ) pvParameters;
pxTopOfStack--;
/* These values are just spacers. The return address of the function
would normally be written here. */
*pxTopOfStack = ( portSTACK_TYPE ) 0xcdcd;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xcdcd;
pxTopOfStack--;
/* The start address / PSW value is also written in as a 32bit value,
so leave a space for the second two bytes. */
pxTopOfStack--;
/* Task function start address combined with the PSW. */
pulLocal = ( unsigned long * ) pxTopOfStack;
*pulLocal = ( ( ( unsigned long ) pxCode ) | ( portPSW << 24UL ) );
pxTopOfStack--;
/* An initial value for the AX register. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
pxTopOfStack--;
}
#else
{
/* Task function address is written to the stack first. As it is
written as a 32bit value a space is left on the stack for the second
two bytes. */
pxTopOfStack--;
/* Task function start address combined with the PSW. */
pulLocal = ( unsigned long * ) pxTopOfStack;
*pulLocal = ( ( ( unsigned long ) pxCode ) | ( portPSW << 24UL ) );
pxTopOfStack--;
/* The parameter is passed in AX. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
}
#endif
/* An initial value for the HL register. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x2222;
pxTopOfStack--;
/* CS and ES registers. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x0F00;
pxTopOfStack--;
/* Finally the remaining general purpose registers DE and BC */
*pxTopOfStack = ( portSTACK_TYPE ) 0xDEDE;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xBCBC;
pxTopOfStack--;
/* Finally the critical section nesting count is set to zero when the task
first starts. */
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack we have generated so this can
be stored in the task control block for the task. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Setup the hardware to generate the tick. Interrupts are disabled when
this function is called. */
prvSetupTimerInterrupt();
/* Restore the context of the first task that is going to run. */
vPortStart();
/* Should not get here as the tasks are now running! */
return pdTRUE;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the 78K0R port will get stopped. If required simply
disable the tick interrupt here. */
}
/*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void )
{
/* Setup channel 5 of the TAU to generate the tick interrupt. */
/* First the Timer Array Unit has to be enabled. */
TAU0EN = 1;
/* To configure the Timer Array Unit all Channels have to first be stopped. */
TT0 = 0xff;
/* Interrupt of Timer Array Unit Channel 5 is disabled to set the interrupt
priority. */
TMMK05 = 1;
/* Clear Timer Array Unit Channel 5 interrupt flag. */
TMIF05 = 0;
/* Set Timer Array Unit Channel 5 interrupt priority */
TMPR005 = 0;
TMPR105 = 0;
/* Set Timer Array Unit Channel 5 Mode as interval timer. */
TMR05 = 0x0000;
/* Set the compare match value according to the tick rate we want. */
TDR05 = ( portTickType ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
/* Set Timer Array Unit Channel 5 output mode */
TOM0 &= ~0x0020;
/* Set Timer Array Unit Channel 5 output level */
TOL0 &= ~0x0020;
/* Set Timer Array Unit Channel 5 output enable */
TOE0 &= ~0x0020;
/* Interrupt of Timer Array Unit Channel 5 enabled */
TMMK05 = 0;
/* Start Timer Array Unit Channel 5.*/
TS0 |= 0x0020;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,157 @@
;/*
; FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
;
; 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 exception 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.
; Alternative commercial license and support terms are also available upon
; request. See the licensing section of http://www.FreeRTOS.org for full
; license details.
;
; 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 along
; with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
; Temple Place, Suite 330, Boston, MA 02111-1307 USA.
;
;
; ***************************************************************************
; * *
; * Looking for a quick start? Then check out the FreeRTOS eBook! *
; * See http://www.FreeRTOS.org/Documentation for details *
; * *
; ***************************************************************************
;
; 1 tab == 4 spaces!
;
; Please ensure to read the configuration and relevant port sections of the
; online documentation.
;
; http://www.FreeRTOS.org - Documentation, latest information, license and
; contact details.
;
; http://www.SafeRTOS.com - A version that is certified for use in safety
; critical systems.
;
; http://www.OpenRTOS.com - Commercial support, development, porting,
; licensing and training services.
;*/
#include "ISR_Support.h"
;------------------------------------------------------------------------------
#if __CORE__ != __78K0R__
#error "This file is only for 78K0R Devices"
#endif
#define CS 0xFFFFC
#define ES 0xFFFFD
; Functions implemented in this file
;------------------------------------------------------------------------------
PUBLIC vPortYield
PUBLIC vPortStart
; Functions used by scheduler
;------------------------------------------------------------------------------
EXTERN vTaskSwitchContext
EXTERN vTaskIncrementTick
; Tick ISR Prototype
;------------------------------------------------------------------------------
; EXTERN ?CL78K0R_V2_L00
PUBWEAK `??MD_INTTM05??INTVEC 68`
PUBLIC MD_INTTM05
MD_INTTM05 SYMBOL "MD_INTTM05"
`??MD_INTTM05??INTVEC 68` SYMBOL "??INTVEC 68", MD_INTTM05
;------------------------------------------------------------------------------
; Yield to another task. Implemented as a software interrupt. The return
; address and PSW will have been saved to the stack automatically before
; this code runs.
;
; Input: NONE
;
; Call: CALL vPortYield
;
; Output: NONE
;
;------------------------------------------------------------------------------
RSEG CODE:CODE
vPortYield:
portSAVE_CONTEXT ; Save the context of the current task.
call vTaskSwitchContext ; Call the scheduler to select the next task.
portRESTORE_CONTEXT ; Restore the context of the next task to run.
retb
;------------------------------------------------------------------------------
; Restore the context of the first task that is going to run.
;
; Input: NONE
;
; Call: CALL vPortStart
;
; Output: NONE
;
;------------------------------------------------------------------------------
RSEG CODE:CODE
vPortStart:
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
reti ; An interrupt stack frame is used so the task
; is started using a RETI instruction.
;------------------------------------------------------------------------------
; Perform the necessary steps of the Tick Count Increment and Task Switch
; depending on the chosen kernel configuration
;
; Input: NONE
;
; Call: ISR
;
; Output: NONE
;
;------------------------------------------------------------------------------
MD_INTTM05:
portSAVE_CONTEXT ; Save the context of the current task.
call vTaskIncrementTick ; Call the timer tick function.
#if configUSE_PREEMPTION == 1
call vTaskSwitchContext ; Call the scheduler to select the next task.
#endif
portRESTORE_CONTEXT ; Restore the context of the next task to run.
reti
; REQUIRE ?CL78K0R_V2_L00
COMMON INTVEC:CODE:ROOT(1) ; Set ISR location to the Interrupt vector table.
ORG 68
`??MD_INTTM05??INTVEC 68`:
DW MD_INTTM05
COMMON INTVEC:CODE:ROOT(1) ; Set ISR location to the Interrupt vector table.
ORG 126
`??vPortYield??INTVEC 126`:
DW vPortYield
; Set value for the usCriticalNesting.
RSEG NEAR_ID:CONST:SORT:NOROOT(1)
`?<Initializer for usCriticalNesting>`:
DW 10
;#endif
END

View file

@ -0,0 +1,161 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 int portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff
#else
typedef unsigned long portTickType;
#define portMAX_DELAY ( portTickType ) 0xffffffff
#endif
/*-----------------------------------------------------------*/
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() __asm ( "DI" )
#define portENABLE_INTERRUPTS() __asm ( "EI" )
/*-----------------------------------------------------------*/
/* Critical section control macros. */
#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned portSHORT ) 0 )
#define portENTER_CRITICAL() \
{ \
extern volatile unsigned portSHORT usCriticalNesting; \
\
portDISABLE_INTERRUPTS(); \
\
/* Now interrupts are disabled ulCriticalNesting can be accessed */ \
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
/* times portENTER_CRITICAL() has been called. */ \
usCriticalNesting++; \
}
#define portEXIT_CRITICAL() \
{ \
extern volatile unsigned portSHORT usCriticalNesting; \
\
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
{ \
/* Decrement the nesting count as we are leaving a critical section. */ \
usCriticalNesting--; \
\
/* If the nesting level has reached zero then interrupts should be */ \
/* re-enabled. */ \
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
{ \
portENABLE_INTERRUPTS(); \
} \
} \
}
/*-----------------------------------------------------------*/
/* Task utilities. */
extern void vPortStart( void );
#define portYIELD() __asm( "BRK" )
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken ) vTaskSwitchContext()
#define portNOP() __asm( "NOP" )
/*-----------------------------------------------------------*/
/* Hardwware specifics. */
#define portBYTE_ALIGNMENT 2
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
static __interrupt void P0_isr (void);
/* --------------------------------------------------------------------------*/
/* Option-bytes and security ID */
/* --------------------------------------------------------------------------*/
#define OPT_BYTES_SIZE 4
#define SECU_ID_SIZE 10
#define WATCHDOG_DISABLED 0x00
#define LVI_ENABLED 0xFE
#define LVI_DISABLED 0xFF
#define RESERVED_FF 0xFF
#define OCD_DISABLED 0x04
#define OCD_ENABLED 0x81
#define OCD_ENABLED_ERASE 0x80
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,209 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Change from V4.2.1:
+ Introduced usage of configKERNEL_INTERRUPT_PRIORITY macro to set the
interrupt priority used by the kernel.
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ARM CM3 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Constants required to manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned portLONG *) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned portLONG *) 0xe000e014 )
#define portNVIC_INT_CTRL ( ( volatile unsigned portLONG *) 0xe000ed04 )
#define portNVIC_SYSPRI2 ( ( volatile unsigned portLONG *) 0xe000ed20 )
#define portNVIC_SYSTICK_CLK 0x00000004
#define portNVIC_SYSTICK_INT 0x00000002
#define portNVIC_SYSTICK_ENABLE 0x00000001
#define portNVIC_PENDSVSET 0x10000000
#define portNVIC_PENDSV_PRI ( ( ( unsigned portLONG ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned portLONG ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
/* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 )
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
defined. The value 255 should also ensure backward compatibility.
FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 0
#endif
/* Each task maintains its own interrupt status in the critical nesting
variable. */
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
/*
* Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void );
/*
* Exception handlers.
*/
void xPortSysTickHandler( void );
/*
* Start first task is a separate function so it can be tested in isolation.
*/
extern void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Simulate the stack frame as it would be created by a context switch
interrupt. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
pxTopOfStack--;
*pxTopOfStack = 0; /* LR */
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Make PendSV and SysTick the lowest priority interrupts. */
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0;
/* Start the first task. */
vPortStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the CM3 port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
void vPortYieldFromISR( void )
{
/* Set a PendSV to request a context switch. */
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
void xPortSysTickHandler( void )
{
unsigned portLONG ulDummy;
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
#endif
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}
/*-----------------------------------------------------------*/
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency.
*/
void prvSetupTimerInterrupt( void )
{
/* Configure SysTick to interrupt at the requested rate. */
*(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,157 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
Change from V4.2.1:
+ Introduced usage of configKERNEL_INTERRUPT_PRIORITY macro to set the
interrupt priority used by the kernel.
*/
#include <FreeRTOSConfig.h>
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
defined. The value zero should also ensure backward compatibility.
FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 0
#endif
RSEG CODE:CODE(2)
thumb
EXTERN vPortYieldFromISR
EXTERN pxCurrentTCB
EXTERN vTaskSwitchContext
PUBLIC vSetMSP
PUBLIC xPortPendSVHandler
PUBLIC vPortSetInterruptMask
PUBLIC vPortClearInterruptMask
PUBLIC vPortSVCHandler
PUBLIC vPortStartFirstTask
/*-----------------------------------------------------------*/
vSetMSP
msr msp, r0
bx lr
/*-----------------------------------------------------------*/
xPortPendSVHandler:
mrs r0, psp
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
ldr r2, [r3]
stmdb r0!, {r4-r11} /* Save the remaining registers. */
str r0, [r2] /* Save the new top of stack into the first member of the TCB. */
stmdb sp!, {r3, r14}
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0
bl vTaskSwitchContext
mov r0, #0
msr basepri, r0
ldmia sp!, {r3, r14}
ldr r1, [r3]
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
ldmia r0!, {r4-r11} /* Pop the registers. */
msr psp, r0
bx r14
/*-----------------------------------------------------------*/
vPortSetInterruptMask:
push { r0 }
mov R0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr BASEPRI, R0
pop { R0 }
bx r14
/*-----------------------------------------------------------*/
vPortClearInterruptMask:
PUSH { r0 }
MOV R0, #0
MSR BASEPRI, R0
POP { R0 }
bx r14
/*-----------------------------------------------------------*/
vPortSVCHandler;
ldr r3, =pxCurrentTCB
ldr r1, [r3]
ldr r0, [r1]
ldmia r0!, {r4-r11}
msr psp, r0
mov r0, #0
msr basepri, r0
orr r14, r14, #13
bx r14
/*-----------------------------------------------------------*/
vPortStartFirstTask
/* Use the NVIC offset register to locate the stack. */
ldr r0, =0xE000ED08
ldr r0, [r0]
ldr r0, [r0]
/* Set the msp back to the start of the stack. */
msr msp, r0
/* Call SVC to start the first task. */
svc 0
END

View file

@ -0,0 +1,127 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 portLONG
#define portBASE_TYPE long
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
extern void vPortYieldFromISR( void );
#define portYIELD() vPortYieldFromISR()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
/*-----------------------------------------------------------*/
/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern void vPortSetInterruptMask( void );
extern void vPortClearInterruptMask( void );
#define portDISABLE_INTERRUPTS() vPortSetInterruptMask()
#define portENABLE_INTERRUPTS() vPortClearInterruptMask()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;vPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask();(void)x
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portNOP()
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,360 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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 ( ( portSTACK_TYPE ) 0x80 )
/* Hardware constants for timer 1. */
#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned portCHAR ) 0x08 )
#define portPRESCALE_64 ( ( unsigned portCHAR ) 0x03 )
#define portCLOCK_PRESCALER ( ( unsigned portLONG ) 64 )
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 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 ( ( unsigned portBASE_TYPE ) 0 )
unsigned portBASE_TYPE 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.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned portSHORT usAddress;
portSTACK_TYPE *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 = ( unsigned portSHORT ) pxCode;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
usAddress >>= 8;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 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 = ( portSTACK_TYPE ) 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 = ( unsigned portSHORT ) pxTopOfHardwareStack;
/* SPL */
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
/* SPH */
usAddress >>= 8;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
/* Now the remaining registers. */
*pxTopOfStack = ( portSTACK_TYPE ) 0x01; /* R1 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */
pxTopOfStack--;
/* Place the parameter on the stack in the expected location. */
usAddress = ( unsigned portSHORT ) pvParameters;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
usAddress >>= 8;
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x24; /* R24 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x25; /* R25 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 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 = ( portSTACK_TYPE ) 0x30; /* R30 Z */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */
pxTopOfStack--;
*pxTopOfStack = portNO_CRITICAL_NESTING; /* Critical nesting is zero when the task starts. */
/*lint +e950 +e611 +e923 */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE 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 )
{
unsigned portLONG ulCompareMatch;
unsigned portCHAR 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 -= ( unsigned portLONG ) 1;
/* Setup compare match value for compare match A. Interrupts are disabled
before this is called so we need not worry here. */
ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );
ulCompareMatch >>= 8;
ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 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 )
{
vTaskIncrementTick();
}
#endif
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == portNO_CRITICAL_NESTING )
{
portENABLE_INTERRUPTS();
}
}

View file

@ -0,0 +1,127 @@
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/*
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 unsigned portCHAR
#define portBASE_TYPE portCHAR
#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
/*-----------------------------------------------------------*/
/* 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_RATE_MS ( ( portTickType ) 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 */

View file

@ -0,0 +1,262 @@
;/*
; FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
;
; 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 exception 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.
; Alternative commercial license and support terms are also available upon
; request. See the licensing section of http://www.FreeRTOS.org for full
; license details.
;
; 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 along
; with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
; Temple Place, Suite 330, Boston, MA 02111-1307 USA.
;
;
; ***************************************************************************
; * *
; * Looking for a quick start? Then check out the FreeRTOS eBook! *
; * See http://www.FreeRTOS.org/Documentation for details *
; * *
; ***************************************************************************
;
; 1 tab == 4 spaces!
;
; Please ensure to read the configuration and relevant port sections of the
; online documentation.
;
; http://www.FreeRTOS.org - Documentation, latest information, license and
; contact details.
;
; http://www.SafeRTOS.com - A version that is certified for use in safety
; critical systems.
;
; http://www.OpenRTOS.com - Commercial support, development, porting,
; licensing and training services.
;*/
#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 vTaskIncrementTick
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 vTaskIncrementTick ; Call the timer tick function.
call vTaskSwitchContext ; Call the scheduler.
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

View file

@ -0,0 +1,310 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Exception and interrupt vectors.
*
* This file maps all events supported by an AVR32UC.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32UC devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <avr32/io.h>
#include "intc.h"
//! @{
//! \verbatim
// Start of Exception Vector Table.
// EVBA must be aligned with a power of two strictly greater than the EVBA-
// relative offset of the last vector.
COMMON EVTAB:CODE:ROOT(9)
// Force EVBA initialization.
EXTERN ??init_EVBA
REQUIRE ??init_EVBA
// Export symbol.
PUBLIC ??EVBA
PUBLIC _evba
??EVBA:
_evba:
ORG 0x000
// Unrecoverable Exception.
_handle_Unrecoverable_Exception:
rjmp $
ORG 0x004
// TLB Multiple Hit: UNUSED IN AVR32UC.
_handle_TLB_Multiple_Hit:
rjmp $
ORG 0x008
// Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
rjmp $
ORG 0x00C
// Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
rjmp $
ORG 0x010
// NMI.
_handle_NMI:
rjmp $
ORG 0x014
// Instruction Address.
_handle_Instruction_Address:
rjmp $
ORG 0x018
// ITLB Protection.
_handle_ITLB_Protection:
rjmp $
ORG 0x01C
// Breakpoint.
_handle_Breakpoint:
rjmp $
ORG 0x020
// Illegal Opcode.
_handle_Illegal_Opcode:
rjmp $
ORG 0x024
// Unimplemented Instruction.
_handle_Unimplemented_Instruction:
rjmp $
ORG 0x028
// Privilege Violation.
_handle_Privilege_Violation:
rjmp $
ORG 0x02C
// Floating-Point: UNUSED IN AVR32UC.
_handle_Floating_Point:
rjmp $
ORG 0x030
// Coprocessor Absent: UNUSED IN AVR32UC.
_handle_Coprocessor_Absent:
rjmp $
ORG 0x034
// Data Address (Read).
_handle_Data_Address_Read:
rjmp $
ORG 0x038
// Data Address (Write).
_handle_Data_Address_Write:
rjmp $
ORG 0x03C
// DTLB Protection (Read).
_handle_DTLB_Protection_Read:
rjmp $
ORG 0x040
// DTLB Protection (Write).
_handle_DTLB_Protection_Write:
rjmp $
ORG 0x044
// DTLB Modified: UNUSED IN AVR32UC.
_handle_DTLB_Modified:
rjmp $
ORG 0x050
// ITLB Miss: UNUSED IN AVR32UC.
_handle_ITLB_Miss:
rjmp $
ORG 0x060
// DTLB Miss (Read): UNUSED IN AVR32UC.
_handle_DTLB_Miss_Read:
rjmp $
ORG 0x070
// DTLB Miss (Write): UNUSED IN AVR32UC.
_handle_DTLB_Miss_Write:
rjmp $
ORG 0x100
// Supervisor Call.
_handle_Supervisor_Call:
lddpc pc, __SCALLYield
// Interrupt support.
// The interrupt controller must provide the offset address relative to EVBA.
// Important note:
// All interrupts call a C function named _get_interrupt_handler.
// This function will read group and interrupt line number to then return in
// R12 a pointer to a user-provided interrupt handler.
ALIGN 2
_int0:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 110b
brlo _int0_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int0_normal:
#endif
mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.
mcall __get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int1:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 110b
brlo _int1_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int1_normal:
#endif
mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.
mcall __get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int2:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 110b
brlo _int2_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int2_normal:
#endif
mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.
mcall __get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int3:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 110b
brlo _int3_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int3_normal:
#endif
mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.
mcall __get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
// Constant data area.
ALIGN 2
// Import symbols.
EXTERN SCALLYield
EXTERN _get_interrupt_handler
__SCALLYield:
DC32 SCALLYield
__get_interrupt_handler:
DC32 _get_interrupt_handler
// Values to store in the interrupt priority registers for the various interrupt priority levels.
// The interrupt priority registers contain the interrupt priority level and
// the EVBA-relative interrupt vector offset.
PUBLIC ipr_val
ipr_val:
DC32 (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\
(INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\
(INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\
(INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)
END
//! \endverbatim
//! @}

View file

@ -0,0 +1,426 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port source for AVR32 UC3.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* AVR32 UC3 includes. */
#include <avr32/io.h>
#include <intrinsics.h>
#include "gpio.h"
#if configDBG
#include "usart.h"
#endif
#if( configTICK_USE_TC==1 )
#include "tc.h"
#endif
/* Constants required to setup the task context. */
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )
/* Each task maintains its own critical nesting variable. */
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
volatile unsigned portLONG ulCriticalNesting = 9999UL;
#if( configTICK_USE_TC==0 )
static void prvScheduleNextTick( void );
#else
static void prvClearTcInt( void );
#endif
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Low-level initialization routine called during startup, before the main
* function.
*/
int __low_level_init(void)
{
#if configHEAP_INIT
#pragma segment = "HEAP"
portBASE_TYPE *pxMem;
#endif
/* Enable exceptions. */
ENABLE_ALL_EXCEPTIONS();
/* Initialize interrupt handling. */
INTC_init_interrupts();
#if configHEAP_INIT
{
/* Initialize the heap used by malloc. */
for( pxMem = __segment_begin( "HEAP" ); pxMem < ( portBASE_TYPE * ) __segment_end( "HEAP" ); )
{
*pxMem++ = 0xA5A5A5A5;
}
}
#endif
/* Code section present if and only if the debug trace is activated. */
#if configDBG
{
static const gpio_map_t DBG_USART_GPIO_MAP =
{
{ configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
{ configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
};
static const usart_options_t DBG_USART_OPTIONS =
{
.baudrate = configDBG_USART_BAUDRATE,
.charlength = 8,
.paritytype = USART_NO_PARITY,
.stopbits = USART_1_STOPBIT,
.channelmode = USART_NORMAL_CHMODE
};
/* Initialize the USART used for the debug trace with the configured parameters. */
extern volatile avr32_usart_t *volatile stdio_usart_base;
stdio_usart_base = configDBG_USART;
gpio_enable_module( DBG_USART_GPIO_MAP,
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
usart_init_rs232(configDBG_USART, &DBG_USART_OPTIONS, configCPU_CLOCK_HZ);
}
#endif
/* Request initialization of data segments. */
return 1;
}
/*-----------------------------------------------------------*/
/* Added as there is no such function in FreeRTOS. */
void *pvPortRealloc( void *pv, size_t xWantedSize )
{
void *pvReturn;
vTaskSuspendAll();
{
pvReturn = realloc( pv, xWantedSize );
}
xTaskResumeAll();
return pvReturn;
}
/*-----------------------------------------------------------*/
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
/* The preemptive scheduler is defined as "naked" as the full context is saved
on entry as part of the context switch. */
#pragma shadow_registers = full // Naked.
static void vTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT_OS_INT();
#if( configTICK_USE_TC==1 )
/* Clear the interrupt flag. */
prvClearTcInt();
#else
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
prvScheduleNextTick();
#endif
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
calls in a critical section . */
portENTER_CRITICAL();
vTaskIncrementTick();
portEXIT_CRITICAL();
/* Restore the context of the "elected task". */
portRESTORE_CONTEXT_OS_INT();
}
/*-----------------------------------------------------------*/
#pragma shadow_registers = full // Naked.
void SCALLYield( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT_SCALL();
vTaskSwitchContext();
portRESTORE_CONTEXT_SCALL();
}
/*-----------------------------------------------------------*/
/* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */
#pragma optimize = no_inline
void vPortEnterCritical( void )
{
/* Disable interrupts */
portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
}
/*-----------------------------------------------------------*/
#pragma optimize = no_inline
void vPortExitCritical( void )
{
if(ulCriticalNesting > portNO_CRITICAL_NESTING)
{
ulCriticalNesting--;
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Enable all interrupt/exception. */
portENABLE_INTERRUPTS();
}
}
}
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called.
*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
/* When the task starts, it will expect to find the function parameter in R12. */
pxTopOfStack--;
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808; /* R8 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909; /* R9 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A; /* R10 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B; /* R11 */
*pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters; /* R12 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF; /* R14/LR */
*pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; /* R15/PC */
*pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR; /* SR */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF; /* R0 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101; /* R1 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202; /* R2 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303; /* R3 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
prvSetupTimerInterrupt();
/* Start the first task. */
portRESTORE_CONTEXT();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the AVR32 port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
#if( configTICK_USE_TC==0 )
static void prvScheduleFirstTick(void)
{
unsigned long lCycles;
lCycles = Get_system_register(AVR32_COUNT);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
Set_system_register(AVR32_COMPARE, lCycles);
}
#pragma optimize = no_inline
static void prvScheduleNextTick(void)
{
unsigned long lCycles, lCount;
lCycles = Get_system_register(AVR32_COMPARE);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
lCount = Get_system_register(AVR32_COUNT);
if( lCycles < lCount )
{ // We missed a tick, recover for the next.
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
}
Set_system_register(AVR32_COMPARE, lCycles);
}
#else
#pragma optimize = no_inline
static void prvClearTcInt(void)
{
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
}
#endif
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt(void)
{
#if( configTICK_USE_TC==1 )
volatile avr32_tc_t *tc = &AVR32_TC;
// Options for waveform genration.
tc_waveform_opt_t waveform_opt =
{
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
.bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */
.beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */
.bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */
.bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */
.aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */
.aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
.enetrg = FALSE, /* External event trigger enable. */
.eevt = 0, /* External event selection. */
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
.cpcdis = FALSE, /* Counter disable when RC compare. */
.cpcstop = FALSE, /* Counter clock stopped with RC compare. */
.burst = FALSE, /* Burst signal selection. */
.clki = FALSE, /* Clock inversion. */
.tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */
};
tc_interrupt_t tc_interrupt =
{
.etrgs=0,
.ldrbs=0,
.ldras=0,
.cpcs =1,
.cpbs =0,
.cpas =0,
.lovrs=0,
.covfs=0,
};
#endif
/* Disable all interrupt/exception. */
portDISABLE_INTERRUPTS();
/* Register the compare interrupt handler to the interrupt controller and
enable the compare interrupt. */
#if( configTICK_USE_TC==1 )
{
INTC_register_interrupt((__int_handler)&vTick, configTICK_TC_IRQ, INT0);
/* Initialize the timer/counter. */
tc_init_waveform(tc, &waveform_opt);
/* Set the compare triggers.
Remember TC counter is 16-bits, so counting second is not possible!
That's why we configure it to count ms. */
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
/* Start the timer/counter. */
tc_start(tc, configTICK_TC_CHANNEL);
}
#else
{
INTC_register_interrupt((__int_handler)&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
prvScheduleFirstTick();
}
#endif
}

View file

@ -0,0 +1,669 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port header for AVR32 UC3.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/*
FreeRTOS V5.4.2 - Copyright (C) 2009 Real Time Engineers Ltd.
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 exception 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.
Alternative commercial license and support terms are also available upon
request. See the licensing section of http://www.FreeRTOS.org for full
license details.
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 along
with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Looking for a quick start? Then check out the FreeRTOS eBook! *
* See http://www.FreeRTOS.org/Documentation for details *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#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.
*-----------------------------------------------------------
*/
#include <avr32/io.h>
#include "intc.h"
#include "compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned portLONG
#define portBASE_TYPE portLONG
#define TASK_DELAY_MS(x) ( (x) /portTICK_RATE_MS )
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
#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
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4
#define portNOP() {__asm__ __volatile__ ("nop");}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* INTC-specific. */
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
/*
* Debug trace.
* Activated if and only if configDBG is nonzero.
* Prints a formatted string to stdout.
* The current source file name and line number are output with a colon before
* the formatted string.
* A carriage return and a linefeed are appended to the output.
* stdout is redirected to the USART configured by configDBG_USART.
* The parameters are the same as for the standard printf function.
* There is no return value.
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
*/
#if configDBG
#define portDBG_TRACE(...) \
{ \
fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout); \
printf(__VA_ARGS__); \
fputs("\r\n", stdout); \
}
#else
#define portDBG_TRACE(...)
#endif
/* Critical section management. */
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical();
/* Added as there is no such function in FreeRTOS. */
extern void *pvPortRealloc( void *pv, size_t xSize );
/*-----------------------------------------------------------*/
/*=============================================================================================*/
/*
* Restore Context for cases other than INTi.
*/
#define portRESTORE_CONTEXT() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
/* R0-R7 should not be used below this line */ \
/* Skip PC and SR (will do it at the end) */ \
"sub sp, -2*4 \n\t"\
/* Restore R8..R12 and LR */ \
"ldm sp++, r8-r12, lr \n\t"\
/* Restore SR */ \
"ld.w r0, sp[-8*4] \n\t" /* R0 is modified, is restored later. */\
"mtsr "ASTRINGZ(AVR32_SR)", r0 \n\t"\
/* Restore r0 */ \
"ld.w r0, sp[-9*4] \n\t"\
/* Restore PC */ \
"ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
); \
\
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
/*
* portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.
* portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.
*
* Had to make different versions because registers saved on the system stack
* are not the same between INT0..3 exceptions and the scall exception.
*/
// Task context stack layout:
// R8 (*)
// R9 (*)
// R10 (*)
// R11 (*)
// R12 (*)
// R14/LR (*)
// R15/PC (*)
// SR (*)
// R0
// R1
// R2
// R3
// R4
// R5
// R6
// R7
// ulCriticalNesting
// (*) automatically done for INT0..INT3, but not for SCALL
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/*
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
*/
#define portSAVE_CONTEXT_OS_INT() \
{ \
/* Save R0..R7 */ \
__asm__ __volatile__ ("stm --sp, r0-r7"); \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context save. */ \
}
/*
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
*/
#define portRESTORE_CONTEXT_OS_INT() \
{ \
__asm__ __volatile__ ( \
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context restore. */ \
"rete" \
); \
}
#else
/*
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
*/
#define portSAVE_CONTEXT_OS_INT() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* When we come here */ \
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
\
__asm__ __volatile__ ( \
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t"\
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0 \n\t"\
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
/* NOTE: we don't enter a critical section here because all interrupt handlers */ \
/* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \
/* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \
/* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp \n"\
\
"LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \
); \
}
/*
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
*/
#define portRESTORE_CONTEXT_OS_INT() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
__asm__ __volatile__ ( \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) \
); \
\
/* Else */ \
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
\
/* Restore all registers */ \
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n"\
\
"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* Now, the stack should be R8..R12, LR, PC and SR */ \
"rete" \
); \
\
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
#endif
/*
* portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.
*
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
*
*/
#define portSAVE_CONTEXT_SCALL() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
/* If SR[M2:M0] == 001 */ \
/* PC and SR are on the stack. */ \
/* Else (other modes) */ \
/* Nothing on the stack. */ \
\
/* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \
/* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \
/* in an interrupt|exception handler. */ \
\
__asm__ __volatile__ ( \
/* in order to save R0-R7 */ \
"sub sp, 6*4 \n\t"\
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t"\
\
/* in order to save R8-R12 and LR */ \
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
"sub r7, sp,-16*4 \n\t"\
/* Copy PC and SR in other places in the stack. */ \
"ld.w r0, r7[-2*4] \n\t" /* Read SR */\
"st.w r7[-8*4], r0 \n\t" /* Copy SR */\
"ld.w r0, r7[-1*4] \n\t" /* Read PC */\
"st.w r7[-7*4], r0 \n\t" /* Copy PC */\
\
/* Save R8..R12 and LR on the stack. */ \
"stm --r7, r8-r12, lr \n\t"\
\
/* Arriving here we have the following stack organizations: */ \
/* R8..R12, LR, PC, SR, R0..R7. */ \
\
/* Now we can finalize the save. */ \
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0" \
); \
\
/* Disable the its which may cause a context switch (i.e. cause a change of */ \
/* pxCurrentTCB). */ \
/* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \
/* critical section because it is a global structure. */ \
portENTER_CRITICAL(); \
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
__asm__ __volatile__ ( \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp" \
); \
}
/*
* portRESTORE_CONTEXT() for SupervisorCALL exception.
*/
#define portRESTORE_CONTEXT_SCALL() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Restore all registers */ \
\
/* Set SP to point to new stack */ \
__asm__ __volatile__ ( \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0]" \
); \
\
/* Leave pxCurrentTCB variable access critical section */ \
portEXIT_CRITICAL(); \
\
__asm__ __volatile__ ( \
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* skip PC and SR */ \
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
"sub r7, sp, -10*4 \n\t"\
/* Restore r8-r12 and LR */ \
"ldm r7++, r8-r12, lr \n\t"\
\
/* RETS will take care of the extra PC and SR restore. */ \
/* So, we have to prepare the stack for this. */ \
"ld.w r0, r7[-8*4] \n\t" /* Read SR */\
"st.w r7[-2*4], r0 \n\t" /* Copy SR */\
"ld.w r0, r7[-7*4] \n\t" /* Read PC */\
"st.w r7[-1*4], r0 \n\t" /* Copy PC */\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
"sub sp, -6*4 \n\t"\
\
"rets" \
); \
\
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
/*
* The ISR used depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
/*
* ISR entry and exit macros. These are only required if a task switch
* is required from the ISR.
*/
#define portENTER_SWITCHING_ISR() \
{ \
/* Save R0..R7 */ \
__asm__ __volatile__ ("stm --sp, r0-r7"); \
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context save. */ \
}
/*
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
*/
#define portEXIT_SWITCHING_ISR() \
{ \
__asm__ __volatile__ ( \
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
/* there is also no context restore. */ \
"rete" \
); \
}
#else
/*
* ISR entry and exit macros. These are only required if a task switch
* is required from the ISR.
*/
#define portENTER_SWITCHING_ISR() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* When we come here */ \
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
\
__asm__ __volatile__ ( \
/* Save R0..R7 */ \
"stm --sp, r0-r7 \n\t"\
\
/* Save ulCriticalNesting variable - R0 is overwritten */ \
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w --sp, r0 \n\t"\
\
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
\
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"st.w r0[0], sp \n"\
\
"LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \
); \
}
/*
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
*/
#define portEXIT_SWITCHING_ISR() \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
__asm__ __volatile__ ( \
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
/* did not previously save SP in its TCB. */ \
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
\
/* If a switch is required then we just need to call */ \
/* vTaskSwitchContext() as the context has already been */ \
/* saved. */ \
"cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
"brne LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":C" \
); \
\
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
\
__asm__ __volatile__ ( \
"LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
/* Restore the context of which ever task is now the highest */ \
/* priority that is ready to run. */ \
\
/* Restore all registers */ \
\
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
"ld.w r0, r8[0] \n\t"\
"ld.w sp, r0[0] \n"\
\
"LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++ \n\t"\
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
\
/* Now, the stack should be R8..R12, LR, PC and SR */ \
"rete" \
); \
\
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}
#endif
#define portYIELD() {__asm__ __volatile__ ("scall");}
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,93 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief System-specific implementation of the \ref __read function used by
the standard library.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <yfuns.h>
#include <avr32/io.h>
#include "usart.h"
_STD_BEGIN
#pragma module_name = "?__read"
extern volatile avr32_usart_t *volatile stdio_usart_base;
/*! \brief Reads a number of bytes, at most \a size, into the memory area
* pointed to by \a buffer.
*
* \param handle File handle to read from.
* \param buffer Pointer to buffer to write read bytes to.
* \param size Number of bytes to read.
*
* \return The number of bytes read, \c 0 at the end of the file, or
* \c _LLIO_ERROR on failure.
*/
size_t __read(int handle, unsigned char *buffer, size_t size)
{
int nChars = 0;
// This implementation only reads from stdin.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDIN)
{
return _LLIO_ERROR;
}
for (; size > 0; --size)
{
int c = usart_getchar(stdio_usart_base);
if (c < 0)
break;
*buffer++ = c;
++nChars;
}
return nChars;
}
_STD_END

View file

@ -0,0 +1,103 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief System-specific implementation of the \ref __write function used by
the standard library.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32 devices with a USART module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <yfuns.h>
#include <avr32/io.h>
#include "usart.h"
_STD_BEGIN
#pragma module_name = "?__write"
//! Pointer to the base of the USART module instance to use for stdio.
__no_init volatile avr32_usart_t *volatile stdio_usart_base;
/*! \brief Writes a number of bytes, at most \a size, from the memory area
* pointed to by \a buffer.
*
* If \a buffer is zero then \ref __write performs flushing of internal buffers,
* if any. In this case, \a handle can be \c -1 to indicate that all handles
* should be flushed.
*
* \param handle File handle to write to.
* \param buffer Pointer to buffer to read bytes to write from.
* \param size Number of bytes to write.
*
* \return The number of bytes written, or \c _LLIO_ERROR on failure.
*/
size_t __write(int handle, const unsigned char *buffer, size_t size)
{
size_t nChars = 0;
if (buffer == 0)
{
// This means that we should flush internal buffers.
return 0;
}
// This implementation only writes to stdout and stderr.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
{
return _LLIO_ERROR;
}
for (; size != 0; --size)
{
if (usart_putchar(stdio_usart_base, *buffer++) < 0)
{
return _LLIO_ERROR;
}
++nChars;
}
return nChars;
}
_STD_END

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more