| 1 | /******************************************************************** |
|---|
| 2 | DHL_OSAL.c |
|---|
| 3 | |
|---|
| 4 | PHOENIX Driver HAL library |
|---|
| 5 | OS Abstraction Layer implementation |
|---|
| 6 | |
|---|
| 7 | Copyright 2006 Digital STREAM Technology, Inc. |
|---|
| 8 | All Rights Reserved |
|---|
| 9 | |
|---|
| 10 | $Id: DHL_OSAL.c v1.00 2006/04 cafrii Exp $ |
|---|
| 11 | |
|---|
| 12 | ********************************************************************/ |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | /* |
|---|
| 16 | Include files |
|---|
| 17 | */ |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | #include "DHL_Types.h" |
|---|
| 21 | |
|---|
| 22 | #include "DHL_OSAL.h" |
|---|
| 23 | #include "DHL_OSAL_Impl.h" |
|---|
| 24 | |
|---|
| 25 | #include "DHL_DBG.h" |
|---|
| 26 | #include "bcm_mips_defs.h" |
|---|
| 27 | #include "bcm_mips.h" |
|---|
| 28 | #include "bcmmemmgr.h" |
|---|
| 29 | #include "bos.h" |
|---|
| 30 | |
|---|
| 31 | /* |
|---|
| 32 | define |
|---|
| 33 | */ |
|---|
| 34 | |
|---|
| 35 | #define USE_BCM_MUTEX 0 |
|---|
| 36 | #define USE_BCM_MSG_QUEUE 0 |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | #if USE_BCM_MUTEX |
|---|
| 40 | #include "bkni.h" |
|---|
| 41 | #include "bkni_multi.h" |
|---|
| 42 | #endif |
|---|
| 43 | |
|---|
| 44 | #if USE_BCM_MSG_QUEUE |
|---|
| 45 | #include "bos.h" |
|---|
| 46 | #endif |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | // to enable verbose debug message. |
|---|
| 50 | #define OSAL_DEBUG 0 |
|---|
| 51 | |
|---|
| 52 | |
|---|
| 53 | // to use message queue in ISR, we should not use mutex. |
|---|
| 54 | // remove codes after verification. |
|---|
| 55 | // |
|---|
| 56 | #define BUGFIX_MSGQ 1 |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | #define max(a,b) (((a) > (b)) ? (a) : (b)) |
|---|
| 60 | #define min(a,b) (((a) < (b)) ? (a) : (b)) |
|---|
| 61 | |
|---|
| 62 | |
|---|
| 63 | #if COMMENT |
|---|
| 64 | _______________(){} |
|---|
| 65 | #endif |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | void dhl_dbg_flush_console(void) |
|---|
| 69 | { |
|---|
| 70 | //BKTEMP console_flush(); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | |
|---|
| 74 | int osi_dbgprint(char *fmt, ...) |
|---|
| 75 | { |
|---|
| 76 | // DMC ¿¡¼ »ç¿ëÇÏ´Â debug print. |
|---|
| 77 | char msgPrefix[50]; |
|---|
| 78 | va_list v; |
|---|
| 79 | int n; |
|---|
| 80 | char buf[200]; |
|---|
| 81 | |
|---|
| 82 | dhl_dbg_flush_console(); |
|---|
| 83 | |
|---|
| 84 | //if (g_Trace_EpgBase <= nLevel) return 0; |
|---|
| 85 | |
|---|
| 86 | snprintf(msgPrefix, 200, "[osi %s %d] ", DHL_OS_TaskName(0), DHL_OS_TaskPriority()); |
|---|
| 87 | |
|---|
| 88 | va_start(v, fmt); |
|---|
| 89 | n = BKNI_Vsnprintf(buf, 200, fmt, v); |
|---|
| 90 | va_end(v); |
|---|
| 91 | |
|---|
| 92 | BKNI_Printf(msgPrefix); BKNI_Printf(buf); |
|---|
| 93 | dhl_dbg_flush_console(); |
|---|
| 94 | |
|---|
| 95 | return n; |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | #undef printf |
|---|
| 99 | #define printf osi_dbgprint |
|---|
| 100 | |
|---|
| 101 | |
|---|
| 102 | |
|---|
| 103 | #if COMMENT |
|---|
| 104 | ___Internal_alloc___(){} |
|---|
| 105 | #endif |
|---|
| 106 | |
|---|
| 107 | /* |
|---|
| 108 | this is only for osal_impl internal. |
|---|
| 109 | do not use this outside. |
|---|
| 110 | */ |
|---|
| 111 | |
|---|
| 112 | static void *osi_calloc(int n) |
|---|
| 113 | { |
|---|
| 114 | void *p; |
|---|
| 115 | #ifdef BCM_DEBUG |
|---|
| 116 | p = malloc_align_dbg(n, 2, __FILE__, __LINE__); |
|---|
| 117 | #else |
|---|
| 118 | p = OS_Malloc(n); |
|---|
| 119 | #endif |
|---|
| 120 | memset(p, 0, n); |
|---|
| 121 | return p; |
|---|
| 122 | } |
|---|
| 123 | static void osi_free(void *p) |
|---|
| 124 | { |
|---|
| 125 | // p is not compatible with OS_Free. |
|---|
| 126 | // this will not reset pointer. |
|---|
| 127 | |
|---|
| 128 | #ifdef BCM_DEBUG |
|---|
| 129 | free_dbg(p, __FILE__, __LINE__); |
|---|
| 130 | #else |
|---|
| 131 | OS_FreeDirect(p); |
|---|
| 132 | #endif |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | #if COMMENT |
|---|
| 138 | ___Tick_Func___(){} |
|---|
| 139 | #endif |
|---|
| 140 | |
|---|
| 141 | UINT32 osi_gettickcount() |
|---|
| 142 | { |
|---|
| 143 | return bos_getticks(); |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | |
|---|
| 147 | UINT32 osi_gettickspersecond() |
|---|
| 148 | { |
|---|
| 149 | return g_ticks_per_second; |
|---|
| 150 | } |
|---|
| 151 | |
|---|
| 152 | |
|---|
| 153 | void osi_delay(UINT32 millisec) |
|---|
| 154 | { |
|---|
| 155 | bos_sleep(millisec); |
|---|
| 156 | } |
|---|
| 157 | |
|---|
| 158 | |
|---|
| 159 | #if COMMENT |
|---|
| 160 | ___Task_related_Func___(){} |
|---|
| 161 | #endif |
|---|
| 162 | |
|---|
| 163 | extern unsigned char OSIntNesting; |
|---|
| 164 | |
|---|
| 165 | BOOL osi_in_interrupt(void) |
|---|
| 166 | { |
|---|
| 167 | return OSIntNesting > 0 ? TRUE : FALSE; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | /* |
|---|
| 171 | interrupt disable/enable: |
|---|
| 172 | |
|---|
| 173 | */ |
|---|
| 174 | UINT32 osi_disableint() |
|---|
| 175 | { |
|---|
| 176 | /* |
|---|
| 177 | ´Ü¼øÈ÷ OS_ENTER_CRITICAL ¸¸ Çϸé ÃæºÐÇÏÁö ¾Ê´Ù. |
|---|
| 178 | int disable ÇØµµ OS scheduleÀÌ µÇ±âµµ Çϴµ¥, |
|---|
| 179 | »õ·Î¿î task¿¡¼ÀÇ cp0:$12ÀÇ int°¡ enable µÇ¾î ÀÖ´Ù¸é ¾Æ¹« Àǹ̰¡ ¾ø¾îÁø´Ù. |
|---|
| 180 | »ç½Ç OSSched() ³»ºÎ¿¡¼µµ OS_ENTER_CRITICAL µÈ »óÅ¿¡¼ switching ÇÑ´Ù. |
|---|
| 181 | |
|---|
| 182 | °á·ÐÀº ¿Ïº®ÇÏ°Ô int disable ÇÏ·Á¸é schedulerµµ °°ÀÌ disable ½ÃÄÑ¾ß ÇÑ´Ù. |
|---|
| 183 | */ |
|---|
| 184 | |
|---|
| 185 | UINT32 flags; |
|---|
| 186 | OSSchedLock(); |
|---|
| 187 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 188 | return flags; |
|---|
| 189 | } |
|---|
| 190 | |
|---|
| 191 | void osi_enableint(UINT32 mask) |
|---|
| 192 | { |
|---|
| 193 | MIPS_SetInterrupts(mask);// OS_EXIT_CRITICAL(mask); |
|---|
| 194 | OSSchedUnlock(); |
|---|
| 195 | } |
|---|
| 196 | |
|---|
| 197 | extern unsigned char OSLockNesting; |
|---|
| 198 | |
|---|
| 199 | BOOL osi_in_tasklock(void) |
|---|
| 200 | { |
|---|
| 201 | return OSLockNesting> 0 ? TRUE : FALSE; |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | /* |
|---|
| 205 | lock/unlock task: |
|---|
| 206 | disable/enable OS scheduler. |
|---|
| 207 | */ |
|---|
| 208 | UINT32 osi_locktask() |
|---|
| 209 | { |
|---|
| 210 | OSSchedLock(); |
|---|
| 211 | // actually, return value is not important.. |
|---|
| 212 | return OSLockNesting; |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | void osi_unlocktask(UINT32 mask) |
|---|
| 216 | { |
|---|
| 217 | //mask is unused. |
|---|
| 218 | OSSchedUnlock(); |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | |
|---|
| 222 | char *osi_taskname(os_task_id tid) |
|---|
| 223 | { |
|---|
| 224 | b_task_stats *stat=bos_get_task_info((b_task_t)tid); |
|---|
| 225 | |
|---|
| 226 | if(stat) return stat->name; |
|---|
| 227 | |
|---|
| 228 | return NULL; |
|---|
| 229 | } |
|---|
| 230 | |
|---|
| 231 | /* |
|---|
| 232 | note! |
|---|
| 233 | OSTCBCur should be accessed with all interrupt disabled. |
|---|
| 234 | */ |
|---|
| 235 | |
|---|
| 236 | int osi_taskpriority() |
|---|
| 237 | { |
|---|
| 238 | int prio; |
|---|
| 239 | UINT32 flags; |
|---|
| 240 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 241 | prio = (int)OSTCBCur->OSTCBPrio; |
|---|
| 242 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flag); |
|---|
| 243 | return prio; |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | |
|---|
| 247 | os_task_id osi_taskid() |
|---|
| 248 | { |
|---|
| 249 | #if 0//#ifdef UCOS_II |
|---|
| 250 | os_task_id id; |
|---|
| 251 | OS_TCB tcb; |
|---|
| 252 | OSTaskQuery( OS_PRIO_SELF, &tcb ); /* use our priority as a task id */ |
|---|
| 253 | id = tcb.OSTCBPrio;; |
|---|
| 254 | #else |
|---|
| 255 | os_task_id id; |
|---|
| 256 | UINT32 flags; |
|---|
| 257 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 258 | id = OSTCBCur->OSTCBPrio; |
|---|
| 259 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flag); |
|---|
| 260 | #endif |
|---|
| 261 | return id; |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | |
|---|
| 265 | os_task_id osi_taskidfromname(char *tname) |
|---|
| 266 | { |
|---|
| 267 | int i; |
|---|
| 268 | b_task_stats *stat=NULL; |
|---|
| 269 | |
|---|
| 270 | for(i=0, stat=bos_get_task_info(i); stat; i++) { |
|---|
| 271 | if(0==strcmp(stat->name, tname)) return (os_task_id)i; |
|---|
| 272 | stat=bos_get_task_info(i); |
|---|
| 273 | } |
|---|
| 274 | |
|---|
| 275 | return 63; |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | |
|---|
| 279 | void osi_changetaskpriority(os_task_id tid, UINT32 newPrio, UINT32 *oldPrioPtr) |
|---|
| 280 | { |
|---|
| 281 | |
|---|
| 282 | if(tid==0) { |
|---|
| 283 | tid=osi_taskpriority(); |
|---|
| 284 | } |
|---|
| 285 | OSTaskChangePrio(tid, newPrio); |
|---|
| 286 | *oldPrioPtr = tid; |
|---|
| 287 | } |
|---|
| 288 | |
|---|
| 289 | |
|---|
| 290 | void osi_selfdeletetask(void) |
|---|
| 291 | { |
|---|
| 292 | OSTaskDel(OS_PRIO_SELF); |
|---|
| 293 | } |
|---|
| 294 | void osi_deletetask(os_task_id tid) |
|---|
| 295 | { |
|---|
| 296 | bos_stop_task((b_task_t)tid); |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | #if 0 |
|---|
| 300 | static void osi_taskbody(int *osparam) |
|---|
| 301 | { |
|---|
| 302 | os_taskfunction func = (os_taskfunction)(osparam[0]); |
|---|
| 303 | void *arg = (void *)(osparam[1]); |
|---|
| 304 | |
|---|
| 305 | #if 1 |
|---|
| 306 | // cafrii 081014 add. |
|---|
| 307 | // turn on IE bit for normal operation. |
|---|
| 308 | // it is possible that parent task call OS_SpawnTask in IE disabled state. |
|---|
| 309 | // in such case, child task start as IE disabled state, which is abnormal. |
|---|
| 310 | // |
|---|
| 311 | unsigned long status; |
|---|
| 312 | |
|---|
| 313 | status = bcm_read_cp0($12,0); |
|---|
| 314 | status |= ST0_IE; |
|---|
| 315 | bcm_write_cp0($12,0, status); |
|---|
| 316 | |
|---|
| 317 | #endif |
|---|
| 318 | |
|---|
| 319 | (*func)(arg); |
|---|
| 320 | |
|---|
| 321 | while (1) { // wait forever.. |
|---|
| 322 | DHL_OS_Delay(DHL_OS_GetTicksPerSecond()*60*60); |
|---|
| 323 | }; |
|---|
| 324 | } |
|---|
| 325 | #endif |
|---|
| 326 | |
|---|
| 327 | /* |
|---|
| 328 | in DST OSAL api, stackSize is byte size. |
|---|
| 329 | in osi_show_taskinfo(), the stack size is word (4-byte) unit. |
|---|
| 330 | |
|---|
| 331 | we provide stub function to call real user task function. |
|---|
| 332 | if user task function completes, it waits forever. |
|---|
| 333 | |
|---|
| 334 | os_task_id is its priority! (NOTICE: inversion value) |
|---|
| 335 | */ |
|---|
| 336 | os_task_id osi_spawntask(os_taskfunction func, const char *name, int priority, UINT32 stackSize, |
|---|
| 337 | UINT32 arg1) |
|---|
| 338 | { |
|---|
| 339 | b_task_t tid; |
|---|
| 340 | b_task_params param; |
|---|
| 341 | unsigned int *p; |
|---|
| 342 | int stk_size_word = (stackSize + 3)/4; // round up. (align) |
|---|
| 343 | |
|---|
| 344 | #if 0 |
|---|
| 345 | /* cafrii 081014 add check code: |
|---|
| 346 | in uCOS, parent task has IE disabled, child (created) task also run in IE disabled state. |
|---|
| 347 | OS_LockTask() makes IE disabled. So, we should not call OS_SpawnTask() after OS_LockTask(). |
|---|
| 348 | */ |
|---|
| 349 | if (OS_IS_ISR()) { |
|---|
| 350 | printf("\n!! spawn task in privileged level\n"); |
|---|
| 351 | printf("SR: %08x\n", bcm_read_cp0($12,0)); |
|---|
| 352 | stack_backtrace(0, 0, 0, 0); |
|---|
| 353 | } |
|---|
| 354 | #endif |
|---|
| 355 | param.priority=priority; |
|---|
| 356 | param.stack_size=stk_size_word; |
|---|
| 357 | |
|---|
| 358 | p = (unsigned int *) osi_calloc(stk_size_word*sizeof(int) + sizeof(int)*2); |
|---|
| 359 | param.stack = p; |
|---|
| 360 | param.name = name; |
|---|
| 361 | |
|---|
| 362 | #if 0//ndef UCOS_II //ucOS |
|---|
| 363 | p = p + stk_size_word; // we place osparam at the end of mem block. (== bottom of stack) |
|---|
| 364 | p[0] = (unsigned int) func; |
|---|
| 365 | p[1] = (unsigned int) arg1; |
|---|
| 366 | #endif |
|---|
| 367 | |
|---|
| 368 | |
|---|
| 369 | //BKTEMP if(b_ok!=bos_start_task(&tid, ¶m, (b_task_func)osi_taskbody, (void *)p)) { |
|---|
| 370 | if(b_ok!=bos_start_task(&tid, ¶m, func, (void *)arg1)) { |
|---|
| 371 | |
|---|
| 372 | printf("!! err : fail to create task\n"); |
|---|
| 373 | return 0; |
|---|
| 374 | } |
|---|
| 375 | |
|---|
| 376 | return (os_task_id)tid; |
|---|
| 377 | } |
|---|
| 378 | |
|---|
| 379 | |
|---|
| 380 | |
|---|
| 381 | |
|---|
| 382 | #if COMMENT |
|---|
| 383 | ___Sem_related_Func___(){} |
|---|
| 384 | #endif |
|---|
| 385 | |
|---|
| 386 | #define SIZE_SEM_NAME 15 |
|---|
| 387 | |
|---|
| 388 | enum { |
|---|
| 389 | SEM_MUTEX=0x1, |
|---|
| 390 | SEM_BINARY=0X2, |
|---|
| 391 | SEM_COUNTING=0X3, |
|---|
| 392 | SEM_MSGQ=0x4, |
|---|
| 393 | }; |
|---|
| 394 | |
|---|
| 395 | typedef struct { |
|---|
| 396 | UINT8 type; |
|---|
| 397 | // UINT32 handler; |
|---|
| 398 | OS_EVENT* handler; |
|---|
| 399 | |
|---|
| 400 | #if USE_BCM_MUTEX |
|---|
| 401 | BKNI_MutexHandle hMutex; |
|---|
| 402 | #endif |
|---|
| 403 | char name[SIZE_SEM_NAME+1]; |
|---|
| 404 | //--------- |
|---|
| 405 | UINT8 nRecursive; |
|---|
| 406 | UINT32 owner; //mutex |
|---|
| 407 | |
|---|
| 408 | void *next; // for free list managent of reuse semaphore. |
|---|
| 409 | } SemType; |
|---|
| 410 | |
|---|
| 411 | |
|---|
| 412 | |
|---|
| 413 | #if OSAL_DEBUG |
|---|
| 414 | int g_os_sem_create_count; |
|---|
| 415 | |
|---|
| 416 | #define trace_sem_create(type) \ |
|---|
| 417 | printf("==== sem create: " #type " %d, os-free %d, dhl-free %d\n", \ |
|---|
| 418 | ++g_os_sem_create_count, OSSemGetFreeCount(), osi_free_reuse_sem_count()) |
|---|
| 419 | #else |
|---|
| 420 | #define trace_sem_create(type) |
|---|
| 421 | #endif |
|---|
| 422 | |
|---|
| 423 | |
|---|
| 424 | /* |
|---|
| 425 | ucos semaphore wrapper |
|---|
| 426 | take -> SemAccept/SemPend |
|---|
| 427 | give -> SemPost |
|---|
| 428 | */ |
|---|
| 429 | static DHL_RESULT _takesemaphore(SemType *sem, int ticks) |
|---|
| 430 | { |
|---|
| 431 | DHL_RESULT result=DHL_OK; |
|---|
| 432 | UINT8 err; |
|---|
| 433 | |
|---|
| 434 | #if OSAL_DEBUG |
|---|
| 435 | if (sem->type != SEM_MUTEX) |
|---|
| 436 | { |
|---|
| 437 | printf("#### take %c sem '%s' %x, h %x, tick %d\n", |
|---|
| 438 | sem->type == SEM_BINARY ? 'b' : |
|---|
| 439 | sem->type == SEM_MUTEX ? 'm' : 'c', |
|---|
| 440 | sem->name, sem, sem->handler, ticks); |
|---|
| 441 | } |
|---|
| 442 | #endif |
|---|
| 443 | |
|---|
| 444 | #if 0 |
|---|
| 445 | if (OS_IS_ISR() && ticks != NO_WAIT) |
|---|
| 446 | return DHL_FAIL_INVALID_STATE; |
|---|
| 447 | #endif |
|---|
| 448 | |
|---|
| 449 | if (ticks == NO_WAIT) |
|---|
| 450 | { |
|---|
| 451 | INT16U value= OSSemAccept((OS_EVENT *)sem->handler); |
|---|
| 452 | // printf("sem_count: %d/%d\n",value, sem->handler->OSEventCnt); |
|---|
| 453 | if (value > 0) |
|---|
| 454 | result = DHL_OK; |
|---|
| 455 | else |
|---|
| 456 | result = DHL_FAIL_TIMEOUT; |
|---|
| 457 | } |
|---|
| 458 | else if (ticks == WAIT_FOREVER) |
|---|
| 459 | { |
|---|
| 460 | do { |
|---|
| 461 | OSSemPend((OS_EVENT *)sem->handler, 0xffff, &err); |
|---|
| 462 | } while (err == OS_TIMEOUT); |
|---|
| 463 | if(err!=OS_NO_ERR) |
|---|
| 464 | { |
|---|
| 465 | printf("ERR: _takesemaphore %d\n", err); |
|---|
| 466 | result=DHL_FAIL_TIMEOUT; |
|---|
| 467 | }else |
|---|
| 468 | result = DHL_OK; |
|---|
| 469 | } |
|---|
| 470 | else // unlimited tick range. |
|---|
| 471 | { |
|---|
| 472 | // repeat until ticks are all consumed or err occurred. |
|---|
| 473 | UINT32 prev, cur, ticks_left = ticks; |
|---|
| 474 | UINT32 rounds = 0; // for debugging. |
|---|
| 475 | cur = osi_gettickcount(); |
|---|
| 476 | do { |
|---|
| 477 | prev = cur; |
|---|
| 478 | rounds++; |
|---|
| 479 | OSSemPend((OS_EVENT *)sem->handler, min(0xffff, ticks_left), &err); |
|---|
| 480 | if (err == OS_TIMEOUT) { |
|---|
| 481 | // we should do more rounds until all 'ticks' consumed. |
|---|
| 482 | cur = osi_gettickcount(); |
|---|
| 483 | if(cur >= prev) |
|---|
| 484 | ticks_left -= (cur - prev); // decrease tick by elapsed time. |
|---|
| 485 | else |
|---|
| 486 | ticks_left -= (cur + prev); |
|---|
| 487 | } |
|---|
| 488 | } while (err == OS_TIMEOUT && ticks_left > 0); |
|---|
| 489 | // if(OS_NO_ERR != err) |
|---|
| 490 | // { |
|---|
| 491 | // printf("!!!! OSSemPend err=%d\n",err); |
|---|
| 492 | // } |
|---|
| 493 | #if OSAL_DEBUG |
|---|
| 494 | if (rounds > 1) { |
|---|
| 495 | printf("!!!! semtype %d: total %d rounds, requested ticks: %d (0x%x)\n", |
|---|
| 496 | sem->type, rounds, ticks); |
|---|
| 497 | } |
|---|
| 498 | #endif |
|---|
| 499 | if(err!=OS_NO_ERR) |
|---|
| 500 | { |
|---|
| 501 | // printf("ERR: _takesemaphore %d\n", err); |
|---|
| 502 | result=DHL_FAIL_TIMEOUT; |
|---|
| 503 | }else |
|---|
| 504 | result = DHL_OK; |
|---|
| 505 | } |
|---|
| 506 | |
|---|
| 507 | return result; |
|---|
| 508 | } |
|---|
| 509 | |
|---|
| 510 | static void _givesemaphore(SemType *sem) |
|---|
| 511 | { |
|---|
| 512 | #if OSAL_DEBUG |
|---|
| 513 | if (sem->type != SEM_MUTEX) |
|---|
| 514 | { |
|---|
| 515 | printf("#### give %c sem %s %x, h %x\n", |
|---|
| 516 | sem->type == SEM_BINARY ? 'b' : |
|---|
| 517 | sem->type == SEM_MUTEX ? 'm' : 'c', |
|---|
| 518 | sem->name, sem, sem->handler); |
|---|
| 519 | } |
|---|
| 520 | #endif |
|---|
| 521 | #if 0//BKTODO: semaphore, mutexÀÎ °æ¿ì °í·Á ÇÊ¿äÇÔ. (ucOS-II¿¡´Â OSSemPostEx()°¡ Á¦°øµÇÁö ¾Ê´Â´Ù.) |
|---|
| 522 | if (sem->type == SEM_BINARY || sem->type == SEM_MUTEX) |
|---|
| 523 | OSSemPostEx((OS_EVENT *)sem->handler, 1); |
|---|
| 524 | // return value 'OS_SEM_OVF' is not error. |
|---|
| 525 | else |
|---|
| 526 | OSSemPost((OS_EVENT *)sem->handler); |
|---|
| 527 | #else |
|---|
| 528 | #if 1//BK - binary semaphore acts like counting semaphore |
|---|
| 529 | if(sem->type == SEM_BINARY) |
|---|
| 530 | { |
|---|
| 531 | if(sem->handler->OSEventCnt > 0) |
|---|
| 532 | { |
|---|
| 533 | printf("skip: bin sema4 cnt=%d\n", sem->handler->OSEventCnt ); |
|---|
| 534 | return; |
|---|
| 535 | } |
|---|
| 536 | } |
|---|
| 537 | #endif |
|---|
| 538 | |
|---|
| 539 | OSSemPost((OS_EVENT *)sem->handler); |
|---|
| 540 | #endif |
|---|
| 541 | } |
|---|
| 542 | |
|---|
| 543 | |
|---|
| 544 | int osi_takesemaphore(os_semaphore_id sid) |
|---|
| 545 | { |
|---|
| 546 | return osi_takesemaphore_wait(sid, WAIT_FOREVER); |
|---|
| 547 | } |
|---|
| 548 | |
|---|
| 549 | |
|---|
| 550 | int osi_takesemaphore_wait(os_semaphore_id sid, int ticks) |
|---|
| 551 | { |
|---|
| 552 | DHL_RESULT result=DHL_OK; |
|---|
| 553 | SemType *sem=(SemType *)sid; |
|---|
| 554 | |
|---|
| 555 | if(sem->type == SEM_MUTEX) { |
|---|
| 556 | return osi_takemutexsemaphore_wait(sid, ticks); |
|---|
| 557 | } |
|---|
| 558 | |
|---|
| 559 | result = _takesemaphore(sem, ticks); |
|---|
| 560 | return result; |
|---|
| 561 | } |
|---|
| 562 | |
|---|
| 563 | |
|---|
| 564 | int osi_takesemaphore_nowait(os_semaphore_id sid) |
|---|
| 565 | { |
|---|
| 566 | return osi_takesemaphore_wait(sid, NO_WAIT); |
|---|
| 567 | } |
|---|
| 568 | |
|---|
| 569 | |
|---|
| 570 | int osi_givesemaphore(os_semaphore_id sid) |
|---|
| 571 | { |
|---|
| 572 | DHL_RESULT result; |
|---|
| 573 | SemType *sem=(SemType *)sid; |
|---|
| 574 | |
|---|
| 575 | if(sem->type==SEM_MUTEX) { |
|---|
| 576 | osi_givemutexsemaphore(sid); |
|---|
| 577 | return DHL_OK; |
|---|
| 578 | } |
|---|
| 579 | _givesemaphore(sem); |
|---|
| 580 | result = DHL_OK; |
|---|
| 581 | return result; |
|---|
| 582 | } |
|---|
| 583 | |
|---|
| 584 | |
|---|
| 585 | |
|---|
| 586 | int osi_flushsemaphore(os_semaphore_id sid) |
|---|
| 587 | { |
|---|
| 588 | SemType *sem=(SemType *)sid; |
|---|
| 589 | |
|---|
| 590 | if(sem->type == SEM_MUTEX) { |
|---|
| 591 | printf("!! %s: error, sem is mutex\n", __FUNCTION__); |
|---|
| 592 | return DHL_FAIL_INVALID_PARAM; |
|---|
| 593 | } |
|---|
| 594 | |
|---|
| 595 | while(OSSemAccept((OS_EVENT *)sem->handler)>0); |
|---|
| 596 | |
|---|
| 597 | return DHL_OK; |
|---|
| 598 | } |
|---|
| 599 | |
|---|
| 600 | |
|---|
| 601 | |
|---|
| 602 | void osi_deletesemaphore(os_semaphore_id sid) |
|---|
| 603 | { |
|---|
| 604 | // printf("!! %s: delete sem not supported!!\n", __FUNCTION__); |
|---|
| 605 | INT8U err; |
|---|
| 606 | SemType *sem=(SemType *)sid; |
|---|
| 607 | if(sem) |
|---|
| 608 | { |
|---|
| 609 | #if USE_BCM_MUTEX |
|---|
| 610 | if(sem->type == SEM_MUTEX) { |
|---|
| 611 | BKNI_DestroyMutex(sem->hMutex); |
|---|
| 612 | osi_free(sem); |
|---|
| 613 | return; |
|---|
| 614 | }else |
|---|
| 615 | #endif |
|---|
| 616 | { |
|---|
| 617 | OSSemDel((OS_EVENT *)sem->handler, OS_DEL_ALWAYS, &err);//BKTODO: option°ª È®ÀοäÇÔ. OS_DEL_NO_PEND -> OS_DEL_ALWAYS |
|---|
| 618 | osi_free(sem); |
|---|
| 619 | return; |
|---|
| 620 | } |
|---|
| 621 | } |
|---|
| 622 | |
|---|
| 623 | } |
|---|
| 624 | |
|---|
| 625 | |
|---|
| 626 | #if COMMENT |
|---|
| 627 | _______(){} |
|---|
| 628 | #endif |
|---|
| 629 | |
|---|
| 630 | int osi_takemutexsemaphore_wait(os_semaphore_id sid, int ticks) |
|---|
| 631 | { |
|---|
| 632 | #if USE_BCM_MUTEX |
|---|
| 633 | SemType *sem=(SemType *)sid; |
|---|
| 634 | UINT32 flags; |
|---|
| 635 | DHL_RESULT result; |
|---|
| 636 | BERR_Code err; |
|---|
| 637 | |
|---|
| 638 | if (sem->type != SEM_MUTEX) { |
|---|
| 639 | printf("!! %s: error, sem is NOT a mutex\n", __FUNCTION__); |
|---|
| 640 | return DHL_FAIL_INVALID_PARAM; |
|---|
| 641 | } |
|---|
| 642 | |
|---|
| 643 | if (ticks == NO_WAIT) |
|---|
| 644 | { |
|---|
| 645 | err = BKNI_TryAcquireMutex(sem->hMutex); |
|---|
| 646 | if(err==BERR_SUCCESS) |
|---|
| 647 | { |
|---|
| 648 | result = DHL_OK; |
|---|
| 649 | }else |
|---|
| 650 | { |
|---|
| 651 | printf("ERR: _takesemaphore %d\n", err); |
|---|
| 652 | result=DHL_FAIL_TIMEOUT; |
|---|
| 653 | } |
|---|
| 654 | } |
|---|
| 655 | else if (ticks == WAIT_FOREVER) |
|---|
| 656 | { |
|---|
| 657 | err = BKNI_AcquireMutex(sem->hMutex); |
|---|
| 658 | if(err==BERR_SUCCESS) |
|---|
| 659 | { |
|---|
| 660 | result = DHL_OK; |
|---|
| 661 | }else |
|---|
| 662 | { |
|---|
| 663 | printf("ERR: _takesemaphore %d\n", err); |
|---|
| 664 | result=DHL_FAIL_TIMEOUT; |
|---|
| 665 | } |
|---|
| 666 | } |
|---|
| 667 | else // unlimited tick range. |
|---|
| 668 | { |
|---|
| 669 | int prev, cur, ticks_left = ticks; |
|---|
| 670 | int rounds = 0; // for debugging. |
|---|
| 671 | cur = osi_gettickcount(); |
|---|
| 672 | do { |
|---|
| 673 | prev = cur; |
|---|
| 674 | rounds++; |
|---|
| 675 | err = BKNI_AcquireMutexTimeout(sem->hMutex, ticks_left); |
|---|
| 676 | if (err != BERR_SUCCESS) { |
|---|
| 677 | // we should do more rounds until all 'ticks' consumed. |
|---|
| 678 | ticks_left -= ((cur = osi_gettickcount()) - prev); // decrease tick by elapsed time. |
|---|
| 679 | } |
|---|
| 680 | } while (err == BERR_SUCCESS && ticks_left > 0); |
|---|
| 681 | |
|---|
| 682 | if(err!=BERR_SUCCESS) |
|---|
| 683 | { |
|---|
| 684 | printf("ERR: _takesemaphore %d\n", err); |
|---|
| 685 | result=DHL_FAIL_TIMEOUT; |
|---|
| 686 | }else |
|---|
| 687 | { |
|---|
| 688 | result = DHL_OK; |
|---|
| 689 | } |
|---|
| 690 | } |
|---|
| 691 | if(result == DHL_OK) |
|---|
| 692 | { |
|---|
| 693 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 694 | sem->owner = (UINT32)OSTCBCur->OSTCBPrio; |
|---|
| 695 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 696 | } |
|---|
| 697 | #else |
|---|
| 698 | SemType *sem=(SemType *)sid; |
|---|
| 699 | UINT32 flags; |
|---|
| 700 | DHL_RESULT result; |
|---|
| 701 | |
|---|
| 702 | if (sem->type != SEM_MUTEX) { |
|---|
| 703 | printf("!! %s: error, sem is NOT a mutex\n", __FUNCTION__); |
|---|
| 704 | return DHL_FAIL_INVALID_PARAM; |
|---|
| 705 | } |
|---|
| 706 | |
|---|
| 707 | #if 0 |
|---|
| 708 | // ISR ³»ºÎÀÎÁö, critical section ¾ÈÀÎÁö ±¸ºÐÇÒ ¼ö ¾øÀ½. |
|---|
| 709 | if (OS_IS_ISR() && ticks != NO_WAIT) { |
|---|
| 710 | printf("!! %s: mutex in ISR! '%s'\n", __FUNCTION__, sem->name); |
|---|
| 711 | return DHL_FAIL_INVALID_STATE; |
|---|
| 712 | } |
|---|
| 713 | #endif |
|---|
| 714 | |
|---|
| 715 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 716 | |
|---|
| 717 | // check if this mutex is already ours. |
|---|
| 718 | if (sem->owner == (UINT32)OSTCBCur->OSTCBPrio) { //osi_taskid()=>OSTCBCur->OSTCBPrio |
|---|
| 719 | // this task already owns this mutex. |
|---|
| 720 | sem->nRecursive++; |
|---|
| 721 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 722 | result = DHL_OK; |
|---|
| 723 | } |
|---|
| 724 | else { |
|---|
| 725 | // its not ours. so, this mutex is similar to normal semaphores. |
|---|
| 726 | // try to take.. |
|---|
| 727 | |
|---|
| 728 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 729 | |
|---|
| 730 | result = _takesemaphore(sem, ticks); |
|---|
| 731 | |
|---|
| 732 | if (result == DHL_OK) { |
|---|
| 733 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 734 | sem->owner = (UINT32)OSTCBCur->OSTCBPrio; |
|---|
| 735 | sem->nRecursive = 0; |
|---|
| 736 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 737 | } |
|---|
| 738 | } |
|---|
| 739 | #endif |
|---|
| 740 | return result; |
|---|
| 741 | |
|---|
| 742 | } |
|---|
| 743 | |
|---|
| 744 | |
|---|
| 745 | /* |
|---|
| 746 | unlock mutex. |
|---|
| 747 | */ |
|---|
| 748 | void osi_givemutexsemaphore(os_semaphore_id sid) |
|---|
| 749 | { |
|---|
| 750 | #if USE_BCM_MUTEX |
|---|
| 751 | SemType *sem=(SemType *)sid; |
|---|
| 752 | UINT32 flags; |
|---|
| 753 | UINT32 tid; |
|---|
| 754 | if(sem->type != SEM_MUTEX) { |
|---|
| 755 | printf("!! %s: error, sem is NOT a mutex\n", __FUNCTION__); |
|---|
| 756 | return; |
|---|
| 757 | } |
|---|
| 758 | |
|---|
| 759 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 760 | if (sem->owner == OSTCBCur->OSTCBPrio) {//osi_taskid()=>OSTCBCur->OSTCBPrio |
|---|
| 761 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 762 | BKNI_ReleaseMutex(sem->hMutex); |
|---|
| 763 | }else |
|---|
| 764 | { |
|---|
| 765 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 766 | printf("!! %s: try unlock mutex (0x%x '%s') of others (tid %d)\n", |
|---|
| 767 | __FUNCTION__, sem, sem->name, sem->owner); |
|---|
| 768 | } |
|---|
| 769 | |
|---|
| 770 | #else |
|---|
| 771 | |
|---|
| 772 | SemType *sem=(SemType *)sid; |
|---|
| 773 | UINT32 flags; |
|---|
| 774 | |
|---|
| 775 | if(sem->type != SEM_MUTEX) { |
|---|
| 776 | printf("!! %s: error, sem is NOT a mutex\n", __FUNCTION__); |
|---|
| 777 | return; |
|---|
| 778 | } |
|---|
| 779 | |
|---|
| 780 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 781 | if (sem->owner == OSTCBCur->OSTCBPrio) {//osi_taskid()=>OSTCBCur->OSTCBPrio |
|---|
| 782 | // this mutex is owned by me! |
|---|
| 783 | if (sem->nRecursive > 0) { |
|---|
| 784 | sem->nRecursive--; |
|---|
| 785 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 786 | } |
|---|
| 787 | else { |
|---|
| 788 | if(sem->owner) |
|---|
| 789 | { |
|---|
| 790 | // this is the last 'give'. |
|---|
| 791 | sem->owner = 0; |
|---|
| 792 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 793 | |
|---|
| 794 | // no body can 'give' this mutex. |
|---|
| 795 | // so i can safely exit critical. |
|---|
| 796 | |
|---|
| 797 | _givesemaphore(sem); |
|---|
| 798 | }else |
|---|
| 799 | { |
|---|
| 800 | printf("err: mutex no ownership\n"); |
|---|
| 801 | } |
|---|
| 802 | } |
|---|
| 803 | } |
|---|
| 804 | else { |
|---|
| 805 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 806 | printf("!! %s: try unlock mutex (0x%x '%s') of others (tid %d)\n", |
|---|
| 807 | __FUNCTION__, sem, sem->name, sem->owner); |
|---|
| 808 | } |
|---|
| 809 | #endif |
|---|
| 810 | } |
|---|
| 811 | |
|---|
| 812 | |
|---|
| 813 | #if COMMENT |
|---|
| 814 | _______(){} |
|---|
| 815 | #endif |
|---|
| 816 | |
|---|
| 817 | os_semaphore_id osi_createcountingsemaphore(const char *name, UINT32 options, UINT32 count) |
|---|
| 818 | { |
|---|
| 819 | SemType *sem; |
|---|
| 820 | |
|---|
| 821 | sem=(SemType *)osi_calloc(sizeof(SemType)); |
|---|
| 822 | if (sem==NULL) { |
|---|
| 823 | return 0; |
|---|
| 824 | } |
|---|
| 825 | |
|---|
| 826 | if (count > 65535) |
|---|
| 827 | count = 65535; |
|---|
| 828 | |
|---|
| 829 | strncpy(sem->name, name, SIZE_SEM_NAME-1); |
|---|
| 830 | sem->type=SEM_COUNTING; |
|---|
| 831 | sem->nRecursive=0; |
|---|
| 832 | sem->owner=0; |
|---|
| 833 | sem->handler=(OS_EVENT*)OSSemCreate(count); |
|---|
| 834 | if (sem->handler == 0) { |
|---|
| 835 | osi_free(sem); |
|---|
| 836 | return 0; |
|---|
| 837 | } |
|---|
| 838 | // OSSaveUserData((OS_EVENT *)sem->handler, sem); |
|---|
| 839 | |
|---|
| 840 | trace_sem_create(count); |
|---|
| 841 | |
|---|
| 842 | return (os_semaphore_id)sem; |
|---|
| 843 | } |
|---|
| 844 | |
|---|
| 845 | |
|---|
| 846 | |
|---|
| 847 | os_semaphore_id osi_createbinarysemaphore(const char *name, UINT32 options, BOOL flag) |
|---|
| 848 | { |
|---|
| 849 | SemType *sem; |
|---|
| 850 | |
|---|
| 851 | sem=(SemType *)osi_calloc(sizeof(SemType)); |
|---|
| 852 | if (sem==NULL) { |
|---|
| 853 | return 0; |
|---|
| 854 | } |
|---|
| 855 | strncpy(sem->name, name, SIZE_SEM_NAME-1); |
|---|
| 856 | sem->type=SEM_BINARY; |
|---|
| 857 | sem->nRecursive=0; |
|---|
| 858 | sem->owner=0; |
|---|
| 859 | sem->handler=(OS_EVENT*)OSSemCreate(flag==TRUE?1:0); |
|---|
| 860 | if (sem->handler == 0) { |
|---|
| 861 | osi_free(sem); |
|---|
| 862 | return 0; |
|---|
| 863 | } |
|---|
| 864 | // OSSaveUserData((OS_EVENT *)sem->handler, sem); |
|---|
| 865 | |
|---|
| 866 | trace_sem_create(binary); |
|---|
| 867 | |
|---|
| 868 | return (os_semaphore_id)sem; |
|---|
| 869 | } |
|---|
| 870 | |
|---|
| 871 | |
|---|
| 872 | os_semaphore_id osi_createmutexsemaphore(const char *name) |
|---|
| 873 | { |
|---|
| 874 | //BKNOTE: uCOS-II¿¡¼ Á¦°øÇÏ´Â OSMutexCreate() »ç¿ëÇÒ Çʿ䰡 ÀÖ´ÂÁö È®ÀÎ ¿äÇÔ |
|---|
| 875 | #if USE_BCM_MUTEX |
|---|
| 876 | SemType *sem; |
|---|
| 877 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 878 | BKNI_MutexHandle hMutex = NULL; |
|---|
| 879 | |
|---|
| 880 | sem=(SemType *)osi_calloc(sizeof(SemType)); |
|---|
| 881 | if (sem==NULL) { |
|---|
| 882 | return 0; |
|---|
| 883 | } |
|---|
| 884 | |
|---|
| 885 | eResult = BKNI_CreateMutex(&hMutex); |
|---|
| 886 | if ((BERR_SUCCESS != eResult) || (NULL == hMutex)) |
|---|
| 887 | { |
|---|
| 888 | osi_free(sem); |
|---|
| 889 | return 0; |
|---|
| 890 | } |
|---|
| 891 | strncpy(sem->name, name, SIZE_SEM_NAME-1); |
|---|
| 892 | sem->type=SEM_MUTEX; |
|---|
| 893 | sem->nRecursive=0; |
|---|
| 894 | sem->owner=0; |
|---|
| 895 | sem->hMutex=hMutex; |
|---|
| 896 | #else |
|---|
| 897 | SemType *sem; |
|---|
| 898 | |
|---|
| 899 | sem=(SemType *)osi_calloc(sizeof(SemType)); |
|---|
| 900 | if (sem==NULL) { |
|---|
| 901 | return 0; |
|---|
| 902 | } |
|---|
| 903 | |
|---|
| 904 | strncpy(sem->name, name, SIZE_SEM_NAME-1); |
|---|
| 905 | sem->type=SEM_MUTEX; |
|---|
| 906 | sem->nRecursive=0; |
|---|
| 907 | sem->owner=0; |
|---|
| 908 | sem->handler=(OS_EVENT*)OSSemCreate(1); |
|---|
| 909 | if (sem->handler == 0) { |
|---|
| 910 | osi_free(sem); |
|---|
| 911 | return 0; |
|---|
| 912 | } |
|---|
| 913 | // OSSaveUserData((OS_EVENT *)sem->handler, sem); |
|---|
| 914 | #endif |
|---|
| 915 | trace_sem_create(mutex); |
|---|
| 916 | |
|---|
| 917 | return (os_semaphore_id)sem; |
|---|
| 918 | } |
|---|
| 919 | |
|---|
| 920 | |
|---|
| 921 | |
|---|
| 922 | |
|---|
| 923 | #if COMMENT |
|---|
| 924 | _______(){} |
|---|
| 925 | #endif |
|---|
| 926 | |
|---|
| 927 | /* |
|---|
| 928 | free list of reuse semaphore. |
|---|
| 929 | linked list. LIFO. |
|---|
| 930 | */ |
|---|
| 931 | |
|---|
| 932 | void *g_os_free_sem_list; |
|---|
| 933 | |
|---|
| 934 | int osi_free_reuse_sem_count(void) |
|---|
| 935 | { |
|---|
| 936 | UINT32 flags; |
|---|
| 937 | SemType *sem; |
|---|
| 938 | int count = 0; |
|---|
| 939 | |
|---|
| 940 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 941 | |
|---|
| 942 | sem = (SemType *) g_os_free_sem_list; |
|---|
| 943 | while (sem) { |
|---|
| 944 | count++; |
|---|
| 945 | sem = (SemType *)sem->next; |
|---|
| 946 | } |
|---|
| 947 | |
|---|
| 948 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flag); |
|---|
| 949 | |
|---|
| 950 | return count; |
|---|
| 951 | } |
|---|
| 952 | |
|---|
| 953 | os_semaphore_id osi_create_reuse_semaphore(char *name, int count) |
|---|
| 954 | { |
|---|
| 955 | os_semaphore_id sid; |
|---|
| 956 | UINT32 flags; |
|---|
| 957 | SemType *sem = NULL; |
|---|
| 958 | |
|---|
| 959 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 960 | |
|---|
| 961 | if (g_os_free_sem_list) { |
|---|
| 962 | sem = (SemType *)g_os_free_sem_list; |
|---|
| 963 | g_os_free_sem_list = sem->next; |
|---|
| 964 | } |
|---|
| 965 | |
|---|
| 966 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flag); |
|---|
| 967 | |
|---|
| 968 | if (sem && sem->handler) { |
|---|
| 969 | // ok! reuse it! |
|---|
| 970 | strncpy(sem->name, name, SIZE_SEM_NAME-1); |
|---|
| 971 | sem->type=SEM_COUNTING; |
|---|
| 972 | sem->nRecursive=0; |
|---|
| 973 | sem->owner=0; |
|---|
| 974 | sem->next = 0; |
|---|
| 975 | //BKNOTE: À̺κÐÀ» ¾î¶»°Ô ó¸®ÇØ¾ß Çϳª.. OSSaveUserData((OS_EVENT *)sem->handler, sem); |
|---|
| 976 | |
|---|
| 977 | trace_sem_create(count); |
|---|
| 978 | |
|---|
| 979 | // match initial 'count' value. |
|---|
| 980 | ((OS_EVENT *)(sem->handler))->OSEventCnt = count; |
|---|
| 981 | |
|---|
| 982 | sid = (os_semaphore_id)sem; |
|---|
| 983 | } |
|---|
| 984 | else { |
|---|
| 985 | sid = osi_createcountingsemaphore(name, 0, count); |
|---|
| 986 | } |
|---|
| 987 | |
|---|
| 988 | return sid; |
|---|
| 989 | } |
|---|
| 990 | |
|---|
| 991 | void osi_delete_reuse_semaphore(os_semaphore_id sid) |
|---|
| 992 | { |
|---|
| 993 | /* necessary condition for deleting. |
|---|
| 994 | no task should be pending for this semaphore. |
|---|
| 995 | */ |
|---|
| 996 | UINT32 flags; |
|---|
| 997 | SemType *sem = (SemType *)sid; |
|---|
| 998 | |
|---|
| 999 | if (sem->type != SEM_COUNTING) { |
|---|
| 1000 | printf("!! %s: only csem should be reusable.\n", __FUNCTION__); |
|---|
| 1001 | return; |
|---|
| 1002 | } |
|---|
| 1003 | |
|---|
| 1004 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 1005 | |
|---|
| 1006 | sem->next = (void *) g_os_free_sem_list; |
|---|
| 1007 | g_os_free_sem_list = sem; |
|---|
| 1008 | |
|---|
| 1009 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flag); |
|---|
| 1010 | |
|---|
| 1011 | } |
|---|
| 1012 | |
|---|
| 1013 | |
|---|
| 1014 | |
|---|
| 1015 | |
|---|
| 1016 | #if COMMENT |
|---|
| 1017 | ____MsgQ____(){} |
|---|
| 1018 | #endif |
|---|
| 1019 | |
|---|
| 1020 | |
|---|
| 1021 | |
|---|
| 1022 | |
|---|
| 1023 | #define MFIFO_INIT(fifo, size) do {(fifo)->bf_wrap=0; \ |
|---|
| 1024 | (fifo)->bf_read=(fifo)->bf_write=0;\ |
|---|
| 1025 | (fifo)->bf_last=(size);}while(0) |
|---|
| 1026 | |
|---|
| 1027 | #define MFIFO_WRITE_PTR(fifo) ((fifo)->q_buf + ((fifo)->bf_write)*((fifo)->item_sz)) |
|---|
| 1028 | #define MFIFO_READ_PTR(fifo) ((fifo)->q_buf + ((fifo)->bf_read)*((fifo)->item_sz)) |
|---|
| 1029 | |
|---|
| 1030 | |
|---|
| 1031 | // availabe free slots in queue. |
|---|
| 1032 | #define MFIFO_WRITE_PEEK(fifo) \ |
|---|
| 1033 | /* |====W---R===| */ ((unsigned)(((fifo)->bf_write < (fifo)->bf_read) ? (fifo)->bf_read - (fifo)->bf_write : ( \ |
|---|
| 1034 | /* |---R===W---| */ ((fifo)->bf_write > (fifo)->bf_read) ? (fifo)->bf_last - (fifo)->bf_write : ( \ |
|---|
| 1035 | /* |---RW---| */ (fifo)->bf_wrap ? 0 : (fifo)->bf_last - (fifo)->bf_write)))) |
|---|
| 1036 | |
|---|
| 1037 | // current message items in queue. |
|---|
| 1038 | #define MFIFO_READ_PEEK(fifo) \ |
|---|
| 1039 | /* |====W---R===| */ ((unsigned)(((fifo)->bf_write < (fifo)->bf_read) ? (fifo)->bf_last - (fifo)->bf_read : ( \ |
|---|
| 1040 | /* |---R===W---| */ ((fifo)->bf_write > (fifo)->bf_read) ? (fifo)->bf_write - (fifo)->bf_read : ( \ |
|---|
| 1041 | /* |---RW---| */ (fifo)->bf_wrap ? (fifo)->bf_last - (fifo)->bf_read:0)))) |
|---|
| 1042 | |
|---|
| 1043 | /// write to fifo. for our case, increment size is always 1. |
|---|
| 1044 | #define MFIFO_WRITE_COMMIT(fifo) do { \ |
|---|
| 1045 | /*BDBG_ASSERT(MFIFO_WRITE_PEEK(fifo) >= 1);*/ \ |
|---|
| 1046 | (fifo)->bf_write += 1; \ |
|---|
| 1047 | if ((fifo)->bf_write >= (fifo)->bf_last) {(fifo)->bf_write = 0;(fifo)->bf_wrap++;} \ |
|---|
| 1048 | } while(0) |
|---|
| 1049 | |
|---|
| 1050 | /// read out from fifo. for our case, increment size is always 1. |
|---|
| 1051 | #define MFIFO_READ_COMMIT(fifo) do { \ |
|---|
| 1052 | /*BDBG_ASSERT(MFIFO_READ_PEEK(fifo) >= 1);*/ \ |
|---|
| 1053 | (fifo)->bf_read += 1; \ |
|---|
| 1054 | if ((fifo)->bf_read >= (fifo)->bf_last) {(fifo)->bf_read = 0;(fifo)->bf_wrap--;} \ |
|---|
| 1055 | } while(0) |
|---|
| 1056 | |
|---|
| 1057 | |
|---|
| 1058 | |
|---|
| 1059 | /* |
|---|
| 1060 | MsgqType µµ SemType ÀÇ ¾ÕºÎºÐ°ú µ¿ÀÏÇÑ ±¸Á¶¸¦ ÃëÇÑ´Ù. |
|---|
| 1061 | ¸ðµÎ uCOS ÀÔÀå¿¡¼ µ¿ÀÏÇÑ osi event typeÀ¸·Î ó¸® °¡´É. |
|---|
| 1062 | */ |
|---|
| 1063 | |
|---|
| 1064 | typedef struct |
|---|
| 1065 | { |
|---|
| 1066 | UINT8 type; |
|---|
| 1067 | UINT32 handler; // actually, this is os couting semaphore |
|---|
| 1068 | char name[SIZE_SEM_NAME+1]; |
|---|
| 1069 | //--------- |
|---|
| 1070 | UINT32 dummy_guard; |
|---|
| 1071 | os_messagequeue_id csem; // counting semaphore for messages |
|---|
| 1072 | os_messagequeue_id mutex; // access mutex for this queue. |
|---|
| 1073 | |
|---|
| 1074 | UINT16 item_sz; // only support uniform size. |
|---|
| 1075 | UINT16 max_num_item; // maximum number of items that this queue can have. |
|---|
| 1076 | |
|---|
| 1077 | //UINT16 num_item; // number of message items currently exist in queue. |
|---|
| 1078 | |
|---|
| 1079 | // fifo implementation. |
|---|
| 1080 | //struct osi_q_fifo fifo; |
|---|
| 1081 | |
|---|
| 1082 | UINT16 bf_write; // this is index, not pointer. |
|---|
| 1083 | UINT16 bf_read; |
|---|
| 1084 | UINT16 bf_last; // same as max_num_item. |
|---|
| 1085 | int bf_wrap; |
|---|
| 1086 | |
|---|
| 1087 | UINT8 *q_buf; |
|---|
| 1088 | |
|---|
| 1089 | } MsgqType; |
|---|
| 1090 | |
|---|
| 1091 | |
|---|
| 1092 | |
|---|
| 1093 | void osi_printmessagequeue(MsgqType *msgq) |
|---|
| 1094 | { |
|---|
| 1095 | } |
|---|
| 1096 | |
|---|
| 1097 | void osi_deletemessagequeue(os_messagequeue_id qid) |
|---|
| 1098 | { |
|---|
| 1099 | #if USE_BCM_MSG_QUEUE |
|---|
| 1100 | b_queue_t* p_msg_queue = (b_queue_t*)(qid); |
|---|
| 1101 | bos_delete_queue(p_msg_queue); |
|---|
| 1102 | OS_FreeDirect(&p_msg_queue); |
|---|
| 1103 | #else |
|---|
| 1104 | printf("!! %s: delete queue not supported!!\n", __FUNCTION__); |
|---|
| 1105 | #endif |
|---|
| 1106 | } |
|---|
| 1107 | |
|---|
| 1108 | //BKTODO: ucOS-II¿¡¼ Á¦°øÇÏ´Â OSQCreate/OSQPost/OSQPend µîÀ» warpÇÑ bos_create_queue/bos_post_event/bos_pend_event·Î ±³Ã¼ÇÒÁö ¿©ºÎ. |
|---|
| 1109 | os_messagequeue_id osi_createmessagequeue(const char *name, UINT32 options, |
|---|
| 1110 | UINT32 maxMessages, UINT32 maxMessageLength) |
|---|
| 1111 | { |
|---|
| 1112 | #if USE_BCM_MSG_QUEUE |
|---|
| 1113 | b_queue_t* p_msg_queue= (b_queue_t*)OS_Malloc(sizeof(b_queue_t)); |
|---|
| 1114 | //BKNOTE: OS°¡ »ç¿ëÇÒ memory¸¦ ÇÒ´çÇÔ.. ÁÖÀÇ (osi_deletemessagequeue ¿¡¼µµ ÇØÁ¦µÇÁö ¾Ê´Â´Ù.. ) |
|---|
| 1115 | b_event_t * p_bufferQ = (b_event_t *)OS_Malloc(maxMessages*maxMessageLength); |
|---|
| 1116 | if(bos_create_queue(p_msg_queue, p_bufferQ, maxMessages)!=b_ok) |
|---|
| 1117 | { |
|---|
| 1118 | printf("FATAL: bos_create_queue\n"); |
|---|
| 1119 | }else |
|---|
| 1120 | { |
|---|
| 1121 | printf("Q[%s] create 0x%x\n", p_msg_queue); |
|---|
| 1122 | } |
|---|
| 1123 | return (os_messagequeue_id)p_msg_queue; |
|---|
| 1124 | #else |
|---|
| 1125 | MsgqType *msgq; |
|---|
| 1126 | char buf[SIZE_SEM_NAME+10]; |
|---|
| 1127 | os_semaphore_id csem = 0; |
|---|
| 1128 | #if !BUGFIX_MSGQ |
|---|
| 1129 | os_semaphore_id mutex = 0; |
|---|
| 1130 | #endif |
|---|
| 1131 | |
|---|
| 1132 | if (maxMessages > 65535) { |
|---|
| 1133 | printf("!! %s: max msg exceed limit\n", __FUNCTION__); |
|---|
| 1134 | return (os_messagequeue_id)NULL; |
|---|
| 1135 | } |
|---|
| 1136 | |
|---|
| 1137 | if (name == NULL) name = ""; |
|---|
| 1138 | |
|---|
| 1139 | // create csem.. |
|---|
| 1140 | strcpy(buf, "S:"); |
|---|
| 1141 | strncpy(buf+2, name, SIZE_SEM_NAME-2); |
|---|
| 1142 | csem = osi_createcountingsemaphore(buf, 0, 0); |
|---|
| 1143 | if (csem == 0) { |
|---|
| 1144 | return (os_messagequeue_id)NULL; |
|---|
| 1145 | } |
|---|
| 1146 | |
|---|
| 1147 | #if !BUGFIX_MSGQ |
|---|
| 1148 | // create mutex.. |
|---|
| 1149 | strcpy(buf, "M:"); |
|---|
| 1150 | strncpy(buf+2, name, SIZE_SEM_NAME-2); |
|---|
| 1151 | mutex = osi_createmutexsemaphore(buf); |
|---|
| 1152 | if (mutex == 0) { |
|---|
| 1153 | osi_deletesemaphore(csem); |
|---|
| 1154 | return (os_messagequeue_id)NULL; |
|---|
| 1155 | } |
|---|
| 1156 | #endif |
|---|
| 1157 | |
|---|
| 1158 | // to avoid memory frag, we alloc only one chunk of memory. |
|---|
| 1159 | msgq = (MsgqType *) osi_calloc(sizeof(MsgqType) + maxMessages*maxMessageLength); |
|---|
| 1160 | if (msgq == NULL) { |
|---|
| 1161 | printf("!! %s: out of mem for queue\n", __FUNCTION__); |
|---|
| 1162 | // oops! we cannot delete mutex sem! |
|---|
| 1163 | osi_deletesemaphore(csem); |
|---|
| 1164 | #if !BUGFIX_MSGQ |
|---|
| 1165 | osi_deletesemaphore(mutex); |
|---|
| 1166 | #endif |
|---|
| 1167 | return (os_messagequeue_id)NULL; |
|---|
| 1168 | } |
|---|
| 1169 | |
|---|
| 1170 | msgq->type = SEM_MSGQ; |
|---|
| 1171 | msgq->handler = ((SemType *)csem)->handler; |
|---|
| 1172 | |
|---|
| 1173 | msgq->dummy_guard = 0xcafe2008; |
|---|
| 1174 | msgq->csem = csem; |
|---|
| 1175 | #if !BUGFIX_MSGQ |
|---|
| 1176 | msgq->mutex = mutex; |
|---|
| 1177 | #endif |
|---|
| 1178 | |
|---|
| 1179 | msgq->item_sz = maxMessageLength; |
|---|
| 1180 | msgq->max_num_item = maxMessages; |
|---|
| 1181 | |
|---|
| 1182 | //msgq->num_item = 0; |
|---|
| 1183 | msgq->q_buf = ((UINT8 *)msgq + sizeof(MsgqType)); |
|---|
| 1184 | |
|---|
| 1185 | MFIFO_INIT(msgq, msgq->max_num_item); |
|---|
| 1186 | |
|---|
| 1187 | if (name && name[0]) |
|---|
| 1188 | strncpy(msgq->name, name, SIZE_SEM_NAME-1); |
|---|
| 1189 | else |
|---|
| 1190 | msgq->name[0] = 0; |
|---|
| 1191 | |
|---|
| 1192 | // override mutex user data with queue's pointer. |
|---|
| 1193 | // OSSaveUserData((OS_EVENT *)msgq->handler, msgq); |
|---|
| 1194 | |
|---|
| 1195 | return (os_messagequeue_id)msgq; |
|---|
| 1196 | #endif |
|---|
| 1197 | } |
|---|
| 1198 | |
|---|
| 1199 | int osi_sendmessage(os_messagequeue_id qid, void *buffer, int nBytes) |
|---|
| 1200 | { |
|---|
| 1201 | #if USE_BCM_MSG_QUEUE |
|---|
| 1202 | b_queue_t* p_msg_queue = (b_queue_t*)(qid); |
|---|
| 1203 | printf("Q send 0x%x\n", p_msg_queue); |
|---|
| 1204 | bos_post_event(*p_msg_queue, (b_event_t *)buffer); |
|---|
| 1205 | return DHL_OK; |
|---|
| 1206 | #else |
|---|
| 1207 | |
|---|
| 1208 | DHL_RESULT result = DHL_OK; |
|---|
| 1209 | MsgqType *msgq = (MsgqType *)qid; |
|---|
| 1210 | |
|---|
| 1211 | #if BUGFIX_MSGQ |
|---|
| 1212 | UINT32 flags; |
|---|
| 1213 | #endif |
|---|
| 1214 | |
|---|
| 1215 | #if BUGFIX_MSGQ |
|---|
| 1216 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flags); |
|---|
| 1217 | #else |
|---|
| 1218 | osi_takemutexsemaphore_wait(msgq->mutex, WAIT_FOREVER); |
|---|
| 1219 | #endif |
|---|
| 1220 | |
|---|
| 1221 | if (MFIFO_WRITE_PEEK(msgq) > 0) |
|---|
| 1222 | { |
|---|
| 1223 | memcpy(MFIFO_WRITE_PTR(msgq), buffer, min(nBytes, msgq->item_sz)); |
|---|
| 1224 | MFIFO_WRITE_COMMIT(msgq); |
|---|
| 1225 | |
|---|
| 1226 | #if OSAL_DEBUG |
|---|
| 1227 | printf("#### queue send, q %x, '%s' h %x, r%d w%d\n", |
|---|
| 1228 | msgq, msgq->name, msgq->handler, msgq->bf_read, msgq->bf_write); |
|---|
| 1229 | #endif |
|---|
| 1230 | osi_givesemaphore(msgq->csem); // now, some other task will wake up. |
|---|
| 1231 | } |
|---|
| 1232 | else |
|---|
| 1233 | { |
|---|
| 1234 | // fifo full! |
|---|
| 1235 | result = DHL_FAIL_NOT_AVAILABLE; |
|---|
| 1236 | } |
|---|
| 1237 | |
|---|
| 1238 | #if BUGFIX_MSGQ |
|---|
| 1239 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 1240 | #else |
|---|
| 1241 | osi_givemutexsemaphore(msgq->mutex); |
|---|
| 1242 | #endif |
|---|
| 1243 | |
|---|
| 1244 | return result; |
|---|
| 1245 | #endif |
|---|
| 1246 | } |
|---|
| 1247 | |
|---|
| 1248 | int osi_receivemessage(os_messagequeue_id qid, void *msgBuf) |
|---|
| 1249 | { |
|---|
| 1250 | #if USE_BCM_MSG_QUEUE |
|---|
| 1251 | b_queue_t* p_msg_queue = (b_queue_t*)(qid); |
|---|
| 1252 | b_event_t * p_event = bos_pend_event(*p_msg_queue,-1); |
|---|
| 1253 | if(p_event==NULL) |
|---|
| 1254 | { |
|---|
| 1255 | msgBuf = NULL; |
|---|
| 1256 | return DHL_FAIL_TIMEOUT; |
|---|
| 1257 | }else |
|---|
| 1258 | { |
|---|
| 1259 | msgBuf = (void *)p_event; |
|---|
| 1260 | return DHL_OK; |
|---|
| 1261 | } |
|---|
| 1262 | #else |
|---|
| 1263 | return osi_receivemessage_wait(qid, msgBuf, WAIT_FOREVER); |
|---|
| 1264 | #endif |
|---|
| 1265 | } |
|---|
| 1266 | |
|---|
| 1267 | /* |
|---|
| 1268 | note! |
|---|
| 1269 | receive message usually used in one task. |
|---|
| 1270 | */ |
|---|
| 1271 | //int osi_receivemessage_wait(os_messagequeue_id qid, void *msgBuf, int maxLen, int *msgLen, int ticks) |
|---|
| 1272 | int osi_receivemessage_wait(os_messagequeue_id qid, void *msgBuf, int ticks) |
|---|
| 1273 | { |
|---|
| 1274 | #if USE_BCM_MSG_QUEUE |
|---|
| 1275 | b_queue_t* p_msg_queue = (b_queue_t*)(qid); |
|---|
| 1276 | b_event_t * p_event = bos_pend_event(*p_msg_queue,ticks /*not ticks, it's msec*/); |
|---|
| 1277 | if(p_event==NULL) |
|---|
| 1278 | { |
|---|
| 1279 | msgBuf = NULL; |
|---|
| 1280 | return DHL_FAIL_TIMEOUT; |
|---|
| 1281 | }else |
|---|
| 1282 | { |
|---|
| 1283 | msgBuf = (void *)p_event; |
|---|
| 1284 | return DHL_OK; |
|---|
| 1285 | } |
|---|
| 1286 | #else |
|---|
| 1287 | |
|---|
| 1288 | DHL_RESULT result = DHL_OK; |
|---|
| 1289 | MsgqType *msgq = (MsgqType *)qid; |
|---|
| 1290 | BOOL bexit = FALSE; |
|---|
| 1291 | |
|---|
| 1292 | #if BUGFIX_MSGQ |
|---|
| 1293 | UINT32 flags; |
|---|
| 1294 | #endif |
|---|
| 1295 | |
|---|
| 1296 | while (bexit == FALSE) |
|---|
| 1297 | { |
|---|
| 1298 | result = osi_takesemaphore_wait(msgq->csem, ticks); |
|---|
| 1299 | |
|---|
| 1300 | if (result == DHL_FAIL_TIMEOUT) |
|---|
| 1301 | break; |
|---|
| 1302 | |
|---|
| 1303 | if (result != DHL_OK) { |
|---|
| 1304 | printf("!! %s: unexpected err 0x%x in take csem\n", __FUNCTION__, result); |
|---|
| 1305 | break; |
|---|
| 1306 | } |
|---|
| 1307 | #if OSAL_DEBUG |
|---|
| 1308 | printf("#### queue receive, q %x, '%s' h %x\n", msgq, msgq->name, msgq->handler); |
|---|
| 1309 | #endif |
|---|
| 1310 | // if csem is taken, it means that there are available messages in the queue. |
|---|
| 1311 | |
|---|
| 1312 | #if BUGFIX_MSGQ |
|---|
| 1313 | flags = MIPS_SetInterrupts(OS_DISABLE); // OS_ENTER_CRITICAL(flag); |
|---|
| 1314 | #else |
|---|
| 1315 | osi_takemutexsemaphore_wait(msgq->mutex, WAIT_FOREVER); |
|---|
| 1316 | #endif |
|---|
| 1317 | |
|---|
| 1318 | if (MFIFO_READ_PEEK(msgq) > 0) |
|---|
| 1319 | { |
|---|
| 1320 | // int copyLen = min(maxLen, msgq->item_sz); |
|---|
| 1321 | int copyLen = msgq->item_sz; |
|---|
| 1322 | memcpy(msgBuf, MFIFO_READ_PTR(msgq), copyLen); |
|---|
| 1323 | MFIFO_READ_COMMIT(msgq); |
|---|
| 1324 | |
|---|
| 1325 | result = DHL_OK; |
|---|
| 1326 | bexit = TRUE; |
|---|
| 1327 | } |
|---|
| 1328 | else |
|---|
| 1329 | { |
|---|
| 1330 | // fifo empty?? |
|---|
| 1331 | printf("!! %s: csem taken, but queue empty?\n", __FUNCTION__); |
|---|
| 1332 | osi_printmessagequeue(msgq); |
|---|
| 1333 | } |
|---|
| 1334 | |
|---|
| 1335 | #if BUGFIX_MSGQ |
|---|
| 1336 | MIPS_SetInterrupts(flags);// OS_EXIT_CRITICAL(flags); |
|---|
| 1337 | #else |
|---|
| 1338 | osi_givemutexsemaphore(msgq->mutex); |
|---|
| 1339 | #endif |
|---|
| 1340 | |
|---|
| 1341 | } |
|---|
| 1342 | |
|---|
| 1343 | return result; |
|---|
| 1344 | #endif |
|---|
| 1345 | } |
|---|
| 1346 | |
|---|
| 1347 | |
|---|
| 1348 | |
|---|
| 1349 | int osi_receivemessage_nowait(os_messagequeue_id qid, void *msgBuf) |
|---|
| 1350 | { |
|---|
| 1351 | return osi_receivemessage_wait(qid, msgBuf, NO_WAIT); |
|---|
| 1352 | } |
|---|
| 1353 | |
|---|
| 1354 | |
|---|
| 1355 | |
|---|
| 1356 | |
|---|
| 1357 | #if COMMENT |
|---|
| 1358 | ____Memory____(){} |
|---|
| 1359 | #endif |
|---|
| 1360 | |
|---|
| 1361 | |
|---|
| 1362 | #if OSAL_HEAP_DEBUG |
|---|
| 1363 | |
|---|
| 1364 | #warning build osal with OSAL_HEAP_DEBUG option. |
|---|
| 1365 | |
|---|
| 1366 | void *os_dbg_malloc(int size, char *file, int line) |
|---|
| 1367 | { |
|---|
| 1368 | // just call ministd api. |
|---|
| 1369 | return malloc_align_dbg(size, 2, file, line); |
|---|
| 1370 | } |
|---|
| 1371 | |
|---|
| 1372 | void *os_dbg_calloc(int n, int m, char *file, int line) |
|---|
| 1373 | { |
|---|
| 1374 | void *p; |
|---|
| 1375 | p = malloc_align_dbg(n*m, 2, file, line); |
|---|
| 1376 | if (p) |
|---|
| 1377 | memset(p, 0, n*m); |
|---|
| 1378 | |
|---|
| 1379 | return p; |
|---|
| 1380 | } |
|---|
| 1381 | |
|---|
| 1382 | void os_dbg_free(void *ptr, char *file, int line) |
|---|
| 1383 | { |
|---|
| 1384 | void **pptr = (void **)ptr; |
|---|
| 1385 | |
|---|
| 1386 | if (pptr == NULL) return; |
|---|
| 1387 | |
|---|
| 1388 | // cafrii 081006 add |
|---|
| 1389 | if (*pptr == NULL) return; // already free()'ed pointer? |
|---|
| 1390 | |
|---|
| 1391 | free_dbg(*pptr, file, line); |
|---|
| 1392 | |
|---|
| 1393 | *pptr = NULL; |
|---|
| 1394 | } |
|---|
| 1395 | |
|---|
| 1396 | #else // OSAL_HEAP_DEBUG |
|---|
| 1397 | |
|---|
| 1398 | #undef malloc |
|---|
| 1399 | #undef calloc |
|---|
| 1400 | #undef free |
|---|
| 1401 | |
|---|
| 1402 | void *OS_Malloc(int size) |
|---|
| 1403 | { |
|---|
| 1404 | void* p = malloc(size); |
|---|
| 1405 | return p; |
|---|
| 1406 | } |
|---|
| 1407 | |
|---|
| 1408 | void OS_FreeDirect(void *ptr) |
|---|
| 1409 | { |
|---|
| 1410 | free(ptr); |
|---|
| 1411 | } |
|---|
| 1412 | |
|---|
| 1413 | void *OS_Calloc(int n, int m) |
|---|
| 1414 | { |
|---|
| 1415 | void *p; |
|---|
| 1416 | p = OS_Malloc(n*m); |
|---|
| 1417 | if (p) |
|---|
| 1418 | memset(p, 0, n*m); |
|---|
| 1419 | |
|---|
| 1420 | return p; |
|---|
| 1421 | } |
|---|
| 1422 | |
|---|
| 1423 | void OS_Free(void *ptr) |
|---|
| 1424 | { |
|---|
| 1425 | void *p; |
|---|
| 1426 | |
|---|
| 1427 | if (ptr == NULL) return; |
|---|
| 1428 | p = *(void **)ptr; |
|---|
| 1429 | OS_FreeDirect(p); |
|---|
| 1430 | } |
|---|
| 1431 | |
|---|
| 1432 | #endif |
|---|
| 1433 | |
|---|
| 1434 | extern bcm_heap_t *g_p_sdram_heap; |
|---|
| 1435 | |
|---|
| 1436 | void dump_heap(int threshold) |
|---|
| 1437 | { |
|---|
| 1438 | #ifdef BCM_DEBUG |
|---|
| 1439 | // show all heap blocks, greater than threshold. |
|---|
| 1440 | mem_reportbrief_ex(g_p_sdram_heap, threshold); |
|---|
| 1441 | #endif |
|---|
| 1442 | } |
|---|
| 1443 | |
|---|
| 1444 | |
|---|
| 1445 | void os_heap_status(dhl_heap_status *pstat) |
|---|
| 1446 | { |
|---|
| 1447 | #ifdef BCM_DEBUG |
|---|
| 1448 | |
|---|
| 1449 | struct bcm_heap_status bhs; |
|---|
| 1450 | |
|---|
| 1451 | memset(pstat, 0, sizeof(dhl_heap_status)); |
|---|
| 1452 | |
|---|
| 1453 | if (mem_status(g_p_sdram_heap, &bhs) == 0) { |
|---|
| 1454 | pstat->size_heap = bhs.size_heap; |
|---|
| 1455 | pstat->num_alloc_chunk = bhs.num_alloc_chunk; |
|---|
| 1456 | pstat->size_alloc = bhs.size_alloc; |
|---|
| 1457 | pstat->num_free_chunk = bhs.num_free_chunk; |
|---|
| 1458 | pstat->size_free = bhs.size_free; |
|---|
| 1459 | } |
|---|
| 1460 | #endif |
|---|
| 1461 | } |
|---|
| 1462 | |
|---|
| 1463 | |
|---|
| 1464 | #if COMMENT |
|---|
| 1465 | ____Debug____(){} |
|---|
| 1466 | #endif |
|---|
| 1467 | |
|---|
| 1468 | #undef printf // do not add tag. |
|---|
| 1469 | #if 0 |
|---|
| 1470 | char *osi_get_eventinfo(void *p, char *outbuf, int outbuflen) |
|---|
| 1471 | { |
|---|
| 1472 | int k; |
|---|
| 1473 | OS_EVENT *pevent = (OS_EVENT *)p; |
|---|
| 1474 | SemType *sem; |
|---|
| 1475 | UBYTE *t; |
|---|
| 1476 | char buf[3*16 + 20]; |
|---|
| 1477 | |
|---|
| 1478 | if (pevent == NULL) { |
|---|
| 1479 | //printf("\t --> no event\n"); |
|---|
| 1480 | outbuf[0] = 0; |
|---|
| 1481 | return outbuf; |
|---|
| 1482 | } |
|---|
| 1483 | |
|---|
| 1484 | sem = (SemType *)OSGetUserData(pevent); |
|---|
| 1485 | if (sem == NULL) { |
|---|
| 1486 | // this event is not created by our OSAL. maybe it belongs driver code. |
|---|
| 1487 | // then, we track more using pevent itself. |
|---|
| 1488 | snprintf(outbuf, outbuflen, "%s event %x", |
|---|
| 1489 | pevent->OSEventPtr ? "que/mbox" : "sem", // uCOS internal. |
|---|
| 1490 | (int)pevent); |
|---|
| 1491 | return outbuf; |
|---|
| 1492 | } |
|---|
| 1493 | |
|---|
| 1494 | buf[0] = 0; |
|---|
| 1495 | if (pevent) |
|---|
| 1496 | { |
|---|
| 1497 | t = pevent->OSEventTbl; |
|---|
| 1498 | for (k=0; k<63; k++) { |
|---|
| 1499 | if (t[k/8] & (1<<(k%8))) |
|---|
| 1500 | sprintf(buf + strlen(buf), "%d ", k); |
|---|
| 1501 | } |
|---|
| 1502 | // this is pending task list. |
|---|
| 1503 | } |
|---|
| 1504 | |
|---|
| 1505 | snprintf(outbuf, outbuflen, "%s '%s' w-list %s", |
|---|
| 1506 | sem->type == SEM_MUTEX ? "mtx" : |
|---|
| 1507 | sem->type == SEM_BINARY ? "bsm" : |
|---|
| 1508 | sem->type == SEM_COUNTING ? "csm" : |
|---|
| 1509 | sem->type == SEM_MSGQ ? "que" : "???", |
|---|
| 1510 | sem->name, |
|---|
| 1511 | buf); |
|---|
| 1512 | |
|---|
| 1513 | return outbuf; |
|---|
| 1514 | } |
|---|
| 1515 | #endif |
|---|
| 1516 | |
|---|
| 1517 | void osi_show_taskinfo(int level) |
|---|
| 1518 | { |
|---|
| 1519 | // bos_print_taskinfo_ex(level, osi_get_eventinfo); |
|---|
| 1520 | bos_print_taskinfo(); |
|---|
| 1521 | } |
|---|
| 1522 | |
|---|
| 1523 | |
|---|
| 1524 | /* end of file */ |
|---|
| 1525 | |
|---|
| 1526 | |
|---|