/**************************************************************************** *^Copyright (c) 2006 DST Technologies Inc. All Rights Reserved. * * Module: OSLIB * * Description: Unified APIs for interfacing with different operating systems * (LINUX) * * Notes: This module implement APIs to interface with the following * operating system's objects: * - Tasks * - Mutexes * - Events * - Timers * - Queues * - Semaphores * * General rules * ------------- * - Mutexes, Events, Semaphores and Queues can be shared among * multiple processes in systems that support multi processes. * - When timeout is used, it is accurate only if the OS provide * a way of getting system ticks. Otherwise, system ticks are * assumed to be 100 per second. Either way, the timeout * resolution required by any API is 1/100 of a second. * - NONE of these APIs can be called from ISRs except for: * DstCore_EventSet * DstCore_EventReset * DstCore_QueuePost * - All objects that can be pended on are created for pending * with priority-inheritence. This is to eliminate priority * inversion. * ***************************************************************************/ /*========================== * Includes *=========================*/ #include #include "dsthalcommon.h" #include "module/dstmodule.h" #include "os.h" #include "os_prive.h" #if USE_V2LIN==1 #include "vxw_hdrs.h" #endif #define MUTEX_IC 0xfffffff0 #ifdef DMALLOC #include #endif /*========================== * External declarations *=========================*/ /*================================== * Local variables per process *=================================*/ /*^^*************************************************************************** *^CORE_TASK_ID DstCore_TaskCreate (void (*TaskFuncPtr) (void *), void *Param, * DS_U32 Priority) * * Description: Dynamically create a task. * * Entry : TaskFuncPtr = Pointer to task starting address * Parameter = Parameter to be passed to the task * Priority = Can be one of the following values: * TASK_PRIOR_CALLER Use caller priority * TASK_PRIOR_LOWEST Lowest possible priority * TASK_PRIOR_LOW * TASK_PRIOR_NORMAL * TASK_PRIOR_HIGH * TASK_PRIOR_HIGHEST * TASK_PRIOR_IST Highest possible priority * If Priority is set to any value between 0-255, it * will be passed as-is to the OS * * Return: Task ID or * NULL if any error * * Notes : If the required task priority is TASK_PRIOR_CALLER and this * function can not obtain caller priority for any reason, the task * will be created with TASK_PRIOR_NORMAL. This function will not * return an error if the priority of the newly created task could * not be set. * **************************************************************************^^*/ CORE_TASK_ID DstCore_TaskCreate (void (*TaskFuncPtr) (void *), void *Parameter, DS_U32 Priority) { pthread_t TaskId; DS_S32 RetVal; void * (*pfnThreadFunc)(void *) = (void * (*)(void*)) TaskFuncPtr; RetVal = pthread_create (&TaskId, NULL, pfnThreadFunc, Parameter); if (RetVal == 0) { DstCore_TaskSetPriority ((CORE_TASK_ID) TaskId, Priority); return ((CORE_TASK_ID) TaskId); } return ((CORE_TASK_ID) 0); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskSuspend (CORE_TASK_ID TaskId) * * Description: Suspend a task. * * Entry : TaskId = Returned by TaskCreate * Use 0 to suspend the calling task * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_TaskSuspend (CORE_TASK_ID TaskId) { if (TaskId == 0) { TaskId = (CORE_TASK_ID)pthread_self(); } if (pthread_kill((pthread_t)TaskId, SIGSTOP) == 0) { return (OS_OK); } return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskResume (CORE_TASK_ID TaskId) * * Description: Resume a previously suspended task. * * Entry : TaskId = Returned by TaskCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_TaskResume (CORE_TASK_ID TaskId) { if (pthread_kill((pthread_t)TaskId, SIGCONT) == 0) { return (OS_OK); } return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskGetInfo (CORE_TASK_ID *TaskId) * * Description: Get information about the current task (the caller). * * Entry : TaskId = Pointer to CORE_TASK_ID to receive task ID. * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_TaskGetInfo (CORE_TASK_ID *TaskId) { *TaskId = (CORE_TASK_ID)pthread_self(); return (OS_OK); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskSetPriority (CORE_TASK_ID TaskId, DS_U32 Priority) * * Description: Change task priority * * Entry : TaskId = Returned by TaskCreate. * Use 0 to specify calling task. * Priority = Can be one of the following values: * TASK_PRIOR_CALLER Use caller priority * TASK_PRIOR_LOWEST Lowest possible priority * TASK_PRIOR_LOW * TASK_PRIOR_NORMAL * TASK_PRIOR_HIGH * TASK_PRIOR_HIGHEST * TASK_PRIOR_IST Highest possible priority * If Priority is set to any value between 0-255, it * will be passed as-is to the OS * * Return: OS_OK * OS_FAIL * * Notes : If the required task priority is TASK_PRIOR_CALLER and this * function can not obtain caller priority for any reason, the task * will be created with TASK_PRIOR_NORMAL * **************************************************************************^^*/ DS_U32 DstCore_TaskSetPriority (CORE_TASK_ID TaskId, DS_U32 Priority) { CORE_TASK_ID CallerTid; int Policy = SCHED_FIFO; struct sched_param SchedParam; if (TaskId == 0) { DstCore_TaskGetInfo (&TaskId); } if (Priority > 255) { switch (Priority) { case TASK_PRIOR_LOWEST: Priority = 1; break; case TASK_PRIOR_LOW: Priority = 20; break; case TASK_PRIOR_NORMAL: Priority = 40; break; case TASK_PRIOR_HIGH: Priority = 70; break; case TASK_PRIOR_HIGHEST: Priority = 90; break; case TASK_PRIOR_IST: Priority = 99; break; case TASK_PRIOR_CALLER: default: Priority = 40; DstCore_TaskGetInfo (&CallerTid); if (pthread_getschedparam((pthread_t)CallerTid, &Policy, &SchedParam)== 0) { Priority = SchedParam.sched_priority; } break; } } SchedParam.sched_priority = Priority; if (pthread_setschedparam ((pthread_t)TaskId, Policy, &SchedParam) == 0) { return (OS_OK); } return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskDelete (CORE_TASK_ID TaskId) * * Description: Delete a task. * * Entry : TaskId = Returned by TaskCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_TaskDelete (CORE_TASK_ID TaskId) { DS_S32 RetVal; CORE_TASK_ID CurrentId = (CORE_TASK_ID)pthread_self(); /* if taskid is zero, thread wants to self terminate, set value to current id */ if( TaskId == 0 ) { TaskId = CurrentId; } /* check if a task wants to terminate itself */ if (CurrentId != TaskId) { /* * Can't terminate another thread. it must do it's self, or must * modify cancellation attributes. Without this attribute, the thread * may refuse to die unless/util it calls a cancellation point, which * means it calls certain system apis, blocking operation like * semaphore wait, or calls pthread_testcancel () periodically... */ pthread_cancel ((pthread_t)TaskId); /* Send cancel request */ pthread_join ((pthread_t) TaskId, NULL); /* Wait for task to exit */ } else { /* Thread wants to terminate itself */ pthread_detach( (pthread_t)CurrentId ); pthread_exit (&RetVal); } return (OS_OK); } /*^^*************************************************************************** *^CORE_SEM_ID DstCore_SemCreate (DS_U32 SemName, DS_U32 InitCount) * * Description: It creates a semaphore object with the specified count. * * Entry : SemName = Unique number identifying the semaphore. * Set to NULL to create unnamed semaphore (can not be * used for inter-process synchronization) * InitCount = Initial semaphore count (1 to 255) * or 0xfffffff0 for a mutex * * Return: Semaphore ID or * 0 if any error * * Notes : The entry SemName is used only in systems that support multiple * processes. * **************************************************************************^^*/ CORE_SEM_ID DstCore_SemCreate (DS_U32 SemName, DS_U32 InitCount) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_CREATE; ObjOp.Prm1 = SemName; ObjOp.Prm2 = InitCount; Os_PerformIoctl (DSTHWIOC_SEM_OP, &ObjOp); if ((ObjOp.RetCode == OBJ_OK) && (ObjOp.Prm2 != 0)) { return (ObjOp.Prm2); } INFO_MSG ("\n*** Semaphore create error 0x%lx ***\n", ObjOp.RetCode); #endif return (0); } /*^^*************************************************************************** *^DS_U32 DstCore_SemLock (CORE_SEM_ID SemId, DS_U32 Timeout) * * Description: * * Entry : SemId = Returned by SemCreate * Timeout = In 1/100 of a second increments. This is ONLY accurate * if the OS provides a way of getting system ticks/second. * = 0 to return immidiately if the resource not available * = WAIT_FOREVER to wait forever on the resource * * Return: OS_OK * OS_TIMEOUT * OS_FAIL * Notes : **************************************************************************^^*/ DS_U32 DstCore_SemLock (CORE_SEM_ID SemId, DS_U32 Timeout) { DS_U32 RetVal = OS_FAIL; #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Prm2 = Timeout; while (_TRUE_) { ObjOp.Opcode = OBJ_OPCODE_LOCK; ObjOp.Prm1 = SemId; Os_PerformIoctl (DSTHWIOC_SEM_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { RetVal = OS_OK; break; } if (ObjOp.RetCode == OBJ_TIMEOUT) { RetVal = OS_TIMEOUT; break; } if (ObjOp.RetCode == OBJ_SIGNAL_RCV) { INFO_MSG ("\n*** Semaphore Signal Received ***\n"); } else { INFO_MSG ("\n*** Semaphore lock error %ld ***\n", ObjOp.RetCode); break; } } #endif return (RetVal); } /*^^*************************************************************************** *^DS_U32 DstCore_SemUnlock (CORE_SEM_ID SemId) * * Description: * * Entry : SemId = Returned by SemCreate * * Return: OS_OK * OS_FAIL * * Description: This function unlock a semaphore. The semaphore count will be * incremented if succeeds. * Note: **************************************************************************^^*/ DS_U32 DstCore_SemUnlock (CORE_SEM_ID SemId) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_UNLOCK; ObjOp.Prm1 = SemId; Os_PerformIoctl (DSTHWIOC_SEM_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { return (OS_OK); } INFO_MSG ("\n*** Semaphore unlock error %ld ***\n", ObjOp.RetCode); #endif return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_SemDelete (CORE_SEM_ID SemId) * * Description: * * Entry : SemId = Returned by SemCreate * * Return: OS_OK * OS_FAIL * * Description: This function delete the semaphore object in the system. * Notes : **************************************************************************^^*/ DS_U32 DstCore_SemDelete (CORE_SEM_ID SemId) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_DELETE; ObjOp.Prm1 = SemId; Os_PerformIoctl (DSTHWIOC_SEM_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { return (OS_OK); } INFO_MSG ("\n*** Semaphore delete error %ld ***\n", ObjOp.RetCode); #endif return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskLockCreate (void) * * Description: Create a task locking object * * Entry : None * * Return: Lock object ID * 0 if error * * Notes : This call creates a task locking object. * The lock object is used as a parameter to DstCore_TaskLockSet() and * can be deleted when not needed by calling DstCore_TaskLockDelete(). * The lock object will obtain execlusive access to a piece of code * only on a process basis. To obtain inter-process execlusive access * to a piece of code or data, use named mutexes. **************************************************************************^^*/ CORE_LOCK_ID DstCore_TaskLockCreate (void) { return ((CORE_LOCK_ID)(DstCore_SemCreate (0, MUTEX_IC))); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskLockSet (CORE_LOCK_ID LockId) * * Description: Obtain execlusive access to a piece of code/data. * * Entry : LockId = Task lock ID returned by DstCore_TaskLockCreate() * * Return: OS_OK * OS_FAIL * * Notes : This call should be paired with DstCore_TaskLockReset. Interrupts * will not be disabled as a result of this call. This call is similar * to DstCore_MutexLock except that Locks applies to tasks in the * current process only. Mutexes, on the other hand, are system wide. * The task that resets the lock must be the same task that set it. **************************************************************************^^*/ DS_U32 DstCore_TaskLockSet (CORE_LOCK_ID LockId) { return (DstCore_SemLock(LockId, OS_WAIT_FOREVER)); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskLockReset (CORE_LOCK_ID LockId) * * Description: Release task execlusive access to a piece of code/data. * * Entry : LockId = Task lock ID returned by DstCore_TaskLockCreate() * * Return: OS_OK * OS_FAIL * * Notes : This call should be paired with DstCore_TaskLockSet. Interrupts * will not be affaected as a result of this call. This call is * similar to DstCore_MutexUnlock except that Locks applies to tasks * in the current process only. Mutexes, on the other hand, are * system wide resources. The task that resets the lock must be the * same task that set it using DstCore_TaskLockSet(). **************************************************************************^^*/ DS_U32 DstCore_TaskLockReset (CORE_LOCK_ID LockId) { return (DstCore_SemUnlock(LockId)); } /*^^*************************************************************************** *^DS_U32 DstCore_TaskLockDelete (CORE_LOCK_ID LockId) * * Description: Delete a task lock object. * * Entry : LockId = Task lock ID returned by DstCore_TaskLockCreate() * * Return: OS_OK * OS_FAIL * * Notes : This call should be paired with DstCore_TaskLockCreate. **************************************************************************^^*/ DS_U32 DstCore_TaskLockDelete (CORE_LOCK_ID LockId) { return (DstCore_SemDelete(LockId)); } /*^^*************************************************************************** *^CORE_MUTEX_ID DstCore_MutexCreate (DS_U32 MutexName) * * Description: Create a mutual execlusion object (Mutex) * * Entry : MutexName = Unique number identifying the mutex. * Set to NULL to create unnamed mutex (can not be used * for inter-process synchronization) * * Return: Mutex ID or * 0 if any error * * Notes : The mutex will be created in non-locked state. * The entry MutexName is used only in systems that support multiple * processes. **************************************************************************^^*/ CORE_MUTEX_ID DstCore_MutexCreate (DS_U32 MutexName) { return (DstCore_SemCreate (MutexName, MUTEX_IC)); } /*^^*************************************************************************** *^DS_U32 DstCore_MutexLock (CORE_MUTEX_ID MutexId, DS_U32 Timeout) * * Description: Lock a mutex with timeout. * * Entry : MutexId = Returned by DstCore_MutexCreate * Timeout = In 1/100 of a second increments. This is ONLY accurate * if the OS provides a way of getting system ticks/second. * = 0 to return immidiately if the resource not available * = OS_WAIT_FOREVER to wait forever on the resource * * Return: OS_OK * OS_TIMEOUT * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_MutexLock (CORE_MUTEX_ID MutexId, DS_U32 Timeout) { return (DstCore_SemLock(MutexId, Timeout)); } /*^^*************************************************************************** *^DS_U32 DstCore_MutexUnlock (CORE_MUTEX_ID MutexId) * * Description: Unlock a previously locked mutex * * Entry : MutexId = Returned by DstCore_MutexCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_MutexUnlock (CORE_MUTEX_ID MutexId) { return (DstCore_SemUnlock(MutexId)); } /*^^*************************************************************************** *^DS_U32 DstCore_MutexDelete (CORE_MUTEX_ID MutexId) * * Description: Delete a mutex * * Entry : MutexId = Returned by DstCore_MutexCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_MutexDelete (CORE_MUTEX_ID MutexId) { return (DstCore_SemDelete(MutexId)); } /*^^************************************************************************* *^CORE_EVENT_ID DstCore_EventCreate(DS_U32 EventName, DS_BOOL bManualReset) * * Description: Creates an event object. * * Entry: EventName = Unique number identifying the Event. * Set to NULL to create unnamed event (can not be used * for inter-process synchronization) * Signaled = _TRUE_ to create the evenet in signaled state. * _FALSE_ to create the evenet in non-signaled state. * * Return: A handle to the event object if succeeds . * It returns 0 if the call fails. * * Notes: The entry EventName is used only in systems that support multiple * processes. *************************************************************************^^*/ CORE_EVENT_ID DstCore_EventCreate (DS_U32 EventName, DS_BOOL Signaled) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_CREATE; ObjOp.Prm1 = EventName; ObjOp.Prm2 = Signaled; Os_PerformIoctl (DSTHWIOC_EVENT_OP, &ObjOp); if ((ObjOp.RetCode == OBJ_OK) && (ObjOp.Prm2 != 0)) { return (ObjOp.Prm2); } INFO_MSG ("\n*** Event create error %ld ***\n", ObjOp.RetCode); #endif return (0); } /*^^*************************************************************************** *^DS_U32 DstCore_EventSet (CORE_EVENT_ID EventId) * * Description: Set an event to signaled state * * Entry : EventId = Returned by EventCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EventSet (CORE_EVENT_ID EventId) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_SET; ObjOp.Prm1 = EventId; Os_PerformIoctl (DSTHWIOC_EVENT_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { return (OS_OK); } INFO_MSG ("\n*** Event set error %ld ***\n", ObjOp.RetCode); #endif return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_EventReset (CORE_EVENT_ID EventId) * * Description: Set an event to non-signaled state * * Entry : EventId = Returned by EventCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EventReset (CORE_EVENT_ID EventId) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_RESET; ObjOp.Prm1 = EventId; Os_PerformIoctl (DSTHWIOC_EVENT_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { return (OS_OK); } INFO_MSG ("\n*** Event set error %ld ***\n", ObjOp.RetCode); #endif return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_EventWait (CORE_EVENT_ID EventId, DS_BOOL AutoReset, DS_U32 Timeout) * * Description: Wait for an event with a timeout. * * Entry : EventId = Returned by EventCreate * AutoReset = _TRUE_ to reset the event after receiving it. * _FALSE_ to leave the event signaled after receiving it. * Timeout = In 1/100 of a second increments. This is ONLY accurate * if the OS provides a way of getting system ticks/sec. * = OS_WAIT_FOREVER to wait forever on the resource * * Return: OS_OK * OS_TIMEOUT * OS_FAIL * * Notes : * **************************************************************************^^*/ DS_U32 DstCore_EventWait (CORE_EVENT_ID EventId, DS_BOOL AutoReset, DS_U32 Timeout) { #if USE_V2LIN==0 OBJ_OPER ObjOp; DS_U32 RetVal = OS_FAIL; ObjOp.Prm2 = Timeout; while (_TRUE_) { ObjOp.Opcode = OBJ_OPCODE_WAIT; ObjOp.Prm1 = EventId; ObjOp.RetCode = AutoReset; Os_PerformIoctl (DSTHWIOC_EVENT_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { RetVal = OS_OK; break; } if (ObjOp.RetCode == OBJ_TIMEOUT) { RetVal = OS_TIMEOUT; break; } if (ObjOp.RetCode == OBJ_SIGNAL_RCV) { INFO_MSG ("\n*** Event Signal Received ***\n"); } else { INFO_MSG ("\n*** Event wait error %ld ***\n", ObjOp.RetCode); break; } } return (RetVal); #else return CORE_INVALID_ID; #endif } /*^^*************************************************************************** *^DS_U32 DstCore_EventDelete (CORE_EVENT_ID EventId) * * Description: Delete an event. * * Entry : EventId = Returned by EventCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EventDelete (CORE_EVENT_ID EventId) { #if USE_V2LIN==0 OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_DELETE; ObjOp.Prm1 = EventId; Os_PerformIoctl (DSTHWIOC_EVENT_OP, &ObjOp); if (ObjOp.RetCode == OBJ_OK) { return (OS_OK); } INFO_MSG ("\n*** Event delete error %ld ***\n", ObjOp.RetCode); #endif return (OS_FAIL); } /*^^*************************************************************************** *^CORE_EVENT_ID DstCore_EvGroupCreate (DS_BOOL Signaled, DS_U32 SubEvents) * * Description: Create multiple events in an event group * * Entry : Signaled = _TRUE_ to create the events in signaled state. * _FALSE_ to create the events in non-signaled state. * SubEvents = Number of distinct sub-events encompassed by the event. * * Return: Event group ID or * NULL if any error * * Notes : An event group is a max of 32 events represented by bits in a * word. An event is set if a bit is set and reset otherwise. * Event groups can not be shared between processes. * **************************************************************************^^*/ CORE_EVENT_ID DstCore_EvGroupCreate(DS_BOOL Signaled, DS_U32 SubEvents) { return (CORE_INVALID_ID); } /*^^*************************************************************************** *^DS_U32 DstCore_EvGroupSet (CORE_EVENT_ID EventId, DS_U32 Mask) * * Description: * * Entry : EventId = Returned by EventsCreate * Mask = Mask to set the required events in the group * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EvGroupSet(CORE_EVENT_ID EventId, DS_U32 Mask) { return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_EvGroupReset (CORE_EVENT_ID EventId, DS_U32 Mask) * * Description: * * Entry : EventId = Returned by EventCreate * Mask = Mask for the events to be reset in the event group * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EvGroupReset(CORE_EVENT_ID EventId, DS_U32 Mask) { return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_EvGroupWait (CORE_EVENT_ID EventId, DS_U32 *EventsPtr, * DS_BOOL AutoReset, DS_U32 Timeout) * * Description: * * Entry : EventId = Returned by EventCreate * AutoReset = _TRUE_ to reset the events after receiving it. * _FALSE_ to leave the events signaled after receiving it. * EventsPtr = Ptr to the mask of the required events bits. Any other * pending sub-events are ingored. This ptr also receives * the pending events on return. * Timeout = In 1/100 of a second increments. This is ONLY accurate * if the OS provides a way of getting system ticks/sec. * = OS_WAIT_FOREVER to wait forever on the resource * * Return: OS_OK * OS_TIMEOUT * OS_FAIL * If OS_OK is returned, *EventsPtr is set to reflect the events * that actually happened * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EvGroupWait (CORE_EVENT_ID EventId, DS_U32 *EventsPtr, DS_BOOL AutoReset, DS_U32 Timeout) { return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_EvGroupDelete (CORE_EVENT_ID EventId) * * Description: Delete an event group. * * Entry : EventId = Returned by EventsCreate * * Return: OS_OK * OS_FAIL * * Notes : **************************************************************************^^*/ DS_U32 DstCore_EvGroupDelete(CORE_EVENT_ID EventId) { return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_Get100HzClockTick (void) * * Description: Get the current clock tick based on a 100 Hz clock. * * Entry : None * * Return: Current system clock tick based on a 100 Hz clock. * * Notes : The returned value will wraparound when reaching 0xffffffff **************************************************************************^^*/ DS_U32 DstCore_Get100HzClockTick (void) { DS_S64 i; i = ((DS_S64)DstCore_GetSysClockTick()) * 100; return ((DS_U32)(i / DstCore_GetSysClockFreq())); } /*^^*************************************************************************** *^DS_U32 DstCore_GetSysClockTick (void) * * Description: Get the current clock tick based on OEM clock frequency. * * Entry : None * * Return: Current system clock tick based on clock frequency provided by * DstCore_GetSysClockFreq(). * * Notes : The returned value will wraparound when reaching 0xffffffff **************************************************************************^^*/ DS_U32 DstCore_GetSysClockTick (void) { struct timeval tv; struct timezone tz; DS_S64 Milliseconds; gettimeofday (&tv, &tz); Milliseconds = ((DS_S64) tv.tv_sec * (DS_S64) 1000) + (DS_S64) (tv.tv_usec / 1000); return ((DS_U32) Milliseconds); } /*^^*************************************************************************** *^DS_U32 DstCore_GetSysClockFreq (void) * * Description: Get system clock frequency defined by the OEM. * * Entry : None * * Return: System clock frequency. If the OS does not provide a way of * getting system clock frequency, the return value will be 100. * * Notes : The system clock frequency varies depending on the operating * system and OEM settings. Typically, the OEM sets the system * clock to 100 Hz, but this can vary. **************************************************************************^^*/ DS_U32 DstCore_GetSysClockFreq (void) { return (1000); } /*^^*************************************************************************** *^DS_U32 DstCore_SetTimeOfDay (DS_U32 UtcSeconds) * * Description: Set system time of day * * Entry : UtcSeconds = Seconds in UTC * * Return: OS_OK * OS_FAIL * * Notes : The time is in UTC (time elapsed since 00:00:00 Jan 1 1970) * **************************************************************************^^*/ DS_U32 DstCore_SetTimeOfDay (DS_U32 UtcSeconds) { struct timeval Time; Time.tv_sec = UtcSeconds; Time.tv_usec = 0; if (settimeofday (&Time, NULL) == 0) { return (OS_OK); } return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_GetTimeOfDay (DS_U32 *UtcSeconds) * * Description: Get system time of day (Coordinated Universal Time) * * Entry : *UtcSeconds = Pointer to receive seconds in UTC * * Return: OS_OK * OS_FAIL * * Notes : The returned time is UTC (time elapsed since 00:00:00 Jan 1 1970) * **************************************************************************^^*/ DS_U32 DstCore_GetLoaderVer (void) { #ifdef USE_CYGWIN return 0; #else return Os_PerformIoctl (DSTHWIOC_GET_LOADER_VER, 0); #endif } DS_U32 DstCore_GetTimeOfDay (DS_U32 *UtcSeconds) { struct timeval Time; if (gettimeofday (&Time, NULL) == 0) { *UtcSeconds = Time.tv_sec; return (OS_OK); } return (OS_FAIL); } /*^^*************************************************************************** *^DS_U32 DstCore_Delay (DS_U32 Delay) * * Description: Enter a delay state. * * Entry : Delay = In 1/1000 of a second increments(milliseconds). * This is ONLY accurate if the OS provides a way of * getting system ticks/second. * * Return: OS_OK * * Notes : This call guarantees the calling task to enter an efficient delay * state so the OS will be able to reschedule other tasks. The caller * will be suspended until the Delay time is elapsed. **************************************************************************^^*/ DS_U32 DstCore_Delay (DS_U32 Delay) { DS_U32 Sec; Sec = Delay / 1000; usleep ((Delay*1000) - (Sec*1000000)); while (Sec) { usleep (1000000); Sec--; } return (OS_OK); } /*^^*************************************************************************** *^DS_U32 DstCore_UsDelay (DS_U32 Delay) * * Description: Enter a delay state. * * Entry : Delay = In micorseconds. * This is may not be accurate on some OSes which will * generally round it up to the nearest millisecond * * Return: OS_OK * * Notes : This call guarantees the calling task to enter an efficient delay * state so the OS will be able to reschedule other tasks. The caller * will be suspended until the Delay time is elapsed. * **************************************************************************^^*/ DS_U32 DstCore_UsDelay (DS_U32 Delay) { DS_U32 Sec; Sec = Delay / 1000000; usleep (Delay - (Sec*1000000)); while (Sec) { usleep (1000000); Sec--; } return (OS_OK); } DS_U32 DstCore_RegRead (DS_U32 Address, int Size) { #ifdef USE_CYGWIN return 0; #else OBJ_OPER ObjOp; if ( Size != 1 && Size != 2 && Size != 4 ) { printf("|%s| ERROR: Invalid Size=%d\n", __FUNCTION__, Size); } ObjOp.Opcode = OBJ_OPCODE_READ; ObjOp.Prm1 = Address; ObjOp.Prm2 = Size; Os_PerformIoctl (DSTHWIOC_ATOMIC_REG_ACCESS, &ObjOp); if ((ObjOp.RetCode == OBJ_OK)) { return (ObjOp.Prm2); } INFO_MSG ("\n*** Register Read Error %ld ***\n", ObjOp.RetCode); return (0xFFFFFFFF); #endif } DS_U32 DstCore_RegWrite (DS_U32 Address, DS_U32 Value, int Size) { #ifdef USE_CYGWIN return 0; #else OBJ_OPER ObjOp; ObjOp.Opcode = OBJ_OPCODE_WRITE; ObjOp.Prm1 = Address; ObjOp.Prm2 = Value; ObjOp.RetCode = Size; Os_PerformIoctl (DSTHWIOC_ATOMIC_REG_ACCESS, &ObjOp); if ((ObjOp.RetCode == OBJ_OK)) { return (0); } INFO_MSG ("\n*** Register Write Error %ld ***\n", ObjOp.RetCode); return (0xFFFFFFFF); #endif }