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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [portable/] [BCC/] [16BitDOS/] [Flsh186/] [port.c] - Blame information for rev 590

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 V1.00:
56
 
57
        + Call to taskYIELD() from within tick ISR has been replaced by the more
58
          efficient portSWITCH_CONTEXT().
59
        + ISR function definitions renamed to include the prv prefix.
60
 
61
Changes from V2.6.1
62
 
63
        + Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
64
          macro to be consistent with the later ports.
65
*/
66
 
67
/*-----------------------------------------------------------
68
 * Implementation of functions defined in portable.h for the Flashlite 186
69
 * port.
70
 *----------------------------------------------------------*/
71
 
72
#include <dos.h>
73
#include <stdlib.h>
74
#include <setjmp.h>
75
 
76
#include "FreeRTOS.h"
77
#include "task.h"
78
#include "portasm.h"
79
 
80
/*lint -e950 Non ANSI reserved words okay in this file only. */
81
 
82
#define portTIMER_EOI_TYPE              ( 8 )
83
#define portRESET_PIC()                 portOUTPUT_WORD( ( unsigned short ) 0xff22, portTIMER_EOI_TYPE )
84
#define portTIMER_INT_NUMBER    0x12
85
 
86
#define portTIMER_1_CONTROL_REGISTER    ( ( unsigned short ) 0xff5e )
87
#define portTIMER_0_CONTROL_REGISTER    ( ( unsigned short ) 0xff56 )
88
#define portTIMER_INTERRUPT_ENABLE              ( ( unsigned short ) 0x2000 )
89
 
90
/* Setup the hardware to generate the required tick frequency. */
91
static void prvSetTickFrequency( unsigned long ulTickRateHz );
92
 
93
/* Set the hardware back to the state as per before the scheduler started. */
94
static void prvExitFunction( void );
95
 
96
/* The ISR used depends on whether the preemptive or cooperative scheduler
97
is being used. */
98
#if( configUSE_PREEMPTION == 1 )
99
        /* Tick service routine used by the scheduler when preemptive scheduling is
100
        being used. */
101
        static void __interrupt __far prvPreemptiveTick( void );
102
#else
103
        /* Tick service routine used by the scheduler when cooperative scheduling is
104
        being used. */
105
        static void __interrupt __far prvNonPreemptiveTick( void );
106
#endif
107
 
108
/* Trap routine used by taskYIELD() to manually cause a context switch. */
109
static void __interrupt __far prvYieldProcessor( void );
110
 
111
/*lint -e956 File scopes necessary here. */
112
 
113
/* Set true when the vectors are set so the scheduler will service the tick. */
114
static portBASE_TYPE xSchedulerRunning = pdFALSE;
115
 
116
/* Points to the original routine installed on the vector we use for manual
117
context switches.  This is then used to restore the original routine during
118
prvExitFunction(). */
119
static void ( __interrupt __far *pxOldSwitchISR )();
120
 
121
/* Used to restore the original DOS context when the scheduler is ended. */
122
static jmp_buf xJumpBuf;
123
 
124
/*lint +e956 */
125
 
126
/*-----------------------------------------------------------*/
127
portBASE_TYPE xPortStartScheduler( void )
128
{
129
        /* This is called with interrupts already disabled. */
130
 
131
        /* Remember what was on the interrupts we are going to use
132
        so we can put them back later if required. */
133
        pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
134
 
135
        /* Put our manual switch (yield) function on a known
136
        vector. */
137
        _dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
138
 
139
        #if( configUSE_PREEMPTION == 1 )
140
        {
141
                /* Put our tick switch function on the timer interrupt. */
142
                _dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
143
        }
144
        #else
145
        {
146
                /* We want the timer interrupt to just increment the tick count. */
147
                _dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
148
        }
149
        #endif
150
 
151
        prvSetTickFrequency( configTICK_RATE_HZ );
152
 
153
        /* Clean up function if we want to return to DOS. */
154
        if( setjmp( xJumpBuf ) != 0 )
155
        {
156
                prvExitFunction();
157
                xSchedulerRunning = pdFALSE;
158
        }
159
        else
160
        {
161
                xSchedulerRunning = pdTRUE;
162
 
163
                /* Kick off the scheduler by setting up the context of the first task. */
164
                portFIRST_CONTEXT();
165
        }
166
 
167
        return xSchedulerRunning;
168
}
169
/*-----------------------------------------------------------*/
170
 
171
/* The ISR used depends on whether the preemptive or cooperative scheduler
172
is being used. */
173
#if( configUSE_PREEMPTION == 1 )
174
        static void __interrupt __far prvPreemptiveTick( void )
175
        {
176
                /* Get the scheduler to update the task states following the tick. */
177
                vTaskIncrementTick();
178
 
179
                /* Switch in the context of the next task to be run. */
180
                portSWITCH_CONTEXT();
181
 
182
                /* Reset the PIC ready for the next time. */
183
                portRESET_PIC();
184
        }
185
#else
186
        static void __interrupt __far prvNonPreemptiveTick( void )
187
        {
188
                /* Same as preemptive tick, but the cooperative scheduler is being used
189
                so we don't have to switch in the context of the next task. */
190
                vTaskIncrementTick();
191
                portRESET_PIC();
192
        }
193
#endif
194
/*-----------------------------------------------------------*/
195
 
196
static void __interrupt __far prvYieldProcessor( void )
197
{
198
        /* Switch in the context of the next task to be run. */
199
        portSWITCH_CONTEXT();
200
}
201
/*-----------------------------------------------------------*/
202
 
203
void vPortEndScheduler( void )
204
{
205
        /* Jump back to the processor state prior to starting the
206
        scheduler.  This means we are not going to be using a
207
        task stack frame so the task can be deleted. */
208
        longjmp( xJumpBuf, 1 );
209
}
210
/*-----------------------------------------------------------*/
211
 
212
static void prvExitFunction( void )
213
{
214
const unsigned short usTimerDisable = 0x0000;
215
unsigned short usTimer0Control;
216
 
217
        /* Interrupts should be disabled here anyway - but no
218
        harm in making sure. */
219
        portDISABLE_INTERRUPTS();
220
        if( xSchedulerRunning == pdTRUE )
221
        {
222
                /* Put back the switch interrupt routines that was in place
223
                before the scheduler started. */
224
                _dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
225
        }
226
 
227
        /* Disable the timer used for the tick to ensure the scheduler is
228
        not called before restoring interrupts.  There was previously nothing
229
        on this timer so there is no old ISR to restore. */
230
        portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
231
 
232
        /* Restart the DOS tick. */
233
        usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
234
        usTimer0Control |= portTIMER_INTERRUPT_ENABLE;
235
        portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
236
 
237
 
238
        portENABLE_INTERRUPTS();
239
 
240
        /* This will free up all the memory used by the scheduler.
241
        exiting back to dos with INT21 AH=4CH will do this anyway so
242
        it is not necessary to call this. */
243
        vTaskCleanUpResources();
244
}
245
/*-----------------------------------------------------------*/
246
 
247
static void prvSetTickFrequency( unsigned long ulTickRateHz )
248
{
249
const unsigned short usMaxCountRegister = 0xff5a;
250
const unsigned short usTimerPriorityRegister = 0xff32;
251
const unsigned short usTimerEnable = 0xC000;
252
const unsigned short usRetrigger = 0x0001;
253
const unsigned short usTimerHighPriority = 0x0000;
254
unsigned short usTimer0Control;
255
 
256
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
257
 
258
const unsigned long ulClockFrequency = ( unsigned long ) 0x7f31a0UL;
259
 
260
unsigned long ulTimerCount = ulClockFrequency / ulTickRateHz;
261
 
262
        portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
263
        portOUTPUT_WORD( usMaxCountRegister, ( unsigned short ) ulTimerCount );
264
        portOUTPUT_WORD( usTimerPriorityRegister, usTimerHighPriority );
265
 
266
        /* Stop the DOS tick - don't do this if you want to maintain a TOD clock. */
267
        usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
268
        usTimer0Control &= ~portTIMER_INTERRUPT_ENABLE;
269
        portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
270
}
271
 
272
 
273
/*lint +e950 */
274
 

powered by: WebSVN 2.1.0

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