source: svn/newcon3bcm2_21bu/dst/dmw/src/psi/DMW_PsiTask.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 12.8 KB
Line 
1/*
2        DMW_PsiTask.c
3
4        DST TV MW PSI Scan Module
5
6        PSI scan Worker Task implementation
7
8        Copyright 2006~2009 Digital STREAM Technology, Inc.
9        All Rights Reserved
10
11*/
12
13
14
15#include "DMW_Platform.h"
16
17#include "DMW_PsiConfig.h"
18#include "DMW_PsiTypes.h"
19#include "DMW_PsiEngine.h"
20
21#if USE_OSX_TASK
22#include "OSX_Task.h"
23#endif
24
25
26DHL_MODULE("psitsk", 1);
27
28
29
30#if COMMENT
31____Config____(){}
32#endif
33
34
35#define PSIM_TASK_PRIORITY TASK_PRI_DMW_PSI
36
37
38
39#if COMMENT
40____Structures____(){}
41#endif
42
43
44#if !USE_OSX_TASK
45
46typedef struct
47{
48        //S_PSIM_MSG_HDR hdr;
49
50        /*
51                ¾î¶² µ¿ÀÛÀ» ¼öÇàÇÒ °ÍÀÎÁö¸¦ ÁöÁ¤ÇÏ´Â ¸í·É ID.
52        */
53        E_PSIM_CMD cmd_id;
54
55        //S_PSIM_PORT *tsport; // it should be part of payload..
56
57        /*
58                message¸¦ º¸³»´Â client°¡ message ½ÇÇà Á¾·á¸¦ ack·Î ¹Þ°í ½ÍÀº °æ¿ì
59                event semÀ» »ý¼ºÇÏ¿© °°ÀÌ º¸³»¸é
60                worker task´Â command ó¸® ÈÄ ÀÌ semÀ» release ÇÑ´Ù.
61        */
62        //OS_SEMAPHORE_ID sem_ack; // ack semaphore.
63        BOOL sync;
64       
65        UINT32 payload[2];
66
67} S_PSIM_MSG;
68
69
70
71/*
72        task context.
73                task state Á¤º¸
74*/
75typedef struct S_PSIM_TASK_t
76{
77        UINT32 magic;
78
79        DHL_OS_TASK_ID task_id;
80
81        DHL_OS_SEMA_ID mutex;
82        DHL_OS_SEMA_ID acksem;
83       
84        DHL_OS_MSGQ_ID queue;
85
86
87        // currently, we have only one psi_scan module.
88        //
89        S_PSIM_CONTEXT *module;
90       
91
92} S_PSIM_TASK;
93
94
95
96S_PSIM_TASK g_psi_task;
97
98PSI_STATIC S_PSIM_TASK *GetPsiTask(void)
99{
100        return &g_psi_task;
101}
102
103#else // USE_OSX_TASK
104
105static H_OSX_TASK s_psi_task_handle;
106static DHL_OS_TASK_ID s_psi_task_id;
107
108#endif
109
110
111
112/* PSI Engine Context */
113S_PSIM_CONTEXT *g_psi_module_context;
114
115
116
117
118#if COMMENT
119____Declare____(){}
120#endif
121
122#if !USE_OSX_TASK
123
124PSI_STATIC void _PsiWorkerTask(UINT32 arg);
125
126#endif
127
128
129
130#if COMMENT
131____MsgHandler____(){}
132#endif
133
134
135#if !USE_OSX_TASK
136
137/*
138        message ó¸® Çڵ鷯ÀÇ prototype
139*/
140
141typedef STATUS (*PSI_MSG_HANDLER)(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg);
142
143
144STATUS PsiMsgHandler_ScanStart(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg)
145{
146        /*
147                event handler of ePSIM_CMD_ScanStart
148                ÀÔ·Â
149                        [0] tDHL_TSD *tsd
150                        [1] S_PSIM_USER_INPUT *input
151        */
152
153        tDHL_TSD tsd = (tDHL_TSD) pMsg->payload[0];
154        S_PSIM_USER_INPUT *input = (S_PSIM_USER_INPUT *) pMsg->payload[1];
155
156        dprint(3, "%s: tsd %x, rf %d, #%d, $%d\n", 
157                __FUNCTION__, tsd, input->rf, input->program_number, input->source_id);
158       
159        return PSIE_StartPsiScan(pTask->module, tsd, input);
160}
161
162STATUS PsiMsgHandler_ScanStop(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg)
163{
164        /*
165                event handler of
166                // [0] S_PSIE_PORT *tsport
167                // [1] --
168        */
169
170        tDHL_TSD *tsd = (tDHL_TSD *) pMsg->payload[0];
171
172        dprint(3, "%s: tsd %x\n", __FUNCTION__, tsd);
173
174        return PSIE_StopPsiScan(pTask->module, tsd);
175}
176
177
178STATUS PsiMsgHandler_TableReceived(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg)
179{
180        /*
181                event handler of ePSIM_CMD_ScanStop
182                ÀÔ·Â
183                        [0] S_PSIE_PORT *tsport,
184                        [1] tDHL_PSIDataArray *desc
185        */
186
187        S_PSIM_PORT *tsport = (S_PSIM_PORT *) pMsg->payload[0];
188        tDHL_PSI_DataArray *desc = (tDHL_PSI_DataArray *) pMsg->payload[1];
189
190        return PSIE_ProcessReceivedTable(pTask->module, tsport, desc);
191}
192
193STATUS PsiMsgHandler_DeleteTables(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg)
194{
195        /*
196                event handler of ePSIM_CMD_DeleteTables
197                ÀÔ·Â
198                // [0] int id (rf). if id is 0, delete all tables.
199                // [1] --
200        */
201
202        int id = (int) pMsg->payload[0];
203
204        return PSIE_DeleteTables(pTask->module, id);
205}
206
207#else // USE_OSX_TASK
208
209
210PSI_STATIC void PsiCmd_ScanStart(E_PSIM_CMD cmd, tDHL_TSD tsd, S_PSIM_USER_INPUT *input)
211{
212        dprint(3, "%s: tsd %x, rf %d, #%d, $%d\n", 
213                __FUNCTION__, tsd, input->rf, input->program_number, input->source_id);
214       
215        PSIE_StartPsiScan(g_psi_module_context, tsd, input);
216}
217
218PSI_STATIC void PsiCmd_ScanStop(E_PSIM_CMD cmd, tDHL_TSD tsd)
219{
220        dprint(3, "%s: tsd %x\n", __FUNCTION__, tsd);
221
222        PSIE_StopPsiScan(g_psi_module_context, tsd);
223}
224
225
226PSI_STATIC void PsiCmd_TableReceived(E_PSIM_CMD cmd, S_PSIM_PORT *tsport, tDHL_PSI_DataArray *desc)
227{
228        PSIE_ProcessReceivedTable(g_psi_module_context, tsport, desc);
229}
230
231PSI_STATIC void PsiCmd_DeleteTables(E_PSIM_CMD cmd, int id)
232{
233        PSIE_DeleteTables(g_psi_module_context, id);
234}
235
236#endif
237
238
239#if COMMENT
240____Private____(){}
241#endif
242
243
244#if !USE_OSX_TASK
245
246/*
247        Command Dispatch Table
248*/
249
250typedef struct
251{
252        E_PSIM_CMD cmd_id;
253       
254        PSI_MSG_HANDLER handler;
255       
256} S_PSIM_CMD_ENTRY;
257
258
259S_PSIM_CMD_ENTRY g_psi_cmd_table[] =
260{
261        { ePSIM_CMD_ScanStart,    PsiMsgHandler_ScanStart,  },
262        { ePSIM_CMD_ScanStop,     PsiMsgHandler_ScanStop,  },
263       
264        { ePSIM_CMD_DeleteTables, PsiMsgHandler_DeleteTables, },
265
266        { ePSIM_CMD_TableReceived,    PsiMsgHandler_TableReceived, },
267
268        { ePSIM_CMD_Exit, 0 },
269};
270
271
272
273
274
275PSI_STATIC BOOL IsExitMessage(S_PSIM_MSG *pMsg)
276{
277        return pMsg->cmd_id == ePSIM_CMD_Exit ? TRUE : FALSE;
278}
279
280
281/*
282        get message ¼öÇà½Ã ÇÊ¿äÇÑ timeoutÀ» ¸®ÅÏÇÑ´Ù.
283        ÇöÀç task state¿¡ µû¶ó ´Þ¶óÁü.
284        idle processing ÇÒ °ÍÀÌ ¾ø´Ù¸é timeout ÇÊ¿ä ¾øÀ½.
285*/
286PSI_STATIC UINT32 GetTimeout(S_PSIM_TASK *pTask)
287{
288        UINT32 timeOut;
289
290        // ÇöÀç ÀÌ task´Â ÇϳªÀÇ ¸ðµâ¸¸À» Áö¿øÇÔ.
291        // º¹¼ö ¸ðµâÀÎ °æ¿ì´Â ¿©·¯ ¸ðµâ Áß¿¡¼­ ªÀº timeout À» ¼±ÅÃ.
292       
293        timeOut = PSIE_GetTimeout(pTask->module);
294
295        return timeOut;
296}
297
298/*
299        queue¿¡¼­ message¸¦ ¹Þ´Â´Ù.
300*/
301PSI_STATIC int GetMessage(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg, UINT32 nWaitTimeout)
302{
303        int nMsgLen;
304        int err;
305
306        /* cafrii 090717
307                OSAL tick Àº signed integer ÀÓ.
308                0 À̸é no wait ·Î µ¿ÀÛ. OSAL API »ó¿¡ ¸íÈ®ÇÏ°Ô ±â¼úÀº ¾ÈµÇ¾î ÀÖ´Â °Í °°Áö¸¸
309                ¼Ò½º ÄÚµå´Â ±×·¸°Ô µÇ¾î ÀÖÀ½.
310        */
311        if ((int)nWaitTimeout >= 0 && nWaitTimeout < 0x7FFFFFFF) {
312                //dprint(2, "rx msg wait tick %x\n", nWaitTimeout);
313                err = DHL_OS_ReceiveMessage(pTask->queue, pMsg, nWaitTimeout);
314        }
315        else {
316                //dprint(2, "rx msg forever\n");
317                err = DHL_OS_ReceiveMessage(pTask->queue, pMsg, DHL_TIMEOUT_FOREVER);
318        }
319        return err;
320}
321
322
323
324/*
325        Task·Î ¸í·ÉÀ» Àü´ÞÇÑ´Ù.
326
327        ÀÌ ÇÔ¼ö´Â Interrupt ISR state¿¡¼­µµ È£ÃâÀÌ °¡´ÉÇØ¾ß ÇÑ´Ù.
328*/
329PSI_STATIC STATUS SendMessage(E_PSIM_CMD cmd_id, UINT32 payload_0, UINT32 payload_1, BOOL bWait)
330{
331        S_PSIM_TASK *pTask = GetPsiTask();
332       
333        int err;
334        STATUS status = statusOK;
335       
336        S_PSIM_MSG msg;
337
338        //dprint(2, "send msg, cmd %x, p0 %x, p1 %x, wait %d\n", cmd_id, payload_0, payload_1, bWait);
339       
340        //memset(&msg, 0, sizeof(msg));
341        msg.cmd_id = cmd_id;
342        msg.payload[0] = payload_0;
343        msg.payload[1] = payload_1;
344        msg.sync = bWait;
345
346        //--------
347        if (bWait) {
348                DHL_OS_TakeSemaphore(pTask->mutex, DHL_TIMEOUT_FOREVER);
349
350                // flush ack semaphore for completeness.
351                // because this is binary sem, one release is enough.
352                //
353                // cafrii, bugfix!!
354                // give sem À» ÇÏ¸é ¾ÈµÇ°í, resetÀ» ÇØ¾ß ÇÔ.
355                DHL_OS_TakeSemaphore(pTask->acksem, 0);
356        }
357
358        err = DHL_OS_SendMessage(pTask->queue, &msg, sizeof(msg));
359
360        if (err) {
361                dprint(0, "!! send cmd msg err %d\n", err);
362                status = statusQueueFull;
363        }
364
365        // for sync mode, we should wait until ack is coming.
366        if (bWait && !err) {
367                //dprint(2, ".. wait ack sem..\n");
368                DHL_OS_TakeSemaphore(pTask->acksem, DHL_TIMEOUT_FOREVER);
369                //dprint(2, ".. ack sem released..\n");
370        }
371
372        //--------
373        if (bWait)
374                DHL_OS_GiveSemaphore(pTask->mutex);
375
376        return status;
377       
378}
379
380/*
381        ÀÔ·Â ¹ÞÀº ¸Þ½ÃÁö¸¦ ó¸®ÇÑ´Ù.
382        µî·ÏµÈ msg handler¸¦ È£ÃâÇÑ´Ù.
383*/
384PSI_STATIC STATUS ProcessMessage(S_PSIM_TASK *pTask, S_PSIM_MSG *pMsg)
385{
386        int i;
387        S_PSIM_CMD_ENTRY *entry;
388        STATUS status = statusOK;
389
390        int nCmds = sizeof(g_psi_cmd_table)/sizeof(g_psi_cmd_table[0]);
391       
392        for (i=0; i<nCmds; i++)
393        {
394                entry = &g_psi_cmd_table[i];
395
396                if (entry->cmd_id == pMsg->cmd_id) 
397                {
398                        dprint(3, "cmd %x matched, handler 0x%x\n", pMsg->cmd_id, entry->handler);
399                        if (entry->handler)
400                                status = (entry->handler)(pTask, pMsg);
401
402                        if (pMsg->sync) {
403                                dprint(2, "ack sem..\n");
404                                DHL_OS_GiveSemaphore(pTask->acksem);
405                        }
406                        break;
407                }
408        }
409
410        if (i>=nCmds) {
411                // no such commands
412                dprint(0, "!! cmd id 0x%x unknown\n", pMsg->cmd_id);
413        }
414
415        return status;
416
417}
418
419
420/*
421
422*/
423PSI_STATIC void DoPeriodicProcessing(S_PSIM_TASK *pTask)
424{
425        PSIE_DoPeridicProcessing(pTask->module);
426}
427
428
429
430
431//-------------------------------------------
432//  psi module ¸®¼Ò½ºµéÀ» ÁغñÇÑ´Ù.
433//
434PSI_STATIC STATUS CreateTaskResources(void)
435{
436        S_PSIM_TASK *pTask = GetPsiTask();
437
438        if (pTask->task_id == 0 || pTask->mutex == 0 || 
439                pTask->acksem == 0 || pTask->queue == 0)
440        {
441                //UINT32 mask;
442
443                int iPriorityScan = PSIM_TASK_PRIORITY;
444
445                dprint(2, "%s..\n", __FUNCTION__);
446               
447                //mask = OS_LockTask();
448
449                if (pTask->mutex == 0)
450                        pTask->mutex = DHL_OS_CreateMutexSemaphore("PsiMutex");
451
452                if (pTask->acksem == 0)
453                        pTask->acksem = DHL_OS_CreateBinarySemaphore("PsiCmdAck", OS_SEM_FIFO, FALSE);
454
455                if (pTask->queue == 0)
456                        pTask->queue = DHL_OS_CreateMessageQueue("PsiCmdQ", 0,
457                                        20,                      // max number of message.
458                                        sizeof(S_PSIM_MSG)); // ¸Þ½ÃÁö ±æÀÌÀÇ ÃÖ´ë°ª. Á¤ÇØÁø ±¸Á¶Ã¼¸¦ »ç¿ëÇÏÀÚ.
459
460                if (pTask->task_id == 0) {
461                        pTask->task_id = DHL_OS_CreateTask(_PsiWorkerTask, "tPsiScan", iPriorityScan, 8192, 0);
462                        if (pTask->task_id == (DHL_OS_TASK_ID)0)
463                                pTask->task_id = 0;
464                }
465
466                //OS_UnlockTask(mask);
467        }
468
469
470        if (pTask->task_id == 0 || pTask->mutex == 0 || 
471                pTask->acksem == 0 || pTask->queue == 0)
472        {
473                // ÇÊ¿äÇÑ resource°¡ ¾øÀ¸¹Ç·Î ÁøÇà ºÒ°¡..
474                // ±×·¯³ª shutdown ÇÒ ¶§ ±îÁö´Â ¸®¼Ò½º »èÁ¦´Â ÇÏÁö ¾Ê´Â´Ù.
475
476                dprint(0, "!! resource err: task %x, mtx %x, ack %x, que %x\n",
477                                pTask->task_id, pTask->mutex, 
478                                pTask->acksem, pTask->queue);
479
480                DHL_ASSERT(FALSE, "");
481               
482                return statusOutOfResource;
483        }
484        return statusOK;
485       
486}
487
488#else
489
490PSI_STATIC STATUS StartOsxTask(void)
491{
492        DHL_RESULT dhr;
493        S_OSX_TASK_INIT_SETTING setting;
494        S_OSX_TASK_INFO info;
495
496        OSX_TaskGetDefaultInitSetting(&setting);
497       
498        setting.name = "Psi";
499        setting.max_scheduled_cmd = 4;
500        setting.priority = PSIM_TASK_PRIORITY;
501        setting.stack_size = 8192;
502        setting.num_cmd_param = 2;
503        setting.msg_que_size = 20;
504
505        dhr = OSX_TaskStart(&setting, &s_psi_task_handle);
506        if (dhr) {
507                dprint(0, "!! psi task start err 0x%x\n", dhr);
508                return statusError;
509        }
510
511        OSX_TaskGetInfo(s_psi_task_handle, &info);
512        s_psi_task_id = info.tid;
513       
514        return statusOK;
515}
516
517#endif // USE_OSX_TASK
518
519
520
521#if COMMENT
522____TaskBody____(){}
523#endif
524
525
526#if !USE_OSX_TASK
527
528PSI_STATIC void _PsiWorkerTask(UINT32 arg)
529{
530        BOOL bExitFlag = FALSE;
531        int err;
532        UINT32 nWaitTimeout;
533
534        S_PSIM_MSG msg;
535        S_PSIM_TASK *pTask = GetPsiTask();
536
537        dprint(2, "psi task started\n");
538
539        // initialize task info..
540        pTask->magic = 0xcafe2009;
541        pTask->module = g_psi_module_context;
542
543        dprint(2, "change engine module (%x) state\n", pTask->module);
544        PSIE_ChangeModuleState(pTask->module, ePSIM_MODULE_STATE_Idle);
545       
546        while (bExitFlag != TRUE)
547        {
548                // check current task state.
549
550                nWaitTimeout = GetTimeout(pTask);
551
552                err = GetMessage(pTask, &msg, nWaitTimeout);
553
554                // message received?
555                if (err) {
556                        dprint(0, "!! get msg err %d\n", err);
557                }
558                else if (IsExitMessage(&msg)) {
559                        dprint(2, "exit psi task..\n");
560                        bExitFlag = TRUE;
561                }
562                else {
563                        ProcessMessage(pTask, &msg);
564                }
565               
566                DoPeriodicProcessing(pTask);
567               
568        }
569
570        pTask->magic = 0x0;
571        DHL_OS_SelfDeleteTask();
572}
573
574#endif // !USE_OSX_TASK
575
576
577
578#if COMMENT
579____Public____(){}
580#endif
581
582
583/*
584        psi task·Î ÀÏ¹Ý command¸¦ º¸³½´Ù.
585*/
586STATUS PSITASK_SendCommand(E_PSIM_CMD cmd_id, UINT32 payload_0, UINT32 payload_1, BOOL bWait)
587{
588#if !USE_OSX_TASK
589
590        return SendMessage(cmd_id, payload_0, payload_1, bWait);
591
592#else
593
594        DHL_RESULT dhr;
595        F_OSX_TASK_PROC fn;
596       
597        if (cmd_id == ePSIM_CMD_ScanStart)
598                fn = (F_OSX_TASK_PROC)PsiCmd_ScanStart;
599        else if (cmd_id == ePSIM_CMD_ScanStop)
600                fn = (F_OSX_TASK_PROC)PsiCmd_ScanStop;
601        else if (cmd_id == ePSIM_CMD_DeleteTables)
602                fn = (F_OSX_TASK_PROC)PsiCmd_DeleteTables;
603        else if (cmd_id == ePSIM_CMD_TableReceived)
604                fn = (F_OSX_TASK_PROC)PsiCmd_TableReceived;
605        else 
606                return statusInvalidArgument;
607
608        dhr = OSX_TaskRunCmd(s_psi_task_handle, 
609                        cmd_id, 0, fn, payload_0, payload_1);
610        if (dhr == DHL_OK && bWait)
611                dhr = OSX_TaskSync(s_psi_task_handle);
612
613        return dhr ? statusError : statusOK;
614
615#endif // USE_OSX_TASK
616
617}
618
619/*
620        return TRUE if current task is psi task.
621*/
622BOOL PSITASK_IsPsiTask(void)
623{
624#if !USE_OSX_TASK
625        S_PSIM_TASK *pTask = GetPsiTask();
626
627        if (DHL_OS_GetTaskID() == pTask->task_id)
628                return TRUE;
629               
630        return FALSE; // this is not psi task..
631
632#else
633        if (DHL_OS_GetTaskID() == s_psi_task_id)
634                return TRUE;
635               
636        return FALSE; // this is not psi task..
637#endif
638}
639
640
641#if COMMENT
642____Init____(){}
643#endif
644
645
646static DHL_SymbolTable __symbols[] =
647{
648        //---- vars
649        //DHL_VAR_SYM_ENTRY(g_Trace_PsiTask),
650        0,
651};
652
653
654STATUS PSITASK_Init(void *pModuleContext)
655{
656        dprint(2, "psitask init..\n");
657       
658        g_psi_module_context = (S_PSIM_CONTEXT *)pModuleContext;
659
660        DHL_DBG_RegisterSymbols(__symbols, DHL_NUMSYMBOLS(__symbols));
661
662#if !USE_OSX_TASK
663        return CreateTaskResources();
664
665#else
666        return StartOsxTask();
667
668#endif // USE_OSX_TASK
669
670}
671
672
Note: See TracBrowser for help on using the repository browser.