/** * * @param dque * @param data_ptr * * @return TN_RETVAL */ TN_RETVAL tnnc_queue_isend_polling (TN_DQUE_S *dque, void *data_ptr) { TN_UWORD tn_save_status_reg TN_UNUSED; TN_RETVAL rc; CDLL_QUEUE_S *que; TN_TCB_S *task; /* Not check parameter error if (dque == TN_NULL) return TERR_WRONG_PARAM; */ if (dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; if (tn_is_non_sys_int_context()) { return TERR_WCONTEXT; } tn_idisable_interrupt(); if (!is_queue_empty(&(dque->wait_receive_list))) { que = queue_remove_head(&(dque->wait_receive_list)); task = get_task_by_tsk_queue(que); task->data_elem = data_ptr; if (task_wait_complete(task, TN_FALSE)) { tn_context_switch_request = TN_TRUE; tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { rc = dque_fifo_write(dque,data_ptr); if (rc != TERR_NO_ERR) { rc = TERR_TIMEOUT; } } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- // Release Semaphore Resource inside Interrupt //---------------------------------------------------------------------------- int tn_sem_isignal(TN_SEM * sem) { TN_INTSAVE_DATA_INT int rc; CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(sem == NULL) return TERR_WRONG_PARAM; if(sem->max_count == 0) return TERR_WRONG_PARAM; if(sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); if(!(is_queue_empty(&(sem->wait_queue)))) { //--- delete from the sem wait queue que = queue_remove_head(&(sem->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { if(sem->count < sem->max_count) { sem->count++; rc = TERR_NO_ERR; } else rc = TERR_OVERFLOW; } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_task_iwakeup(TN_TCB * task) { TN_INTSAVE_DATA_INT int rc; #if TN_CHECK_PARAM if(task == NULL) return TERR_WRONG_PARAM; if(task->id_task != TN_ID_TASK) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); if(task->task_state == TSK_STATE_DORMANT) { rc = TERR_WCONTEXT; } else { if((task->task_state & TSK_STATE_WAIT) && task->task_wait_reason == TSK_WAIT_REASON_SLEEP) { if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { // v.2.7 - Thanks to Eugene Scopal if(task->wakeup_count == 0) //-- if here - the task is { //-- not in the SLEEP mode task->wakeup_count++; rc = TERR_NO_ERR; } else rc = TERR_OVERFLOW; } } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_task_irelease_wait(TN_TCB * task) { TN_INTSAVE_DATA_INT int rc; #if TN_CHECK_PARAM if(task == NULL) return TERR_WRONG_PARAM; if(task->id_task != TN_ID_TASK) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); if((task->task_state & TSK_STATE_WAIT) == 0) rc = TERR_WCONTEXT; else { queue_remove_entry(&(task->task_queue)); task_wait_complete(task); rc = TERR_NO_ERR; } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- // Acquire(Polling) Semaphore Resource inside interrupt //---------------------------------------------------------------------------- int tn_sem_ipolling(TN_SEM * sem) { TN_INTSAVE_DATA_INT int rc; #if TN_CHECK_PARAM if(sem == NULL) return TERR_WRONG_PARAM; if(sem->max_count == 0) return TERR_WRONG_PARAM; if(sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); if(sem->count >= 1) { sem->count--; rc = TERR_NO_ERR; } else rc = TERR_TIMEOUT; tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_fmem_get_ipolling(TN_FMP * fmp,void ** p_data) { TN_INTSAVE_DATA_INT int rc; void * ptr; #if TN_CHECK_PARAM if(fmp == NULL || p_data == NULL) return TERR_WRONG_PARAM; if(fmp->id_fmp != TN_ID_FSMEMORYPOOL) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); ptr = fm_get(fmp); if(ptr != NULL) //-- Get memory { *p_data = ptr; rc = TERR_NO_ERR; } else rc = TERR_TIMEOUT; tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_queue_isend_polling(TN_DQUE * dque, void * data_ptr) { TN_INTSAVE_DATA_INT int rc; CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(dque == NULL) return TERR_WRONG_PARAM; if(dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); //-- there are task(s) in the data queue's wait_receive list if(!is_queue_empty(&(dque->wait_receive_list))) { que = queue_remove_head(&(dque->wait_receive_list)); task = get_task_by_tsk_queue(que); task->data_elem = data_ptr; if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else //-- the data queue's wait_receive list is empty { rc = dque_fifo_write(dque,data_ptr); if(rc != TERR_NO_ERR) //-- No free entries in data queue rc = TERR_TIMEOUT; //-- Just convert errorcode } tn_ienable_interrupt(); return rc; }
TN_RETVAL tnec_event_iwait (TN_EVENT_S *evf, TN_UWORD wait_pattern, TN_UWORD wait_mode, TN_UWORD *p_flags_pattern) { TN_UWORD tn_save_status_reg TN_UNUSED; TN_RETVAL rc; TN_BOOL fCond; /* Check parameter */ if (evf == TN_NULL || wait_pattern == 0 || p_flags_pattern == TN_NULL) return TERR_WRONG_PARAM; /* Check event control block */ if (evf->id_event != TN_ID_EVENT) return TERR_NOEXS; /* Check calling context - only in first level interrupt and not before system start */ if (tn_is_non_sys_int_context()) return TERR_WCONTEXT; tn_idisable_interrupt(); /* If event attr is TN_EVENT_ATTR_SINGLE and another task already in event wait queue - return ERROR without checking release condition */ if ((evf->attr & TN_EVENT_ATTR_SINGLE) && !is_queue_empty(&(evf->wait_queue))) { rc = TERR_ILUSE; } else { /* Get pattern coincidence flag */ if (wait_mode & TN_EVENT_WCOND_OR) fCond = (TN_BOOL)((evf->pattern & wait_pattern) != 0); else fCond = (TN_BOOL)((evf->pattern & wait_pattern) == wait_pattern); if (fCond) { *p_flags_pattern = evf->pattern; if (evf->attr & TN_EVENT_ATTR_CLR) evf->pattern = 0; /* Clear event flag, if TN_EVENT_ATTR_CLR parameter set */ rc = TERR_NO_ERR; } else { rc = TERR_TIMEOUT; } } tn_ienable_interrupt(); return rc; }
/** * * @param task * * @return TN_RETVAL */ TN_RETVAL tnec_task_iactivate (TN_TCB_S *task) { TN_UWORD tn_save_status_reg TN_UNUSED; TN_RETVAL rc; if (task == TN_NULL) return TERR_WRONG_PARAM; if (task->id_task != TN_ID_TASK) return TERR_NOEXS; if (tn_is_non_sys_int_context()) { return TERR_WCONTEXT; } tn_idisable_interrupt(); if (task->task_state == TSK_STATE_DORMANT) { task_to_runnable(task); if ((tn_next_task_to_run != tn_curr_run_task) && (tn_enable_switch_context != TN_FALSE)) { tn_context_switch_request = TN_TRUE; } tn_ienable_interrupt(); return TERR_NO_ERR; } else { if (task->activate_count == 0) { task->activate_count++; rc = TERR_NO_ERR; } else rc = TERR_OVERFLOW; } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_iwait(TN_EVENT * evf, unsigned int wait_pattern, int wait_mode, unsigned int * p_flags_pattern) { TN_INTSAVE_DATA_INT int rc; int fCond; #if TN_CHECK_PARAM if(evf == NULL || wait_pattern == 0 || p_flags_pattern == NULL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); //-- If event attr is TN_EVENT_ATTR_SINGLE and another task already //-- in event wait queue - return ERROR without checking release condition if((evf->attr & TN_EVENT_ATTR_SINGLE) && !is_queue_empty(&(evf->wait_queue))) { rc = TERR_ILUSE; } else { //-- Check release condition if(wait_mode & TN_EVENT_WCOND_OR) //-- any setted bit is enough for release condition fCond = ((evf->pattern & wait_pattern) != 0); else //-- TN_EVENT_WCOND_AND is default mode fCond = ((evf->pattern & wait_pattern) == wait_pattern); if(fCond) { *p_flags_pattern = evf->pattern; if(evf->attr & TN_EVENT_ATTR_CLR) evf->pattern = 0; rc = TERR_NO_ERR; } else rc = TERR_TIMEOUT; } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_task_iactivate(TN_TCB * task) { TN_INTSAVE_DATA_INT int rc; #if TN_CHECK_PARAM if(task == NULL) return TERR_WRONG_PARAM; if(task->id_task != TN_ID_TASK) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); if(task->task_state == TSK_STATE_DORMANT) { task_to_runnable(task); tn_ienable_interrupt(); return TERR_NO_ERR; } else { if(task->activate_count == 0) { task->activate_count++; rc = TERR_NO_ERR; } else rc = TERR_OVERFLOW; } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_fmem_irelease(TN_FMP * fmp, void * p_data) { TN_INTSAVE_DATA_INT CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(fmp == NULL || p_data == NULL) return TERR_WRONG_PARAM; if(fmp->id_fmp != TN_ID_FSMEMORYPOOL) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); if(!is_queue_empty(&(fmp->wait_queue))) { que = queue_remove_head(&(fmp->wait_queue)); task = get_task_by_tsk_queue(que); task->data_elem = p_data; if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } } else fm_put(fmp,p_data); tn_ienable_interrupt(); return TERR_NO_ERR; }
TN_RETVAL tnec_event_iclear (TN_EVENT_S *evf, TN_UWORD pattern) { TN_UWORD tn_save_status_reg TN_UNUSED; /* Check parameter */ if (evf == TN_NULL || pattern == (TN_UWORD)0xFFFFFFFF) return TERR_WRONG_PARAM; /* Check event control block */ if (evf->id_event != TN_ID_EVENT) return TERR_NOEXS; /* Check calling context - only in first level interrupt and not before system start */ if (tn_is_non_sys_int_context()) return TERR_WCONTEXT; tn_idisable_interrupt(); evf->pattern &= pattern; tn_ienable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_queue_ireceive(TN_DQUE * dque,void ** data_ptr) { TN_INTSAVE_DATA_INT int rc; CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(dque == NULL || data_ptr == NULL) return TERR_WRONG_PARAM; if(dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); rc = dque_fifo_read(dque,data_ptr); if(rc == TERR_NO_ERR) //-- There was entry(s) in data queue { if(!is_queue_empty(&(dque->wait_send_list))) { que = queue_remove_head(&(dque->wait_send_list)); task = get_task_by_tsk_queue(que); dque_fifo_write(dque,task->data_elem); //-- Put to data FIFO if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } } } else //-- data FIFO is empty { if(!is_queue_empty(&(dque->wait_send_list))) { que = queue_remove_head(&(dque->wait_send_list)); task = get_task_by_tsk_queue(que); *data_ptr = task->data_elem; //-- Return to caller if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { rc = TERR_TIMEOUT; } } tn_ienable_interrupt(); return rc; }