void init_scheduler(void) { int rtc_ticks_per_sec; /* get handle to the system realtime clock */ rtclock = cyg_real_time_clock (); rtc_resolution = cyg_clock_get_resolution ( rtclock ); rtc_ticks_per_sec = rtc_resolution.divisor; cyg_clock_to_counter ( rtclock, &rtc_counter ); // Real time clock frequency must be changed in eCos configuration, as there is another // macro that depends on its value. //fprintf ( stderr, "cyg_realtime_clock() resolution: dividend=%d, \t divisor=%d\n", rtc_resolution.dividend, rtc_resolution.divisor ); // Create alarms cyg_alarm_create ( rtc_counter, alarm_handlerfn_daq,0,&alarm_hdl[0],&alarm_obj[0] ); cyg_alarm_create ( rtc_counter, alarm_handlerfn_actuators,0,&alarm_hdl[1],&alarm_obj[1] ); cyg_alarm_create ( rtc_counter, alarm_handlerfn_thread1,0,&alarm_hdl[2],&alarm_obj[2] ); // Initialize conditional variables pthread_cond_init (&trigger_daq, NULL); pthread_cond_init (&trigger_actuators, NULL); pthread_cond_init (&trigger_thread1, NULL); // Start alarms // DAQ, executes at t0 + 0.0000 cyg_alarm_initialize ( alarm_hdl[0], DAQ_OFFSET*rtc_ticks_per_sec, rtc_ticks_per_sec/BASE_HZ ); // ACTUATORS, executes at t0 + 0.014 cyg_alarm_initialize ( alarm_hdl[1], ACTUATORS_OFFSET*rtc_ticks_per_sec, rtc_ticks_per_sec/BASE_HZ); // Thread1, executes at t0 + 0.0130 cyg_alarm_initialize ( alarm_hdl[2], THREAD1_OFFSET*rtc_ticks_per_sec, rtc_ticks_per_sec/THREAD1_HZ ); }
void alarmfn2(cyg_handle_t alarmh, cyg_addrword_t data) { db_printf("%s: %d\n",__PRETTY_FUNCTION__,cyg_counter_current_value( counter )); alarmfn_called[2]++; // Reschedule alarm[0] to run every 2 ticks until alarm[1] next runs. cyg_alarm_initialize( alarm[0], cyg_counter_current_value( counter )+1, 2 ); // Reschedule alarm[1] to run every 3 ticks starting in 6 ticks time. cyg_alarm_initialize( alarm[1], cyg_counter_current_value( counter )+6, 3 ); }
void fptest_main( void ) { CYG_TEST_INIT(); if( cyg_test_is_simulator ) { run_ticks = RUN_TICKS_SIM; } CYG_TEST_INFO("Run fptest in cyg_start"); do_test( fpt3_values, FP3_COUNT, 1000, 0, "start" ); CYG_TEST_INFO( "cyg_start run done"); cyg_thread_create( BASE_PRI-1, fptest1, 0, "fptest1", &stacks[0][0], STACK_SIZE, &thread[0], &thread_struct[0]); cyg_thread_resume( thread[0] ); cyg_thread_create( BASE_PRI, fptest2, 1, "fptest2", &stacks[1][0], STACK_SIZE, &thread[1], &thread_struct[1]); cyg_thread_resume( thread[1] ); cyg_thread_create( BASE_PRI, fptest3, 2, "fptest3", &stacks[2][0], STACK_SIZE, &thread[2], &thread_struct[2]); cyg_thread_resume( thread[2] ); cyg_alarm_create( cyg_real_time_clock(), alarm_fn, 0, &alarm, &alarm_struct ); cyg_alarm_initialize( alarm, cyg_current_time()+1, 1 ); cyg_scheduler_start(); }
void alarmfn1(cyg_handle_t alarmh, cyg_addrword_t data) { db_printf("%s: %d\n",__PRETTY_FUNCTION__,cyg_counter_current_value( counter )); alarmfn_called[1]++; // Reschedule alarm[0] to run every tick until alarm[2] next runs. cyg_alarm_initialize( alarm[0], cyg_counter_current_value( counter )+1, 1 ); }
static void sco_sock_set_timer(struct sock *sk, long timeout) { BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout); // if (!mod_timer(&sk->timer, jiffies + timeout)) // sock_hold(sk); cyg_alarm_disable(sk->timeout_alarm_handle); cyg_alarm_initialize(sk->timeout_alarm_handle, cyg_current_time()+timeout, 0); cyg_alarm_enable(sk->timeout_alarm_handle); sock_hold(sk); }
// ------------------------------------------------------------------------ // CALLBACK FUNCTION // Called from the thread, this runs the alarm callbacks. // Locking is already in place when this is called. static void do_timeout(void) { int i; cyg_int32 min_delta; timeout_entry *e; CYG_ASSERT( 0 < last_delta, "last_delta underflow" ); min_delta = last_delta; // local copy last_delta = -1; // flag recursive call underway for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) { if (e->delta) { CYG_ASSERT( e->delta >= min_delta, "e->delta underflow" ); e->delta -= min_delta; if (e->delta <= 0) { // Defensive // Time for this item to 'fire' timeout_fun *fun = e->fun; void *arg = e->arg; // Call it *after* cleansing the record e->fun = 0; e->delta = 0; (*fun)(arg); } } } // Now scan for a new timeout *after* running all the callbacks // (because they can add timeouts themselves) min_delta = 0x7FFFFFFF; // Maxint for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) if (e->delta) if (e->delta < min_delta) min_delta = e->delta; CYG_ASSERT( 0 < min_delta, "min_delta underflow" ); if (min_delta != 0x7FFFFFFF) { // Still something to do, schedule it last_set_time = cyg_current_time(); cyg_alarm_initialize(timeout_alarm_handle, last_set_time+min_delta, 0); last_delta = min_delta; } else { last_delta = 0; // flag no activity } }
void alarm0_main(void) { int i; CYG_TEST_INIT(); // Create the counter cyg_counter_create( &counter, &counter_obj ); // Create the alarms cyg_alarm_create( counter, alarmfn0, 0, &alarm[0], &alarm_obj[0]); cyg_alarm_create( counter, alarmfn1, 1, &alarm[1], &alarm_obj[1]); cyg_alarm_create( counter, alarmfn2, 2, &alarm[2], &alarm_obj[2]); // Kick it all off by starting alarm[2] cyg_alarm_initialize( alarm[2], 0, 10 ); // Run the whole thing for 10000 ticks for( i = 0; i < 10000; i++ ) cyg_counter_tick( counter ); db_printf("alarmfn_called: %d %d %d\n", alarmfn_called[0],alarmfn_called[1],alarmfn_called[2]); CYG_TEST_CHECK( alarmfn_called[0]==5000, "alarmfn0 not called 5000 times\n"); CYG_TEST_CHECK( alarmfn_called[1]==2000, "alarmfn1 not called 2000 times\n"); CYG_TEST_CHECK( alarmfn_called[2]==1001, "alarmfn2 not called 1001 times\n"); CYG_TEST_PASS_FINISH("KAlarm0"); }
void tcp_hole() { int interval = 30000; TCP_HOLE_FLAG = 1; /* Attach the timer to the CloseTcpHole clock */ CloseTcpHole_SysClk = cyg_real_time_clock(); cyg_clock_to_counter(CloseTcpHole_SysClk, &CloseTcpHole_Counter); cyg_alarm_create(CloseTcpHole_Counter, (cyg_alarm_t *)CloseTcpHole, 0, &CloseTcpHole_Alarm, &CloseTcpHole_timerAlarm); /* This creates a periodic timer */ cyg_alarm_initialize(CloseTcpHole_Alarm, cyg_current_time() + interval, 0); //only trigger once after 5 minutes }
void linklocal_alarm(void){ /* 10 sec, Follow Link Local IP Stard. If we got ip conflict twice within 10 seconds, we have to change our link local ip. <<<Ron 12/13/04 >>> */ int interval = 10; //10 sec /* Attach the timer to the real-time clock */ hSysClk = cyg_real_time_clock(); cyg_clock_to_counter(hSysClk, &hCounter); // cyg_alarm_create(hCounter, (cyg_alarm_t *)linklocal_msg_post, cyg_alarm_create(hCounter, (cyg_alarm_t *)linklocal_msg_timer, (cyg_addrword_t) &alarmData, &hAlarm, &timerAlarm); /* This creates a periodic timer */ cyg_alarm_initialize(hAlarm, cyg_current_time() + interval, 10); }
void CECOSTimerHandler::enableHandler(void){ cyg_alarm_initialize(m_stAlarmHandle, cyg_current_time() + 1, 1); }
// ------------------------------------------------------------------------ // EXPORTED API: SET A TIMEOUT // This can be called from anywhere, including recursively from the timeout // functions themselves. cyg_uint32 timeout(timeout_fun *fun, void *arg, cyg_int32 delta) { int i; timeout_entry *e; cyg_uint32 stamp; // this needs to be atomic - recursive calls from the alarm // handler thread itself are allowed: int spl = cyg_splinternal(); CYG_ASSERT( 0 < delta, "delta is right now, or even sooner!" ); // Renormalize delta wrt the existing set alarm, if there is one if ( last_delta > 0 ) delta += (cyg_int32)(cyg_current_time() - last_set_time); // So recorded_delta is set to either: // alarm is active: delta + NOW - THEN // alarm is inactive: delta stamp = 0; // Assume no slots available for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) { if ((e->delta == 0) && (e->fun == 0)) { // Free entry e->delta = delta; e->fun = fun; e->arg = arg; stamp = (cyg_uint32)e; break; } } if ( stamp && // we did add a record AND (0 == last_delta || // alarm was inactive OR delta < last_delta) ) { // alarm was active but later than we need // (if last_delta is -1, this call is recursive from the handler so // also do nothing in that case) // Here, we know the new item added is sooner than that which was // most recently set, if any, so we can just go and set it up. if ( 0 == last_delta ) last_set_time = cyg_current_time(); // So we use, to set the alarm either: // alarm is active: (delta + NOW - THEN) + THEN // alarm is inactive: delta + NOW // and in either case it is true that // (recorded_delta + last_set_time) == (delta + NOW) cyg_alarm_initialize(timeout_alarm_handle, last_set_time+delta, 0); last_delta = delta; } // Otherwise, the alarm is active, AND it is set to fire sooner than we // require, so when it does, that will sort out calling the item we // just added. Or we didn't actually add a record, so nothing has // changed. #ifdef CYGPKG_INFRA_DEBUG // Do some more checking akin to that in the alarm handler: if ( last_delta != -1 ) { // not a recursive call cyg_tick_count_t now = cyg_current_time(); CYG_ASSERT( last_delta >= 0, "Bad last delta" ); delta = 0x7fffffff; for (e = timeouts, i = 0; i < NTIMEOUTS; i++, e++) { if (e->delta) { CYG_ASSERT( e->delta >= last_delta, "e->delta underflow" ); CYG_ASSERT( last_set_time + e->delta + 1000 > now, "Recorded alarm not in the future!" ); if ( e->delta < delta ) delta = e->delta; } else { CYG_ASSERT( 0 == e->fun, "Function recorded for 0 delta" ); } } CYG_ASSERT( delta == last_delta, "We didn't pick the smallest delta!" ); } #endif cyg_splx(spl); return stamp; }
// ------------------------------------------------------------------------ // CALLBACK FUNCTION // Called from the thread, this runs the alarm callbacks. // Locking is already in place when this is called. static void do_timeout(void) { cyg_int32 min_delta; timeout_entry *e, *e_next; CYG_ASSERT( 0 < last_delta, "last_delta underflow" ); min_delta = last_delta; // local copy last_delta = -1; // flag recursive call underway e = timeouts; while (e) { e_next = e->next; // Because this can change during processing if (e->delta) { #ifdef TIMEOUT_DEBUG if ( !(e->delta >= min_delta)) { diag_printf("Bad delta in timeout: %p, delta: %d, min: %d, last: %ld\n", e, e->delta, min_delta, last_set_time); _show_timeouts(); } #endif // Note: this _can_ happen if timeouts are scheduled before the clock starts! // CYG_ASSERT( e->delta >= min_delta, "e->delta underflow" ); e->delta -= min_delta; if (e->delta <= 0) { // Defensive // Time for this item to 'fire' timeout_fun *fun = e->fun; void *arg = e->arg; // Call it *after* cleansing the record // diag_printf("%s(%p, %p, %p)\n", __FUNCTION__, e, e->fun, e->arg); e->flags &= ~CALLOUT_PENDING; e->delta = 0; if (e->next) { e->next->prev = e->prev; } if (e->prev) { e->prev->next = e->next; } else { timeouts = e->next; } (*fun)(arg); } } e = e_next; } // Now scan for a new timeout *after* running all the callbacks // (because they can add timeouts themselves) min_delta = 0x7FFFFFFF; // Maxint for (e = timeouts; e; e = e->next ) if (e->delta) if (e->delta < min_delta) min_delta = e->delta; CYG_ASSERT( 0 < min_delta, "min_delta underflow" ); if (min_delta != 0x7FFFFFFF) { // Still something to do, schedule it last_set_time = cyg_current_time(); cyg_alarm_initialize(timeout_alarm_handle, last_set_time+min_delta, 0); last_delta = min_delta; } else { last_delta = 0; // flag no activity } #ifdef TIMEOUT_DEBUG diag_printf("Timeout list after %s\n", __FUNCTION__); _show_timeouts(); #endif }
void callout_reset(struct callout *c, int delta, timeout_fun *f, void *p) { int spl = cyg_splinternal(); CYG_ASSERT( 0 < delta, "delta is right now, or even sooner!" ); // Renormalize delta wrt the existing set alarm, if there is one if (last_delta > 0) { #ifdef TIMEOUT_DEBUG int _delta = delta; int _time = cyg_current_time(); #endif // TIMEOUT_DEBUG // There is an active alarm if (last_set_time != 0) { // Adjust the delta to be absolute, relative to the alarm delta += (cyg_int32)(cyg_current_time() - last_set_time); } else { // We don't know exactly when the alarm will fire, so just // schedule this event for the first time, or sometime after ; // Leaving the value alone won't be "too wrong" } #ifdef TIMEOUT_DEBUG diag_printf("delta changed from %d to %d, now: %d, then: %d, last_delta: %d\n", _delta, delta, _time, (int)last_set_time, last_delta); _show_timeouts(); #endif } // So recorded_delta is set to either: // alarm is active: delta + NOW - THEN // alarm is inactive: delta // Add this callout/timeout to the list of things to do if (c->flags & CALLOUT_PENDING) { callout_stop(c); } c->prev = (timeout_entry *)NULL; c->next = timeouts; if (c->next != (timeout_entry *)NULL) { c->next->prev = c; } timeouts = c; c->flags |= CALLOUT_PENDING | CALLOUT_ACTIVE; c->fun = f; c->arg = p; c->delta = delta; #ifdef TIMEOUT_DEBUG diag_printf("%s(%p, %d, %p, %p)\n", __FUNCTION__, c, delta, f, p); _show_timeouts(); #endif if ((0 == last_delta || // alarm was inactive OR delta < last_delta) ) { // alarm was active but later than we need // (if last_delta is -1, this call is recursive from the handler so // also do nothing in that case) // Here, we know the new item added is sooner than that which was // most recently set, if any, so we can just go and set it up. if ( 0 == last_delta ) last_set_time = cyg_current_time(); // So we use, to set the alarm either: // alarm is active: (delta + NOW - THEN) + THEN // alarm is inactive: delta + NOW // and in either case it is true that // (recorded_delta + last_set_time) == (delta + NOW) cyg_alarm_initialize(timeout_alarm_handle, last_set_time+delta, 0); #ifdef TIMEOUT_DEBUG if ((int)last_set_time == 0) { diag_printf("delta: %d, time: %ld, last_delta: %d\n", delta, last_set_time, last_delta); } #endif last_delta = delta; } // Otherwise, the alarm is active, AND it is set to fire sooner than we // require, so when it does, that will sort out calling the item we // just added. #ifdef CYGPKG_INFRA_DEBUG // Do some more checking akin to that in the alarm handler: if ( last_delta != -1 ) { // not a recursive call cyg_tick_count_t now = cyg_current_time(); timeout_entry *e; CYG_ASSERT( last_delta >= 0, "Bad last delta" ); delta = 0x7fffffff; for (e = timeouts; e; e = e->next) { if (e->delta) { CYG_ASSERT( e->delta >= last_delta, "e->delta underflow" ); // the following triggers if the "next" timeout has not just // passed, but passed by 1000 ticks - which with the normal // 1 tick = 10ms means 10 seconds - a long time. CYG_ASSERT( last_set_time + e->delta + 1000 > now, "Recorded alarm not in the future! Starved network thread?" ); if ( e->delta < delta ) delta = e->delta; } else { CYG_ASSERT( 0 == e->fun, "Function recorded for 0 delta" ); } } if (delta < last_delta) { diag_printf("Failed to pick smallest delta - picked: %d, last: %d\n", delta, last_delta); for (e = timeouts; e; e = e->next) { diag_printf(" timeout: %p at %d\n", e->fun, e->delta); } } CYG_ASSERT( delta >= last_delta, "We didn't pick the smallest delta!" ); } #endif cyg_splx(spl); }
void kclock0_main(void) { CYG_TEST_INIT(); CHECK(flash()); CHECK(flash()); cyg_counter_create( &counter0, &counter0o); CHECK( 0 == cyg_counter_current_value( counter0 ) ); cyg_counter_tick(counter0); CHECK( 1 == cyg_counter_current_value(counter0) ); cyg_counter_tick(counter0); CHECK( 2 == cyg_counter_current_value(counter0) ); cyg_counter_set_value( counter0, 0xffffffff ); CHECK( 0xffffffff == cyg_counter_current_value(counter0) ); cyg_counter_tick(counter0); // Overflows 32 bits CHECK( 0x100000000ULL == cyg_counter_current_value(counter0) ); cyg_counter_set_value(counter0, 11); CHECK( 11 == cyg_counter_current_value(counter0) ); /* the call_me functions cause the "called" bits to toggle // checking the value of called checks the parity of # of calls // made by each alarm. */ cyg_alarm_create(counter0, call_me, (cyg_addrword_t)0x1, &alarm0, &alarmo[0]); cyg_alarm_create(counter0, call_me, (cyg_addrword_t)0x2, &alarm1, &alarmo[1]); cyg_alarm_create(counter0, call_me2, (cyg_addrword_t)0x4, &alarm2, &alarmo[2]); CHECK( 0x00 == called ); cyg_alarm_initialize(alarm0, 12,3); cyg_alarm_initialize(alarm2, 21,2); CHECK( 0x00 == called ); cyg_counter_tick(counter0); /* 12 a0 */ CHECK( 0x01 == called ); cyg_alarm_initialize(alarm1, 13,0); cyg_counter_tick(counter0); /* 13 a1 */ CHECK( 0x03 == called ); cyg_alarm_initialize(alarm1, 17,0); cyg_counter_tick(counter0); /* 14 */ CHECK( 0x03 == called ); cyg_counter_tick(counter0); /* 15 a0 */ CHECK( 0x02 == called ); cyg_counter_tick(counter0); /* 16 */ cyg_counter_tick(counter0); /* 17 a1 */ CHECK( 0x00 == called ); cyg_counter_tick(counter0); /* 18 a0 */ CHECK( 0x01 == called ); cyg_counter_tick(counter0); /* 19 */ cyg_counter_tick(counter0); /* 20 */ cyg_counter_tick(counter0); /* 21 a0 a2 */ CHECK( 0x14 == called ); cyg_counter_tick(counter0); /* 22 */ cyg_counter_tick(counter0); /* 23 a2 */ CHECK( 0x00 == called ); cyg_alarm_disable(alarm2); cyg_counter_tick(counter0); /* 24 a0 */ cyg_counter_tick(counter0); /* 25 */ CHECK( 0x01 == called ); cyg_alarm_enable(alarm2); /* a2 (enabled at 25) */ CHECK( 0x15 == called ); cyg_counter_tick(counter0); /* 26 */ CHECK( 0x15 == called ); cyg_counter_tick(counter0); /* 27 a0 a2 */ cyg_counter_tick(counter0); /* 28 */ CHECK( 0x00 == called ); cyg_counter_tick(counter0); /* 29 a2 */ cyg_counter_tick(counter0); /* 30 a0 */ cyg_counter_tick(counter0); /* 31 a2 */ CHECK( 0x01 == called ); res0.dividend = 100; res0.divisor = 3; cyg_clock_create( res0, &clock0, &clock0o ); res1 = cyg_clock_get_resolution(clock0); CHECK( res0.dividend == res1.dividend ); CHECK( res0.divisor == res1.divisor ); res1.dividend = 12; res1.divisor = 25; cyg_clock_set_resolution(clock0, res1); res0 = cyg_clock_get_resolution(clock0); CHECK( res0.dividend == res1.dividend ); CHECK( res0.divisor == res1.divisor ); cyg_clock_to_counter(clock0, &counter1); CHECK( 0 == cyg_counter_current_value( counter1 ) ); CHECK( 0 == cyg_current_time() ); cyg_counter_tick(counter1); CHECK( 1 == cyg_counter_current_value(counter1) ); res0 = cyg_clock_get_resolution(cyg_real_time_clock()); /* Current time should be 0 as interrupts will still be disabled */ CHECK( 0 == cyg_current_time() ); CYG_TEST_PASS_FINISH("Kernel C API Clock 0 OK"); }
void cyg_user_start(void){ // Initialize framebuffer in graphic mode ezs_fb_init(); // Initialize soundblaster ezs_sb16_init(&sb16, 0x220 /* io address */, 5 /* interrupt */, 1 /* 8 bit DMA */, 5 /* 16 bit DMA */); // Initialize HPET counter ezs_counter_init(); // Initialize Tracer int res = ezs_trace_init(); printf("init res: %d\r\n" , res); // Create keyboard interrupt, attach to handler table and umask cyg_interrupt_create(CYGNUM_HAL_INTERRUPT_KEYBOARD, 1, (cyg_addrword_t) &keyhandle, keyb_isr_handler, keyb_dsr_handler, &handle, &intr) ; cyg_interrupt_attach(handle); cyg_interrupt_unmask(CYGNUM_HAL_INTERRUPT_KEYBOARD); // Create test thread cyg_thread_create(17, &thread, 0, "Abtastung1", my_stack, STACKSIZE, &threadhndl1, &threaddata); // Create keyboard thread cyg_thread_create(1, &keythread, 0, "Keyboard", keystack, STACKSIZE, &keyhandle, &keydata); // Create other threads cyg_thread_create(1, abtastung1, 0, "thread_abtastung1", my_stack_abt1, STACKSIZE, &(threadhndl_abt1), &(threaddata_abt1)); cyg_thread_create(5, abtastung2, 0, "thread_abtastung2", my_stack_abt2, STACKSIZE, &(threadhndl_abt2), &(threaddata_abt2)); cyg_thread_create(10, analyse, 0, "thread_analyse", my_stack_anal, STACKSIZE, &(threadhndl_anal), &(threaddata_anal)); cyg_thread_create(15, darstellung, 0, "thread_darstellung", my_stack_darst, STACKSIZE, &(threadhndl_darst), &(threaddata_darst)); cyg_handle_t counter; cyg_clock_to_counter(cyg_real_time_clock(), &counter); /* cyg_alarm_create(counter, alarm_handler, (cyg_addrword_t) &threadhndl1 , &alarmhnd1, &alarm1); cyg_alarm_initialize(alarmhnd1, 0, 10); cyg_alarm_enable(alarmhnd1); */ cyg_alarm_create(counter, alarm_handler, (cyg_addrword_t) &threadhndl_abt1 , &alarmhnd_abt1, &alarm_abt1); cyg_alarm_initialize(alarmhnd_abt1, cyg_counter_current_value(counter) + 10, 10); cyg_alarm_create(counter, alarm_handler, (cyg_addrword_t) &threadhndl_abt2 , &alarmhnd_abt2, &alarm_abt2); cyg_alarm_initialize(alarmhnd_abt2, cyg_counter_current_value(counter) + 12, 20); cyg_alarm_create(counter, alarm_handler, (cyg_addrword_t) &threadhndl_anal , &alarmhnd_anal, &alarm_anal); cyg_alarm_initialize(alarmhnd_anal, cyg_counter_current_value(counter) + 14, 20); cyg_alarm_create(counter, alarm_handler, (cyg_addrword_t) &threadhndl_darst , &alarmhnd_darst, &alarm_darst); cyg_alarm_initialize(alarmhnd_darst, cyg_counter_current_value(counter) + 22, 100); }