From 2931f43895e6f362c62394f2ec60d09d7f9b0d2c Mon Sep 17 00:00:00 2001 From: Richard Barry Date: Sat, 1 Dec 2007 20:29:54 +0000 Subject: [PATCH] Missing PIC32 files. --- Source/portable/MPLAB/PIC32MX/ISR_Support.h | 191 +++++++++++++++++++ Source/portable/MPLAB/PIC32MX/port.c | 192 ++++++++++++++++++++ Source/portable/MPLAB/PIC32MX/port_asm.S | 157 ++++++++++++++++ Source/portable/MPLAB/PIC32MX/portmacro.h | 111 +++++++++++ 4 files changed, 651 insertions(+) create mode 100644 Source/portable/MPLAB/PIC32MX/ISR_Support.h create mode 100644 Source/portable/MPLAB/PIC32MX/port.c create mode 100644 Source/portable/MPLAB/PIC32MX/port_asm.S create mode 100644 Source/portable/MPLAB/PIC32MX/portmacro.h diff --git a/Source/portable/MPLAB/PIC32MX/ISR_Support.h b/Source/portable/MPLAB/PIC32MX/ISR_Support.h new file mode 100644 index 000000000..2a3af5957 --- /dev/null +++ b/Source/portable/MPLAB/PIC32MX/ISR_Support.h @@ -0,0 +1,191 @@ +/* + FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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.org 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.org; 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.org, 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. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + + Also see http://www.SafeRTOS.com a version that has been certified for use + in safety critical systems, plus commercial licensing, development and + support options. + *************************************************************************** +*/ + +#include "FreeRTOSConfig.h" + +#define portCONTEXT_SIZE 136 +#define portEXL_AND_IE_BITS 0x03 + +#define portEPC_STACK_LOCATION 124 +#define portSTATUS_STACK_LOCATION 128 +#define portCAUSE_STACK_LOCATION 132 + +/******************************************************************/ +.macro portSAVE_CONTEXT + + /* Make room for the context. */ + addiu sp, sp, -portCONTEXT_SIZE + + /* Get interrupts above the kernel priority enabled again ASAP. First + save the current status so we can manipulate it, and the cause and EPC + registers so we capture their original values in case of interrupt nesting. */ + + mfc0 k0, _CP0_CAUSE + sw k0, portCAUSE_STACK_LOCATION(sp) + mfc0 k1, _CP0_STATUS + sw k1, portSTATUS_STACK_LOCATION(sp) + + /* Also save s6 so we can use it during this interrupt. Any + nesting interrupts should maintain the values of this register + accross the ISR. */ + sw s6, 44(sp) + + /* s6 holds the EPC value, we may want this during the context switch. */ + mfc0 s6, _CP0_EPC + + /* Enable interrupts above the kernel priority. */ + addiu k0, zero, configKERNEL_INTERRUPT_PRIORITY + ins k1, k0, 10, 6 + ins k1, zero, 1, 4 + mtc0 k1, _CP0_STATUS + + /* Save the context into the space just created. s6 is saved again + here as it now contains the EPC value. */ + sw ra, 120(sp) + sw s8, 116(sp) + sw t9, 112(sp) + sw t8, 108(sp) + sw t7, 104(sp) + sw t6, 100(sp) + sw t5, 96(sp) + sw t4, 92(sp) + sw t3, 88(sp) + sw t2, 84(sp) + sw t1, 80(sp) + sw t0, 76(sp) + sw a3, 72(sp) + sw a2, 68(sp) + sw a1, 64(sp) + sw a0, 60(sp) + sw v1, 56(sp) + sw v0, 52(sp) + sw s7, 48(sp) + sw s6, portEPC_STACK_LOCATION(sp) + sw s5, 40(sp) + sw s4, 36(sp) + sw s3, 32(sp) + sw s2, 28(sp) + sw s1, 24(sp) + sw s0, 20(sp) + sw $1, 16(sp) + + /* s7 is used as a scratch register. */ + mfhi s7 + sw s7, 12(sp) + mflo s7 + sw s7, 8(sp) + + /* Each task maintains its own nesting count. */ + la s7, uxCriticalNesting + lw s7, (s7) + sw s7, 4(sp) + + /* Update the TCB stack pointer value */ + la s7, pxCurrentTCB + lw s7, (s7) + sw sp, (s7) + + /* Switch to the ISR stack, saving the current stack in s5. This might + be used to determine the cause of a general exception. */ + add s5, zero, sp + la s7, xISRStackTop + lw sp, (s7) + + .endm + +/******************************************************************/ +.macro portRESTORE_CONTEXT + + /* Restore the stack pointer from the TCB */ + la s0, pxCurrentTCB + lw s1, (s0) + lw sp, (s1) + + /* Restore the context, the first item of which is the critical nesting + depth. */ + la s0, uxCriticalNesting + lw s1, 4(sp) + sw s1, (s0) + + /* Restore the rest of the context. */ + lw s0, 8(sp) + mtlo s0 + lw s0, 12(sp) + mthi s0 + lw $1, 16(sp) + lw s0, 20(sp) + lw s1, 24(sp) + lw s2, 28(sp) + lw s3, 32(sp) + lw s4, 36(sp) + lw s5, 40(sp) + lw s6, 44(sp) + lw s7, 48(sp) + lw v0, 52(sp) + lw v1, 56(sp) + lw a0, 60(sp) + lw a1, 64(sp) + lw a2, 68(sp) + lw a3, 72(sp) + lw t0, 76(sp) + lw t1, 80(sp) + lw t2, 84(sp) + lw t3, 88(sp) + lw t4, 92(sp) + lw t5, 96(sp) + lw t6, 100(sp) + lw t7, 104(sp) + lw t8, 108(sp) + lw t9, 112(sp) + lw s8, 116(sp) + lw ra, 120(sp) + + /* Protect access to the k registers. */ + di + lw k1, portSTATUS_STACK_LOCATION(sp) + lw k0, portEPC_STACK_LOCATION(sp) + + /* Leave the stack how we found it. */ + addiu sp, sp, portCONTEXT_SIZE + + mtc0 k1, _CP0_STATUS + ehb + mtc0 k0, _CP0_EPC + eret + nop + + .endm + diff --git a/Source/portable/MPLAB/PIC32MX/port.c b/Source/portable/MPLAB/PIC32MX/port.c new file mode 100644 index 000000000..8ffbdba1a --- /dev/null +++ b/Source/portable/MPLAB/PIC32MX/port.c @@ -0,0 +1,192 @@ +/* + FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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.org 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.org; 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.org, 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. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + + Also see http://www.SafeRTOS.com a version that has been certified for use + in safety critical systems, plus commercial licensing, development and + support options. + *************************************************************************** +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the PIC32MX port. + *----------------------------------------------------------*/ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Hardware specifics. */ +#define portTIMER_PRESCALE 8 + +/* Bits within various registers. */ +#define portIE_BIT ( 0x00000001 ) +#define portEXL_BIT ( 0x00000002 ) +#define portIPL_SHIFT ( 10 ) +#define portALL_IPL_BITS ( 0x1f << portIPL_SHIFT ) + +/* The EXL bit is set to ensure interrupts do not occur while the context of +the first task is being restored. */ +#define portINITIAL_SR ( portIE_BIT | portEXL_BIT ) + +/* Records the nesting depth of calls to portENTER_CRITICAL(). */ +unsigned portBASE_TYPE uxCriticalNesting = 0x55555555; + +/* The stack used by interrupt service routines that cause a context switch. */ +portSTACK_TYPE xISRStack[ configISR_STACK_SIZE ] = { 0 }; + +/* The top of stack value ensures there is enough space to store 6 registers on +the callers stack, as some functions seem to want to do this. */ +const portBASE_TYPE * const xISRStackTop = &( xISRStack[ configISR_STACK_SIZE - 7 ] ); + +/* Place the prototype here to ensure the interrupt vector is correctly installed. */ +extern void __attribute__( (interrupt(ipl1), vector(_TIMER_1_VECTOR))) vT1InterruptHandler( void ); + +/* + * General exception handler that will be called for all general exceptions + * other than SYS. This should be overridden by a user provided handler. + */ +void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus ) __attribute__((weak)); + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ + *pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF; + pxTopOfStack--; + + *pxTopOfStack = (portSTACK_TYPE) 0x12345678; /* Word to which the stack pointer will be left pointing after context restore. */ + pxTopOfStack--; + + *pxTopOfStack = (portSTACK_TYPE) _CP0_GET_CAUSE(); + pxTopOfStack--; + + *pxTopOfStack = (portSTACK_TYPE) portINITIAL_SR; /* CP0_STATUS */ + pxTopOfStack--; + + *pxTopOfStack = (portSTACK_TYPE) pxCode; /* CP0_EPC */ + pxTopOfStack--; + + *pxTopOfStack = (portSTACK_TYPE) NULL; /* ra */ + pxTopOfStack -= 15; + + *pxTopOfStack = (portSTACK_TYPE) pvParameters; /* Parameters to pass in */ + pxTopOfStack -= 14; + + *pxTopOfStack = (portSTACK_TYPE) 0x00000000; /* critical nesting level */ + pxTopOfStack--; + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +/* + * Setup a timer for a regular tick. + */ +void prvSetupTimerInterrupt( void ) +{ +const unsigned portLONG ulCompareMatch = (configPERIPHERAL_CLOCK_HZ / portTIMER_PRESCALE) / configTICK_RATE_HZ; + + OpenTimer1( ( T1_ON | T1_PS_1_8 | T1_SOURCE_INT ), ulCompareMatch ); + ConfigIntTimer1( T1_INT_ON | configKERNEL_INTERRUPT_PRIORITY ); +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler(void) +{ + /* It is unlikely that the scheduler for the PIC port will get stopped + once running. If required disable the tick interrupt here, then return + to xPortStartScheduler(). */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical(void) +{ +unsigned portLONG ulStatus; + + /* Mask interrupts at and below the kernel interrupt priority. */ + ulStatus = _CP0_GET_STATUS(); + ulStatus |= ( configKERNEL_INTERRUPT_PRIORITY << portIPL_SHIFT ); + _CP0_SET_STATUS( ulStatus ); + + /* Once interrupts are disabled we can access the nesting count directly. */ + uxCriticalNesting++; +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical(void) +{ +unsigned portLONG ulStatus; + + /* If we are in a critical section then we can access the nesting count + directly. */ + uxCriticalNesting--; + + /* Has the nesting unwound? */ + if( uxCriticalNesting == 0 ) + { + /* Unmask all interrupts. */ + ulStatus = _CP0_GET_STATUS(); + ulStatus &= ~portALL_IPL_BITS; + _CP0_SET_STATUS( ulStatus ); + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortStartScheduler( void ) +{ +extern void vPortStartFirstTask( void ); + + /* Setup the timer to generate the tick. Interrupts will have been + disabled by the time we get here. */ + prvSetupTimerInterrupt(); + + /* Kick off the highest priority task that has been created so far. */ + vPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +void vApplicationGeneralExceptionHandler( unsigned portLONG ulCause, unsigned portLONG ulStatus ) +{ + /* This function is declared weak and should be overridden by the users + application. */ + while( 1 ); +} + + + + + diff --git a/Source/portable/MPLAB/PIC32MX/port_asm.S b/Source/portable/MPLAB/PIC32MX/port_asm.S new file mode 100644 index 000000000..eeadd3faa --- /dev/null +++ b/Source/portable/MPLAB/PIC32MX/port_asm.S @@ -0,0 +1,157 @@ +/* + FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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.org 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.org; 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.org, 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. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + + Also see http://www.SafeRTOS.com a version that has been certified for use + in safety critical systems, plus commercial licensing, development and + support options. + *************************************************************************** +*/ + +#include +#include +#include "ISR_Support.h" + +#define portEXC_CODE_MASK ( 0x1f << 2 ) + + .set nomips16 + .set noreorder + + .extern pxCurrentTCB + .extern uxCriticalNesting + .extern vTaskSwitchContext + .extern vTaskIncrementTick + .extern vApplicationGeneralExceptionHandler + .extern xISRStackTop + + .global vPortStartFirstTask + .global _general_exception_context + .global vT1InterruptHandler + + +/******************************************************************/ + + .section .FreeRTOS, "ax", @progbits + .set noreorder + .set noat + .ent vT1InterruptHandler + +vT1InterruptHandler: + + portSAVE_CONTEXT + + jal vTaskIncrementTick + nop + + /* If we are using the preemptive scheduler then we might want to select + a different task to execute. */ + #if configUSE_PREEMPTION == 1 + jal vTaskSwitchContext + nop + #endif /* configUSE_PREEMPTION */ + + /* Clear timer 0 interrupt. */ + la s1, IFS0CLR + addiu s0,zero,_IFS0_T1IF_MASK + sw s0, 0(s1) + + portRESTORE_CONTEXT + + .end vT1InterruptHandler + +/******************************************************************/ + + .section .FreeRTOS, "ax", @progbits + .set noreorder + .set noat + .ent xPortStartScheduler + +vPortStartFirstTask: + + /* Simply restore the context of the highest priority task that has been + created so far. */ + portRESTORE_CONTEXT + + .end xPortStartScheduler + +/*******************************************************************/ + + .section .FreeRTOS, "ax", @progbits + .set noreorder + .set noat + .ent _general_exception_context + +_general_exception_context: + + /* Save the context of the current task. */ + portSAVE_CONTEXT + + /* Was this handler caused by a syscall? The original Cause + value was saved to the stack as it could change as interrupts + nest. Use of k registers must be protected from use by nesting + interrupts. */ + lw s7, portCAUSE_STACK_LOCATION(s5) + andi s7, s7, portEXC_CODE_MASK + addi s7, s7, -( _EXCCODE_SYS << 2 ) + + /* Yes - call the SYSCALL handler to select a new task to execute. */ + beq s7, zero, SyscallHandler + nop + + /* No - call the application handler to handle all other types of + exception. Pass the status and cause to the application provided + handler. Interrupts are disabled during the execution of the user + defined handler. */ + di + lw a1, portSTATUS_STACK_LOCATION(s5) + lw a0, portCAUSE_STACK_LOCATION(s5) + jal vApplicationGeneralExceptionHandler + nop + ei + beq zero, zero, FinishExceptionHandler + nop + +SyscallHandler: + + /* Adjust the return that was placed onto the stack to be the + address of the instruction following the syscall. s6 already + contains the EPC value. */ + addi s6, 4 + sw s6, portEPC_STACK_LOCATION(s5) + + jal vTaskSwitchContext + nop + +FinishExceptionHandler: + portRESTORE_CONTEXT + + .end _general_exception_context + + + diff --git a/Source/portable/MPLAB/PIC32MX/portmacro.h b/Source/portable/MPLAB/PIC32MX/portmacro.h new file mode 100644 index 000000000..c98ade4c3 --- /dev/null +++ b/Source/portable/MPLAB/PIC32MX/portmacro.h @@ -0,0 +1,111 @@ +/* + FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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.org 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.org; 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.org, 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. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + + Also see http://www.SafeRTOS.com a version that has been certified for use + in safety critical systems, plus commercial licensing, development and + support options. + *************************************************************************** +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +/* System include files */ +#include + +#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 -4 +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +#define portDISABLE_INTERRUPTS() INTDisableInterrupts() +#define portENABLE_INTERRUPTS() INTEnableInterrupts() + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/* Task utilities. */ +#define portYIELD() asm volatile ( "ehb \r\n" \ + "SYSCALL \r\n" ) + +#define portNOP() asm volatile ( "nop" ) + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn)) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +#define portEND_SWITCHING_ISR( vSwitchRequired ) if( vSwitchRequired ) vTaskSwitchContext() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ +