to reach zero, so it is initialised to a high value. */\r
#define portINITIAL_NESTING_VALUE ( 0xff )\r
\r
to reach zero, so it is initialised to a high value. */\r
#define portINITIAL_NESTING_VALUE ( 0xff )\r
\r
-/* Our hardware setup only uses one counter. */\r
-#define portCOUNTER_0 0\r
-\r
-/* The stack used by the ISR is filled with a known value to assist in\r
-debugging. */\r
-#define portISR_STACK_FILL_VALUE 0x55555555\r
-\r
/*-----------------------------------------------------------*/\r
\r
/*\r
/*-----------------------------------------------------------*/\r
\r
/*\r
\r
portBASE_TYPE xPortStartScheduler( void )\r
{\r
\r
portBASE_TYPE xPortStartScheduler( void )\r
{\r
-extern void ( vStartFirstTask )( void );\r
+extern void ( vPortStartFirstTask )( void );\r
+extern unsigned long *_stack;\r
\r
/* Setup the hardware to generate the tick. Interrupts are disabled when\r
this function is called. */\r
vApplicationSetupTimerInterrupt();\r
\r
/* Allocate the stack to be used by the interrupt handler. */\r
\r
/* Setup the hardware to generate the tick. Interrupts are disabled when\r
this function is called. */\r
vApplicationSetupTimerInterrupt();\r
\r
/* Allocate the stack to be used by the interrupt handler. */\r
- pulISRStack = ( unsigned long * ) pvPortMalloc( configINTERRUPT_STACK_SIZE * sizeof( portSTACK_TYPE ) );\r
- configASSERT( pulISRStack != NULL );\r
+ pulISRStack = _stack;\r
- /* Restore the context of the first task that is going to run. */\r
- if( pulISRStack != NULL )\r
- {\r
- /* Fill the ISR stack with a known value to facilitate debugging. */\r
- memset( pulISRStack, portISR_STACK_FILL_VALUE, configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ) );\r
- pulISRStack += ( configMINIMAL_STACK_SIZE - 1 );\r
-\r
- /* From here on, the created tasks will be executing. */\r
- vStartFirstTask();\r
- }\r
+ /* Restore the context of the first task that is going to run. From here\r
+ on, the created tasks will be executing. */\r
+ vPortStartFirstTask();\r
\r
/* Should not get here as the tasks are now running! */\r
return pdFALSE;\r
\r
/* Should not get here as the tasks are now running! */\r
return pdFALSE;\r
.extern uxCriticalNesting\r
.extern pulISRStack\r
\r
.extern uxCriticalNesting\r
.extern pulISRStack\r
\r
-/* .global vPortFreeRTOSInterruptHandler */\r
.global _interrupt_handler\r
.global VPortYieldASM\r
.global _interrupt_handler\r
.global VPortYieldASM\r
- .global vStartFirstTask\r
+ .global vPortStartFirstTask\r
\r
\r
.macro portSAVE_CONTEXT\r
\r
\r
.macro portSAVE_CONTEXT\r
/* Make room for the context on the stack. */\r
addik r1, r1, -132\r
/* Make room for the context on the stack. */\r
addik r1, r1, -132\r
- /* Save r31 so it can then be used. */\r
+\r
+ /* Save r31 so it can then be used as a temporary. */\r
/* Copy the msr into r31 - this is stacked later. */\r
mfs r31, rmsr\r
/* Copy the msr into r31 - this is stacked later. */\r
mfs r31, rmsr\r
/* Stack general registers. */\r
swi r30, r1, 12\r
swi r29, r1, 16\r
/* Stack general registers. */\r
swi r30, r1, 12\r
swi r29, r1, 16\r
swi r4, r1, 116\r
swi r3, r1, 120\r
swi r2, r1, 124\r
swi r4, r1, 116\r
swi r3, r1, 120\r
swi r2, r1, 124\r
/* Stack the critical section nesting value. */\r
lwi r3, r0, uxCriticalNesting\r
swi r3, r1, 128\r
/* Stack the critical section nesting value. */\r
lwi r3, r0, uxCriticalNesting\r
swi r3, r1, 128\r
/* Save the top of stack value to the TCB. */\r
lwi r3, r0, pxCurrentTCB\r
sw r1, r0, r3\r
/* Save the top of stack value to the TCB. */\r
lwi r3, r0, pxCurrentTCB\r
sw r1, r0, r3\r
.endm\r
\r
.macro portRESTORE_CONTEXT\r
.endm\r
\r
.macro portRESTORE_CONTEXT\r
/* Load the top of stack value from the TCB. */\r
lwi r3, r0, pxCurrentTCB\r
lw r1, r0, r3 \r
/* Load the top of stack value from the TCB. */\r
lwi r3, r0, pxCurrentTCB\r
lw r1, r0, r3 \r
/* Restore the general registers. */\r
lwi r31, r1, 4 \r
lwi r30, r1, 12 \r
/* Restore the general registers. */\r
lwi r31, r1, 4 \r
lwi r30, r1, 12 \r
lwi r4, r1, 116\r
lwi r2, r1, 124\r
\r
lwi r4, r1, 116\r
lwi r2, r1, 124\r
\r
+ /* Reload the rmsr from the stack. */\r
+ lwi r3, r1, 8\r
+ mts rmsr, r3\r
+\r
/* Load the critical nesting value. */\r
lwi r3, r1, 128\r
swi r3, r0, uxCriticalNesting\r
\r
/* Load the critical nesting value. */\r
lwi r3, r1, 128\r
swi r3, r0, uxCriticalNesting\r
\r
- /* Obtain the MSR value from the stack. */\r
- lwi r3, r1, 8\r
+ /* Test the critical nesting value. If it is non zero then the task last\r
+ exited the running state using a yield. If it is zero, then the task\r
+ last exited the running state through an interrupt. */\r
+ xori r3, r3, 0\r
+ bnei r3, exit_from_yield\r
- /* Are interrupts enabled in the MSR? If so return using an return from \r
- interrupt instruction to ensure interrupts are enabled only once the task\r
- is running again. */\r
- andi r3, r3, 2\r
- beqid r3, 36\r
- or r0, r0, r0\r
-\r
- /* Reload the rmsr from the stack, clear the enable interrupt bit in the\r
- value before saving back to rmsr register, then return enabling interrupts\r
- as we return. */\r
- lwi r3, r1, 8\r
- andi r3, r3, ~2\r
- mts rmsr, r3\r
+ /* r3 was being used as a temporary. Now restore its true value from the\r
+ stack. */\r
- addik r1, r1, 132\r
- rtid r14, 0\r
- or r0, r0, r0\r
- /* Reload the rmsr from the stack, place it in the rmsr register, and\r
- return without enabling interrupts. */\r
- lwi r3, r1, 8\r
- mts rmsr, r3\r
- lwi r3, r1, 120\r
+ /* Remove the stack frame. */\r
+\r
+ /* Return using rtid so interrupts are re-enabled as this function is\r
+ exited. */\r
+ rtid r14, 0\r
or r0, r0, r0\r
\r
.endm\r
or r0, r0, r0\r
\r
.endm\r
+/* This function is used to exit portRESTORE_CONTEXT() if the task being\r
+returned to last left the Running state by calling taskYIELD() (rather than\r
+being preempted by an interrupt. */\r
+exit_from_yield:\r
+\r
+ /* r3 was being used as a temporary. Now restore its true value from the\r
+ stack. */\r
+ lwi r3, r1, 120\r
+\r
+ /* Remove the stack frame. */\r
+ addik r1, r1, 132\r
+\r
+ /* Return to the task. */\r
+ rtsd r14, 0\r
+ or r0, r0, r0\r
+\r
-/*vPortFreeRTOSInterruptHandler:*/\r
- /* Entered via an interrupt so interrupts must be enabled in msr. */\r
- ori r31, r31, 2\r
/* Stack msr. */\r
swi r31, r1, 8\r
/* Stack msr. */\r
swi r31, r1, 8\r
- /* Stack the return address. As we entered via an interrupt we do\r
- not need to modify the return address prior to stacking. */\r
+\r
+ /* Stack the return address. */\r
- /* Now switch to use the ISR stack. */\r
- lwi r3, r0, pulISRStack\r
- add r1, r3, r0\r
+\r
+ /* Switch to the ISR stack. */\r
+ lwi r1, r0, pulISRStack\r
+\r
+ /* Execute any pending interrupts. */\r
bralid r15, XIntc_DeviceInterruptHandler\r
or r0, r0, r0\r
bralid r15, XIntc_DeviceInterruptHandler\r
or r0, r0, r0\r
+\r
+ /* Restore the context of the next task scheduled to execute. */\r
portRESTORE_CONTEXT\r
\r
\r
VPortYieldASM:\r
portRESTORE_CONTEXT\r
\r
\r
VPortYieldASM:\r
/* Stack msr. */\r
swi r31, r1, 8\r
/* Stack msr. */\r
swi r31, r1, 8\r
- /* Modify the return address so we return to the instruction after the\r
- exception. */\r
+\r
+ /* Modify the return address so a return is done to the instruction after\r
+ the call to VPortYieldASM. */\r
addi r14, r14, 8\r
swi r14, r1, 76\r
addi r14, r14, 8\r
swi r14, r1, 76\r
- /* Now switch to use the ISR stack. */\r
- lwi r3, r0, pulISRStack\r
- add r1, r3, r0\r
+\r
+ /* Switch to use the ISR stack. */\r
+ lwi r1, r0, pulISRStack\r
+\r
+ /* Select the next task to execute. */\r
bralid r15, vTaskSwitchContext\r
or r0, r0, r0\r
bralid r15, vTaskSwitchContext\r
or r0, r0, r0\r
+\r
+ /* Restore the context of the next task scheduled to execute. */\r
+vPortStartFirstTask:\r
+\r
portRESTORE_CONTEXT\r
\r
\r
portRESTORE_CONTEXT\r
\r
\r
{\r
portBASE_TYPE xStatus;\r
const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U;\r
{\r
portBASE_TYPE xStatus;\r
const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U;\r
-const unsigned long ulCounterValue = ( ( XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ / configTICK_RATE_HZ ) - 1UL );\r
+//const unsigned long ulCounterValue = ( ( XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ / configTICK_RATE_HZ ) - 1UL );\r
+const unsigned long ulCounterValue = ( ( ( XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ / configTICK_RATE_HZ ) - 1UL ) ) * 2UL; //_RB_ there is a clock set up incorrectly somwehre, the *2 should not be required. */\r
extern void vTickISR( void *pvUnused );\r
\r
/* Initialise the timer/counter. */\r
extern void vTickISR( void *pvUnused );\r
\r
/* Initialise the timer/counter. */\r
ulCSR = XTmrCtr_GetControlStatusReg( XPAR_AXI_TIMER_0_BASEADDR, 0 );\r
XTmrCtr_SetControlStatusReg( XPAR_AXI_TIMER_0_BASEADDR, 0, ulCSR );\r
}\r
ulCSR = XTmrCtr_GetControlStatusReg( XPAR_AXI_TIMER_0_BASEADDR, 0 );\r
XTmrCtr_SetControlStatusReg( XPAR_AXI_TIMER_0_BASEADDR, 0, ulCSR );\r
}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vAssertCalled( char *pcFile, long lLine )\r
+{\r
+volatile unsigned long ul = 1;\r
+ taskDISABLE_INTERRUPTS();\r
+ while( ul == 1 )\r
+ {\r
+ /* Just for somewhere to put a breakpoint. */\r
+ portNOP();\r
+ }\r
+ taskENABLE_INTERRUPTS();\r
+}\r
}\r
/*-----------------------------------------------------------*/\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-extern void vAssertCalled( char *pcFile, long lLine )\r
+void vAssertCalled( char *pcFile, long lLine )\r
{\r
volatile unsigned long ul = 1;\r
\r
{\r
volatile unsigned long ul = 1;\r
\r