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 }