volatile unsigned portLONG ulCriticalNesting = 9999UL;\r
\r
/*-----------------------------------------------------------*/\r
-\r
-\r
\r
#pragma asm\r
#macro SaveContext\r
ANDCCR #0xDF ;Switch to system stack\r
ST R0,@-R15 ;Store PC to system stack\r
\r
- ORCCR #0x20 ;Switch back to retreive the remaining context\r
+ ORCCR #0x20 ;Switch back to retrieve the remaining context\r
\r
LDI #_ulCriticalNesting, R0 ;Get the address of the critical nesting counter\r
LD @R15+, R1 ;Get the saved critical nesting value\r
*pxTopOfStack = 0x33333333;\r
pxTopOfStack--;\r
\r
- /* This is a redundant push to the stack, it may be required if in some implentation of the compiler\r
- the parameter to the task is passed on to the stack rather than in R4 register*/\r
+ /* This is a redundant push to the stack, it may be required if \r
+ in some implementations of the compiler the parameter to the task \r
+ is passed on to the stack rather than in R4 register. */\r
*pxTopOfStack = (portSTACK_TYPE)(pvParameters);\r
pxTopOfStack--; \r
\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* RP */\r
pxTopOfStack--;\r
-\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00007777; /* R7 */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00006666; /* R6 */\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00005555; /* R5 */\r
pxTopOfStack--;\r
\r
- /* In the current implemention of the compiler the first \r
- parameter to the task(or function) is passed via R4 parameter \r
- to the task, hennce the pvParameters pointer is copied in R4 \r
- regsiter. See compiler manual section 4.6.2 for more information.*/\r
+ /* In the current implementation of the compiler the first \r
+ parameter to the task (or function) is passed via R4 parameter \r
+ to the task, hence the pvParameters pointer is copied into the R4 \r
+ register. See compiler manual section 4.6.2 for more information. */\r
*pxTopOfStack = ( portSTACK_TYPE ) (pvParameters); /* R4 */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00003333; /* R3 */\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00001111; /* R1 */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000001; /* R0 */\r
- pxTopOfStack--;\r
- \r
+ pxTopOfStack--; \r
*pxTopOfStack = ( portSTACK_TYPE ) 0x0000EEEE; /* R14 */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x0000DDDD; /* R13 */\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00009999; /* R9 */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x00008888; /* R8 */\r
- pxTopOfStack--;\r
- \r
+ pxTopOfStack--; \r
*pxTopOfStack = ( portSTACK_TYPE ) 0x11110000; /* MDH */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) 0x22220000; /* MDL */\r
pxTopOfStack--;\r
\r
- /* The task starts with its ulCriticalNesting variable set to 0, interrupts\r
- being enabled. */\r
+ /* The task starts with its ulCriticalNesting variable set to 0, \r
+ interrupts being enabled. */\r
*pxTopOfStack = portNO_CRITICAL_NESTING;\r
pxTopOfStack--;\r
\r
prvSetupTimerInterrupt();\r
\r
/* Restore the context of the first task that is going to run. */\r
-#pragma asm\r
- RestoreContext\r
-#pragma endasm\r
+ #pragma asm\r
+ RestoreContext\r
+ #pragma endasm\r
\r
/* Simulate a function call end as generated by the compiler. We will now\r
- jump to the start of the task the context of which we have just restored. */\r
- \r
+ jump to the start of the task the context of which we have just restored. */ \r
__asm(" reti ");\r
\r
-\r
/* Should not get here. */\r
- return pdTRUE;\r
+ return pdFAIL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-/*\r
- * Setup RLT0 to generate a tick interrupt.\r
- */\r
static void prvSetupTimerInterrupt( void )\r
{\r
/* The peripheral clock divided by 32 is used by the timer. */\r
const unsigned portSHORT usReloadValue = ( unsigned portSHORT ) ( ( ( configPER_CLOCK_HZ / configTICK_RATE_HZ ) / 32UL ) - 1UL );\r
\r
- TMCSR0_CNTE=0; /* Count Disable */\r
- TMCSR0_CSL=0x2; /* CLKP/32 */\r
- TMCSR0_MOD=0; /* Software trigger */\r
- TMCSR0_RELD=1; /* Reload */\r
+ /* Setup RLT0 to generate a tick interrupt. */\r
+\r
+ TMCSR0_CNTE = 0; /* Count Disable */\r
+ TMCSR0_CSL = 0x2; /* CLKP/32 */\r
+ TMCSR0_MOD = 0; /* Software trigger */\r
+ TMCSR0_RELD = 1; /* Reload */\r
\r
- TMCSR0_UF=0; /* Clear underflow flag */\r
- TMRLR0=usReloadValue;\r
- TMCSR0_INTE=1; /* Interrupt Enable */\r
- TMCSR0_CNTE=1; /* Count Enable */\r
- TMCSR0_TRG=1; /* Trigger */\r
+ TMCSR0_UF = 0; /* Clear underflow flag */\r
+ TMRLR0 = usReloadValue;\r
+ TMCSR0_INTE = 1; /* Interrupt Enable */\r
+ TMCSR0_CNTE = 1; /* Count Enable */\r
+ TMCSR0_TRG = 1; /* Trigger */\r
\r
- PORTEN = 0x3; /* Port Enable */\r
+ PORTEN = 0x3; /* Port Enable */\r
}\r
/*-----------------------------------------------------------*/\r
\r
/* \r
* Tick ISR for preemptive scheduler. The tick count is incremented \r
* after the context is saved. Then the context is switched if required,\r
- * at last the context of the task which is to be resume is restored.\r
+ * and last the context of the task which is to be resumed is restored.\r
*/\r
\r
#pragma asm\r
_ReloadTimer0_IRQHandler:\r
\r
ANDCCR #0xEF ;Disable Interrupts\r
-\r
SaveContext ;Save context\r
-\r
ORCCR #0x10 ;Re-enable Interrupts\r
\r
LDI #0xFFFB,R1\r
AND R1,@R0 ;Clear RLT0 interrupt flag\r
\r
CALL32 _vTaskIncrementTick,R12 ;Increment Tick\r
-\r
CALL32 _vTaskSwitchContext,R12 ;Switch context if required\r
\r
ANDCCR #0xEF ;Disable Interrupts\r
-\r
RestoreContext ;Restore context\r
-\r
ORCCR #0x10 ;Re-enable Interrupts\r
\r
RETI\r
\r
#endif\r
\r
- /*\r
- * Manual context switch. We can use a __nosavereg attribute as the context \r
- * would be saved by PortSAVE_CONTEXT(). The context is switched and then \r
- * the context of the new task is restored saved. \r
- */\r
+/*\r
+ * Manual context switch. We can use a __nosavereg attribute as the context \r
+ * would be saved by PortSAVE_CONTEXT(). The context is switched and then \r
+ * the context of the new task is restored saved. \r
+ */\r
#pragma asm\r
\r
.global _vPortYieldDelayed\r
_vPortYieldDelayed:\r
\r
ANDCCR #0xEF ;Disable Interrupts\r
-\r
SaveContext ;Save context\r
-\r
ORCCR #0x10 ;Re-enable Interrupts\r
\r
LDI #_dicr, R0\r
CALL32 _vTaskSwitchContext,R12 ;Switch context if required\r
\r
ANDCCR #0xEF ;Disable Interrupts\r
-\r
RestoreContext ;Restore context\r
-\r
ORCCR #0x10 ;Re-enable Interrupts\r
\r
RETI\r
\r
#pragma endasm\r
+/*-----------------------------------------------------------*/\r
\r
- /*\r
- * Manual context switch. We can use a __nosavereg attribute as the context \r
- * would be saved by PortSAVE_CONTEXT(). The context is switched and then \r
- * the context of the new task is restored saved. \r
- */\r
- \r
+/*\r
+ * Manual context switch. We can use a __nosavereg attribute as the context \r
+ * would be saved by PortSAVE_CONTEXT(). The context is switched and then \r
+ * the context of the new task is restored saved. \r
+ */ \r
#pragma asm\r
\r
.global _vPortYield\r
_vPortYield:\r
\r
SaveContext ;Save context\r
-\r
CALL32 _vTaskSwitchContext,R12 ;Switch context if required\r
-\r
RestoreContext ;Restore context\r
\r
RETI\r
\r
#pragma endasm\r
-\r
/*-----------------------------------------------------------*/\r
\r
void vPortEnterCritical( void )\r
#ifndef PORTMACRO_H\r
#define PORTMACRO_H\r
\r
+/* Hardware specific includes. */\r
#include "mb91467d.h"\r
+\r
+/* Standard includes. */\r
#include <stddef.h>\r
\r
/*-----------------------------------------------------------\r
#define portSTACK_TYPE unsigned portLONG\r
#define portBASE_TYPE long\r
\r
-/* This is required since SOFTUNE doesn't support inline directive as is. */\r
-#define inline\r
-\r
#if( configUSE_16_BIT_TICKS == 1 )\r
typedef unsigned portSHORT portTickType;\r
#define portMAX_DELAY ( portTickType ) 0xffff\r
#define portNOP() __asm( " nop " );\r
/*-----------------------------------------------------------*/\r
\r
-/* portYIELD() uses SW interrupt */\r
+/* portYIELD() uses a SW interrupt */\r
#define portYIELD() __asm( " INT #40H " );\r
\r
/* portYIELD_FROM_ISR() uses delayed interrupt */\r
\r
#define portMINIMAL_STACK_SIZE configMINIMAL_STACK_SIZE\r
\r
+/* Remove the inline statement from within the kernel code. */\r
+#define inline\r
+\r
#endif /* PORTMACRO_H */\r
\r
*/\r
portSTACK_TYPE xGet_DTB_PCB_bank( void );\r
\r
-/* \r
- * Get current register pointer \r
- */ \r
-portCHAR xGet_RP( void ); \r
-\r
/*\r
* Sets up the periodic ISR used for the RTOS tick. This uses RLT0, but\r
* can be done using any given RLT.\r
* stack. Finally the resultant stack pointer value is saved into the \r
* task control block so it can be retrieved the next time the task \r
* executes.\r
- */\r
- \r
+ */ \r
#if( ( configMEMMODEL == portSMALL ) || ( configMEMMODEL == portMEDIUM ) )\r
\r
#define portSAVE_CONTEXT() \\r
__asm(" OR CCR,#H'20 "); \\r
}\r
\r
- /* \r
- * Macro to restore a task context from the task stack. This is effecti-\r
- * vely the reverse of SAVE_CONTEXT(). First the stack pointer value\r
- * (USP for SMALL and MEDIUM memory model amd USB:USP for COMPACT and \r
- * LARGE memory model ) is loaded from the task control block. Next the \r
- * value of all the general purpose registers RW0-RW7 is retrieved. Fina-\r
- * lly it copies of the context ( AH:AL, DPR:ADB, DTB:PCB, PC and PS) of \r
- * the task to be executed upon RETI from user stack to system stack. \r
- */\r
+/* \r
+ * Macro to restore a task context from the task stack. This is effecti-\r
+ * vely the reverse of SAVE_CONTEXT(). First the stack pointer value\r
+ * (USP for SMALL and MEDIUM memory model amd USB:USP for COMPACT and \r
+ * LARGE memory model ) is loaded from the task control block. Next the \r
+ * value of all the general purpose registers RW0-RW7 is retrieved. Fina-\r
+ * lly it copies of the context ( AH:AL, DPR:ADB, DTB:PCB, PC and PS) of \r
+ * the task to be executed upon RETI from user stack to system stack. \r
+ */\r
\r
#define portRESTORE_CONTEXT() \\r
{ __asm(" MOVW A, _pxCurrentTCB "); \\r
__asm(" POPW (RW0) "); \\r
\\r
/* Save the loaded value into the uxCriticalNesting variable. */ \\r
- __asm(" MOVW _uxCriticalNesting, RW0 "); \\r
+ __asm(" MOVW _uxCriticalNesting, RW0 "); \\r
\\r
__asm(" POPW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) "); \\r
__asm(" POPW A "); \\r
__asm(" PUSHW A "); \\r
}\r
\r
-#elif (configMEMMODEL == portCOMPACT || configMEMMODEL == portLARGE) \r
+#elif( ( configMEMMODEL == portCOMPACT ) || ( configMEMMODEL == portLARGE ) )\r
\r
#define portSAVE_CONTEXT() \\r
{ __asm(" POPW A "); \\r
__asm(" AND CCR,#H'DF "); \\r
__asm(" PUSHW A "); \\r
__asm(" PUSHW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) "); \\r
+ \\r
+ /* Save the critical nesting count to the stack. */ \\r
+ __asm(" MOVW RW0, _uxCriticalNesting "); \\r
+ __asm(" PUSHW (RW0) "); \\r
+ \\r
__asm(" MOVL A, _pxCurrentTCB "); \\r
__asm(" MOVL RL2, A "); \\r
__asm(" MOVW A, SP "); \\r
__asm(" MOVW SP, A "); \\r
__asm(" MOV A, @RL2+2 "); \\r
__asm(" MOV USB, A "); \\r
+ \\r
+ /* Load the saved uxCriticalNesting value into RW0. */ \\r
+ __asm(" POPW (RW0) "); \\r
+ \\r
+ /* Save the loaded value into the uxCriticalNesting variable. */ \\r
+ __asm(" MOVW _uxCriticalNesting, RW0 "); \\r
+ \\r
__asm(" POPW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) "); \\r
__asm(" POPW A "); \\r
__asm(" OR CCR,#H'20 "); \\r
/*-----------------------------------------------------------*/ \r
\r
/* \r
- * The below are the functions for getting the current value of DPR:ADB, \r
- * DTB:PCB bank registers\r
+ * Functions for obtaining the current value of DPR:ADB, DTB:PCB bank registers\r
*/\r
\r
#pragma asm\r
\r
.GLOBAL _xGet_DPR_ADB_bank\r
.GLOBAL _xGet_DTB_PCB_bank\r
- .GLOBAL _xGet_RP\r
.SECTION CODE, CODE, ALIGN=1\r
\r
_xGet_DPR_ADB_bank:\r
RET\r
#endif \r
\r
-\r
-_xGet_RP:\r
-\r
- PUSHW PS\r
- POPW A\r
- SWAP\r
- ANDW A,#0x1f\r
- #if configMEMMODEL == portMEDIUM || configMEMMODEL == portLARGE\r
- RETP\r
- #elif configMEMMODEL == portSMALL || configMEMMODEL == portCOMPACT \r
- RET\r
- #endif \r
-\r
-\r
#pragma endasm\r
/*-----------------------------------------------------------*/\r
\r
pxTopOfStack--;\r
\r
/* Once the task is called the task would push the pointer to the\r
- parameter on to the stack. Hence here the pointer would be copied first\r
- to the stack. In case of COMPACT or LARGE memory model such pointer \r
- would be 24 bit and in case of SMALL or MEDIUM memory model such pointer \r
- would be 16 bit */ \r
+ parameter onto the stack. Hence here the pointer would be copied to the stack\r
+ first. When using the COMPACT or LARGE memory model the pointer would be 24 \r
+ bits, and when using the SMALL or MEDIUM memory model the pointer would be 16 \r
+ bits. */ \r
#if( ( configMEMMODEL == portCOMPACT ) || ( configMEMMODEL == portLARGE ) )\r
{\r
*pxTopOfStack = ( portSTACK_TYPE ) ( ( unsigned portLONG ) ( pvParameters ) >> 16 );\r
#endif\r
\r
/* This is redundant push to the stack. This is required in order to introduce \r
- an offset so that the task accesses a parameter correctly that is passed on to \r
- the task stack. */\r
+ an offset so the task correctly accesses the parameter passed on the task stack. */\r
*pxTopOfStack = ( portSTACK_TYPE ) ( pxCode );\r
pxTopOfStack--; \r
\r
}\r
#endif\r
\r
- /* DTB | PCB, in case of portMEDIUM or portLARGE memory model PCB would be used\r
- along with PC to indicate the start address of the functiom */\r
+ /* DTB | PCB, in case of MEDIUM and LARGE memory models, PCB would be used\r
+ along with PC to indicate the start address of the function. */\r
#if( ( configMEMMODEL == portMEDIUM ) || ( configMEMMODEL == portLARGE ) )\r
{\r
*pxTopOfStack = ( xGet_DTB_PCB_bank() & 0xff00 ) | ( ( ( portLONG ) ( pxCode ) >> 16 ) & 0xff );\r
\r
static void prvSetupRLT0Interrupt( void )\r
{\r
+/* The peripheral clock divided by 16 is used by the timer. */\r
+const unsigned portSHORT usReloadValue = ( unsigned portSHORT ) ( ( ( configCLKP1_CLOCK_HZ / configTICK_RATE_HZ ) / 16UL ) - 1UL );\r
+\r
/* set reload value = 34999+1, TICK Interrupt after 10 ms @ 56MHz of CLKP1 */\r
- TMRLR0 = 0x88B7; \r
+ TMRLR0 = usReloadValue; \r
\r
/* prescaler 1:16, reload, interrupt enable, count enable, trigger */\r
TMCSR0 = 0x041B; \r
portRESTORE_CONTEXT();\r
\r
/* Simulate a function call end as generated by the compiler. We will now\r
- jump to the start of the task the context of which we have just restored. */\r
- \r
+ jump to the start of the task the context of which we have just restored. */ \r
__asm(" reti ");\r
\r
\r
\r
/* \r
* Tick ISR for preemptive scheduler. We can use a __nosavereg attribute\r
- * as the context would be saved by PortSAVE_CONTEXT(). The tick count \r
- * is incremented after the context is saved. \r
+ * as the context is to be saved by the portSAVE_CONTEXT() macro, not the\r
+ * compiler generated code. The tick count is incremented after the context \r
+ * is saved. \r
*/\r
__nosavereg __interrupt void prvRLT0_TICKISR( void )\r
{\r
\r
/*\r
* Manual context switch. We can use a __nosavereg attribute as the context \r
- * would be saved by PortSAVE_CONTEXT(). The context is switched and then \r
- * the context of the new task is restored saved. \r
+ * is to be saved by the portSAVE_CONTEXT() macro, not the compiler generated \r
+ * code.\r
*/\r
__nosavereg __interrupt void vPortYield( void )\r
{\r
#ifndef PORTMACRO_H\r
#define PORTMACRO_H\r
\r
+/* Device specific includes. */\r
#include "mb96348hs.h"\r
+\r
+/* Standard includes. */\r
#include <stddef.h>\r
\r
+/* Constants denoting the available memory models. These are used within\r
+FreeRTOSConfig.h to set the configMEMMODEL value. */\r
#define portSMALL 0\r
#define portMEDIUM 1\r
#define portCOMPACT 2\r