/* * アラームの設定(絶対値) */ StatusType SetAbsAlarm(AlarmType almid, TickType start, TickType cycle) { StatusType ercd = E_OK; CounterType cntid; TickType maxval, start2; LOG_SETABS_ENTER(almid, start, cycle); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_ALMID(almid); cntid = alminib_cntid[almid]; maxval = cntinib_maxval[cntid]; CHECK_VALUE(start <= 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; } start2 = start + maxval + 1; if (cntcb_curval[cntid] <= maxval) { if (start <= cntcb_curval[cntid]) { almcb_almval[almid] = start2; } else { almcb_almval[almid] = start; } } else { if (start2 <= cntcb_curval[cntid]) { almcb_almval[almid] = start; } else { almcb_almval[almid] = start2; } } almcb_cycle[almid] = cycle; enqueue_alarm(almid, cntid); exit: unlock_cpu(); LOG_SETABS_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); d_error_exit: _errorhook_par1.almid = almid; _errorhook_par2.start = start; _errorhook_par3.cycle = cycle; call_errorhook(ercd, OSServiceId_SetAbsAlarm); goto exit; }
/* * アラーム機能の初期化 */ void alarm_initialize(void) { CounterType cntid; AlarmType almid; for (cntid = 0; cntid < tnum_counter; cntid++) { cntcb_curval[cntid] = 0u; cntcb_almque[cntid] = ALMID_NULL; } for (almid = 0; almid < tnum_alarm; almid++) { almcb_next[almid] = almid; if ((alminib_autosta[almid] & appmode) != APPMODE_NONE) { almcb_almval[almid] = alminib_almval[almid]; almcb_cycle[almid] = alminib_cycle[almid]; enqueue_alarm(almid, alminib_cntid[almid]); } } }
/* * アラームの設定(相対値) */ 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; }
/* * 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; }