fsmReturnStatus led_toggle(Fsm * fsm, const Event* e) { //!!!!!!make all tasks global. //!!!mistake: set td.next=NULL will disrupt scheduler!!!! // static taskDescriptor td; // td.task = &wrapper_red_led; // //td.param = &; //void pointer point to void, param is of type void // td.expire = 0; // td.period = 250; //0.25s = 4Hz // td.execute = 0; // td.next = NULL; // // static taskDescriptor td2; // td2.task = &wrapper_turnoff_led; // td2.param = fsm; //void pointer point to void, param is of type void // td2.expire = 5000; //count 5s // td2.period = 0; // td2.execute = 0; // td2.next = NULL; // // static taskDescriptor td3; // td3.task = &time_increment; // td3.param = fsm; // td3.expire = 0; // td3.period = 1000; // every second update the time of the clock // td3.execute = 0; // td3.next = NULL; switch (e->signal) { case ENTRY: td_toggle_led.expire = 0; td_turnoff_led.expire = 5000; td_time_increment.expire = 0; scheduler_add(&td_toggle_led); scheduler_add(&td_turnoff_led); scheduler_add(&td_time_increment); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(normal_operating); case ROTARY_PRESSED: return TRANSITION(normal_operating); case EXIT: led_redOff(); scheduler_remove(&td_toggle_led); scheduler_remove(&td_turnoff_led); scheduler_remove(&td_time_increment); return RET_HANDLED; default: return RET_IGNORED; } }
int main(void) { button_init(true); led_greenInit(); led_yellowInit(); led_redInit();//testing lcd_init(); scheduler_init(); //5.2.1:toggle green led every 2s taskDescriptor td1; //= (taskDescriptor*) malloc(sizeof(taskDescriptor)); td1.task = &wrapper_greenToggle; //td.param = &; //void pointer point to void, param is of type void td1.expire = 2000; td1.period = 2000; td1.execute = 0; td1.next = NULL; scheduler_add(&td1); //5.2.2: schedule button_checkState taskDescriptor td2; //= (taskDescriptor*) malloc(sizeof(taskDescriptor)); td2.task = &wrapper_button_checkState; //td.param = &; //void pointer point to void, param is of type void td2.expire = 0; td2.period = 5; td2.execute = 0; td2.next = NULL; scheduler_add(&td2); //5.2.3: scheduler or button click determines the situation button_setJoystickButtonCallback(control_yellow); //5.2.4 :schedule stopwatch fprintf(lcdout, "Please press the rotary button to start the stopwatch"); button_setRotaryButtonCallback(stopWatch); taskDescriptor td5; //= (taskDescriptor*) malloc(sizeof(taskDescriptor)); td5.task = &calc_time; //td5.param = ; //void pointer point to void, param is of type void td5.expire = 0; //immediately run td5.period = 100; //0.1s td5.execute = 0; td5.next = NULL; scheduler_add(&td5); sei(); scheduler_run(); return 1; }
fsmReturnStatus normal_operating(Fsm * fsm, const Event* e) { static bool enable = false; switch (e->signal) { case ENTRY: td_time_increment.expire = 0; scheduler_add(&td_time_increment); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(set_alarm_hour); case ROTARY_PRESSED: enable = !enable; fsm->isAlarmEnabled = enable; if (enable) led_yellowOn(); else led_yellowOff(); return RET_HANDLED; case MATCHING: if (fsm->isAlarmEnabled) { return TRANSITION(led_toggle); } else return RET_HANDLED; case EXIT: scheduler_remove(&td_time_increment); return RET_HANDLED; default: return RET_IGNORED; } }
int main() { //task 6.1 pButtonCallback joystickButton = wrapper_pwm; button_init(true); //debouncing, timer1 is initialized in this function button_setJoystickButtonCallback(joystickButton); pwm_init(); pwm_setDutyCycle(0); //initially motor idle //task 6.2,6.3 lcd_init(); led_yellowInit(); led_greenInit(); scheduler_init(); // timer2_start() is called there. motorFrequency_init(); //timer 5 and external interrupt settings taskDescriptor td1; //= (taskDescriptor*) malloc(sizeof(taskDescriptor)); td1.task = &display; //td.param = &; //void pointer point to void, param is of type void td1.expire = 0; td1.period = 500; //timer2 INT every 1ms td1.execute = 0; td1.next = NULL; scheduler_add(&td1); //task6.4 uart_init(57600); //debugging pidData_t pidData; pid_Init(P * SCALING_FACTOR, I* SCALING_FACTOR, D *SCALING_FACTOR, &pidData); //set p=0; i=1.5, d=0; taskDescriptor td2; //= (taskDescriptor*) malloc(sizeof(taskDescriptor)); td2.task = &wrapper_pid; td2.param = &pidData; //void pointer point to void, param is of type void td2.expire = 0; td2.period = 200; //timer2 INT every 1ms td2.execute = 0; td2.next = NULL; scheduler_add(&td2); sei(); scheduler_run(); return 0; }
void scheduler_clear(void) { // deb = get_iopin(9); // set_dir(deb, 1); for (uint16_t i=0; i<MAX_TRIGGERED; i++) { triggered_tasks[i] = 0; } num_scheduled = 0; scheduler_add(10, led_task); }
fsmReturnStatus alarm_init(Fsm * fsm, const Event* e) { td_toggle_led.task = &wrapper_red_led; //td.param = ; td_toggle_led.expire = 0; td_toggle_led.period = 250; //0.25s = 4Hz td_toggle_led.execute = 0; td_toggle_led.next = NULL; td_turnoff_led.task = &wrapper_turnoff_led; td_turnoff_led.param = fsm; td_turnoff_led.expire = 5000; //count 5s td_turnoff_led.period = 0; td_turnoff_led.execute = 0; td_turnoff_led.next = NULL; td_time_increment.task = &time_increment; // td3.param ; td_time_increment.expire = 0; td_time_increment.period = 1000; // every second update the time of the clock td_time_increment.execute = 0; td_time_increment.next = NULL; td_check_matching.task = &check_matching; // td4.param td_check_matching.expire = 0; td_check_matching.period = 1000; // every second check if matching td_check_matching.execute = 0; td_check_matching.next = NULL; td_check_rotary_encoder.task = &wrapper_check_rotary; td_check_rotary_encoder.expire = 0; //immediately execute the task td_check_rotary_encoder.period = 1; // td_check_rotary_encoder.execute = 0; td_check_rotary_encoder.next = NULL; scheduler_add(&td_check_rotary_encoder); switch (e->signal) { case ENTRY: fsm->isAlarmEnabled = false; fprintf(lcdout, "%02d:%02d\n", 0, 0); fprintf(lcdout, "set clock hour"); (fsm->timeSet).hour = 0; (fsm->timeSet).minute = 0; (fsm->timeSet).second = 0; return TRANSITION(sethour); default: return RET_IGNORED; } }
/*-------------------------------------------------------------------------*/ message_t *fsm_handle_preload(fsm_t *fsm, message_t *msg) { ophcrack_t *crack = fsm->crack; scheduler_t *sched = crack->sched; // If the preloading of the tables is finished, then we start // searching into the tables. if (msg->kind == msg_done) { msg_done_t *done = (msg_done_t*)msg->data; int nthreads = sched->nthreads; int n; if (done->kind == preload_all) { assert(fsm->psize_curr <= fsm->psize_total); // Check that the tables have been correctly preloaded. // if (fsm->psize_curr < fsm->psize_total) // ophcrack_preload_check(crack); // This is necessary to prevent the status bar from indicating // that a preload task is 'waiting' if no preloading occured. fsm->psize_curr = 1; fsm->psize_total = 1; // Start the work tasks. for (n=0; n < MY_MAX(1, nthreads-1); ++n) if (ophcrack_next(crack) == 0) break; // If no tasks have been scheduled, then we schedule a fake task // which will possibly trigger the 'done(all)' message if it is // the last one to be executed. This trick is required since the // brute force might still be running, therefore we should not // stop here, but wait until the 'done(all)' message is // received. if (n == 0) { ophtask_t *task = ophtask_alloc(find); scheduler_add(sched, task, low); } fsm->state = st_work1; } } return msg; }
/*-------------------------------------------------------------------------*/ void fsm_launch_preload(fsm_t *fsm) { ophcrack_t *crack = fsm->crack; scheduler_t *sched = crack->sched; ophtask_t *task = ophtask_alloc(preload_all); ophload_t *load = (ophload_t*)task->data; list_t *enabled = crack->enabled; list_nd_t *tnd = 0; for (tnd = enabled->head; tnd != 0; tnd = tnd->next) list_add_tail(load->tables, tnd->data); scheduler_add(sched, task, disk); fsm->preload = 0; }
fsmReturnStatus set_alarm_min(Fsm * fsm, const Event* e) { Time_t *temp = &(fsm->timeSet); switch (e->signal) { case ENTRY: lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case ROTARY_PRESSED: if (++(temp->minute) > 59) temp->minute = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case ROTARY_INC: if (++(temp->minute) > 59) temp->minute = 0; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, temp->minute); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case ROTARY_DEC: if ((temp->minute) == 0) temp->minute = 60; lcd_clear(); lcd_setCursor(0, 0); fprintf(lcdout, "%02d:%02d\n", temp->hour, --(temp->minute)); fprintf(lcdout, "set alarm min"); return RET_HANDLED; case JOYSTICK_PRESSED: return TRANSITION(normal_operating); case EXIT: td_check_matching.param = fsm;//in order to get the timeSet in the check matching td_check_matching.expire = 0; scheduler_add(&td_check_matching); return RET_HANDLED; default: return RET_IGNORED; } }
void control_yellow() { static taskDescriptor td3; //td3 should remain same as before. //without static, the parameter in wrapper_yellowOff(&td3); would be null. state_on = !state_on; if (state_on) { led_yellowOn(); td3.task = &wrapper_yellowOff; td3.param = &td3; td3.expire = 5000; //count 5s td3.period = 0;//run once td3.execute = 0; td3.next = NULL; scheduler_add(&td3); } else { led_redOff(); wrapper_yellowOff(&td3); scheduler_remove(&td3); } }
/*-------------------------------------------------------------------------*/ void fsm_launch_bforce(fsm_t *fsm) { ophcrack_t *crack = fsm->crack; scheduler_t *sched = crack->sched; ophtask_t *task = ophtask_alloc(bforce_all); ophbforce_t *force = (ophbforce_t*)task->data; list_t *hashes = crack->hashes; list_nd_t *nd; int nhashes = hashes->size; int n; force->nhashes = nhashes; force->hashes = (hash_t**)malloc(nhashes*sizeof(hash_t*)); for (nd=hashes->head, n=0; nd!=0; nd=nd->next, ++n) force->hashes[n] = (hash_t*)nd->data; scheduler_add(sched, task, low); fsm->bforce = 0; }
/*-------------------------------------------------------------------------*/ message_t *fsm_handle_work2(fsm_t *fsm, message_t *msg) { ophcrack_t *crack = fsm->crack; scheduler_t *sched = crack->sched; arg_t *arg = fsm->arg; if (msg->kind != msg_done) return msg; msg_done_t *done = (msg_done_t*)msg->data; if (done->kind == all) { // If there are still some hashes to crack and some tables remain, // then we continue. int npwds_total = crack->npwds_total; int npwds_found = crack->npwds_found; if (crack->remaining->size > 0 && npwds_found < npwds_total) { ophtask_t *task = ophtask_alloc(preload_all); scheduler_add(sched, task, disk); fsm->state = st_preload; } // Otherwise, we stop. else { if (arg->bforce) { fsm->bforce_curr = 1; fsm->bforce_total = 1; } fsm->state = st_wait; } } return msg; }
int main( int argc, char* argv[] ) { // setup COM2/terminal bwsetfifo( COM2, OFF ); // setup peripherals and handlers kernel_init(); // Create idle task struct task* idle_task = task_create(&idle_task_entry, PRIORITY_IDLE, -1); scheduler_add(idle_task); // bootstrap first user task struct task* first_task = task_create(&first_task_entry, PRIORITY_HIGHEST, -1); scheduler_add(first_task); long idleTicks = 0; long userTicks = 0; struct task *current_task; int request; long elapsed; while (1) { current_task = scheduler_get_next(); if (current_task == 0) { break; } ACTIVATE: // Time the execution of the task elapsed = rtc_get_ticks(); // run the user task request = task_activate(current_task); elapsed = rtc_get_ticks() - elapsed; if (current_task == idle_task) { idleTicks += elapsed; } userTicks += elapsed; switch (__interrupt_type) { case INT_TYPE_HWI: // handle the interrupt request and determine if we should preempt the running task if (interrupts_handle_irq(current_task) == HWI_CONTINUE && current_task != idle_task) { goto ACTIVATE; } else { scheduler_add(current_task); } break; case INT_TYPE_SWI: // handle the system call request and determine if we should shutdown if (sys_handle_request(current_task, request) == -1) { goto shutdown; } break; default: KASSERT(0, "We got a weird interrupt type... %d", __interrupt_type); break; } } shutdown: kernel_shutdown(); // reset the scrolling window, in case it exists! bwprintf(COM2, CURSOR_SCROLL, 0, 999); bwprintf(COM2, CURSOR_CLEAR_SCREEN); // int i; // for (i = 0; i < MAX_NUM_TASKS; i++) { // task_print(COM2, i); // } printSensorTicks(); bwprintf(COM2, "Idle time: %d%%\r\n", ((idleTicks * 100) / userTicks)); bwprintf(COM2, "Kernel exiting.\r\n"); return 0; }
void qlevel_load(STRING *filename) { STRING *file = "#256"; make_path(file, filename); if(!file_exists(file)) { error("FIXIT! qlevel_load: File does not exist!"); return; } level_load(NULL); int countEntity = ini_read_int(file, "Level Information", "EntityCount", 0); int countLight = ini_read_int(file, "Level Information", "LightCount", 0); int countFog = ini_read_int(file, "Level Information", "FogCount", 0); STRING *section = "#64"; int i; char buffer[256]; STRING *strTemp = "#128"; for(i = 0; i < countEntity; i++) { diag("\nLoad :"); str_cpy(section, "Entity "); str_cat(section, str_for_int(NULL, i)); diag(section); ini_read_buffer(file, section, "Model", "error.mdl", buffer, 256); ENTITY *ent = ent_create(buffer, nullvector, qlevel_entity_init); ent->group = GROUP_LEVEL; ent->x = ini_read_float(file, section, "X", 0); ent->y = ini_read_float(file, section, "Y", 0); ent->z = ini_read_float(file, section, "Z", 0); ent->pan = ini_read_float(file, section, "Pan", 0); ent->tilt = ini_read_float(file, section, "Tilt", 0); ent->roll = ini_read_float(file, section, "Roll", 0); ent->scale_x = ini_read_float(file, section, "ScaleX", 0); ent->scale_y = ini_read_float(file, section, "ScaleY", 0); ent->scale_z = ini_read_float(file, section, "ScaleZ", 0); ent->lightrange = ini_read_float(file, section, "Lightrange", 0); int iActionCount = ini_read_int(file, section, "ActionCount", 0); int iA = 0; STRING *actionName = "#64"; for(iA = 0; iA < iActionCount; iA++) { str_cpy(actionName, "Action"); str_cat(actionName, str_for_int(NULL, iA)); ini_read_buffer(file, section, actionName, "", buffer, 256); str_cpy(strTemp, buffer); diag("\nTry adding action '"); diag(strTemp); diag("'..."); if(actinfo_add(ent->string1, strTemp)) { diag(" SUCCESS!\n\tTry getting function pointer..."); void *fn = action_getptr(strTemp); if(fn != NULL) { diag(" SUCCESS!"); scheduler_add(fn, ent); } else { diag(" FAILED!"); } } else { diag(" FAILED!"); } } diag("\nEntity loaded!"); } }
static void get_note_list(note_list *l, doc *d) { struct { int delta; alteration_type alter[128]; alteration_type armature_alter[128]; } *sl; struct { int n; unsigned long start_time; unsigned long end_time; } midi[16]; /* we may have as many silence channels as ncessary */ struct { int on; unsigned long start_time; unsigned long end_time; } *silence = NULL; int silence_size = 0; int silence_used_size = 0; schedule_list s; int i, n; int line; int max; unsigned long curtime; unsigned long min_advance; double duration; memset(&s, 0, sizeof(s)); for (i = 0; i < 16; i++) midi[i].n = -1; /* get biggest line size and allocate sl appropriately */ max = 0; for (i = 0; i < d->size; i++) { if (d->l[i].n > max) max = d->l[i].n; } sl = malloc(max * sizeof(*sl)); if (sl == NULL) abort(); curtime = 0; /* feed the scheduler */ for (line = 0; line < d->size; line++) { int it; for (i = 0; i < d->l[line].n; i++) { /* by default central line is si */ sl[i].delta = 0; memset(&sl[i].alter, 0, sizeof(sl[i].alter)); memset(&sl[i].armature_alter, 0, sizeof(sl[i].armature_alter)); } for (it = 0; it < d->l[line].size; it++) { item *cur = &d->l[line].i[it]; int k; min_advance = ULONG_MAX; for (k = 0; k < cur->size; k++) { vertical_item *v = &cur->i[k]; switch (v->t) { case CLEF: switch (v->clef.t) { case CLEF_SOL: sl[v->clef.s].delta = -v->clef.p - 2; break; case CLEF_FA: sl[v->clef.s].delta = -v->clef.p - 10; break; case CLEF_DO: sl[v->clef.s].delta = -v->clef.p - 6; break; } break; case ARMATURE: switch (v->armature.t) { default: /* normally you can't come here */ break; case DIESE: case BEMOL: case BECARRE: i = pos_to_midi(v->armature.p+sl[v->armature.s].delta) % 12; while (i < 128) { sl[v->armature.s].alter[i] = sl[v->armature.s].armature_alter[i] = v->armature.t; i += 12; } break; } break; case NOTE: { int cc; double dd; int mm, deltamm; duration = 4. / (1UL << v->note.duration); duration = 60000. / d->tempo * duration; /* not fully sure of how to deal with multiple dots */ for (cc = 0, dd = duration / 2; cc < v->note.dots; cc++, dd /= 2) duration += dd; mm = pos_to_midi(v->note.p+sl[v->note.s].delta); /* deal with alterations */ /* not sure about DDIESE/BBEMOL, do they imply continuous DIESE/BEMOL * or continuous DDIESE/BBEMOL or something else? * let's go continuous DIESE/BEMOL */ switch (v->note.alteration) { case DDIESE: deltamm = 1; sl[v->note.s].alter[mm] = DIESE; break; case DIESE: deltamm = 0; sl[v->note.s].alter[mm] = DIESE; break; case BBEMOL: deltamm = -1; sl[v->note.s].alter[mm] = BEMOL; break; case BEMOL: deltamm = 0; sl[v->note.s].alter[mm] = BEMOL; break; case BECARRE: deltamm = 0; sl[v->note.s].alter[mm] = NO_ALTERATION; break; case NO_ALTERATION: deltamm = 0; break; } switch (sl[v->note.s].alter[mm]) { case DIESE: mm++; break; case BEMOL: mm--; break; case NO_ALTERATION: /* nothing */ break; default: abort(); } mm += deltamm; if (mm < 0) mm = 0; if (mm > 127) mm = 127; scheduler_add(&s, mm, curtime, curtime + duration, line, it); if (duration < min_advance) min_advance = duration; break; } case SILENCE: { /* add a note -1 */ int cc; double dd; duration = 4. / (1UL << v->silence.duration); duration = 60000. / d->tempo * duration; /* not fully sure of how to deal with multiple dots */ for (cc = 0, dd = duration / 2; cc < v->silence.dots; cc++, dd /= 2) duration += dd; scheduler_add(&s, -1, curtime, curtime + duration, line, it); if (duration < min_advance) min_advance = duration; break; } case BAR: for (i = 0; i < d->l[line].n; i++) memcpy(&sl[i].alter, &sl[i].armature_alter, sizeof(sl[i].alter)); break; } } if (min_advance != ULONG_MAX) curtime += min_advance; } } /* sort the scheduler */ qsort(s.s, s.size, sizeof(s.s[0]), sched_sort); /* schedule the 16 midi channels with our notes */ /* If all 16 channels are full when scheduling a note * stop the note that would stop first and take its place. * I don't think a more complex scheme is required practically speaking, * even if this one is not very good (the shortest note might be a new one * that has not even been played yet at all). */ /* 2015-07-19: I think I get it wrong. I think midi can throw more * than one note per channel. * Anyway, I'll keep the thing as it is, no big deal. */ n = 0; curtime = 0; while (1) { unsigned long nexttime = ULONG_MAX; /* schedule note off */ for (i = 0; i < 16; i++) if (midi[i].n != -1 && midi[i].end_time == curtime) { add_note_elem(l, (note_elem){ t:NOTE_OFF, port:i, note:midi[i].n }); midi[i].n = -1; }
Item *every(List *expression) { scheduler_add(eval_as_uint16(second(expression)),store_expression(rest(rest(expression)))); return 0; }