/* * アラームの設定(相対値) */ StatusType SetRelAlarm(AlarmType almid, TickType incr, TickType cycle) { StatusType ercd = E_OK; CounterType cntid; TickType maxval; LOG_SETREL_ENTER(almid, incr, cycle); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_ALMID(almid); cntid = alminib_cntid[almid]; maxval = cntinib_maxval[cntid]; CHECK_VALUE((0u < incr) && (incr <= maxval)); CHECK_VALUE((cycle == 0u) || ((cntinib_mincyc[cntid] <= cycle) && (cycle <= maxval))); lock_cpu(); if (almcb_next[almid] != almid) { ercd = E_OS_STATE; goto d_error_exit; } almcb_almval[almid] = add_tick(cntcb_curval[cntid], incr, cntinib_maxval2[cntid]); almcb_cycle[almid] = cycle; enqueue_alarm(almid, cntid); exit: unlock_cpu(); LOG_SETREL_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); d_error_exit: _errorhook_par1.almid = almid; _errorhook_par2.incr = incr; _errorhook_par3.cycle = cycle; call_errorhook(ercd, OSServiceId_SetRelAlarm); goto exit; }
/* * カウンタを進める */ StatusType SignalCounter(CounterType cntid) { StatusType ercd = E_OK; TickType newval; AlarmType almid, next; LOG_SIGCNT_ENTER(cntid); CHECK_CALLEVEL(TCL_ISR2); CHECK_CNTID(cntid); lock_cpu(); /* * 更新後のカウンタ値を求める */ newval = add_tick(cntcb_curval[cntid], cntinib_tickbase[cntid], cntinib_maxval2[cntid]); /* * カウンタの現在値の更新 */ cntcb_curval[cntid] = newval; /* * アラームの expire 処理 */ while (((almid = cntcb_almque[cntid]) != ALMID_NULL) && diff_tick(newval, almcb_almval[almid], cntinib_maxval2[cntid]) <= cntinib_maxval[cntid]) { /* * アラームキューの先頭のアラームを,キューから外す. */ next = almcb_next[almid]; cntcb_almque[cntid] = next; if (next != ALMID_NULL) { almcb_prev[next] = ALMID_NULL; } almcb_next[almid] = almid; /* * アラームコールバックの呼び出し */ unlock_cpu(); (*alminib_cback[almid])(); lock_cpu(); /* * アラームキューへの再挿入(周期アラームの場合) * * アラームコールバックの中で自アラームを SetRelAlarm/ * SetAbsAlarm した状況(OSEK仕様では許されていないが, * TOPPERS/OSEKカーネルでは許している)で,アラームキュー * への再挿入を防ぐために,almcb_next[almid] == almid * の場合のみ再挿入する. */ if ((almcb_next[almid] == almid) && (almcb_cycle[almid] > 0u)) { almcb_almval[almid] = add_tick(almcb_almval[almid], almcb_cycle[almid], cntinib_maxval2[cntid]); enqueue_alarm(almid, cntid); } } exit: unlock_cpu(); LOG_SIGCNT_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); _errorhook_par1.cntid = cntid; call_errorhook(ercd, OSServiceId_SignalCounter); goto exit; }
static int calculate_ticks (double min, double max, double distance, int log_scale, TICKS * ticks) { double step ; /* Put numbered ticks at multiples of this */ double range = max - min ; int k ; double value ; /* Temporary */ if (log_scale == 1) return calculate_log_ticks (min, max, distance, ticks) ; /* Linear version */ /* Choose a step between successive axis labels so that one digit ** changes by 1, 2 or 5 amd that gives us at least the number of ** divisions (and numberic labels) that we would like to have. ** ** We do this by starting "step" at the lowest power of ten <= max, ** which can give us at most 9 divisions (e.g. from 0 to 9999, step 1000) ** Then try 5*this, 2*this and 1*this. */ step = pow (10.0, floor (log10 (max))) ; do { if (range / (step * 5) >= TARGET_DIVISIONS) { step *= 5 ; break ; } ; if (range / (step * 2) >= TARGET_DIVISIONS) { step *= 2 ; break ; } ; if (range / step >= TARGET_DIVISIONS) break ; step /= 10 ; } while (1) ; /* This is an odd loop! */ /* Ensure that the least significant digit that changes gets printed, */ ticks->decimal_places_to_print = lrint (-floor (log10 (step))) ; if (ticks->decimal_places_to_print < 0) ticks->decimal_places_to_print = 0 ; /* Now go from the first multiple of step that's >= min to * the last one that's <= max. */ k = 0 ; value = ceil (min / step) * step ; #define add_tick(val, just_a_tick) do \ { if (val >= min - DELTA && val < max + DELTA) \ { ticks->value [k] = just_a_tick ? NO_NUMBER : val ; \ ticks->distance [k] = distance * \ (log_scale == 2 \ ? /*log*/ (log (val) - log (min)) / (log (max) - log (min)) \ : /*lin*/ (val - min) / range) ; \ k++ ; \ } ; \ } while (0) /* Add the half-way tick before the first number if it's in range */ add_tick (value - step / 2, true) ; while (value <= max + DELTA) { /* Add a tick next to each printed number */ add_tick (value, false) ; /* and at the half-way tick after the number if it's in range */ add_tick (value + step / 2, true) ; value += step ; } ; return k ; } /* calculate_ticks */
/* * signal the counter that it should increment */ StatusType SignalCounter(CounterType cntid) { StatusType ercd = E_OK; TickType newval; AlarmType almid, next; LOG_SIGCNT_ENTER(cntid); CHECK_CALLEVEL(TCL_ISR2); CHECK_CNTID(cntid); lock_cpu(); /* * calculate the counter next value */ newval = add_tick(cntcb_curval[cntid], cntinib_tickbase[cntid], cntinib_maxval2[cntid]); /* * store the counter current value */ cntcb_curval[cntid] = newval; /* * process the already expiried one */ while (((almid = cntcb_almque[cntid]) != ALMID_NULL) && diff_tick(newval, almcb_almval[almid], cntinib_maxval2[cntid]) <= cntinib_maxval[cntid]) { /* * find one,first remove it from the counter queue */ next = almcb_next[almid]; cntcb_almque[cntid] = next; if (next != ALMID_NULL) { almcb_prev[next] = ALMID_NULL; } almcb_next[almid] = almid; /* * process it,call its callback routine */ unlock_cpu(); (*alminib_cback[almid])(); lock_cpu(); /* * if this alarm is cyclic alarm,put it to the counter queue again */ if ((almcb_next[almid] == almid) && (almcb_cycle[almid] > 0u)) { almcb_almval[almid] = add_tick(almcb_almval[almid], almcb_cycle[almid], cntinib_maxval2[cntid]); enqueue_alarm(almid, cntid); } } exit: unlock_cpu(); LOG_SIGCNT_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); _errorhook_par1.cntid = cntid; call_errorhook(ercd, OSServiceId_SignalCounter); goto exit; }