/* * カウンタを進める */ 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; }