/**************************************************************************** *_Copyright (c) 2004 DST Technologies Inc. All Rights Reserved. * * Module: dstos.c * * Description: DST HAL OS wrapper functions ***************************************************************************/ #include #include #include #include #include #include #include #include "dstoslayer.h" #include "os.h" #include "os_prive.h" #if USE_V2LIN==1 #include "vxw_hdrs.h" #endif #ifdef DMALLOC #include #endif /*------------------------------------------------------------------------------- Configuration Definitions *------------------------------------------------------------------------------*/ #define DEBUG_SEM 0 // Semaphore Debug Message »ðÀÔ ¿©ºÎ. int os_debug = 0; /*------------------------------------------------------------------------------- Local Variables *------------------------------------------------------------------------------*/ DS_TASK_T *task_list = NULL; #if USE_V2LIN==0 OS_SEMAPHORE_ID task_list_lock = (OS_SEMAPHORE_ID)NULL; #else pthread_mutex_t task_list_lock = PTHREAD_MUTEX_INITIALIZER; #endif static int g_TaskCount = 0; /*------------------------------------------------------------------------------- Local Functions *------------------------------------------------------------------------------*/ static void lockTaskList(void); static void unlockTaskList(void); static DS_U32 taskInit(DS_TASK_T *p_new_task, void (*func)(DS_U32), char *name, DS_U16 prio, DS_U16 stacksize, DS_U32 arg); static DS_U32 taskDelete(DS_U32 taskId); #if 0 ___Thread_API_________________() #endif void OS_Init(void) { static DS_BOOL bInit = DS_FALSE; DS_TASK_T *t; if ( bInit == DS_TRUE ) return; bInit = DS_TRUE; t = (DS_TASK_T *)malloc(sizeof(DS_TASK_T)); if (!t) { printf("|%s| ERROR, Out of resources\n", __FUNCTION__); return; } memset( t, 0, sizeof(DS_TASK_T) ); taskInit(t, (void (*)(DS_U32))OS_Init, "Main", 0, 0, 0); t->taskId = OS_GetSelfTaskId(); t->pid = getpid(); } #ifndef OS_SpawnTask static void OS_StartThread(void *arg) { DS_TASK_T *t = (DS_TASK_T *)arg; void (*funcPtr)(DS_U32); DS_U32 funcArg; lockTaskList(); funcPtr = t->funcPtr; funcArg = t->arg; t->taskId = (DS_U32)OS_GetSelfTaskId(); t->pid = (int)getpid(); t->status = DS_TSTAT_READY; unlockTaskList(); printf("%s: PID=%d\n", t->name, t->pid); funcPtr( funcArg ); OS_SelfDeleteTask(); } DS_U32 OS_SpawnTask (void (*func)(DS_U32), char *name, DS_U16 prio, DS_U16 stacksize, DS_U32 arg) { CORE_TASK_ID tId; // void (*pFuncPtr)(void *) = (void (*)(void *))func; DS_TASK_T *t; t = (DS_TASK_T *)malloc(sizeof(DS_TASK_T)); if (!t) { printf("|%s| ERROR, Out of resources\n", __FUNCTION__); return (DS_U32)-1; } memset( t, 0, sizeof(DS_TASK_T) ); taskInit(t, func, name, prio, stacksize, arg); prio *= 100; prio /= 255; tId = DstCore_TaskCreate( OS_StartThread, (void *)t, prio ); return (DS_U32)tId; } #endif #ifndef OS_DeleteTask DS_U32 OS_DeleteTask(DS_U32 TaskId) { if ( TaskId == 0 ) { OS_SelfDeleteTask(); return 0; } /* * Do not delete TCB of taskId here, since we cannot force any task to be deleted. */ DstCore_TaskDelete((CORE_TASK_ID)TaskId); return 0; } #endif #ifndef OS_SelfDeleteTask void OS_SelfDeleteTask(void) { taskDelete(0); pthread_exit((void *)0); } #endif #ifndef OS_SuspendTask DS_U32 OS_SuspendTask(DS_U32 TaskId) { printf("%s: This function is not implemented.\n", __FUNCTION__); return (DS_U32)-1; } #endif #ifndef OS_ResumeTask DS_U32 OS_ResumeTask(DS_U32 TaskId) { printf("%s: This function is not implemented.\n", __FUNCTION__); return (DS_U32)-1; } #endif #ifndef OS_GetSelfTaskId OS_TASK_ID OS_GetSelfTaskId(void) { CORE_TASK_ID tId; DstCore_TaskGetInfo(&tId); return (OS_TASK_ID)tId; } #endif #if 0 ___Thread_Control_APIs___() #endif static void lockTaskList(void) { #if USE_V2LIN==0 if ( task_list_lock == (OS_SEMAPHORE_ID)NULL ) { task_list_lock = OS_CreateMutex( "semMutex"); SysASSERT( task_list_lock ); } OS_TakeSemaphore( task_list_lock ); #else pthread_mutex_lock( &task_list_lock ); #endif } static void unlockTaskList(void) { #if USE_V2LIN==0 SysASSERT( task_list_lock ); OS_GiveSemaphore( task_list_lock ); #else pthread_mutex_unlock( &task_list_lock ); #endif } #if USE_V2LIN==1 /***************************************************************************** ** link_susp_task - appends a new task pointer to a linked list of task pointers ** for tasks suspended on the object owning the list. *****************************************************************************/ void link_susp_task(DS_TASK_T ** list_head, DS_TASK_T * new_entry) { DS_TASK_T **i = list_head; if (!new_entry) return; lockTaskList(); new_entry->nxt_susp = NULL; while (*i) { if (*i==new_entry) { //TRACEF("warning: double entry"); printf("!!! Same entry is queued\n"); *i = (*i)->nxt_susp; // remove the task continue; } i = &(*i)->nxt_susp; // look for the tail } *i = new_entry; /* ** Initialize the suspended task's pointer back to suspend list ** This is used for cleanup during task deletion. */ //new_entry->suspend_list = *list_head; new_entry->status |= DS_TSTAT_PEND; unlockTaskList(); } /***************************************************************************** ** unlink_susp_task - removes task pointer from a linked list of task pointers ** for tasks suspended on the object owning the list. *****************************************************************************/ void unlink_susp_task(DS_TASK_T **list_head, DS_TASK_T * entry) { DS_TASK_T **i = list_head; //TRACEF("%x %x", list_head, entry); if (!entry) return; lockTaskList(); while (*i && (*i != entry) ) i = &(*i)->nxt_susp; if (*i) { //TRACEF("%x", entry); *i = (*i)->nxt_susp; // remove the task entry->nxt_susp = NULL; entry->status &= ~DS_TSTAT_PEND; } else { //TRACEF("warning: entry not found"); printf("WARNING: cannot find the entry, 0x%08lX 0x%08lX\n", (DS_U32)(*list_head), (DS_U32)entry); } unlockTaskList(); } /***************************************************************************** ** signal_for_my_task - searches the specified 'pended task list' for the ** task to be selected according to the specified ** pend order. If the selected task is the currently ** executing task, the task is deleted from the ** specified pended task list and returns a non-zero ** result... otherwise the pended task list is not ** modified and a zero result is returned. *****************************************************************************/ int signal_for_my_task(DS_TASK_T **list_head, int pend_order) { // used in lmsgQLib.c //TRACEF(); DS_TASK_T *signalled_task; DS_TASK_T *t; int result; result = DS_FALSE; //TRACEF("list head = %p", *list_head); if (!list_head) return result; signalled_task = *list_head; // First determine which task is being signalled if (pend_order != 0) { /* ** Tasks pend in priority order... locate the highest priority ** task in the pended list. */ for (t = *list_head; t; t = t->nxt_susp) { if (t->priority > signalled_task->priority) signalled_task = t; //TRACEF("%x priority %d", (int)t, t->priority); } } /* else ** ** Tasks pend in FIFO order... signal is for task at list head. */ // Signalled task located... see if it's the currently executing task. if (signalled_task->taskId == OS_GetSelfTaskId()) { // The currently executing task is being signalled... result = DS_TRUE; } //TRACEF("signalled task @ %p my task @ %p", signalled_task->taskId, OS_GetSelfTaskId()); return result; } #endif DS_TASK_T *taskFind(DS_U32 taskId, int bLock) { DS_TASK_T *t = (DS_TASK_T *)NULL; DS_BOOL b_found = DS_FALSE; if (!taskId) taskId = OS_GetSelfTaskId(); if (bLock) lockTaskList(); for (t = task_list; t != NULL; t = t->nxt_task) { if (t->taskId == taskId) { b_found = DS_TRUE; break; } } if (bLock) unlockTaskList(); if ( b_found ) return t; return NULL; } static DS_U32 taskInit(DS_TASK_T *p_new_task, void (*func)(DS_U32), char *name, DS_U16 prio, DS_U16 stacksize, DS_U32 arg) { DS_TASK_T **i = &task_list; p_new_task->status = DS_TSTAT_DEAD; p_new_task->funcPtr = func; p_new_task->arg = arg; p_new_task->taskId = -1; p_new_task->priority = prio; if (name) strcpy(p_new_task->name, name); lockTaskList(); /* * Add new task to tail of task list. */ while (*i) i = &(*i)->nxt_task; // search_last *i = p_new_task; // add to tail g_TaskCount++; unlockTaskList(); return OS_OK; } static DS_U32 taskDelete(DS_U32 taskId) { DS_TASK_T *task; DS_TASK_T **i; if ( taskId == 0 ) taskId = OS_GetSelfTaskId(); if ( taskId != OS_GetSelfTaskId() ) { printf("%s: This function is not implemented.\n", __FUNCTION__); return (DS_U32)-1; } task = taskFind(taskId, 1); if ( task ) { lockTaskList(); for (i = &task_list; *i; i = &(*i)->nxt_task) { if (task == *i) { *i = (*i)->nxt_task; // remove break; } } g_TaskCount--; unlockTaskList(); return 0; } return (DS_U32)-1; } char *taskName(OS_TASK_ID tid) { DS_TASK_T *t; if (tid == 0) tid=OS_GetSelfTaskId(); t = taskFind(tid, 0); if ( t == (DS_TASK_T *)NULL ) return ((char *)NULL); return (t->name); } OS_TASK_ID taskNameToId(char *name) { DS_TASK_T **i; for (i = &task_list; *i; i = &(*i)->nxt_task) { if (i && strcmp((*i)->name, name) == 0) { return (*i)->taskId; } } return (OS_TASK_ID)-1; } int taskPriorityGet(OS_TASK_ID tid, int *pPriority) { DS_TASK_T *t; int priority = -1; if (tid == 0) { tid=OS_GetSelfTaskId(); } t = taskFind( tid, 0 ); if ( t == (DS_TASK_T *)NULL ) return -1; priority = t->priority; if (priority < 0) { return -1; } (*pPriority) = priority; return 0; } static int taskGetStatus(int pid, DS_U32 *p_sp, DS_U32 *p_ip) { *p_sp = 0; *p_ip = 0; return 0; } void taskShow(OS_TASK_ID tid) { DS_TASK_T *t; DS_U32 sp, ip; #ifdef _MAKEFILE_INCLUDE_TSHELL_ DS_U32 *stackPtr; int i, j; #endif char *libname, *funcname; t = taskFind(tid, 0); if (t == NULL) return; sp = ip = 0; if ( taskGetStatus( t->pid, &sp, &ip ) ) sp = ip = 0; if ( ip ) { // libname = FindLibrary( ip ); } else { libname = (char *)NULL; funcname = (char *)NULL; } #ifdef _MAKEFILE_INCLUDE_TSHELL_ funcname = find_function( ip ); printf("<<< Task/Thread Information >>>\n"); printf(" PID: %d, TID: 0x%04X\n", (int)t->pid, (int)t->tid ); printf(" SP : 0x%08lX, IP: 0x%08lX\n", sp, ip ); printf(" Symbol: %s\n", funcname ? funcname : "Unknown" ); printf(" Library: %s\n", libname ? libname : "Unknown" ); printf("<<< Stack Contents >>>\n"); stackPtr = (DS_U32 *)sp; for ( i=0, j=0; i<128 && j<10; i++ ) { libname = FindLibrary( stackPtr[i] ); funcname = find_function( stackPtr[i] ); if ( libname && funcname ) { printf(" SP[%d] = 0x%08lX (%s)\n", i, stackPtr[i], funcname ? funcname : "Unknown or arguments"); j++; } } #else printf(" PID: %d, TID: 0x%04X\n", t->pid, (int)t->taskId ); printf(" SP : 0x%08lX, IP: 0x%08lX\n", sp, ip ); printf(" Library: %s\n", libname ? libname : "Unknown" ); #endif } void taskShowAll() { DS_TASK_T *t; DS_U32 sp, ip; char *libname, *funcname; lockTaskList(); printf("\t TASK NUM=%d\n", (int) g_TaskCount); printf("\t-------------------------------------------------------------\n"); #ifdef _MAKEFILE_INCLUDE_TSHELL_ printf("\t%10s\tPID (TID)\tPR(ST)\tSTACK\t\t PC\tSymbol\tLibrary\r\n", "NAME"); #else printf("\t%10s\tPID (TID)\tPR(ST)\tSTACK\t\t PC\tLibrary\r\n", "NAME"); #endif printf("\t-------------------------------------------------------------\n"); for (t = task_list; t; t = t->nxt_task) { sp = ip = 0; if ( taskGetStatus( t->pid, &sp, &ip ) ) sp = ip = 0; if ( ip ) { // libname = FindLibrary( ip ); } else { libname = (char *)NULL; funcname = (char *)NULL; } #ifdef _MAKEFILE_INCLUDE_TSHELL_ funcname = find_function( ip ); printf("\t%10s\t%4d (0x%4x)\t%d(%d)\t0x%08lX\t0x%08lX\t%s\t%s", t->name, (int) t->pid, (int) t->taskId, (int) t->priority, (int) t->status, sp, ip, funcname ? funcname : "Unknown", libname ? libname : "Unknown\n" ); #else printf("\t%10s\t%4d (0x%4x)\t%d(%d)\t0x%08lX\t0x%08lX\t%s\n", t->name, (int) t->pid, (int) t->taskId, (int) t->priority, (int) t->status, sp, ip, libname ? libname : "Unknown\n" ); #endif } printf("\t-------------------------------------------------------------\n"); unlockTaskList(); } #if 0 ___Time_API__________________() #endif #ifndef OS_GetTicksPerSecond DS_U32 OS_GetTicksPerSecond (void) { } #endif #ifndef OS_Delay void OS_Delay(DS_U32 Ticks) { usleep((Ticks) * (1000000/OS_GetTicksPerSecond())); } #endif #ifndef OS_mDelay void OS_mDelay(DS_U32 milliseconds) { if (milliseconds) usleep((milliseconds) * 1000); } #endif #ifndef OS_GetTickCount DS_U32 OS_GetTickCount(void) { return DstCore_Get100HzClockTick(); } #endif #if 0 ___Semaphore_API____________() #endif #ifndef OS_CreateCountingSemaphore OS_SEMAPHORE_ID OS_CreateCountingSemaphore (const char *name, DS_U32 options, DS_U32 count) { CORE_SEM_ID semId; OS_Init(); #if USE_V2LIN==0 semId = DstCore_SemCreate( 0, count ); #else semId = (CORE_SEM_ID)semCCreate( 0, (int)count ); #endif if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX\n", __FUNCTION__, semId); return (OS_SEMAPHORE_ID)semId; } #endif #ifndef OS_CreateBinarySemaphore OS_SEMAPHORE_ID OS_CreateBinarySemaphore(const char *name, DS_U32 options, DS_U32 count) { CORE_SEM_ID semId; OS_Init(); #if USE_V2LIN==0 semId = DstCore_SemCreate( 0, 1 ); if ( semId && count == 0 ) { DstCore_SemLock( semId, OS_WAIT_FOREVER ); } #else semId = (CORE_SEM_ID)semBCreate( 0, (int)count ); #endif if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX\n", __FUNCTION__, semId); if ( semId == 0 ) { printf("\n*** Semaphore create error ***\n" ); } return (OS_SEMAPHORE_ID)semId; } #endif #ifndef OS_DeleteSemaphore DS_U32 OS_DeleteSemaphore (OS_SEMAPHORE_ID SemId) { DS_U32 RetVal = 0; if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX\n", __FUNCTION__, SemId); #if USE_V2LIN==0 DstCore_SemDelete( (CORE_SEM_ID)SemId ); return 0; #else RetVal = semDelete( (SEM_ID)SemId ); if ( RetVal == 0 ) return (OS_OK); printf("\n*** Semaphore delete error %ld ***\n", RetVal); return (OS_FAIL); #endif } #endif #ifndef OS_TakeSemaphore DS_U32 OS_TakeSemaphore (OS_SEMAPHORE_ID SemId) { DS_U32 RetVal = 0; #if USE_V2LIN==0 if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX\n", __FUNCTION__, SemId); return DstCore_SemLock( (CORE_SEM_ID)SemId, OS_WAIT_FOREVER ); #else RetVal = semTake( (SEM_ID)SemId, OS_WAIT_FOREVER ); if ( RetVal == 0 ) { return OS_OK; } else if ( RetVal == S_objLib_OBJ_TIMEOUT ) { RetVal = OS_TIMEOUT; } else { printf("\n*** Semaphore lock error %ld ***\n", RetVal ); RetVal = OS_FAIL; } return (RetVal); #endif } #endif #ifndef OS_TakeSemaphore_Wait DS_U32 OS_TakeSemaphore_Wait(OS_SEMAPHORE_ID SemId, DS_U32 timeout) { DS_U32 RetVal = 0; if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX, timeout=0x%lX\n", __FUNCTION__, SemId, timeout); #if USE_V2LIN==0 return DstCore_SemLock( (CORE_SEM_ID)SemId, timeout ); #else RetVal = semTake( (SEM_ID)SemId, (int)timeout ); if ( RetVal == 0 ) { return OS_OK; } else if ( RetVal == S_objLib_OBJ_TIMEOUT ) { RetVal = OS_TIMEOUT; } else { printf("\n*** Semaphore lock error %ld ***\n", RetVal ); RetVal = OS_FAIL; } return RetVal; #endif } #endif #ifndef OS_TakeSemaphore_NoWait DS_U32 OS_TakeSemaphore_NoWait(OS_SEMAPHORE_ID SemId) { DS_U32 RetVal = 0; if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX\n", __FUNCTION__, SemId); #if USE_V2LIN==0 return DstCore_SemLock( (CORE_SEM_ID)SemId, 0 ); #else RetVal = semTake( (SEM_ID)SemId, (int)0 ); if ( RetVal == 0 ) { return OS_OK; } else if ( RetVal == S_objLib_OBJ_TIMEOUT ) { RetVal = OS_TIMEOUT; } else { printf("\n*** Semaphore lock error %ld ***\n", RetVal ); RetVal = OS_FAIL; } return RetVal; #endif } #endif #ifndef OS_GiveSemaphore DS_U32 OS_GiveSemaphore(OS_SEMAPHORE_ID SemId) { DS_U32 RetVal = 0; if ( DEBUG_SEM ) fprintf(stderr, "|%s| SemId=0x%lX\n", __FUNCTION__, SemId); #if USE_V2LIN==0 return DstCore_SemUnlock( (CORE_SEM_ID)SemId ); #else RetVal = semGive( (SEM_ID)SemId ); if ( RetVal == 0 ) return (OS_OK); printf("\n*** Semaphore unlock error %ld ***\n", RetVal); return RetVal; #endif } #endif #ifndef OS_FlushSemaphore DS_U32 OS_FlushSemaphore(OS_SEMAPHORE_ID SemId) { return 0; } #endif #if 0 ___Mutex_API__________________() #endif #ifndef OS_CreateMutex OS_MUTEX_ID OS_CreateMutex(const char *name) { OS_Init(); #if USE_V2LIN==0 return (OS_MUTEX_ID)DstCore_MutexCreate(0); #else return (OS_MUTEX_ID)semMCreate(0); #endif } #endif #ifndef OS_DeleteMutex DS_U32 OS_DeleteMutex(OS_MUTEX_ID mutexId) { #if USE_V2LIN==0 DstCore_MutexDelete((CORE_MUTEX_ID)mutexId); return (0); #else DS_U32 retVal = 0; retVal = semDelete( (SEM_ID)mutexId ); if ( retVal == 0 ) return (OS_OK); printf("\n*** Semaphore delete error %ld ***\n", retVal); return (OS_FAIL); #endif } #endif #ifndef OS_TakeMutex DS_U32 OS_TakeMutex(OS_MUTEX_ID mutexId) { #if USE_V2LIN==0 return DstCore_MutexLock((CORE_MUTEX_ID)mutexId, OS_WAIT_FOREVER); #else DS_U32 retVal = 0; retVal = semTake( (SEM_ID)mutexId, OS_WAIT_FOREVER ); if ( retVal == 0 ) return (OS_OK); printf("\n*** Mutex Take error %ld ***\n", retVal); return retVal; #endif } #endif #ifndef OS_TakeMutex_NoWait DS_U32 OS_TakeMutex_NoWait(DS_U32 mutexId) { #if USE_V2LIN==0 return DstCore_MutexLock((CORE_MUTEX_ID)mutexId, 0); #else DS_U32 retVal = 0; retVal = semTake( (SEM_ID)mutexId, OS_WAIT_FOREVER ); if ( retVal == 0 ) { return (OS_OK); } else if ( retVal == S_objLib_OBJ_TIMEOUT ) { retVal = OS_TIMEOUT; } printf("\n*** Mutex Take error %ld ***\n", retVal); return retVal; #endif } #endif #ifndef OS_GiveMutex DS_U32 OS_GiveMutex(DS_U32 mutexId) { #if USE_V2LIN==0 return DstCore_MutexUnlock((CORE_MUTEX_ID)mutexId); #else DS_U32 RetVal = 0; RetVal = semGive( (SEM_ID)mutexId ); if ( RetVal == 0 ) return (OS_OK); printf("\n*** Mutex unlock error %ld ***\n", RetVal); return RetVal; #endif } #endif #if 0 ___Dynamic_Memory_API______________() #endif #define MAX_FUNC_NAME 32 // Çã¿ëÇÒ ÃÖ´ë ÇÔ¼ö À̸§ ±æÀÌ #define MAX_COUNT 2000 // °ü¸®ÇÒ °¹¼ö static struct MEM_LIST { char func[MAX_FUNC_NAME+1]; int nLine; void *p; int nSize; unsigned int tick; } memlist[MAX_COUNT]; void Print_All_MemUnit(void) { int i = 0, nSum = 0, nCount = 0; printf("|------------+----------+----------------------------------+------|\n"); printf("| Address | Size | Function | Line |\n"); printf("|------------+----------+----------------------------------+------|\n"); for (i = 0; i < MAX_COUNT; i++) { if (memlist[i].p == 0) continue; printf("| 0x%08X | %8d | %32s | %4d | %4d |\n", (int)memlist[i].p, memlist[i].nSize, memlist[i].func, memlist[i].nLine, (int)(OS_GetTickCount() - memlist[i].tick)/100 ); nSum+=memlist[i].nSize; nCount++; } printf("|------------+----------+----------------------------------+------|\n"); printf("| %10d | %8d | |\n", nCount, nSum); printf("|------------+----------+----------------------------------+------|\n"); } static void Add_MemUint(const char* func, int nLine, void *p, int nSize) { int i = 0; for (i = 0; i < MAX_COUNT; i++) { if (memlist[i].p != 0) continue; if (strlen(func) > MAX_FUNC_NAME) { memcpy(memlist[i].func, func, MAX_FUNC_NAME); memlist[i].func[MAX_FUNC_NAME] = 0; } else { strcpy(memlist[i].func, func); } memlist[i].nLine = nLine; memlist[i].p = p; memlist[i].nSize = nSize; memlist[i].tick = OS_GetTickCount(); break; } //Print_MemUnit(); } static void Del_MemUnit(void *p, const char * func, int nLine) { int i = 0; if (p == 0) return; for (i = 0; i < MAX_COUNT; i++) { if (memlist[i].p != p) continue; memlist[i].p = 0; break; } if (i >= MAX_COUNT) { #if 0 printf("\n\n\n\nTry to delete unallocated memory 0x%08X. %s %d\n\n\n", (int)p, func, nLine); Print_All_MemUnit(); OS_Delay(5); #endif } //Print_MemUnit(); } void *_OS_malloc(unsigned int size, const char* func, int nLine) { void *p = 0; if (size == 0) return 0; p = malloc(size); Add_MemUint(func, nLine, p, size); return p; } void *_OS_calloc(unsigned int count, unsigned int size, const char* func, int nLine) { void *p = 0; if (count == 0 || size == 0) return 0; p = calloc(count, size); Add_MemUint(func, nLine, p, size); return p; } void *_OS_realloc(void* memory, unsigned int size, const char* func, int nLine) { void *p = 0; Del_MemUnit(memory, func, nLine); p = realloc(memory, size); Add_MemUint(func, nLine, p, size); return p; } void _OS_free(void *where, const char* func, int nLine) { if (where == 0) return; Del_MemUnit(where, func, nLine); free(where); where = 0; } void *OS_malloc2(unsigned int size) { void *p = 0; if (size == 0) return 0; p = malloc(size); // Add_MemUint(func, nLine, p, size); return p; } void *OS_calloc2(unsigned int count, unsigned int size) { void *p = 0; if (count == 0 || size == 0) return 0; p = calloc(count, size); // Add_MemUint(func, nLine, p, size); return p; } void *OS_realloc2(void* memory, unsigned int size) { void *p = 0; // Del_MemUnit(memory, func, nLine); p = realloc(memory, size); // Add_MemUint(func, nLine, p, size); return p; } void OS_free2(void *where) { if (where == 0) return; // Del_MemUnit(memBlock, func, nLine); free(where); where = 0; } #if 0 ___Message_Queue_API____________() #endif #ifndef OS_CreateMessageQueue DS_U32 OS_CreateMessageQueue (const char *name, DS_U32 option, DS_U32 maxMessage, DS_U32 messageLength) { CORE_QUEUE_ID qId; OS_Init(); #if USE_V2LIN==0 qId = DstCore_QueueCreate( (DS_U32)name, maxMessage, messageLength ); #else qId = (CORE_QUEUE_ID)msgQCreate( maxMessage, messageLength, option ); #endif return (DS_U32)qId; } #endif #ifndef OS_SendMessage DS_U32 OS_SendMessage (DS_U32 qId, DS_U32 *pBuffer, DS_U32 nBytes) { #if USE_V2LIN==0 return DstCore_QueuePost( (CORE_QUEUE_ID)qId, pBuffer, nBytes ); #else DS_U32 err; err = msgQSend( (MSG_Q_ID)qId, (char *)pBuffer, nBytes, OS_WAIT_FOREVER, 0 ); if ( err ) { printf("\n*** Queue Send error %ld ***\n", err); return OS_FAIL; } else return OS_OK; #endif } #endif #ifndef OS_ReceiveMessage DS_U32 OS_ReceiveMessage(DS_U32 qId, DS_U32 *msgBuf, DS_U32 maxLen, DS_U32 *retLen) { #if USE_V2LIN==0 return DstCore_QueueWait( (CORE_QUEUE_ID)qId, msgBuf, OS_WAIT_FOREVER, retLen ); #else int msgLen; msgLen = msgQReceive( (MSG_Q_ID)qId, (char *)msgBuf, maxLen, OS_WAIT_FOREVER ); if ( msgLen > 0 ) { *retLen = (DS_U32)msgLen; return OS_OK; } return OS_FAIL; #endif } #endif #ifndef OS_ReceiveMessage_Wait DS_U32 OS_ReceiveMessage_Wait(DS_U32 qId, DS_U32 *msgBuf, DS_U32 maxLen, DS_U32 *retLen, DS_U32 timeOut) { #if USE_V2LIN==0 return DstCore_QueueWait( (CORE_QUEUE_ID)qId, msgBuf, timeOut, retLen ); #else int msgLen; msgLen = msgQReceive( (MSG_Q_ID)qId, (char *)msgBuf, maxLen, timeOut ); if ( msgLen > 0 ) { *retLen = (DS_U32)msgLen; return OS_OK; } if (errno == S_objLib_OBJ_TIMEOUT) return OS_TIMEOUT; printf("\n*** Queue Recv error 0x%X ***\n", errno); return OS_FAIL; #endif } #endif #ifndef OS_ReceiveMessage_NoWait DS_U32 OS_ReceiveMessage_NoWait(DS_U32 qId, DS_U32 *msgBuf, DS_U32 maxLen, DS_U32 *retLen) { #if USE_V2LIN==0 return DstCore_QueueWait( (CORE_QUEUE_ID)qId, msgBuf, 0, retLen ); #else int msgLen; msgLen = msgQReceive( (MSG_Q_ID)qId, (char *)msgBuf, maxLen, 0 ); if ( msgLen > 0 ) { *retLen = (DS_U32)msgLen; return OS_OK; } if (errno == S_objLib_OBJ_TIMEOUT || errno == S_objLib_OBJ_UNAVAILABLE) return OS_TIMEOUT; printf("\n*** Queue Recv error 0x%X ***\n", errno); return OS_FAIL; #endif } #endif #ifndef OS_DeleteMessageQueue DS_U32 OS_DeleteMessageQueue(DS_U32 qId) { #if USE_V2LIN==0 return DstCore_QueueDelete( (CORE_QUEUE_ID)qId ); #else DS_U32 err; err = msgQDelete( (MSG_Q_ID)qId ); if ( err ) return OS_FAIL; return OS_OK; #endif } #endif #if 0 ___Semaphore_Test_Routines______________() #endif // // Option // 0: Test infinite timeout routines. // 1: Test finite timeout routines. // 2: Test no timeout routines. // static OS_SEMAPHORE_ID semId1, semId2; void tSemProd( DS_U32 arg ) { int *pResult = (int *)arg; int i; DS_U32 ret=0; printf("|%s| entry.\n", __FUNCTION__); while(*pResult) OS_mDelay(100); i = 0; while ( 1 ) { OS_mDelay(1000); printf("[%s] give semaphore to tSemCons. [%d]\n", __FUNCTION__, i); ret = OS_GiveSemaphore( semId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } #if 0 if ( i==5 ) { printf("[%s] Wait for semaphore from tSemCons. timeout = 100[%d]\n", __FUNCTION__, i); ret = OS_TakeSemaphore_Wait( semId2, 100 ); if ( ret ) { printf("|%s:%d| ret = %s[%ld] ==> %s\n", __FUNCTION__, __LINE__, ret == OS_TIMEOUT ? "TIMEOUT" : ret == OS_FAIL ? "FAIL" : ret == OS_NOT_SUPPORTED ? "NOT SUPPORTED" : "Unknown", ret, ret == OS_TIMEOUT ? "TIMEOUT OK" : "TIMEOUT FAIL" ); break; } } else { printf("[%s] Wait for semaphore from tSemCons. [%d]\n", __FUNCTION__, i); ret = OS_TakeSemaphore_Wait( semId2, OS_WAIT_FOREVER ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } } if ( ++i > 5 ) #endif break; } if ( i == 5 ) *pResult = 1; else *pResult = -1; fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__); OS_DeleteTask(0); } void tSemCons( DS_U32 arg ) { int *pResult = (int *)arg; int i; DS_U32 ret; printf("|%s| entry.\n", __FUNCTION__); while(*pResult) OS_mDelay(100); i = 0; while ( 1 ) { printf("[%s] Wait for semaphore from tSemProd. [%d]\n", __FUNCTION__, i); ret = OS_TakeSemaphore_Wait( semId1, 200 ); //ret = OS_TakeSemaphore_Wait( semId1, OS_WAIT_FOREVER); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } #if 0 if ( i == 5 ) { printf("[%s] Delay 1000msec.\n", __FUNCTION__); OS_mDelay(1000); } printf("[%s] give semaphore to tSemProd. [%d]\n", __FUNCTION__, i); ret = OS_GiveSemaphore( semId2 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } if ( ++i > 5 ) #endif break; } if ( i == 6 ) *pResult = 1; else *pResult = -1; fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__); OS_DeleteTask(0); } void test_semaphore(DS_U32 Option) { int ret = 0; static int test_result1 = -1; static int test_result2 = -1; DS_U32 Result; // // Create 2 semaphores. // if (Option) semId1 = OS_CreateBinarySemaphore( 0, 0, 0 ); else semId1 = OS_CreateCountingSemaphore( 0, 0, 0 ); if ( semId1 == 0 ) { printf("|%s:%d| ERROR: cannot create semaphore.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } if (Option) semId2 = OS_CreateBinarySemaphore( 0, 0, 0 ); else semId2 = OS_CreateCountingSemaphore( 0, 0, 0 ); if ( semId2 == 0 ) { printf("|%s:%d| ERROR: cannot create semaphore.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Create the product task. // Result = OS_SpawnTask( tSemProd, "tSemProd", 60, 0, (DS_U32)&test_result1 ); if ( Result == 0 ) { printf("|%s:%d| ERROR: cannot create thread.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Create the consumer task. // Result = OS_SpawnTask( tSemCons, "tSemCons", 60, 0, (DS_U32)&test_result2 ); if ( Result == 0 ) { printf("|%s:%d| ERROR: cannot create thread.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Starts the task. // test_result1 = 0; test_result2 = 0; while ( test_result1 == 0 || test_result2 == 0 ) { OS_mDelay(1000); fprintf(stderr, ".\n"); } if ( test_result1 > 0 && test_result2 > 0 ) ret = 1; else ret = -1; done: if ( ret < 0 ) printf("*** Semaphore Test: FAIL ***\n"); else printf("*** Semaphore Test: PASS ***\n"); OS_DeleteSemaphore( semId1 ); OS_DeleteSemaphore( semId2 ); } #if 0 ___Mutex_Test_Routines______________() #endif // // Option // 0: Test infinite timeout routines. // 1: Test finite timeout routines. // 2: Test no timeout routines. // static OS_MUTEX_ID mtxId1, mtxId2; void tMutexProd( DS_U32 arg ) { int *pResult = (int *)arg; int i; DS_U32 ret; printf("|%s| entry.\n", __FUNCTION__); ret = OS_TakeMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); } while(*pResult) OS_mDelay(100); i = 0; while ( 1 ) { printf("[%s] give semaphore to tMutexCons. [%d]\n", __FUNCTION__, i); ret = OS_GiveMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } OS_Delay(1); printf("[%s] Wait for semaphore from tMutexCons. [%d]\n", __FUNCTION__, i); ret = OS_TakeMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } if ( ++i > 5 ) break; } ret = OS_GiveMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); } printf("%s | i = %d , pResult = 0x%x\n",__FUNCTION__,i,(int)pResult); if ( i == 6 ) *pResult = 1; else *pResult = -1; OS_mDelay(1000); } void tMutexCons( DS_U32 arg ) { int *pResult = (int *)arg; int i; DS_U32 ret; printf("|%s| entry.\n", __FUNCTION__); ret = OS_TakeMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); } while(*pResult) OS_mDelay(100); i = 0; while ( 1 ) { printf("[%s] Wait for semaphore from tMutexProd. [%d]\n", __FUNCTION__, i); ret = OS_TakeMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } printf("[%s] give semaphore to tMutexProd. [%d]\n", __FUNCTION__, i); ret = OS_GiveMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); break; } if ( ++i > 5 ) break; } printf("[%s] give semaphore to tMutexProd. [%d]\n", __FUNCTION__, i); ret = OS_GiveMutex( mtxId1 ); if ( ret ) { printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__); } printf("%s | i = %d, pResult = 0x%x\n",__FUNCTION__,i,(int)pResult); if ( i == 6 ) *pResult = 1; else *pResult = -1; OS_mDelay(1000); } void test_mutex(DS_U32 Option) { int ret = 0; static int test_result1 = -1; static int test_result2 = -1; DS_U32 Result; // // Create 2 semaphores. // mtxId1 = OS_CreateMutex( 0 ); if ( mtxId1 == 0 ) { printf("|%s:%d| ERROR: cannot create semaphore.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } mtxId2 = OS_CreateMutex( 0 ); if ( mtxId2 == 0 ) { printf("|%s:%d| ERROR: cannot create semaphore.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Create the product task. // printf("t1 = 0x%x, t2 = 0x%x\n",(int)&test_result1,(int)&test_result2); Result = OS_SpawnTask( tMutexProd, 0, 60, 8*1024, (DS_U32)&test_result1 ); if ( Result == 0 ) { printf("|%s:%d| ERROR: cannot create thread.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Create the consumer task. // Result = OS_SpawnTask( tMutexCons, 0, 60, 8*1024, (DS_U32)&test_result2 ); if ( Result == 0 ) { printf("|%s:%d| ERROR: cannot create thread.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Starts the task. // test_result1 = 0; test_result2 = 0; while ( test_result1 == 0 || test_result2 == 0 ) { OS_mDelay(1000); printf("."); } if ( test_result1 > 0 && test_result2 > 0 ) ret = 1; else ret = -1; done: if ( ret < 0 ) printf("*** Mutex Test: FAIL ***\n"); else printf("*** Mutex Test: PASS ***\n"); OS_DeleteMutex( mtxId1 ); OS_DeleteMutex( mtxId2 ); } #if 0 ___Message_Test_Routines______________() #endif // // Option // 0: Test infinite timeout routines. // 1: Test finite timeout routines. // 2: Test no timeout routines. // typedef struct tag_MyMessage { DS_U32 dummy; DS_U32 senderID; DS_U32 Length; DS_U32 Command; DS_U32 CommandCPL; DS_U32 du; } MyMessage; #define N_TEST_MSG 100 static DS_U32 msgId1, msgId2; void tMsgProd( DS_U32 arg ) { int *pResult = (int *)arg; int i; DS_U32 ret; CORE_TASK_ID tId; MyMessage smsg, rmsg; DS_U32 len; DstCore_TaskGetInfo( &tId ); printf("|%s| entry. tId = 0x%08lX\n", __FUNCTION__, tId); while(*pResult) OS_mDelay(100); i = 0; while ( 1 ) { printf("[%s] give message to tMsgCons. [%d]\n", __FUNCTION__, i); smsg.senderID = (DS_U32)tId; smsg.Length = 1; smsg.Command = 0xAAAAAAAA; smsg.CommandCPL = ~smsg.Command; ret = OS_SendMessage( msgId2, (DS_U32 *)&smsg, sizeof(MyMessage) ); if ( ret ) { printf("|%s| ERROR, LINE=%d, ret = %ld\n", __FUNCTION__, __LINE__, ret); break; } printf("[%s] Wait for message from tMsgCons. [%d]\n", __FUNCTION__, i); if ( i!=N_TEST_MSG ) { ret = OS_ReceiveMessage_Wait( msgId1, (DS_U32 *)&rmsg, sizeof(MyMessage), &len, OS_WAIT_FOREVER ); if ( ret ) { printf("|%s| ERROR, LINE=%d, ret = %ld\n", __FUNCTION__, __LINE__, ret); break; } } else { ret = OS_ReceiveMessage_Wait( msgId1, (DS_U32 *)&rmsg, sizeof(MyMessage), &len, 100 ); if ( ret ) { printf("|%s:%d| ret = %s[%ld] ==> %s\n", __FUNCTION__, __LINE__, ret == OS_TIMEOUT ? "TIMEOUT" : ret == OS_FAIL ? "FAIL" : ret == OS_NOT_SUPPORTED ? "NOT SUPPORTED" : "Unknown", ret, ret == OS_TIMEOUT ? "TIMEOUT OK" : "TIMEOUT FAIL" ); break; } } printf("[%s] MyMessage.senderID = 0x%08lX\n", __FUNCTION__, rmsg.senderID ); printf("[%s] MyMessage.Length = %ld\n", __FUNCTION__, rmsg.Length); printf("[%s] MyMessage.Command = 0x%08lX\n", __FUNCTION__, rmsg.Command ); printf("[%s] MyMessage.CommandCPL = 0x%08lX\n", __FUNCTION__, rmsg.CommandCPL ); if ( ++i > N_TEST_MSG ) break; } if ( i == N_TEST_MSG ) *pResult = 1; else *pResult = -1; } void tMsgCons( DS_U32 arg ) { int *pResult = (int *)arg; int i; CORE_TASK_ID tId; MyMessage smsg, rmsg; DS_U32 len; DS_U32 ret; DstCore_TaskGetInfo( &tId ); printf("|%s| entry. tId = 0x%08lX\n", __FUNCTION__, tId); while(*pResult) OS_mDelay(100); i = 0; while ( 1 ) { printf("[%s] Wait for message from tMsgProd. [%d]\n", __FUNCTION__, i); ret = OS_ReceiveMessage_Wait( msgId2, (DS_U32 *)&rmsg, sizeof(MyMessage), &len, OS_WAIT_FOREVER ); if ( ret ) { printf("|%s| ERROR, LINE=%d, ret = %ld\n", __FUNCTION__, __LINE__, ret); break; } if ( i == N_TEST_MSG ) { printf("[%s] Delay 1000msec.\n", __FUNCTION__); OS_mDelay(1000); } printf("[%s] MyMessage.senderID = 0x%08lX\n", __FUNCTION__, rmsg.senderID ); printf("[%s] MyMessage.Length = %ld\n", __FUNCTION__, rmsg.Length); printf("[%s] MyMessage.Command = 0x%08lX\n", __FUNCTION__, rmsg.Command ); printf("[%s] MyMessage.CommandCPL = 0x%08lX\n", __FUNCTION__, rmsg.CommandCPL ); printf("[%s] give message to tMsgProd. [%d]\n", __FUNCTION__, i); smsg.senderID = (DS_U32)tId; smsg.Length = 1; smsg.Command = 0x55aa55aa; smsg.CommandCPL = ~smsg.Command; ret = OS_SendMessage( msgId1, (DS_U32 *)&smsg, sizeof(MyMessage) ); if ( ret ) { printf("|%s| ERROR, LINE=%d, ret = %ld\n", __FUNCTION__, __LINE__, ret); break; } if ( ++i > N_TEST_MSG ) break; } if ( i == (N_TEST_MSG+1) ) *pResult = 1; else *pResult = -1; } void test_message(DS_U32 Option) { int ret = 0; static int test_result1 = -1; static int test_result2 = -1; DS_U32 Result; // // Create 2 semaphores. // msgId1 = OS_CreateMessageQueue ( "msgQ1", 0, 20, sizeof(MyMessage) ); if ( msgId1 == 0 ) { printf("|%s:%d| ERROR: cannot create message queue.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } msgId2 = OS_CreateMessageQueue ( "msgQ2", 0, 20, sizeof(MyMessage) ); if ( msgId2 == 0 ) { printf("|%s:%d| ERROR: cannot create message queue.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Create the product task. // Result = OS_SpawnTask( tMsgProd, 0, 60, 8*1024, (DS_U32)&test_result1 ); if ( Result == 0 ) { printf("|%s:%d| ERROR: cannot create thread.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Create the consumer task. // Result = OS_SpawnTask( tMsgCons, 0, 60, 8*1024, (DS_U32)&test_result2 ); if ( Result == 0 ) { printf("|%s:%d| ERROR: cannot create thread.\n", __FUNCTION__, __LINE__); ret = -1; goto done; } // // Starts the task. // test_result1 = 0; test_result2 = 0; while ( test_result1 == 0 || test_result2 == 0 ) { OS_mDelay(1000); printf("test_result1: %d, test_result2: %d\n", test_result1, test_result2); // msgQList( stdout, 0 ); } if ( test_result1 > 0 && test_result2 > 0 ) ret = 1; else ret = -1; done: if ( ret < 0 ) printf("*** MessageQueue Test: FAIL ***\n"); else printf("*** MessageQueue Test: PASS ***\n"); OS_DeleteMessageQueue( msgId1 ); OS_DeleteMessageQueue( msgId2 ); } DS_U32 OS_ReadRegister( DS_U32 Address ) { return DstCore_RegRead( Address, 4 ); } DS_U32 OS_WriteRegister( DS_U32 Address, DS_U32 Value ) { return DstCore_RegWrite(Address, Value, 4); } DS_U32 OS_ReadRegisterWord( DS_U32 Address ) { return DstCore_RegRead( Address, 2 ); } DS_U32 OS_WriteRegisterWord( DS_U32 Address, DS_U32 Value ) { return DstCore_RegWrite(Address, Value, 2); } DS_U32 OS_ReadRegisterByte( DS_U32 Address ) { return DstCore_RegRead( Address, 1 ); } DS_U32 OS_WriteRegisterByte( DS_U32 Address, DS_U32 Value ) { return DstCore_RegWrite(Address, Value, 1); } DS_U32 OS_GetLoaderVer(void) { return DstCore_GetLoaderVer(); } #if USE_V2LIN==1 void print_msgq(int mem) { msgQList( stdout, mem ); } void print_sem(int mem) { semList(stdout, mem); } #endif