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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [portable/] [WizC/] [PIC18/] [port.c] - Blame information for rev 583

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
Changes from V3.2.1
56
        + CallReturn Depth increased from 8 to 10 levels to accomodate wizC/fedC V12.
57
 
58
Changes from V3.2.0
59
        + TBLPTRU is now initialised to zero during the initial stack creation of a new task. This solves
60
        an error on devices with more than 64kB ROM.
61
 
62
Changes from V3.0.0
63
        + ucCriticalNesting is now initialised to 0x7F to prevent interrupts from being
64
          handled before the scheduler is started.
65
 
66
Changes from V3.0.1
67
*/
68
 
69
/* Scheduler include files. */
70
#include <FreeRTOS.h>
71
#include <task.h>
72
 
73
#include <malloc.h>
74
 
75
/*---------------------------------------------------------------------------
76
 * Implementation of functions defined in portable.h for the WizC PIC18 port.
77
 *---------------------------------------------------------------------------*/
78
 
79
/*
80
 * We require the address of the pxCurrentTCB variable, but don't want to
81
 * know any details of its type.
82
 */
83
typedef void tskTCB;
84
extern volatile tskTCB * volatile pxCurrentTCB;
85
 
86
/*
87
 * Define minimal-stack constants
88
 * -----
89
 * FSR's:
90
 *              STATUS, WREG, BSR, PRODH, PRODL, FSR0H, FSR0L,
91
 *              FSR1H, FSR1L,TABLAT, (TBLPTRU), TBLPTRH, TBLPTRL,
92
 *              (PCLATU), PCLATH
93
 *              sfr's within parenthesis only on devices > 64kB
94
 * -----
95
 * Call/Return stack:
96
 *               2 bytes per entry on devices <= 64kB
97
 *               3 bytes per entry on devices >  64kB
98
 * -----
99
 * Other bytes:
100
 *               2 bytes: FunctionParameter for initial taskcode
101
 *               1 byte : Number of entries on call/return stack
102
 *               1 byte : ucCriticalNesting
103
 *              16 bytes: Free space on stack
104
 */
105
#if _ROMSIZE > 0x8000
106
        #define portSTACK_FSR_BYTES                             ( 15 )
107
        #define portSTACK_CALLRETURN_ENTRY_SIZE (  3 )
108
#else
109
        #define portSTACK_FSR_BYTES                             ( 13 )
110
        #define portSTACK_CALLRETURN_ENTRY_SIZE (  2 )
111
#endif
112
 
113
#define portSTACK_MINIMAL_CALLRETURN_DEPTH      ( 10 )
114
#define portSTACK_OTHER_BYTES                           ( 20 )
115
 
116
unsigned short usCalcMinStackSize               = 0;
117
 
118
/*-----------------------------------------------------------*/
119
 
120
/*
121
 * We initialise ucCriticalNesting to the middle value an
122
 * unsigned char can contain. This way portENTER_CRITICAL()
123
 * and portEXIT_CRITICAL() can be called without interrupts
124
 * being enabled before the scheduler starts.
125
 */
126
register unsigned char ucCriticalNesting = 0x7F;
127
 
128
/*-----------------------------------------------------------*/
129
 
130
/*
131
 * Initialise the stack of a new task.
132
 * See portSAVE_CONTEXT macro for description.
133
 */
134
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
135
{
136
unsigned char ucScratch;
137
        /*
138
         * Get the size of the RAMarea in page 0 used by the compiler
139
         * We do this here already to avoid W-register conflicts.
140
         */
141
        _Pragma("asm")
142
                movlw   OVERHEADPAGE0-LOCOPTSIZE+MAXLOCOPTSIZE
143
                movwf   PRODL,ACCESS            ; PRODL is used as temp register
144
        _Pragma("asmend")
145
        ucScratch = PRODL;
146
 
147
        /*
148
         * Place a few bytes of known values on the bottom of the stack.
149
         * This is just useful for debugging.
150
         */
151
//      *pxTopOfStack-- = 0x11;
152
//      *pxTopOfStack-- = 0x22;
153
//      *pxTopOfStack-- = 0x33;
154
 
155
        /*
156
         * Simulate how the stack would look after a call to vPortYield()
157
         * generated by the compiler.
158
         */
159
 
160
        /*
161
         * First store the function parameters.  This is where the task expects
162
         * to find them when it starts running.
163
         */
164
        *pxTopOfStack-- = ( portSTACK_TYPE ) ( (( unsigned short ) pvParameters >> 8) & 0x00ff );
165
        *pxTopOfStack-- = ( portSTACK_TYPE ) (  ( unsigned short ) pvParameters       & 0x00ff );
166
 
167
        /*
168
         * Next are all the registers that form part of the task context.
169
         */
170
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x11; /* STATUS. */
171
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x22; /* WREG. */
172
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x33; /* BSR. */
173
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x44; /* PRODH. */
174
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x55; /* PRODL. */
175
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x66; /* FSR0H. */
176
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x77; /* FSR0L. */
177
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x88; /* FSR1H. */
178
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x99; /* FSR1L. */
179
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0xAA; /* TABLAT. */
180
#if _ROMSIZE > 0x8000
181
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0x00; /* TBLPTRU. */
182
#endif
183
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0xCC; /* TBLPTRH. */
184
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0xDD; /* TBLPTRL. */
185
#if _ROMSIZE > 0x8000
186
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0xEE; /* PCLATU. */
187
#endif
188
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF; /* PCLATH. */
189
 
190
        /*
191
         * Next the compiler's scratchspace.
192
         */
193
        while(ucScratch-- > 0)
194
        {
195
                *pxTopOfStack-- = ( portSTACK_TYPE ) 0;
196
        }
197
 
198
        /*
199
         * The only function return address so far is the address of the task entry.
200
         * The order is TOSU/TOSH/TOSL. For devices > 64kB, TOSU is put on the
201
         * stack, too. TOSU is always written as zero here because wizC does not allow
202
         * functionpointers to point above 64kB in ROM.
203
         */
204
#if _ROMSIZE > 0x8000
205
        *pxTopOfStack-- = ( portSTACK_TYPE ) 0;
206
#endif
207
        *pxTopOfStack-- = ( portSTACK_TYPE ) ( ( ( unsigned short ) pxCode >> 8 ) & 0x00ff );
208
        *pxTopOfStack-- = ( portSTACK_TYPE ) ( (   unsigned short ) pxCode        & 0x00ff );
209
 
210
        /*
211
         * Store the number of return addresses on the hardware stack.
212
         * So far only the address of the task entry point.
213
         */
214
        *pxTopOfStack-- = ( portSTACK_TYPE ) 1;
215
 
216
        /*
217
         * The code generated by wizC does not maintain separate
218
         * stack and frame pointers. Therefore the portENTER_CRITICAL macro cannot
219
         * use the stack as per other ports.  Instead a variable is used to keep
220
         * track of the critical section nesting.  This variable has to be stored
221
         * as part of the task context and is initially set to zero.
222
         */
223
        *pxTopOfStack-- = ( portSTACK_TYPE ) portNO_CRITICAL_SECTION_NESTING;
224
 
225
        return pxTopOfStack;
226
}
227
/*-----------------------------------------------------------*/
228
 
229
unsigned short usPortCALCULATE_MINIMAL_STACK_SIZE( void )
230
{
231
        /*
232
         * Fetch the size of compiler's scratchspace.
233
         */
234
        _Pragma("asm")
235
                movlw   OVERHEADPAGE0-LOCOPTSIZE+MAXLOCOPTSIZE
236
                movlb   usCalcMinStackSize>>8
237
                movwf   usCalcMinStackSize,BANKED
238
        _Pragma("asmend")
239
 
240
        /*
241
         * Add minimum needed stackspace
242
         */
243
        usCalcMinStackSize      +=      ( portSTACK_FSR_BYTES )
244
                +       ( portSTACK_MINIMAL_CALLRETURN_DEPTH * portSTACK_CALLRETURN_ENTRY_SIZE )
245
                +       ( portSTACK_OTHER_BYTES );
246
 
247
        return(usCalcMinStackSize);
248
}
249
 
250
/*-----------------------------------------------------------*/
251
 
252
portBASE_TYPE xPortStartScheduler( void )
253
{
254
        extern void portSetupTick( void );
255
 
256
        /*
257
         * Setup a timer for the tick ISR for the preemptive scheduler.
258
         */
259
        portSetupTick();
260
 
261
        /*
262
         * Restore the context of the first task to run.
263
         */
264
        portRESTORE_CONTEXT();
265
 
266
        /*
267
         * This point should never be reached during execution.
268
         */
269
        return pdTRUE;
270
}
271
 
272
/*-----------------------------------------------------------*/
273
 
274
void vPortEndScheduler( void )
275
{
276
        /*
277
         * It is unlikely that the scheduler for the PIC port will get stopped
278
         * once running. When called a reset is done which is probably the
279
         * most valid action.
280
         */
281
        _Pragma(asmline reset);
282
}
283
 
284
/*-----------------------------------------------------------*/
285
 
286
/*
287
 * Manual context switch.  This is similar to the tick context switch,
288
 * but does not increment the tick count.  It must be identical to the
289
 * tick context switch in how it stores the stack of a task.
290
 */
291
void vPortYield( void )
292
{
293
        /*
294
         * Save the context of the current task.
295
         */
296
        portSAVE_CONTEXT( portINTERRUPTS_UNCHANGED );
297
 
298
        /*
299
         * Switch to the highest priority task that is ready to run.
300
         */
301
        vTaskSwitchContext();
302
 
303
        /*
304
         * Start executing the task we have just switched to.
305
         */
306
        portRESTORE_CONTEXT();
307
}
308
 
309
/*-----------------------------------------------------------*/
310
 
311
void *pvPortMalloc( unsigned short usWantedSize )
312
{
313
void *pvReturn;
314
 
315
        vTaskSuspendAll();
316
        {
317
                pvReturn = malloc( ( malloc_t ) usWantedSize );
318
        }
319
        xTaskResumeAll();
320
 
321
        return pvReturn;
322
}
323
 
324
void vPortFree( void *pv )
325
{
326
        if( pv )
327
        {
328
                vTaskSuspendAll();
329
                {
330
                        free( pv );
331
                }
332
                xTaskResumeAll();
333
        }
334
}

powered by: WebSVN 2.1.0

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