source: svn/newcon3bcm2_21bu/dst/dmw/src/System/DMW_MsgQue.c @ 76

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

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

  • Property svn:executable set to *
File size: 10.0 KB
Line 
1/********************************************************************
2        DMW_MsgQue.c
3       
4        OS API¿¡ ÀÇÁ¸ÇÏÁö ¾Ê´Â General Purpose MW Message Queue Á¦°ø
5       
6        Copyright 2006 Digital STREAM Technology, Inc.
7        All Rights Reserved
8
9        cafrii@dstreamtech.com
10
11 ********************************************************************/
12
13
14#include "DMW_Platform.h"
15
16
17#include "DHL_OSAL.h"
18
19
20
21#include "DMW_Status.h"
22#include "DMW_MsgQue.h"
23
24//#include <string.h>
25
26#define max(a,b) (((a) > (b)) ? (a) : (b))
27#define min(a,b) (((a) < (b)) ? (a) : (b))
28
29/*
30        cafrii 090119 change policy
31        mutex°¡ ¾Æ´Ñ ¹æ½ÄÀ¸·Î º¸È£ ±â´É ±¸ÇöÀ» À§ÇØ
32        OS_LockTask() ·ùÀÇ ÇÔ¼ö ´ë½Å DHL_OS_DisableInterrupts() ·ùÀÇ ÇÔ¼ö »ç¿ë.
33
34        »çÀ¯: º¸È£µÇ´Â ±¸°£ ³»¿¡ °¢Á¾ callbackµéÀÌ È£ÃâµÇ´Âµ¥,
35        OS Scheduler disable »óÅ¿¡¼­ Pending API°¡ ºÒ¸®´Â °æ¿ì ¹®Á¦°¡ »ý±æ ¼ö ÀÖÀ½.
36*/
37
38
39//----------------------------------------------------------------
40//
41// todo
42//   AllocateMsgQue ¹æ½ÄÀÇ API Á¦°ø
43//
44//
45
46BOOL g_bUseInterruptMasking = 0;
47
48// 060303 ÇöÀç interrupt ¸ðµå·Î µ¿ÀÛ½ÃÄ×À» ¶§ º° ¹®Á¦¾øÀÌ µ¿ÀÛÇÏ¿´À½.
49//   interrupt°¡ disable µÈ »óÅ¿¡¼­ ½Ã°£ÀÌ ¿À·¡ °É¸®´Â ÀÛ¾÷À» Çϸé
50//   ¹®Á¦°¡ »ý±æ¼ö ÀÖÀ¸¹Ç·Î Á¶½ÉÇÒ °Í.
51//
52// ¾ÆÁ÷ mutex ¸ðµå·Î Å×½ºÆ®´Â ÇØº¸Áö ¾Ê¾ÒÀ½.
53//
54// 091221, cafrii 1->0
55// linux usermode¿¡¼­´Â ISR lock »óÅ¿¡¼­ mem alloc/free¸¦ Çã¿ëÇÏÁö ¾Ê´Â´Ù.
56// DMC message Áß¿¡´Â mem free (ex: FreePMT)¸¦ ¼öÇàÇÏ´Â cleanupÀ» µ¿¹ÝÇÏ´Â °ÍÀÌ À־
57// isr disable ¹æ½ÄÀº »ç¿ëÀÌ ºÒ°¡´ÉÇÔ.
58//
59
60
61#define MSG_ENTRY(idx) &(hMsgQue->MsgBuf[(idx)*(hMsgQue->nMsgSize)])
62
63#define MSG_NAME(idx,fnName) ((fnName) ? (fnName)(MSG_ENTRY(idx)) : "")
64
65#define MSG_NAME2(idx)  MSG_NAME((idx),(hMsgQue->pfnMsgName))
66
67
68
69STATUS DMW_SYS_InitMsgQue(DMW_MSGQUE *hMsgQue, int nMsgSize, int nInitialQueSize,
70                                                        char *(*pfnMsgName)(void *))
71{
72        if (hMsgQue == NULL)
73                return statusInvalidArgument;
74       
75        if (nMsgSize == 0)
76                nMsgSize = hMsgQue->nMsgSize;
77       
78        if (nInitialQueSize == 0)
79                nInitialQueSize = hMsgQue->nMaxQueSize;
80       
81        // msg size should be 4 bytes alignment..
82        //
83        if (nMsgSize & 3)
84                nMsgSize = (nMsgSize+3)/4*4;
85       
86        hMsgQue->nMsgSize = nMsgSize;
87        hMsgQue->nMaxQueSize = nInitialQueSize;
88        hMsgQue->nNumberMsg = 0;
89        hMsgQue->Mutex = DHL_OS_CreateMutexSemaphore("MsgQMutex");
90        hMsgQue->Sema4 = DHL_OS_CreateCountingSemaphore("MsgQSem", OS_SEM_PRIO, 0);
91       
92        hMsgQue->pfnMsgName = pfnMsgName;
93        hMsgQue->MsgBuf = DHL_OS_Malloc(nMsgSize * nInitialQueSize);
94       
95        if (hMsgQue->MsgBuf == NULL ||
96                hMsgQue->Mutex == (DHL_OS_SEMA_ID)DHL_INVALID_SEMA_ID)
97        {
98                return statusOutOfResource;     
99        }
100        memset(hMsgQue->MsgBuf, 0, nMsgSize * nInitialQueSize);
101        return statusOK;
102}
103
104
105
106STATUS DMW_SYS_ResizeMsgQue()
107{
108       
109        return statusNotImpl;
110}
111
112
113// User Message Queue API
114//
115
116STATUS DMW_SYS_AddUserMsg(DMW_MSGQUE *hMsgQue, void *pMsg)
117{
118        // UserQueue¿¡ DMC message¸¦ insertÇÑ´Ù. ArrayÀÇ Á¦ÀÏ µÞÂÊ¿¡ ³Ö´Â´Ù.
119        //
120        BOOL bOverflow = FALSE;
121       
122        if (hMsgQue == NULL || pMsg == NULL) 
123                return statusInvalidArgument;
124       
125        if (hMsgQue->Mutex == 0 || hMsgQue->Sema4 == 0 || hMsgQue->MsgBuf == NULL) {
126                DHL_OS_Printf("!! DMW_SYS_GetUserMsg (0x%x) not init\n", hMsgQue);
127                return statusNotInitialized;
128        }
129
130        if (1)
131        {
132                UINT32 mask = 0;
133               
134                if (g_bUseInterruptMasking)
135                        mask = DHL_OS_DisableInterrupts();
136                else
137                        DHL_OS_TakeSemaphore(hMsgQue->Mutex, DHL_TIMEOUT_FOREVER);
138       
139                if (hMsgQue->nNumberMsg >= hMsgQue->nMaxQueSize-1) {
140                        bOverflow = TRUE;
141                }
142                else {  // QueueÀÇ Á¦ÀÏ µÚÂÊ¿¡ ºÙÀδÙ.
143                        memcpy(MSG_ENTRY(hMsgQue->nNumberMsg), pMsg, hMsgQue->nMsgSize);
144                        hMsgQue->nNumberMsg++;
145                }
146               
147                if (g_bUseInterruptMasking)
148                        DHL_OS_RestoreInterrupts(mask);
149                else
150                        DHL_OS_GiveSemaphore(hMsgQue->Mutex);
151        }
152       
153        if (bOverflow) {
154                DHL_OS_Printf("!! MsgQue overflow. msg 0x%x (%s) ignored.\n", 
155                                pMsg, hMsgQue->pfnMsgName ? hMsgQue->pfnMsgName(pMsg) : "");
156                return statusOverflow;
157        }
158        else {
159                DHL_OS_GiveSemaphore(hMsgQue->Sema4);
160        }
161       
162        return statusOK;
163}
164
165STATUS DMW_SYS_GetUserMsg(DMW_MSGQUE *hMsgQue, void *pMsg, UINT32 uTimeoutTicks)
166{
167        // UserQueue¿¡¼­ DMC message¸¦ °¡Á®¿Â´Ù.
168        // ¾Õ¿¡¼­ 1°³¸¦ »©°í ºó °ø°£Àº shift½ÃÄѼ­ ¸Þ²Û´Ù.
169        //
170        STATUS status = statusOK;
171        BOOL bEmptyError = FALSE;
172       
173        if (hMsgQue == NULL || pMsg == NULL)
174                return statusInvalidArgument;
175       
176        if (hMsgQue->Sema4 == 0 || hMsgQue->MsgBuf == NULL) {
177                DHL_OS_Printf("!! DMW_SYS_GetUserMsg (0x%x) not init\n", hMsgQue);
178                return statusNotInitialized;
179        }
180       
181        if (uTimeoutTicks == 0) {
182                // no wait mode..
183                if (DHL_OS_TakeSemaphore(hMsgQue->Sema4, 0))
184                        status = statusNotFound;
185        }
186        else if (uTimeoutTicks == DHL_TIMEOUT_FOREVER) {
187                DHL_OS_TakeSemaphore(hMsgQue->Sema4, DHL_TIMEOUT_FOREVER);
188        }
189        else {
190                if (DHL_OS_TakeSemaphore(hMsgQue->Sema4, uTimeoutTicks))
191                        status = statusTimeout;
192        }
193       
194        if (status) {
195                return status; 
196        }
197        else  // if we successfully take semaphore, we are sure there is message.
198        {
199                UINT32 mask = 0;
200               
201                if (g_bUseInterruptMasking)
202                        mask = DHL_OS_DisableInterrupts();
203                else
204                        DHL_OS_TakeSemaphore(hMsgQue->Mutex, DHL_TIMEOUT_FOREVER);
205
206                if (hMsgQue->nNumberMsg > 0) 
207                {
208                        // ¾Õ¿¡¼­ºÎÅÍ Çϳª¾¿ »©°£´Ù.
209                        memcpy(pMsg, MSG_ENTRY(0), hMsgQue->nMsgSize);
210               
211                        // ºó °ø°£À» ä¿ì±â À§ÇØ shift..
212                #if 0
213                        // Çϳª¾¿ º¹»ç..
214                        //for (i=1; i<hMsgQue->nNumberMsg; i++)
215                        //      memcpy(MSG_ENTRY[i-1] = MSG_ENTRY[i];
216                #else
217                        hMsgQue->nNumberMsg--;
218                        if (hMsgQue->nNumberMsg)
219                                memmove(MSG_ENTRY(0), MSG_ENTRY(1), hMsgQue->nNumberMsg * hMsgQue->nMsgSize);
220                #endif
221                }
222                else {
223                        bEmptyError = TRUE;
224                }
225               
226                if (g_bUseInterruptMasking)
227                        DHL_OS_RestoreInterrupts(mask);
228                else
229                        DHL_OS_GiveSemaphore(hMsgQue->Mutex);
230        }
231       
232        if (bEmptyError) {
233                DHL_OS_Printf("!! Sema4 taken but Que empty?\n");
234                //DHL_OS_GiveSemaphore(hMsgQue->Sema4);
235               
236                return statusNotFound;
237        }
238       
239        return statusOK;
240}
241
242BOOL DMW_SYS_UserMsgExist(DMW_MSGQUE *hMsgQue)
243{
244        if (hMsgQue == NULL) 
245                return FALSE;
246       
247        if (hMsgQue->Mutex == 0 || hMsgQue->Sema4 == 0 || hMsgQue->MsgBuf == NULL) {
248                DHL_OS_Printf("!! DMW_SYS_GetUserMsg (0x%x) not init\n", hMsgQue);
249                return FALSE;
250        }
251       
252        // °£´ÜÇÑ ÇÔ¼öÀ̹ǷΠlockÀ» ÇÏÁö ¾Ê°í ÂüÁ¶..
253        //
254        return hMsgQue->nNumberMsg > 0 ? TRUE : FALSE;
255}
256
257
258STATUS DMW_SYS_DeleteMsgConditionally(DMW_MSGQUE *hMsgQue, 
259                                                                DMW_FN_MSG_CHECK fnCondition, UINT32 param,
260                                                                DMW_FN_MSG_DELETE fnDelete)
261{
262        int i, errCnt = 0;
263        int nMsgDeleted = 0;
264        UINT32 mask = 0;
265
266        if (fnCondition == NULL)
267                return statusInvalidArgument;
268               
269        //DHL_OS_Printf("delete %d msgs..\n", hMsgQue->nNumberMsg);
270
271        if (g_bUseInterruptMasking)
272                mask = DHL_OS_DisableInterrupts();
273        else
274                DHL_OS_TakeSemaphore(hMsgQue->Mutex, DHL_TIMEOUT_FOREVER);
275       
276        for (i=0; i<hMsgQue->nNumberMsg; i++) 
277        {
278                if (fnCondition(MSG_ENTRY(i), param) == FALSE)
279                        continue;
280               
281                //DHL_OS_Printf("\t *** delete msg[%d] (%s) \n", i, MSG_NAME2(i));
282
283                // cafrii 060831 add
284                // fnDelete¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é ±×³É »ç¶óÁø´Ù.
285                if (fnDelete)
286                        fnDelete(MSG_ENTRY(i));
287               
288                // queueÀÇ ¸¶Áö¸· index´Â  hMsgQue->nNumberMsg - 1 ÀÌ´Ù.
289                //
290                if (i < hMsgQue->nNumberMsg - 1)
291                        memmove(MSG_ENTRY(i), MSG_ENTRY(i+1), 
292                                (hMsgQue->nNumberMsg-1-i) * hMsgQue->nMsgSize);
293               
294                // Çϳª Áö¿üÀ¸´Ï±î index¸¦ Á¶Á¤..
295                hMsgQue->nNumberMsg--;
296                i--;
297                nMsgDeleted++;
298
299                errCnt += (DHL_OS_TakeSemaphore(hMsgQue->Sema4, 0) ? 1 : 0);
300        }
301       
302        if (g_bUseInterruptMasking)
303                DHL_OS_RestoreInterrupts(mask);
304        else
305                DHL_OS_GiveSemaphore(hMsgQue->Mutex);
306
307        if (errCnt)
308                DHL_OS_Printf("!! MsgQue: count semaphore err %d times\n", errCnt);
309               
310        //DHL_OS_Printf("\t total %d msg deleted\n", nMsgDeleted);
311       
312        return statusOK;
313}
314
315
316BOOL DMW_SYS_CheckSpecificMsgExist(DMW_MSGQUE *hMsgQue, 
317                                                                DMW_FN_MSG_CHECK fnCheck, UINT32 param)
318{
319        int i;
320        BOOL bExist = FALSE;
321        UINT32 mask = 0;
322       
323        if (fnCheck == NULL) 
324                return FALSE;
325
326        if (g_bUseInterruptMasking)
327                mask = DHL_OS_DisableInterrupts();
328        else
329                DHL_OS_TakeSemaphore(hMsgQue->Mutex, DHL_TIMEOUT_FOREVER);
330       
331        for (i=0; i<hMsgQue->nNumberMsg; i++) {
332                if (fnCheck(MSG_ENTRY(i), param)) {
333                        bExist = TRUE;
334                        break;
335                }
336        }
337
338        if (g_bUseInterruptMasking)
339                DHL_OS_RestoreInterrupts(mask);
340        else
341                DHL_OS_GiveSemaphore(hMsgQue->Mutex);
342
343        return bExist;
344}
345
346
347void DMW_SYS_PrintUserMsgs(DMW_MSGQUE *hMsgQue, DMW_FN_MSG_NAME fnName)
348{
349        int i;
350        char buf[300], *pName;
351        UINT32 mask = 0;
352       
353        if (g_bUseInterruptMasking)
354                mask = DHL_OS_DisableInterrupts();
355        else
356                DHL_OS_TakeSemaphore(hMsgQue->Mutex, DHL_TIMEOUT_FOREVER);
357
358        buf[0] = 0;
359        for (i=0; i<min(hMsgQue->nNumberMsg, 20); i++) {
360                pName = fnName ? MSG_NAME(i,fnName) : MSG_NAME2(i);
361                if (strlen(buf) + strlen(pName) + 10 >= 300) // margin 10
362                        break;
363                sprintf(buf+strlen(buf), "%s ", pName);
364        }
365
366        if (g_bUseInterruptMasking)
367                DHL_OS_RestoreInterrupts(mask);
368        else
369                DHL_OS_GiveSemaphore(hMsgQue->Mutex);
370
371        DHL_OS_Printf("MsgQue: %d msgs\n", hMsgQue->nNumberMsg);
372        DHL_OS_Printf("  [ %s]\n", buf);
373}
374
375
376
377
378#if 0
379____Example____()
380#endif
381
382#if 0
383
384
3851. DMW_MSGQUE ¸Þ¸ð¸® (°ø°£) ÇÒ´ç
386
387        MsgQue object¸¦ µ¿ÀûÀ¸·Î ÇÒ´çÇÏ´Â ¹æ½ÄÀº ¾Æ´Ï°í
388        ÀÏ´Ü space´Â caller°¡ Á¦°øÇÑ´Ù. (stackÀº ¾ÈµÇ°í, BSS³ª DATA, HEAP »ç¿ëÇØ¾ß ÇÔ)
389
390        DMW_MSGQUE MsgQueObject, *g_MsgQue = &MsgQueObject;
391                ¶Ç´Â
392        g_pMsgQue = OS_Malloc(sizeof(DMW_MSGQUE));
393
3942. ¸Þ½ÃÁö ŸÀÔ Á¤ÀÇ
395
396        ±×´ÙÀ½¿¡ Message·Î »ç¿ëÇÒ structure¸¦ define.
397       
398        typedef struct {
399                int id;
400                ...
401        } MyMsgType;
402       
403       
4043. ÃʱâÈ­
405
406        // ÃʱâÈ­
407        DMW_SYS_InitMsgQue(g_MsgQue, sizeof(MyMsgType), 10,
408                                                (DMW_FN_MSG_NAME) MsgName);
409
410       
411        ¸Ç µÚÀÇ ÀÎÀÚ´Â debugging¿¡ ¿ëÀÌÇϵµ·Ï °¢ Message¿¡ namingÀ» ÇÏ¿© Ç¥½ÃÇÒ ¶§ »ç¿ëµÈ´Ù.
412        ÇÊ¿ä¾øÀ¸¸é NULLÀ» ÁöÁ¤ÇÏ¸é µÈ´Ù.
413       
414        ¿¹:
415                char *MsgName(MyMsgType *pMsg)
416                {
417                        switch (pMsg->id) {
418                                case 0 : return "msg_init";
419                                case 1 : return "msg_start";
420                                case 2 : return "msg_resume";
421                                ..
422                        }
423                }
424
4254. ¸Þ½ÃÁö Å¥¿¡ ³Ö±â
426
427        MsgType msg;
428        msg.id = 1;
429        ..
430       
431        DMW_SYS_AddUserMsg(g_MsgQue, &msg);
432
433
4345. ¸Þ½ÃÁö Å¥¿¡¼­ »©³»±â
435
436        MsgType msg;
437       
438        DMW_SYS_GetUserMsg(g_MsgQue, &msg, 0);
439
440
441
442#endif
Note: See TracBrowser for help on using the repository browser.