Subversion Repositories Bart

Rev

Blame | Last modification | View Log | RSS feed

  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
  190.