//---------------------------------------------------------------------------- int tn_queue_delete(TN_DQUE * dque) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT while(!is_queue_empty(&(dque->wait_send_list))) { tn_disable_interrupt(); //--- delete from sem wait queue que = queue_remove_head(&(dque->wait_send_list)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } while(!is_queue_empty(&(dque->wait_receive_list))) { tn_disable_interrupt(); //--- delete from sem wait queue que = queue_remove_head(&(dque->wait_receive_list)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); dque->id_dque = 0; // Data queue not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_mutex_delete(TN_MUTEX * mutex) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(mutex == NULL) return TERR_WRONG_PARAM; if(mutex->id_mutex != TN_ID_MUTEX) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT if(tn_curr_run_task != mutex->holder) { tn_enable_interrupt(); return TERR_ILUSE; } //-- Remove all tasks(if any) from mutex's wait queue while(!is_queue_empty(&(mutex->wait_queue))) { tn_disable_interrupt(); que = queue_remove_head(&(mutex->wait_queue)); task = get_task_by_tsk_queue(que); //-- If the task in system's blocked list, remove it if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) tn_disable_interrupt(); if(mutex->holder != NULL) //-- If the mutex is locked { do_unlock_mutex(mutex); queue_reset(&(mutex->mutex_queue)); } mutex->id_mutex = 0; // Mutex not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
void hw_delay(unsigned long uS) { TN_INTSAVE_DATA tn_disable_interrupt(); MAP_SysCtlDelay(MAP_SysCtlClockGet() / 1000000 * uS / 3); // The loop takes 3 cycles/loop tn_enable_interrupt(); }
//---------------------------------------------------------------------------- int tn_task_sleep(unsigned long timeout) { TN_INTSAVE_DATA int rc; if(timeout == 0) return TERR_WRONG_PARAM; TN_CHECK_NON_INT_CONTEXT tn_disable_interrupt(); if(tn_curr_run_task->wakeup_count > 0) { tn_curr_run_task->wakeup_count--; rc = TERR_NO_ERR; } else { task_curr_to_wait_action(NULL, TSK_WAIT_REASON_SLEEP, timeout); tn_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- // Acquire(Polling) Semaphore Resource (do not call in the interrupt) //---------------------------------------------------------------------------- int tn_sem_polling(TN_SEM * sem) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_interrupt(); if(sem->count >= 1) { sem->count--; rc = TERR_NO_ERR; } else rc = TERR_TIMEOUT; tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_fmem_get_polling(TN_FMP * fmp,void ** p_data) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_interrupt(); ptr = fm_get(fmp); if(ptr != NULL) //-- Get memory { *p_data = ptr; rc = TERR_NO_ERR; } else rc = TERR_TIMEOUT; tn_enable_interrupt(); return rc; }
/** * * @param task * * @return TN_RETVAL */ TN_RETVAL tnec_task_delete (TN_TCB_S *task) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ 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_task_context()) return TERR_WCONTEXT; tn_disable_interrupt(); rc = TERR_NO_ERR; for (;;) { if (task->task_state != TSK_STATE_DORMANT) { rc = TERR_WCONTEXT; break; } queue_remove_entry(&(task->create_queue)); tn_created_tasks_qty--; task->id_task = TN_ID_UNKNOWN; break; } tn_enable_interrupt(); return rc; }
//----------------------------------------------------------------------------- int tn_task_delete(TN_TCB * task) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_interrupt(); rc = TERR_NO_ERR; if(task->task_state != TSK_STATE_DORMANT) rc = TERR_WCONTEXT; //-- Cannot delete not-terminated task else { queue_remove_entry(&(task->create_queue)); tn_created_tasks_qty--; task->id_task = 0; } tn_enable_interrupt(); return rc; }
/** * * @param timeout * * @return TN_RETVAL */ TN_RETVAL tnnc_task_sleep (TN_TIMEOUT timeout) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ TN_RETVAL rc; /* Not check parameter error if (timeout == 0) return TERR_WRONG_PARAM; */ if (tn_is_non_task_context()) { return TERR_WCONTEXT; } tn_disable_interrupt(); if (tn_curr_run_task->wakeup_count > 0) { tn_curr_run_task->wakeup_count--; rc = TERR_NO_ERR; } else { task_curr_to_wait_action(TN_NULL, TSK_WAIT_REASON_SLEEP, timeout); tn_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } tn_enable_interrupt(); return rc; }
/** * * @param sem * @param timeout * * @return TN_RETVAL */ TN_RETVAL tnec_sem_acquire (TN_SEM_S *sem, TN_TIMEOUT timeout) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ TN_RETVAL rc; if (sem == TN_NULL || timeout == 0 || sem->max_count == 0) return TERR_WRONG_PARAM; if (sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; if (tn_is_non_task_context()) { return TERR_WCONTEXT; } tn_disable_interrupt(); if (sem->count >= 1) { sem->count--; rc = TERR_NO_ERR; } else { task_curr_to_wait_action(&(sem->wait_queue),TSK_WAIT_REASON_SEM,timeout); tn_enable_interrupt(); tn_switch_context(); return tn_curr_run_task->task_wait_rc; } tn_enable_interrupt(); return rc; }
unsigned long hw_time() { TN_INTSAVE_DATA tn_disable_interrupt(); unsigned long const ticks = g_sys_ticks; tn_enable_interrupt(); return ticks; }
unsigned long hw_time_span(unsigned long time) { TN_INTSAVE_DATA tn_disable_interrupt(); unsigned long const span = g_sys_ticks - time; // unsigned half owerflov tn_enable_interrupt(); return span; }
/** * * @param dque * @param data_ptr * @param timeout * * @return TN_RETVAL */ TN_RETVAL tnnc_queue_send (TN_DQUE_S *dque, void *data_ptr, TN_TIMEOUT timeout) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ TN_RETVAL rc; CDLL_QUEUE_S *que; TN_TCB_S *task; /* Not check parameter error if (dque == TN_NULL || timeout == 0) return TERR_WRONG_PARAM; */ if (dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; if (tn_is_non_task_context()) { return TERR_WCONTEXT; } tn_disable_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_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { rc = dque_fifo_write(dque,data_ptr); if (rc != TERR_NO_ERR) { tn_curr_run_task->data_elem = data_ptr; task_curr_to_wait_action(&(dque->wait_send_list), TSK_WAIT_REASON_DQUE_WSEND, timeout); tn_enable_interrupt(); tn_switch_context(); return tn_curr_run_task->task_wait_rc; } } tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_wait(TN_EVENT * evf, unsigned int wait_pattern, int wait_mode, unsigned int * p_flags_pattern, unsigned int timeout) { TN_INTSAVE_DATA int rc; //-- return code int fCond; if(evf == NULL || wait_pattern == 0 || p_flags_pattern == NULL || timeout == 0) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; TN_CHECK_NON_INT_CONTEXT tn_disable_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 { tn_curr_run_task->ewait_mode = wait_mode; tn_curr_run_task->ewait_pattern = wait_pattern; task_curr_to_wait_action(&(evf->wait_queue),TSK_WAIT_REASON_EVENT,timeout); tn_enable_interrupt(); tn_switch_context(); if(tn_curr_run_task->task_wait_rc == TERR_NO_ERR) *p_flags_pattern = tn_curr_run_task->ewait_pattern; return tn_curr_run_task->task_wait_rc; } } tn_enable_interrupt(); return rc; }
TN_RETVAL tnnc_event_wait_polling (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; /* for SR save */ TN_RETVAL rc; TN_BOOL fCond; /* Not check parameter error if (evf == TN_NULL || wait_pattern == 0 || p_flags_pattern == TN_NULL) return TERR_WRONG_PARAM; */ if (evf->id_event != TN_ID_EVENT) return TERR_NOEXS; /* Check calling context - not interrupt and not user critical section */ if (tn_is_non_task_context()) return TERR_WCONTEXT; tn_disable_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) { /* Event pattern is equal asked */ *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 { /* Return with TERR_TIMEOUT code */ rc = TERR_TIMEOUT; } } tn_enable_interrupt(); return rc; }
/** * * @param attr */ void tnec_task_exit (TN_UWORD attr) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ TN_TCB_S *task; CDLL_QUEUE_S *que; TN_MUTEX_S *mutex; TN_UWORD *ptr_stack; if (tn_is_non_task_context()) return; tn_save_sr(); /* just for PIC24/dsPIC */ tn_disable_interrupt(); while (!is_queue_empty(&(tn_curr_run_task->mutex_queue))) { que = queue_remove_head(&(tn_curr_run_task->mutex_queue)); mutex = get_mutex_by_mutex_queue(que); do_unlock_mutex(mutex); } task = tn_curr_run_task; task_to_non_runnable(tn_curr_run_task); task_set_dormant_state(task); ptr_stack = tn_stack_init(task->task_func_addr, task->stk_start, task->stk_size, task->task_func_param ); task->task_stk = ptr_stack; if (task->activate_count > 0) { task->activate_count--; task_to_runnable(task); } else { /* Alex B. - delete task only if activate counter = 0 ! */ if (attr == TN_EXIT_AND_DELETE_TASK) { queue_remove_entry(&(task->create_queue)); tn_created_tasks_qty--; task->id_task = TN_ID_UNKNOWN; } } tn_switch_context_exit(tn_save_status_reg); /* Exit from task with restore saved SR*/ }
//---------------------------------------------------------------------------- int tn_fmem_delete(TN_FMP * fmp) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(fmp == NULL) return TERR_WRONG_PARAM; if(fmp->id_fmp != TN_ID_FSMEMORYPOOL) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT while(!is_queue_empty(&(fmp->wait_queue))) { tn_disable_interrupt(); //--- delete from sem wait queue que = queue_remove_head(&(fmp->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) tn_disable_interrupt(); fmp->id_fmp = 0; //-- Fixed-size memory pool not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_sem_delete(TN_SEM * sem) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(sem == NULL) return TERR_WRONG_PARAM; if(sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT while(!is_queue_empty(&(sem->wait_queue))) { tn_disable_interrupt(); //--- 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)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); sem->id_sem = 0; // Semaphore not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
/** * * @param sem * * @return TN_RETVAL */ TN_RETVAL tnnc_sem_signal (TN_SEM_S *sem) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ TN_RETVAL rc; CDLL_QUEUE_S *que; TN_TCB_S *task; /* Not check parameter error if (sem == TN_NULL || sem->max_count == 0) return TERR_WRONG_PARAM; */ if (sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; if (tn_is_non_task_context()) { return TERR_WCONTEXT; } tn_disable_interrupt(); if (!(is_queue_empty(&(sem->wait_queue)))) { que = queue_remove_head(&(sem->wait_queue)); task = get_task_by_tsk_queue(que); if (task_wait_complete(task, TN_FALSE)) { tn_enable_interrupt(); tn_switch_context(); 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_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- static void tn_timer_task_func(void * par) { TN_INTSAVE_DATA volatile TN_TCB * task; volatile CDLL_QUEUE * curr_que; //-- User application init - user's objects initial (tasks etc.) creation tn_app_init(); //-- Enable interrupt here ( include tick int) tn_cpu_int_enable(); //------------------------------------------------------------------------- for(;;) { //------------ OS timer tick ------------------------------------- tn_disable_interrupt(); curr_que = tn_wait_timeout_list.next; while(curr_que != &tn_wait_timeout_list) { task = get_task_by_timer_queque((CDLL_QUEUE*)curr_que); if(task->tick_count != TN_WAIT_INFINITE) { if(task->tick_count > 0) { task->tick_count--; if(task->tick_count == 0) //-- Time out expiried { queue_remove_entry(&(((TN_TCB*)task)->task_queue)); task_wait_complete((TN_TCB*)task); task->task_wait_rc = TERR_TIMEOUT; } } } curr_que = curr_que->next; } task_curr_to_wait_action(NULL, TSK_WAIT_REASON_SLEEP, TN_WAIT_INFINITE); tn_enable_interrupt(); tn_switch_context(); } }
//---------------------------------------------------------------------------- int tn_queue_send(TN_DQUE * dque, void * data_ptr, unsigned long timeout) { TN_INTSAVE_DATA int rc; CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(dque == NULL || timeout == 0) return TERR_WRONG_PARAM; if(dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT tn_disable_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_enable_interrupt(); tn_switch_context(); 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 the data queue { tn_curr_run_task->data_elem = data_ptr; //-- Store data_ptr task_curr_to_wait_action(&(dque->wait_send_list), TSK_WAIT_REASON_DQUE_WSEND, timeout); tn_enable_interrupt(); tn_switch_context(); return tn_curr_run_task->task_wait_rc; } } tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_wait_polling(TN_EVENT * evf, unsigned int wait_pattern, int wait_mode, unsigned int * p_flags_pattern) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_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_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- // Release Semaphore Resource //---------------------------------------------------------------------------- int tn_sem_signal(TN_SEM * sem) { TN_INTSAVE_DATA int rc; //-- return code 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_NON_INT_CONTEXT tn_disable_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_enable_interrupt(); tn_switch_context(); 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_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_delete(TN_EVENT * evf) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(evf == NULL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT tn_disable_interrupt(); // v.2.7 - thanks to Eugene Scopal while(!is_queue_empty(&(evf->wait_queue))) { //--- delete from sem wait queue que = queue_remove_head(&(evf->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); tn_disable_interrupt(); // v.2.7 } } evf->id_event = 0; // Event not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
TN_SYS_TIM_T tncm_sys_time_get (void) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ TN_SYS_TIM_T ret; tn_save_sr(); if (tn_sys_context == TN_CONTEXT_TASK) { /* in task now */ tn_disable_interrupt(); } ret = tn_sys_time_count; tn_rest_sr(); return ret; }
//---------------------------------------------------------------------------- int tn_task_wakeup(TN_TCB * task) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_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_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { // v.2.7 - Thanks to Eugene Scopal //-- Check for 0 - case max wakeup_count value is 1 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_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_delete(TN_EVENT * evf) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; if(evf == NULL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; TN_CHECK_NON_INT_CONTEXT while(!is_queue_empty(&(evf->wait_queue))) { if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); //--- delete from sem wait queue que = queue_remove_head(&(evf->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task,FALSE)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); evf->id_event = 0; // Event not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
/** * * @param task * * @return TN_RETVAL */ TN_RETVAL tnec_task_wakeup (TN_TCB_S *task) { TN_UWORD tn_save_status_reg TN_UNUSED; /* for SR save */ 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_task_context()) { return TERR_WCONTEXT; } tn_disable_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_FALSE)) { tn_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { if (tn_curr_run_task->wakeup_count == 0) { tn_curr_run_task->wakeup_count++; rc = TERR_NO_ERR; } else rc = TERR_OVERFLOW; } } tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- // If the task is runnable, it is moved to the SUSPENDED state. If the task // is in the WAITING state, it is moved to the WAITINGÂSUSPENDED state. //---------------------------------------------------------------------------- int tn_task_suspend(TN_TCB * task) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_interrupt(); if(task->task_state & TSK_STATE_SUSPEND) rc = TERR_OVERFLOW; else { if(task->task_state == TSK_STATE_DORMANT) rc = TERR_WSTATE; else { if(task->task_state == TSK_STATE_RUNNABLE) { task->task_state = TSK_STATE_SUSPEND; task_to_non_runnable(task); tn_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } else { task->task_state |= TSK_STATE_SUSPEND; rc = TERR_NO_ERR; } } } tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_queue_send_polling(TN_DQUE * dque, void * data_ptr) { TN_INTSAVE_DATA 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_NON_INT_CONTEXT tn_disable_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_enable_interrupt(); tn_switch_context(); 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_enable_interrupt(); return rc; }