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