/* * === FUNCTION ====================================================================== * Name: OS_SemDestroy * Description: Destroys a binary semaphore and resets the associated list. * ===================================================================================== */ int OS_SemDestroy(OS_SemID_t *_sem) { OS_SemID_t id_sem = *_sem; _sem = NULL; OS_ListReset(&(SEM(id_sem)->list)); return 0; }
/* * === FUNCTION ====================================================================== * Name: OS_SemPost * Description: This functions release the semaphore and wakes up the task * being blocked on it. A task can be also be waiting for a time event, so this * function vefiries whether the relased task is also waiting for a time event * or not. In case it is, the task is also removed from the time queue. * ===================================================================================== */ int OS_SemPost(OS_SemID_t _sem) { OS_task_t *task; OS_Node_t *n; OS_SemID_t id_sem = _sem; KTRACE_EVENT_SEM(KEVENT_UNLOCK, SEM(id_sem)->sem_id); if(OS_ListGetNum(&(SEM(id_sem)->list)) != 0) { /* Outs the task from the semaphore queue */ n = OS_ListGetNode(&(SEM(id_sem)->list)); task = GET_ELEMENT(OS_task_t, n, resource_node); /* Store what is the blocked thread in the semaphore structure */ SEM(id_sem)->tid_in = task->tid; KTRACE_EVENT_SEM_TID(KEVENT_LOCK_CATCHED, SEM(id_sem)->sem_id, task->tid); /* * Verifies if the thread is blocked in the time queue * due to a TimedWait system call */ if(task->status | TS_TIME_BLOCKED) { OS_TimeRemoveFromQueue(task); } /* Reset the wait_sem value */ task->wait_sem = 0; /* Add the blocked task to the ready task queue */ OS_SchedTaskReady(task->tid); } else { /* Increment the semaphore counter */ SEM(id_sem)->sem_value = 1; OS_ListReset(&(SEM(id_sem)->list)); } return 0; }
/* * === FUNCTION ====================================================================== * Name: OS_SemInit * Description: This function initializes a binary semaphore. The parameters * taken from the function is the pointer to the binary semaphore structure and * the initial value. The value only can be 0 (catched) or 1 (free). * ===================================================================================== */ int OS_SemInit(OS_SemID_t *_sem, uint32 _value) { OS_SemID_t id_sem; GET_NEXT_SEM_ID(id_sem); SEM(id_sem)->sem_id = id_sem; if(_value <= 0) SEM(id_sem)->sem_value = 0; /* Binary semaphore */ else SEM(id_sem)->sem_value = 1; /* Counter semaphore = 1 */ SEM(id_sem)->tid_in = 0; OS_ListReset(&(SEM(id_sem)->list)); *_sem = id_sem; return 0; }
/* * Function: void OS_TCBInit(void) * * This function initializes all the Thread Control Blocks to the init state */ void OS_TCBInit(void) { int i; OS_ListReset(&tcb_list); /* Assure that the priority of the task 0 is 0. This is important if ERCOS * is linked to C++ stuff; constructors (called from OS_CPPInit) may do * system calls and the task 0 will store the context of OS_Start function * before the first official dispatch (at the end of the function). Until * now, priority was 0 because task_table is allocated in the bss which is * zeroed at startup time (!!) */ task_table[0].priority = 0; for (i = MAIN_THREAD_TID; i < CONFIG_ERCOS_MAX_THREADS; ++i) { /* Init the thread status */ task_table[i].status = 0; /* Traps off, set S, PS and FP unit */ //task_table[i].context.psr = 0x000010c0; /* Init the thread identifier */ task_table[i].tid = i; /* Reset all the nodes associated with each thread */ OS_ListNodeReset(&task_table[i].node); OS_ListNodeReset(&task_table[i].time_node); OS_ListNodeReset(&task_table[i].resource_node); /* Add the TCB into the free TCBs queue */ OS_ListAppend(&tcb_list, &task_table[i].node); } /* create the idle task, with the minimum priority */ OS_TaskCreate (NULL, 0x600, OS_IdleTask, NULL, SCHED_MIN_PRIORITY); /* create the main task, with the maximum priority */ OS_TaskCreate (NULL, CONFIG_ERCOS_MAIN_STACK_SIZE, (void *) main, NULL, SCHED_MAX_PRIORITY); }