📄 time_calls.c
字号:
#if USE_DBGSPT/* * Get object name from control block */#if USE_OBJECT_NAMEEXPORT ER cyclichandler_getname(ID id, UB **name){ CYCCB *cyccb; ER ercd = E_OK; CHECK_CYCID(id); BEGIN_DISABLE_INTERRUPT; cyccb = get_cyccb(id); if ( cyccb->cychdr == NULL ) { ercd = E_NOEXS; goto error_exit; } if ( (cyccb->cycatr & TA_DSNAME) == 0 ) { ercd = E_OBJ; goto error_exit; } *name = cyccb->name; error_exit: END_DISABLE_INTERRUPT; return ercd;}#endif /* USE_OBJECT_NAME *//* * Refer cyclic handler usage state */SYSCALL INT _td_lst_cyc( ID list[], INT nent ){ CYCCB *cyccb, *end; INT n = 0; BEGIN_DISABLE_INTERRUPT; end = cyccb_table + NUM_CYCID; for ( cyccb = cyccb_table; cyccb < end; cyccb++ ) { /* Unregistered handler */ if ( cyccb->cychdr == NULL ) continue; if ( n++ < nent ) { *list++ = ID_CYC(cyccb - cyccb_table); } } END_DISABLE_INTERRUPT; return n;}/* * Refer cyclic handler state */SYSCALL ER _td_ref_cyc( ID cycid, TD_RCYC* pk_rcyc ){ CYCCB *cyccb; LSYSTIM tm; ER ercd = E_OK; CHECK_CYCID(cycid); cyccb = get_cyccb(cycid); BEGIN_DISABLE_INTERRUPT; if ( cyccb->cychdr == NULL ) { /* Unregistered handler */ ercd = E_NOEXS; } else { tm = cyccb->cyctmeb.time; if ( (cyccb->cycstat & TCYC_STA) == 0 ) { if ( ll_cmp(tm, current_time) <= 0 ) { tm = cyc_next_time(cyccb); } } tm = ll_sub(tm, current_time); tm = ll_sub(tm, ltoll(TIMER_PERIOD)); if ( ll_sign(tm) < 0 ) tm = ltoll(0); pk_rcyc->exinf = cyccb->exinf; pk_rcyc->lfttim = tm; pk_rcyc->cycstat = cyccb->cycstat; } END_DISABLE_INTERRUPT; return ercd;}#endif /* USE_DBGSPT */#endif /* NUM_CYCID *//* ------------------------------------------------------------------------ *//* * Alarm handler */#ifdef NUM_ALMIDEXPORT ID max_almid; /* Maximum alarm handler ID *//* * Alarm handler control block */typedef struct alarm_handler_control_block { VP exinf; /* Extended information */ ATR almatr; /* Alarm handler attribute */ FP almhdr; /* Alarm handler address */ UINT almstat; /* Alarm handler state */ TMEB almtmeb; /* Timer event block */#if TA_GP VP gp; /* Global pointer */#endif#if USE_OBJECT_NAME UB name[OBJECT_NAME_LENGTH]; /* name */#endif} ALMCB;LOCAL ALMCB *almcb_table; /* Alarm handler control block */LOCAL QUEUE free_almcb; /* FreeQue */#define get_almcb(id) ( &almcb_table[INDEX_ALM(id)] )/* * Initialization of alarm handler control block */EXPORT ER alarmhandler_initialize( void ){ ALMCB *almcb, *end; W n; /* Get system information */ n = _tk_get_cfn("TMaxAlmId", &max_almid, 1); if ( n < 1 || NUM_ALMID < 1 ) return E_SYS; /* Create alarm handler control block */ almcb_table = Imalloc(NUM_ALMID * sizeof(ALMCB)); if ( almcb_table == NULL ) return E_NOMEM; /* Register all control blocks onto FeeQue*/ QueInit(&free_almcb); end = almcb_table + NUM_ALMID; for ( almcb = almcb_table; almcb < end; almcb++ ) { almcb->almhdr = NULL; /* Unregistered handler */ QueInsert((QUEUE*)almcb, &free_almcb); } return E_OK;}/* * Alarm handler start routine */LOCAL void call_almhdr( ALMCB *almcb ){ almcb->almstat &= ~TALM_STA; /* Execute alarm handler/ Enable interrupt nesting */ ENABLE_INTERRUPT_UPTO(TIMER_INTLEVEL);#if TA_GP CallUserHandler((INT)almcb->exinf, 0, 0, almcb->almhdr, almcb->gp);#else (*almcb->almhdr)(almcb->exinf);#endif DISABLE_INTERRUPT;}/* * Alarm handler immediate call */LOCAL void immediate_call_almhdr( ALMCB *almcb ){ almcb->almstat &= ~TALM_STA; /* Execute alarm handler in task-independent part (Keep interrupt disabled) */ ENTER_TASK_INDEPENDENT;#if TA_GP CallUserHandler((INT)almcb->exinf, 0, 0, almcb->almhdr, almcb->gp);#else (*almcb->almhdr)(almcb->exinf);#endif LEAVE_TASK_INDEPENDENT;}/* * Register onto timer event queue */Inline void alm_timer_insert( ALMCB *almcb, RELTIM reltim ){ LSYSTIM tm; /* To guarantee to start the handler after the specified time, add TIMER_PERIOD */ tm = ll_add(current_time, ltoll(reltim)); tm = ll_add(tm, ltoll(TIMER_PERIOD)); timer_insert_abs(&almcb->almtmeb, tm, (CBACK)call_almhdr, almcb);}/* * Create alarm handler */SYSCALL ID _tk_cre_alm P1( T_CALM *pk_calm ){ const ATR VALID_ALMATR = { TA_HLNG |TA_GP#if USE_OBJECT_NAME |TA_DSNAME#endif }; ALMCB *almcb; ER ercd = E_OK; CHECK_RSATR(pk_calm->almatr, VALID_ALMATR); CHECK_PAR(pk_calm->almhdr != NULL); BEGIN_CRITICAL_SECTION; /* Get control block from free queue */ almcb = (ALMCB*)QueRemoveNext(&free_almcb); if ( almcb == NULL ) { ercd = E_LIMIT; goto error_exit; } /* Initialize control block */ almcb->exinf = pk_calm->exinf; almcb->almatr = pk_calm->almatr; almcb->almhdr = pk_calm->almhdr; almcb->almstat = TALM_STP;#if USE_OBJECT_NAME if ( (pk_calm->almatr & TA_DSNAME) != 0 ) { strncpy(almcb->name, pk_calm->dsname, OBJECT_NAME_LENGTH); }#endif#if TA_GP if ( (pk_calm->almatr & TA_GP) != 0 ) gp = pk_calm->gp; almcb->gp = gp;#endif ercd = ID_ALM(almcb - almcb_table); error_exit: END_CRITICAL_SECTION; return ercd;}/* * Delete alarm handler */SYSCALL ER _tk_del_alm( ID almid ){ ALMCB *almcb; ER ercd = E_OK; CHECK_ALMID(almid); almcb = get_almcb(almid); BEGIN_CRITICAL_SECTION; if ( almcb->almhdr == NULL ) { /* Unregistered handler */ ercd = E_NOEXS; } else { if ( (almcb->almstat & TALM_STA) != 0 ) { /* Delete from timer event queue */ timer_delete(&almcb->almtmeb); } /* Return to FreeQue */ QueInsert((QUEUE*)almcb, &free_almcb); almcb->almhdr = NULL; /* Unregistered handler */ } END_CRITICAL_SECTION; return ercd;}/* * Start alarm handler */SYSCALL ER _tk_sta_alm( ID almid, RELTIM almtim ){ ALMCB *almcb; ER ercd = E_OK; CHECK_ALMID(almid); almcb = get_almcb(almid); BEGIN_CRITICAL_SECTION; if ( almcb->almhdr == NULL ) { /* Unregistered handler */ ercd = E_NOEXS; goto error_exit; } if ( (almcb->almstat & TALM_STA) != 0 ) { /* Cancel current settings */ timer_delete(&almcb->almtmeb); } if ( almtim > 0 ) { /* Register onto timer event queue */ alm_timer_insert(almcb, almtim); almcb->almstat |= TALM_STA; } else { /* Immediate execution */ immediate_call_almhdr(almcb); } error_exit: END_CRITICAL_SECTION; return ercd;}/* * Stop alarm handler */SYSCALL ER _tk_stp_alm( ID almid ){ ALMCB *almcb; ER ercd = E_OK; CHECK_ALMID(almid); almcb = get_almcb(almid); BEGIN_CRITICAL_SECTION; if ( almcb->almhdr == NULL ) { /* Unregistered handler */ ercd = E_NOEXS; } else { if ( (almcb->almstat & TALM_STA) != 0 ) { /* Stop alarm handler address */ timer_delete(&almcb->almtmeb); almcb->almstat &= ~TALM_STA; } } END_CRITICAL_SECTION; return ercd;}/* * Refer alarm handler state */SYSCALL ER _tk_ref_alm( ID almid, T_RALM *pk_ralm ){ ALMCB *almcb; LSYSTIM tm; ER ercd = E_OK; CHECK_ALMID(almid); almcb = get_almcb(almid); BEGIN_CRITICAL_SECTION; if ( almcb->almhdr == NULL ) { /* Unregistered handler */ ercd = E_NOEXS; } else { if ( (almcb->almstat & TALM_STA) != 0 ) { tm = almcb->almtmeb.time; tm = ll_sub(tm, current_time); tm = ll_sub(tm, ltoll(TIMER_PERIOD)); if ( ll_sign(tm) < 0 ) tm = ltoll(0); } else { tm = ltoll(0); } pk_ralm->exinf = almcb->exinf; pk_ralm->lfttim = tm; pk_ralm->almstat = almcb->almstat; } END_CRITICAL_SECTION; return ercd;}#if USE_DBGSPT/* * Get object name from control block */#if USE_OBJECT_NAMEEXPORT ER alarmhandler_getname(ID id, UB **name){ ALMCB *almcb; ER ercd = E_OK; CHECK_ALMID(id); BEGIN_DISABLE_INTERRUPT; almcb = get_almcb(id); if ( almcb->almhdr == NULL ) { ercd = E_NOEXS; goto error_exit; } if ( (almcb->almatr & TA_DSNAME) == 0 ) { ercd = E_OBJ; goto error_exit; } *name = almcb->name; error_exit: END_DISABLE_INTERRUPT; return ercd;}#endif /* USE_OBJECT_NAME *//* * Refer alarm handler usage state */SYSCALL INT _td_lst_alm( ID list[], INT nent ){ ALMCB *almcb, *end; INT n = 0; BEGIN_DISABLE_INTERRUPT; end = almcb_table + NUM_ALMID; for ( almcb = almcb_table; almcb < end; almcb++ ) { /* Unregistered handler */ if ( almcb->almhdr == NULL ) continue; if ( n++ < nent ) { *list++ = ID_ALM(almcb - almcb_table); } } END_DISABLE_INTERRUPT; return n;}/* * Refer alarm handler state */SYSCALL ER _td_ref_alm( ID almid, TD_RALM *pk_ralm ){ ALMCB *almcb; LSYSTIM tm; ER ercd = E_OK; CHECK_ALMID(almid); almcb = get_almcb(almid); BEGIN_DISABLE_INTERRUPT; if ( almcb->almhdr == NULL ) { /* Unregistered handler */ ercd = E_NOEXS; } else { if ( (almcb->almstat & TALM_STA) != 0 ) { tm = almcb->almtmeb.time; tm = ll_sub(tm, current_time); tm = ll_sub(tm, ltoll(TIMER_PERIOD)); if ( ll_sign(tm) < 0 ) tm = ltoll(0); } else { tm = ltoll(0); } pk_ralm->exinf = almcb->exinf; pk_ralm->lfttim = tm; pk_ralm->almstat = almcb->almstat; } END_DISABLE_INTERRUPT; return ercd;}#endif /* USE_DBGSPT */#endif /* NUM_ALMID */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -