Subversion Repositories Bart

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 mjames 1
/* RCS revision control
2
   $Header: c:/cvsroot/bart/rt_task.h,v 1.5 2004/03/09 00:45:20 mjames Exp $
3
 
4
   RCS Log file
5
 
6
   $Log: rt_task.h,v $
7
   Revision 1.5  2004/03/09 00:45:20  mjames
8
   Corrected mistakes, made task numbers visible
9
 
10
   Revision 1.4  2004/03/08 22:45:45  mjames
11
   Updated some useful macros
12
 
13
   Revision 1.3  2004/03/06 12:17:48  mjames
14
   Moved headers around, made it clearer that there are no configurable
15
   parts to the OS unless it is rebuilt
16
 
17
   Revision 1.2  2004/03/04 21:53:02  mjames
18
   Made the files work with a demo project
19
 
20
   Revision 1.1.1.1  2004/03/03 22:54:33  mjames
21
   no message
22
 
23
 
24
 
25
 */
26
#if !defined RT_TASK_H
27
#define RT_TASK_H
28
/******************************************************************************/
29
/* Task settings  */
30
 
31
/** this means n tasks + virtual idle task  */
32
#define TASKS 3
33
#define STACK0SIZE 41 /**< stack 0 overlaps with real stack . take care in memory map */
34
#define STACK1SIZE 46
35
#define STACK2SIZE 46
36
#define STACK3SIZE 46
37
 
38
 
39
/******************************************************************************/
40
/* Interrupt vectors */
41
 
42
#define T0_INTVEC   1
43
#define T1_INTVEC   3
44
#define SIO_INTVEC  4
45
#define T2_INTVEC   5
46
 
47
#define SIO_INTERRUPT_BANK    1 /**< defined for serial use */
48
#define T0_INTERRUPT_BANK     2
49
#define T2_INTERRUPT_BANK     3
50
 
51
/** Interrupt declaration so that main() containing function has correct interface */
52
extern void T0Interrupt(void) interrupt T0_INTVEC using T0_INTERRUPT_BANK;
53
 
54
/* Exported for main() to see in scope */
55
extern void T2Interrupt(void) interrupt T2_INTVEC using T2_INTERRUPT_BANK;
56
 
57
extern void SIOInterrupt(void) interrupt SIO_INTVEC using SIO_INTERRUPT_BANK;
58
 
59
/******************************************************************************/
60
 
61
 
62
#define TASK_BIT(taskno) (1<<(taskno))
63
 
64
#define RUNNING(task) (ready & (TASK_BIT(task)))
65
 
66
 
67
/** Used in functions which may or may not have EA on on entry but which contain critical sections.
68
 *  Each usage in a function uses another bit variable
69
 * do not use in an ISR as it modifies the carry bit in END_CRITICAL and the running task gets hit with the C bit change  */
70
 
71
#define USE_CRITICAL      static Bool EA_local /**< declaration section: using a bit flag to copy old EA status */
72
#define BEGIN_CRITICAL    { if(EA) {EA =0; EA_local =1; } else {EA_local = 0;};} /**< this code encourages SDCC to use JBC atomic operation, so EA will be 0 inside section, and old state is stored in local flag. */
73
#define END_CRITICAL      { EA=EA_local; } /**< EA is restored */
74
 
75
 
76
#define RESCHEDULE reschedule(); /**< do not use sleep() as this now waits 100ms */
77
 
78
/* need all of these in scope in main() */
79
 
80
extern volatile STACK_PTR_TYPE stack_save[TASKS];   /**< Idata pointers to task stacks */  
81
 
82
extern volatile SIGNAL_TYPE task_signals[TASKS]; /**< Bytes representing the task structures */
83
extern volatile SIGNAL_TYPE task_masks[TASKS];   /**< if a signal bit set then it is masked with this */
84
extern volatile TIMER_TYPE  task_timer[TASKS];   /**< Counters decrementing at 112.5Hz */
85
 
86
extern volatile TASKID_TYPE   ready ;     /**< bits 5,4 are schedule table index, bits 3 2 1 0 are task ready to run bits */
87
extern volatile TASKID_TYPE   run  ;      /**< currently running task */
88
 
89
extern code char const priotab[];
90
 
91
 
92
typedef enum { QUEUED,FAILED,STARTED } start_rc;
93
 
94
typedef void (*task_p)(void );
95
 
96
/** the stack for the task is built and then its run flag is set. Not necessary to call this
97
    for task 0 as will be effectively started in call to tasks_init() */
98
 
99
extern start_rc start_task(task_p f,      /**< address of function */
100
                           char tasknum); /**< task number to assign function to */
101
 
102
 
103
extern void end_run_task(void);
104
 
105
/* look at task flags and run the appropriate task. Repeated calls will eventully try and run all the other tasks */
106
extern void reschedule(void);
107
 
108
/** schedules future timer signal as well as earlier timeouts of signals  */
109
extern char wait_timed(char signal,/**< A byte made out of all the signals which are to be acknowledged.
110
                                        TIMER_SIG is implicit in the use of this call */
111
                       char ticks);/**< The number of 100ms periods before timeout  */
112
 
113
/** Add the signals to the set which will set the ready flag for this task.*/
114
#define enable_signal(pattern) task_masks[run] |= (pattern)/**< A byte made out of all the signals which are to be enabled */
115
 
116
/** Remove the signals from the set which will set the ready flag for this task. Does
117
   not clear the signal itself. */
118
#define disable_signal(pattern) task_masks[run]&= ~(pattern)/**< A byte made out of all the signals which are to be disabled */
119
 
120
/** the list of all of the signals currently active on this task before masking */
121
#define curr_signal() task_signals[run]
122
 
123
/** the current running task acknowledges the signal bits in the argument */
124
extern void clear_signal(SIGNAL_TYPE pattern);/**< A byte made out of all the signals which are to be acknowledged */
125
 
126
/** Sends a signal to the task referred to. Does not actually cause rescheduling
127
  until either a T0 interrupt,  or a sleep, reschedule or wait_timed call made by this task */
128
extern void signal(char task,     /**< Task number (0 to 3) */
129
                  SIGNAL_TYPE pattern); /**< A byte made out of all the signals which are to be sent */
130
 
131
/** Signal sending acro for interrupt context
132
 * Sends a signal to the task referred to. Does not actually cause rescheduling
133
 * until either a T0 interrupt,  or a sleep or wait_timed call made by this task */
134
#define INT_SIGNAL(task,pattern) \
135
  task_signals[(task)]|=(pattern);\
136
  if(task_signals[(task)] & task_masks[(task)])\
137
    {\
138
    ready |= TASK_BIT(task);\
139
    }
140
 
141
 
142
/** Function to cooperatively reschedule : sleep = 0 or wait for up to ticks before
143
 return. Although this uses the timer signal it is acknowledged and cleared internally.
144
 Use wait_timed() to obtain a timer signal : Will poll for timer signal if the scheduler
145
 returns this task as next to run even if the timer is not expired (happens on task 0) */
146
extern void sleep(TIMER_TYPE ticks);
147
 
148
 
149
/** Function to configure Hardware to run RT */
150
extern void rt_system_init(void);
151
 
152
/** setup the scheduler workspace. Use with EA off. Initially sets Task 0 (IDLE_TASK) as
153
  running and ready to run */
154
extern void rt_tasks_init(void);
155
 
156
 
157
 
158
/*************************************************************************/
159
/** Timebase counting
160
 *
161
 *  The MAXT100ms
162
 *  wrap value should be divisible by 4 because of
163
 *  the fractional N counting in T0 Interrupt code*/
164
#define MAXT100ms             100
165
 
166
#define TIMER      T100ms
167
#define TIMER10sec T10sec
168
 
169
/** can use the 100ms counter as an extra timer up to 10 seconds
170
   in the future by using this macro to determine the final value */
171
#define WRAP_TIME(x) if(x>=MAXT100ms) x-= MAXT100ms
172
 
173
/** definitions of timer rates */
174
#define MS_PER_TICK 100
175
/** a macro to get the count necessary for a certain delay */
176
#define CONV_MS(x) (((x)+(MS_PER_TICK-1))/MS_PER_TICK)
177
 
178
#define CLOCKS_PER_SEC (1000/MS_PER_TICK)
179
 
180
/** timer registers used by T0 IRQ : T0 interrupts at 112.5 Hz */
181
extern volatile unsigned char T0ctr;/**< counts from 11 down to 1 or from 12 down to 1 (25% of time). Prescales to give exact 1 second timing from this timer  */
182
 
183
extern volatile unsigned char T100ms;/**< counts modulo 200, increment once every about 100ms .
184
                                             BUT 10 counts is exactly one second */
185
 
186
extern volatile unsigned char T10sec;/**< counts modulo 10 seconds off T0 interrupt */
187
 
188
 
189
#endif