/* DHL_OSAL.c OS Abstraction Layer Implementation Description: OS Heap/.. implementation Copyright 2006~2010 Digital STREAM Technology, Inc. All Rights Reserved */ #include "DHL_OSAL.h" #include "DHL_OSAL_Priv.h" #include "DHL_DBG.h" #include "DHL_OSAL_Impl.h" #include "bcmmemmgr.h" /* ¸ðµç Çì´õ ÆÄÀÏÀ» Æ÷ÇÔÇÏÁö´Â ¾ÊÀ¸¸ç, compile timeÀ» ÁÙÀ̱â À§ÇØ °¢ ¸ðµâÀº ÇÊ¿äÇÑ ¸¸Å­ÀÇ Çì´õ¸¦ ¼±¾ðÇϵµ·Ï ÇÔ. */ /* DHL µð¹ö±× ¸ðµâ À̸§ Á¤ÀÇ ·ê Âü°í: DHL ¸ðµâµéÀº ¸ðµÎ * ·Î ½ÃÀÛ. API´Â ´ë¹®ÀÚ, Platform ¹× ±âŸ´Â ¼Ò¹®ÀÚ »ç¿ë. µðÆúÆ® ·¹º§Àº 0À¸·Î ¼³Á¤ÇÑ´Ù. (0: ¿¡·¯ ¸Þ½ÃÁö¸¸ Ãâ·Â) */ //DHL_MODULE("*osal", 0); #if COMMENT ____Config____(){} #endif /* ÀÌ ¸ðµâ ³»ºÎ¿¡¼­ »ç¿ëµÇ´Â °¢Á¾ configuration Á¤ÀÇ. */ /* #define SUPPORT_FAST_SWITCHING_OPTIMIZATION 1 */ /* #define FUNC_MONITOR_TIMER_ID TIMER_ID_FUNC_MONITOR */ /* 1·Î ¼³Á¤Çϸé malloc ¹öÆÛ ¾Õ µÚ·Î guard ¿µ¿ªÀ» Ãß°¡ È®º¸Çϰí, memory overrun µîÀÇ ¿¡·¯ üũ ¼öÇà. heap debug ¿É¼ÇÀ» »ç¿ëÇϰí ÀÖ´Ù¸é buf headerÀÇ memCheck°¡ ÀÌ ¿ªÇÒÀ» ´ë½ÅÇϰí ÀÖÀ¸¹Ç·Î guard ¿É¼ÇÀÌ ÇÊ¿äÇÏÁö ¾ÊÀ½. */ #if DHL_OS_USE_HEAP_DEBUG #define USE_MEMORY_GUARD 0 #else #define USE_MEMORY_GUARD 1 #endif #if DHL_OS_USE_HEAP_DEBUG #define USE_MEM_FOOTER 1 // 1À̸é HEADER »Ó¸¸ ¾Æ´Ï¶ó FOOTER±îÁöµµ Ãß°¡ÇÑ´Ù. // Ãß°¡ÀÇ ¸Þ¸ð¸®°¡ ¼Ò¿äµÇ³ª // memory corruption ±îÁö üũÇÏ·Á¸é ÀÌ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. #define CHECK_MEM_CORRUPTION 1 // memory corruption (overrun) check¸¦ ¼öÇàÇÑ´Ù. // »ç¿ëµÇÁö ¾Ê´Â ºó °ø°£¿¡ check patternÀ» ±â·ÏÇϱ⠶§¹®¿¡ ¾à°£ÀÇ ¼º´É °¨¼Ò ¿¹»ó. #define CHECK_MEM_LEAK 1 // memory ´©¼ö¸¦ È®ÀÎÇϱâ À§ÇØ ÀÏÁ¤ ÀÌ»ó memory°¡ »ç¿ëµÇ¸é // heap »óŸ¦ Ãâ·ÂÇϵµ·Ï ÇÑ´Ù. #endif static DHL_OS_SEMA_ID semTask; // store BSS storage. /* osi_takemutexsemaphore api´Â Ç¥ÁØ api°¡ ¾Æ´Ï¶ó¼­ Á¦°Å. ¸ðµç sem¿¡¼­ °ø¿ëÀ¸·Î »ç¿ëÇÏ´Â api »ç¿ëÇÏ¸é µÊ. */ #define osi_takemutexsemaphore(s) osi_takesemaphore(s) extern int printf(const char *format, ...); #if COMMENT ____Types____(){} #endif #if COMMENT ____Variables____(){} #endif /* global·Î Àû¿ëµÇ´Â variable Á¤ÀÇ. °¢ function º°·Î Ư¼öÇÑ ¿ëµµÀÇ variableÀº °¢ functionX block ¿¡¼­ Á¤ÀÇ °¡´É. */ #if COMMENT ____Task____(){} #endif //BKNOTE: ¹Ýµå½Ã task Á¾·á½Ã¿¡ DHL_OS_SelfDeleteTask() È£ÃâÇØÁà¾ß ÇÔ. (uCOS-II Á¦¾à) DHL_OS_TASK_ID DHL_OS_CreateTask(DHL_OS_TASKFUNCTION func, const char *name, int priority, int stackSize, UINT32 arg1) { // UINT32 i; DHL_OS_TASK_ID tid; osi_takemutexsemaphore(semTask); tid = osi_spawntask(func, name, priority, stackSize, arg1); osi_givemutexsemaphore(semTask); if(tid==0) { DHL_OS_Printf("|%s| fail to add task(name:%s).\n", __FUNCTION__, name); return DHL_INVALID_TASK_ID; } DHL_OS_Printf("|%s| func = %x, arg1 = %d(%x), stk_size = %d\n", __FUNCTION__, func, arg1, arg1, stackSize); return (DHL_OS_TASK_ID)tid; } void DHL_OS_SelfDeleteTask(void) { DHL_OS_Printf("|%s| delete Task\n", __FUNCTION__); osi_selfdeletetask(); } void DHL_OS_SetTaskPriority(DHL_OS_TASK_ID tid, UINT32 newPrio, UINT32 *pOldPrio) { if (pOldPrio == NULL) { return; } osi_changetaskpriority(tid, newPrio, pOldPrio); // void osi_changetaskpriority(os_task_id tid, UINT32 newPrio, UINT32 *oldPrioPtr) DHL_OS_Printf("|%s| change priority %d -> %d \n", __FUNCTION__, *pOldPrio, newPrio ); } DHL_RESULT DHL_OS_FindTaskByName(const char *name, DHL_OS_TASK_ID *returnTid) { if(!name || strlen(name)==0) { printf("bad task name !!\n"); *returnTid=0; return DHL_FAIL_INVALID_PARAM; } osi_takemutexsemaphore(semTask); *returnTid=osi_taskidfromname((char *)name); osi_givemutexsemaphore(semTask); return DHL_OK; } DHL_OS_TASK_ID DHL_OS_GetTaskID(void) { DHL_OS_TASK_ID tid; tid = osi_taskid(); return tid; } DHL_RESULT DHL_OS_GetTaskInfo(DHL_OS_TASK_ID tid, DHL_OS_TASK_INFO *pTaskInfo) { b_task_stats *stat; if (pTaskInfo == NULL) { DHL_OS_Printf("|%s| null arg(pTaskInfo).\n", __FUNCTION__); return DHL_FAIL_NULL_POINTER; } stat=bos_get_task_info((b_task_t)tid); if(stat) { pTaskInfo->tid = tid; pTaskInfo->name = stat->name; pTaskInfo->priority= tid; }else { DHL_OS_Printf("|%s| fail to find task(tid:0x%x).\n", __FUNCTION__, tid); return DHL_FAIL_INVALID_HANDLE; } return DHL_OK; } char *DHL_OS_TaskName(DHL_OS_TASK_ID tid) { if(tid==(DHL_OS_TASK_ID)0) { tid=osi_taskid(); } return osi_taskname(tid); } int DHL_OS_TaskPriority() { return osi_taskpriority(); } #if COMMENT ____Semaphore____(){} #endif DHL_OS_SEMA_ID DHL_OS_CreateCountingSemaphore(const char *name, UINT32 options, UINT32 count) { return osi_createcountingsemaphore(name, options, count); } DHL_OS_SEMA_ID DHL_OS_CreateBinarySemaphore(const char *name, UINT32 options, BOOL flag) { return osi_createbinarysemaphore(name, options, flag); } DHL_OS_SEMA_ID DHL_OS_CreateMutexSemaphore(const char *name) { return osi_createmutexsemaphore(name); } void DHL_OS_DeleteSemaphore(DHL_OS_SEMA_ID sem) { printf("delete sem %x\n", sem); osi_deletesemaphore(sem); } DHL_RESULT DHL_OS_TakeSemaphore(DHL_OS_SEMA_ID sem, UINT32 millisec) { int ticks; if (millisec == DHL_TIMEOUT_FOREVER) { if (osi_in_interrupt() || osi_in_tasklock()) { // osi_dbgprint("\a !! take sem in isr or tasklock\n"); return DHL_FAIL_INVALID_STATE; } return osi_takesemaphore(sem); } else if(millisec == 0) { return osi_takesemaphore_nowait(sem); }else { if (osi_in_interrupt() || osi_in_tasklock()) { // osi_dbgprint("\a !! take sem in isr\n"); return DHL_FAIL_INVALID_STATE; } ticks = MS_TO_TICKS(millisec); return osi_takesemaphore_wait(sem, ticks); } return DHL_OK; } DHL_RESULT DHL_OS_GiveSemaphore(DHL_OS_SEMA_ID sem) { return osi_givesemaphore(sem); } #if COMMENT ____OS_MessageQ____(){} #endif void _msg_api_test(void) { #if 0 typedef struct { unsigned char f; unsigned int a; unsigned short int b; unsigned short int c; unsigned int d; } TEST_MSG; MS_S32 qid; TEST_MSG smsg, rmsg; MS_U32 rmsg_size; MS_BOOL ret; int i; // create qid = MsOS_CreateQueue(NULL, 96, E_MSG_FIXED_SIZE, sizeof(TEST_MSG), E_MSOS_FIFO, "Test"); printf("qid=%x\n", qid); // send for (i = 0; i < 100; i++) { printf("<%5d>snd %3d:", DHL_OS_GetMsCount(), i + 1); smsg.f = i; smsg.a = 0x82600628 + (0x08 * i); smsg.b = 0x25099052 + (0x04 * i); smsg.c = 0xcafeefac + (0x10 * i); smsg.d = 0xbeeffeeb + (0x02 * i); ret = MsOS_SendToQueue(qid, (MS_U8 *)&smsg, sizeof(TEST_MSG), 100); printf("ret=%x, f=%x, a=%x, b=%x, c=%x, d=%x\n", ret, smsg.f, smsg.a, smsg.b, smsg.c, smsg.d); } // receive for (i = 0; i < 150; i++) { printf("<%5d>rcv %3d:", DHL_OS_GetMsCount(), i + 1); ret = MsOS_RecvFromQueue(qid, (MS_U8 *)&rmsg, sizeof(TEST_MSG), &rmsg_size, 100); printf("ret=%x, size=%x, f=%x, a=%x, b=%x, c=%x, d=%x\n", ret, rmsg_size, rmsg.f, rmsg.a, rmsg.b, rmsg.c, rmsg.d); } #endif } DHL_OS_MSGQ_ID DHL_OS_CreateMessageQueue(const char *name, UINT32 options, UINT32 maxMessages, UINT32 maxMessageLength) { return osi_createmessagequeue(name, options, maxMessages, maxMessageLength); } void DHL_OS_DeleteMessageQueue(DHL_OS_MSGQ_ID qid) { osi_deletemessagequeue(qid); } DHL_RESULT DHL_OS_SendMessage(DHL_OS_MSGQ_ID qid, void *buffer, int bytes) { return osi_sendmessage(qid, buffer, bytes); } DHL_RESULT DHL_OS_ReceiveMessage(DHL_OS_MSGQ_ID qid, void *msgBuf, UINT32 millisec) { if (millisec == DHL_TIMEOUT_FOREVER) { if (osi_in_interrupt() || osi_in_tasklock()) { osi_dbgprint("\a !! rcv msg in isr or tasklock\n"); return DHL_FAIL_INVALID_STATE; } return osi_receivemessage(qid, msgBuf); } else if(millisec == 0) { return osi_receivemessage_wait(qid, msgBuf, NO_WAIT); }else { if (osi_in_interrupt() || osi_in_tasklock()) { osi_dbgprint("\a !! rcv msg in isr\n"); return DHL_FAIL_INVALID_STATE; } return osi_receivemessage_wait(qid, msgBuf, MS_TO_TICKS(millisec)); } return DHL_OK; } #if COMMENT ____OS_Heap____(){} #endif void *DHL_OS_Malloc(int size) { return OS_Malloc(size); } void DHL_OS_Free(void **pptr) { return OS_Free(pptr); } extern bcm_heap_t *g_p_sdram_heap; void DHL_OS_GetHeapStatus(DHL_OS_HEAP_STATUS *pHeapStatus) { #ifdef BCM_DEBUG struct bcm_heap_status bhs; memset(pHeapStatus, 0, sizeof(dhl_heap_status)); if (mem_status(g_p_sdram_heap, &bhs) == 0) { pHeapStatus->size_heap = bhs.size_heap; pHeapStatus->num_alloc_chunk = bhs.num_alloc_chunk; pHeapStatus->size_alloc = bhs.size_alloc; pHeapStatus->num_free_chunk = bhs.num_free_chunk; pHeapStatus->size_free = bhs.size_free; } #endif } #if COMMENT ____OS_Tick____(){} #endif void DHL_OS_Delay(UINT32 millisec) { if (osi_in_interrupt() || osi_in_tasklock()) { osi_dbgprint("\a !! delay in isr or tasklock\n"); return;; } osi_delay(millisec); } UINT32 DHL_OS_GetMsCount(void) { return TICKS_TO_MS(osi_gettickcount()); } UINT32 DHL_OS_GetTickCount(void) { return osi_gettickcount(); } UINT32 DHL_OS_GetTicksPerSecond(void) { return osi_gettickspersecond(); } #if COMMENT ____OS_Interrupt____(){} #endif BOOL DHL_OS_GetIntState() { return osi_in_interrupt(); } UINT32 DHL_OS_DisableInterrupts() { return osi_disableint(); } void DHL_OS_RestoreInterrupts(UINT32 mask) { osi_enableint(mask); } #if COMMENT ___Task_Enum___(){} #endif void DHL_OS_ShowTaskInfo(int level) { } #if COMMENT ___Task_Priority___(){} #endif /* OS º°·Î highest, lowest priority°¡ ´Ù¸£¹Ç·Î inversion ÀÛ¾÷À» ´ë½ÅÇØ ÁÖ´Â ¸ÅÅ©·Î¸¦ »ç¿ë. ¾Æ·¡ Å×ÀÌºí¿¡¼­´Â °¢ taskÀÇ »ó´ëÀûÀÎ ¼ø¼­¸¸ Àâ¾ÆÁÖ¸é µÇµµ·Ï ÇÔ. */ #define PRIO(x) (64-(x)) struct { const char *signiture; int prio; } p_prio_tbl[] = { #if 1//Newcon3 DST { "APP_INIT", 14, }, { "DRV_GPB", 15, }, //x { "DRV_IR", 30, }, //uio_task (x-1) //16->30 { "DRV_GPIO", 18, }, { "DRV_UART", 20, }, { "DRV_TIMER", 21, }, { "DRV_FE", 23, }, { "DRV_BASE", 24, }, { "DHL_PSIPRX", 29, }, //26->29 { "DHL_EVENT", 27, }, { "DHL_AV_EVT", 28, }, //{ "DMW_TUNER", 29, }, // UI °ü·Ã { "DIGIT_KEY", 32, }, { "MENU", 22, }, //19 -> 22 { "COMM", 31, }, //22->31 // Caption °ü·Ã { "DCC_AUX", 34, }, { "AUX_CC", 35, }, { "DCC_DCD", 36, }, { "DCC_DMX", 37, }, { "VBI_DEC", 38, }, { "CC_TIMER", 39, }, { "EA", 44, }, { "DMC_TASK", 45, }, // old channel mw { "DMW_CHM", 46, }, // new channel mw, channel tuning control { "DMW_PSI", 47, }, // new psi mw, psi/psip scan task { "DMW_EPGSCN", 48, }, // old epg mw { "DMW_EPGEVT", 49, }, // old epg mw { "DMW_TIMER", 51, }, // General purpose timer { "APP_TIMER", 53, }, // Sleep timer ¿ëÀ¸·Î »ç¿ëµÇ´Â °ÍÀ¸·Î º¸ÀÓ. { "SIGMON", 54, }, // signal monitor task { "DHL_SHELL", 56, }, // µð¹ö±× ½© { "DHL_SHELLX", 57, }, // µð¹ö±× ½© background ½ÇÇà { "DHL_PRINTF", 58, }, // console printf task { "DMW_FLASH", 59, }, // Flash worker task (for NVM) #else { "APP_INIT", PRIO(50), }, { "DRV_GPB", PRIO(49), }, { "DRV_IR", PRIO(48), }, { "DRV_GPIO", PRIO(46), }, { "DRV_UART", PRIO(44), }, { "DRV_TIMER", PRIO(43), }, { "DRV_FE", PRIO(41), }, { "DRV_BASE", PRIO(40), }, { "DHL_PSIPRX", PRIO(38), }, { "DHL_EVENT", PRIO(37), }, { "DHL_AV_EVT", PRIO(36), }, { "DMW_TUNER", PRIO(35), }, // UI °ü·Ã { "DIGIT_KEY", PRIO(32), }, { "MENU", PRIO(45), }, { "COMM", PRIO(42), }, // Caption °ü·Ã { "DCC_AUX", PRIO(30), }, { "AUX_CC", PRIO(29), }, { "DCC_DCD", PRIO(28), }, { "DCC_DMX", PRIO(27), }, { "VBI_DEC", PRIO(26), }, { "CC_TIMER", PRIO(25), }, { "EA", PRIO(20), }, { "DMC_TASK", PRIO(19), }, // old channel mw { "DMW_CHM", PRIO(18), }, // new channel mw, channel tuning control { "DMW_PSI", PRIO(17), }, // new psi mw, psi/psip scan task { "DMW_EPGSCN", PRIO(16), }, // old epg mw { "DMW_EPGEVT", PRIO(15), }, // old epg mw //{ "SCTESI_RX", PRIO(17), }, // scte oob si scan task { "DMW_TIMER", PRIO(13), }, // General purpose timer { "APP_TIMER", PRIO(11), }, // Sleep timer ¿ëÀ¸·Î »ç¿ëµÇ´Â °ÍÀ¸·Î º¸ÀÓ. { "SIGMON", PRIO(10), }, // signal monitor task { "DHL_SHELL", PRIO(8), }, // µð¹ö±× ½© { "DHL_SHELLX", PRIO(7), }, // µð¹ö±× ½© background ½ÇÇà { "DHL_PRINTF", PRIO(6), }, // console printf task { "DMW_FLASH", PRIO(5), }, // Flash worker task (for NVM) #endif }; /* task signiture¸¦ task priority·Î º¯È¯ÇÏ¿© ÁÖ´Â util ÇÔ¼ö. */ int os_sig2taskprio(const char *signiture) { int i; for (i=0;(unsigned int)i