OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [portable/] [Renesas/] [RX600/] [port.c] - Blame information for rev 595

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 572 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
/*-----------------------------------------------------------
55
 * Implementation of functions defined in portable.h for the SH2A port.
56
 *----------------------------------------------------------*/
57
 
58
/* Scheduler includes. */
59
#include "FreeRTOS.h"
60
#include "task.h"
61
 
62
/* Library includes. */
63
#include "string.h"
64
 
65
/* Hardware specifics. */
66
#include "iodefine.h"
67
 
68
/*-----------------------------------------------------------*/
69
 
70
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
71
PSW is set with U and I set, and PM and IPL clear. */
72
#define portINITIAL_PSW     ( ( portSTACK_TYPE ) 0x00030000 )
73
#define portINITIAL_FPSW    ( ( portSTACK_TYPE ) 0x00000100 )
74
 
75
/*-----------------------------------------------------------*/
76
 
77
/*
78
 * Function to start the first task executing - written in asm code as direct
79
 * access to registers is required.
80
 */
81
static void prvStartFirstTask( void );
82
 
83
/*
84
 * Software interrupt handler.  Performs the actual context switch (saving and
85
 * restoring of registers).  Written in asm code as direct register access is
86
 * required.
87
 */
88
static void prvYieldHandler( void );
89
 
90
/*
91
 * The entry point for the software interrupt handler.  This is the function
92
 * that calls the inline asm function prvYieldHandler().  It is installed in
93
 * the vector table, but the code that installs it is in prvYieldHandler rather
94
 * than using a #pragma.
95
 */
96
void vSoftwareInterruptISR( void );
97
 
98
/*-----------------------------------------------------------*/
99
 
100
/* This is accessed by the inline assembler functions so is file scope for
101
convenience. */
102
extern void *pxCurrentTCB;
103
extern void vTaskSwitchContext( void );
104
 
105
/*-----------------------------------------------------------*/
106
 
107
/*
108
 * See header file for description.
109
 */
110
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
111
{
112
        /* R0 is not included as it is the stack pointer. */
113
 
114
        *pxTopOfStack = 0xdeadbeef;
115
        pxTopOfStack--;
116
        *pxTopOfStack = portINITIAL_PSW;
117
        pxTopOfStack--;
118
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;
119
 
120
        /* When debugging it can be useful if every register is set to a known
121
        value.  Otherwise code space can be saved by just setting the registers
122
        that need to be set. */
123
        #ifdef USE_FULL_REGISTER_INITIALISATION
124
        {
125
                pxTopOfStack--;
126
                *pxTopOfStack = 0xffffffff;     /* r15. */
127
                pxTopOfStack--;
128
                *pxTopOfStack = 0xeeeeeeee;
129
                pxTopOfStack--;
130
                *pxTopOfStack = 0xdddddddd;
131
                pxTopOfStack--;
132
                *pxTopOfStack = 0xcccccccc;
133
                pxTopOfStack--;
134
                *pxTopOfStack = 0xbbbbbbbb;
135
                pxTopOfStack--;
136
                *pxTopOfStack = 0xaaaaaaaa;
137
                pxTopOfStack--;
138
                *pxTopOfStack = 0x99999999;
139
                pxTopOfStack--;
140
                *pxTopOfStack = 0x88888888;
141
                pxTopOfStack--;
142
                *pxTopOfStack = 0x77777777;
143
                pxTopOfStack--;
144
                *pxTopOfStack = 0x66666666;
145
                pxTopOfStack--;
146
                *pxTopOfStack = 0x55555555;
147
                pxTopOfStack--;
148
                *pxTopOfStack = 0x44444444;
149
                pxTopOfStack--;
150
                *pxTopOfStack = 0x33333333;
151
                pxTopOfStack--;
152
                *pxTopOfStack = 0x22222222;
153
                pxTopOfStack--;
154
        }
155
        #else
156
        {
157
                pxTopOfStack -= 15;
158
        }
159
        #endif
160
 
161
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R1 */
162
        pxTopOfStack--;
163
        *pxTopOfStack = portINITIAL_FPSW;
164
        pxTopOfStack--;
165
        *pxTopOfStack = 0x12345678; /* Accumulator. */
166
        pxTopOfStack--;
167
        *pxTopOfStack = 0x87654321; /* Accumulator. */
168
 
169
        return pxTopOfStack;
170
}
171
/*-----------------------------------------------------------*/
172
 
173
portBASE_TYPE xPortStartScheduler( void )
174
{
175
extern void vApplicationSetupTimerInterrupt( void );
176
 
177
        /* Use pxCurrentTCB just so it does not get optimised away. */
178
        if( pxCurrentTCB != NULL )
179
        {
180
                /* Call an application function to set up the timer that will generate the
181
                tick interrupt.  This way the application can decide which peripheral to
182
                use.  A demo application is provided to show a suitable example. */
183
                vApplicationSetupTimerInterrupt();
184
 
185
                /* Enable the software interrupt. */
186
                _IEN( _ICU_SWINT ) = 1;
187
 
188
                /* Ensure the software interrupt is clear. */
189
                _IR( _ICU_SWINT ) = 0;
190
 
191
                /* Ensure the software interrupt is set to the kernel priority. */
192
                _IPR( _ICU_SWINT ) = configKERNEL_INTERRUPT_PRIORITY;
193
 
194
                /* Start the first task. */
195
                prvStartFirstTask();
196
        }
197
 
198
        /* Just to make sure the function is not optimised away. */
199
        ( void ) vSoftwareInterruptISR();
200
 
201
        /* Should not get here. */
202
        return pdFAIL;
203
}
204
/*-----------------------------------------------------------*/
205
 
206
#pragma inline_asm prvStartFirstTask
207
static void prvStartFirstTask( void )
208
{
209
        /* When starting the scheduler there is nothing that needs moving to the
210
        interrupt stack because the function is not called from an interrupt.
211
        Just ensure the current stack is the user stack. */
212
        SETPSW  U
213
 
214
        /* Obtain the location of the stack associated with which ever task
215
        pxCurrentTCB is currently pointing to. */
216
        MOV.L   #_pxCurrentTCB, R15
217
        MOV.L   [R15], R15
218
        MOV.L   [R15], R0
219
 
220
        /* Restore the registers from the stack of the task pointed to by
221
        pxCurrentTCB. */
222
    POP         R15
223
    MVTACLO     R15             /* Accumulator low 32 bits. */
224
    POP         R15
225
    MVTACHI     R15             /* Accumulator high 32 bits. */
226
    POP         R15
227
    MVTC        R15,FPSW        /* Floating point status word. */
228
    POPM        R1-R15          /* R1 to R15 - R0 is not included as it is the SP. */
229
    RTE                                 /* This pops the remaining registers. */
230
    NOP
231
    NOP
232
}
233
/*-----------------------------------------------------------*/
234
 
235
#pragma interrupt ( vTickISR( vect = _VECT( configTICK_VECTOR ), enable ) )
236
void vTickISR( void )
237
{
238
        /* Increment the tick, and perform any processing the new tick value
239
        necessitates. */
240
        set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
241
        {
242
                vTaskIncrementTick();
243
        }
244
        set_ipl( configKERNEL_INTERRUPT_PRIORITY );
245
 
246
        /* Only select a new task if the preemptive scheduler is being used. */
247
        #if( configUSE_PREEMPTION == 1 )
248
                taskYIELD();
249
        #endif
250
}
251
/*-----------------------------------------------------------*/
252
 
253
void vSoftwareInterruptISR( void )
254
{
255
        prvYieldHandler();
256
}
257
/*-----------------------------------------------------------*/
258
 
259
#pragma inline_asm prvYieldHandler
260
static void prvYieldHandler( void )
261
{
262
        /* Install as the software interrupt handler. */
263
        .RVECTOR    _VECT( _ICU_SWINT ), _vSoftwareInterruptISR
264
 
265
        /* Re-enable interrupts. */
266
        SETPSW  I
267
 
268
        /* Move the data that was automatically pushed onto the interrupt stack when
269
        the interrupt occurred from the interrupt stack to the user stack.
270
 
271
        R15 is saved before it is clobbered. */
272
        PUSH.L  R15
273
 
274
        /* Read the user stack pointer. */
275
        MVFC    USP, R15
276
 
277
        /* Move the address down to the data being moved. */
278
        SUB             #12, R15
279
        MVTC    R15, USP
280
 
281
        /* Copy the data across. */
282
        MOV.L   [ R0 ], [ R15 ] ; R15
283
        MOV.L   4[ R0 ], 4[ R15 ]  ; PC
284
        MOV.L   8[ R0 ], 8[ R15 ]  ; PSW
285
 
286
        /* Move the interrupt stack pointer to its new correct position. */
287
        ADD     #12, R0
288
 
289
        /* All the rest of the registers are saved directly to the user stack. */
290
        SETPSW  U
291
 
292
        /* Save the rest of the general registers (R15 has been saved already). */
293
        PUSHM   R1-R14
294
 
295
        /* Save the FPSW and accumulator. */
296
        MVFC    FPSW, R15
297
        PUSH.L  R15
298
        MVFACHI R15
299
        PUSH.L  R15
300
        MVFACMI R15     ; Middle order word.
301
        SHLL    #16, R15 ; Shifted left as it is restored to the low order word.
302
        PUSH.L  R15
303
 
304
        /* Save the stack pointer to the TCB. */
305
        MOV.L   #_pxCurrentTCB, R15
306
        MOV.L   [ R15 ], R15
307
        MOV.L   R0, [ R15 ]
308
 
309
        /* Ensure the interrupt mask is set to the syscall priority while the kernel
310
        structures are being accessed. */
311
        MVTIPL  #configMAX_SYSCALL_INTERRUPT_PRIORITY
312
 
313
        /* Select the next task to run. */
314
        BSR.A   _vTaskSwitchContext
315
 
316
        /* Reset the interrupt mask as no more data structure access is required. */
317
        MVTIPL  #configKERNEL_INTERRUPT_PRIORITY
318
 
319
        /* Load the stack pointer of the task that is now selected as the Running
320
        state task from its TCB. */
321
        MOV.L   #_pxCurrentTCB,R15
322
        MOV.L   [ R15 ], R15
323
        MOV.L   [ R15 ], R0
324
 
325
        /* Restore the context of the new task.  The PSW (Program Status Word) and
326
        PC will be popped by the RTE instruction. */
327
        POP             R15
328
        MVTACLO R15
329
        POP             R15
330
        MVTACHI R15
331
        POP             R15
332
        MVTC    R15,FPSW
333
        POPM    R1-R15
334
        RTE
335
        NOP
336
        NOP
337
}
338
/*-----------------------------------------------------------*/
339
 
340
void vPortEndScheduler( void )
341
{
342
        /* Not implemented as there is nothing to return to. */
343
 
344
        /* The following line is just to prevent the symbol getting optimised away. */
345
        ( void ) vTaskSwitchContext();
346
}
347
/*-----------------------------------------------------------*/
348
 
349
 
350
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.