00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023
00024 #include <aversive.h>
00025 #include <scheduler_config.h>
00026 #include <scheduler_private.h>
00027
00029 static volatile uint8_t priority_running=0;
00030
00032 static volatile uint8_t nb_stacking=0;
00033
00034 uint8_t scheduler_disable_save(void)
00035 {
00036 uint8_t ret;
00037 ret = priority_running;
00038 priority_running = 255;
00039 return ret;
00040 }
00041
00042 void scheduler_enable_restore(uint8_t old_prio)
00043 {
00044 priority_running = old_prio;
00045 }
00046
00058 void
00059 scheduler_interrupt(void)
00060 {
00061 uint8_t i;
00062 uint8_t priority_tmp;
00063 SLIST_HEAD(event_list_t, event_t) event_list;
00064 struct event_t *e, *next_e, *prev_e=NULL;
00065
00066
00067 if (nb_stacking >= SCHEDULER_NB_STACKING_MAX)
00068 return;
00069
00070 nb_stacking ++;
00071 sei();
00072
00073 SLIST_INIT(&event_list);
00074
00075
00076
00077 for (i=0 ; i<SCHEDULER_NB_MAX_EVENT ; i++) {
00078 cli();
00079
00080
00081
00082 if (g_tab_event[i].state == SCHEDULER_EVENT_SCHEDULED &&
00083 g_tab_event[i].current_time > 1) {
00084 g_tab_event[i].current_time --;
00085 sei();
00086 continue;
00087 }
00088
00089
00090 if (g_tab_event[i].state != SCHEDULER_EVENT_ACTIVE) {
00091 sei();
00092 continue;
00093 }
00094
00095
00096
00097 g_tab_event[i].current_time --;
00098
00099
00100 if ( g_tab_event[i].current_time != 0 ) {
00101 sei();
00102 continue;
00103 }
00104
00105
00106
00107 if (g_tab_event[i].priority <= priority_running) {
00108 g_tab_event[i].current_time = 1;
00109 sei();
00110 continue;
00111 }
00112
00113
00114 g_tab_event[i].current_time = g_tab_event[i].period;
00115
00116
00117 g_tab_event[i].state = SCHEDULER_EVENT_SCHEDULED;
00118 sei();
00119
00120
00121
00122
00123
00124 e = SLIST_FIRST(&event_list);
00125
00126 if (e == NULL) {
00127 SLIST_INSERT_HEAD(&event_list, &g_tab_event[i], next);
00128 continue;
00129 }
00130
00131
00132 if (g_tab_event[i].priority >= e->priority) {
00133 SLIST_INSERT_HEAD(&event_list, &g_tab_event[i], next);
00134 continue;
00135 }
00136
00137
00138 SLIST_FOREACH(e, &event_list, next) {
00139 next_e = SLIST_NEXT(e, next);
00140 if (next_e == NULL ||
00141 g_tab_event[i].priority >= next_e->priority) {
00142 SLIST_INSERT_AFTER(e, &g_tab_event[i], next);
00143 break;
00144 }
00145 }
00146 }
00147
00148
00149 DUMP_EVENTS();
00150
00151 cli();
00152 priority_tmp = priority_running;
00153
00154 SLIST_FOREACH(e, &event_list, next) {
00155
00156 if (prev_e)
00157 SLIST_NEXT(prev_e, next) = NULL;
00158
00159
00160 priority_running = e->priority;
00161 sei();
00162
00163
00164
00165 e->f(e->data);
00166
00167 cli();
00168
00169 if (!e->period) {
00170 e->state = SCHEDULER_EVENT_FREE;
00171 }
00172
00173
00174
00175 if (e->state == SCHEDULER_EVENT_DELETING) {
00176 e->state = SCHEDULER_EVENT_FREE;
00177 }
00178
00179
00180 if (e->state == SCHEDULER_EVENT_SCHEDULED) {
00181 e->state = SCHEDULER_EVENT_ACTIVE;
00182 }
00183
00184 prev_e = e;
00185 }
00186
00187 if (prev_e)
00188 SLIST_NEXT(prev_e, next) = NULL;
00189
00190 priority_running = priority_tmp;
00191 nb_stacking--;
00192 }