cocoOS  4.0.0
os_msgqueue.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Peter Eckstrand
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted (subject to the limitations in the
8  * disclaimer below) provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the
16  * distribution.
17  *
18  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
19  * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
20  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
21  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * This file is part of the cocoOS operating system.
33  * Author: Peter Eckstrand <info@cocoos.net>
34  */
35 
36 
37 
38 #ifndef OS_MSGQUEUE_H__
39 #define OS_MSGQUEUE_H__
40 
43 #include "os_defines.h"
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 
50 typedef struct {
51  uint8_t signal;
52  uint8_t reserved; /* Alignment byte */
53  uint16_t delay; /* Delay of posting in ticks */
54  uint16_t reload; /* Reload value for periodic messages */
55 } Msg_t;
56 
57 
58 typedef uint8_t MsgQ_t;
59 
60 
61 enum {
62  MSG_QUEUE_UNDEF,
63  MSG_QUEUE_DEF,
64  MSG_QUEUE_EMPTY,
65  MSG_QUEUE_FULL,
66  MSG_QUEUE_RECEIVED,
67  MSG_QUEUE_POSTED
68 };
69 
70 
71 #define OS_MSG_Q_POST(task, msg, delay, period, async ) do {\
72  static uint8_t os_posted;\
73  static MsgQ_t queue;\
74  static Sem_t sem;\
75  queue = os_msgQ_find( task );\
76  sem = os_msgQ_sem_get( queue );\
77  sem_wait( sem );\
78  do {\
79  os_posted = os_msg_post( (Msg_t*)&msg, queue, delay, period );\
80  if ( os_posted == MSG_QUEUE_FULL ){\
81  if ( async == 0 ) {\
82  OS_SIGNAL_SEM_NO_SCHEDULE( sem );\
83  event_wait(os_msgQ_event_get( queue ));\
84  if ( os_sem_larger_than_zero( sem ) )\
85  os_sem_decrement( sem );\
86  else {\
87  os_task_wait_sem_set( running_tid, sem );\
88  os_task_internal_state_set( running_tid, __LINE__+50000 );\
89  running_tid = NO_TID;\
90  return;\
91  case (__LINE__+50000):\
92  continue;\
93  }\
94  }\
95  else {\
96  os_posted = MSG_QUEUE_POSTED;\
97  }\
98  }\
99  } while ( os_posted == MSG_QUEUE_FULL );\
100  sem_signal( sem );\
101  } while(0)
102 
103 
104 #define OS_MSG_Q_RECEIVE(task, pMsg, async) do {\
105  static MsgQ_t queue;\
106  static Sem_t sem;\
107  static uint8_t os_received;\
108  queue = os_msgQ_find( task );\
109  sem = os_msgQ_sem_get( queue );\
110  sem_wait( sem );\
111  do {\
112  os_received = os_msg_receive( (Msg_t*)pMsg, queue );\
113  if ( os_received == MSG_QUEUE_EMPTY ){\
114  if ( async == 0 ) {\
115  OS_SIGNAL_SEM_NO_SCHEDULE( sem );\
116  event_wait(os_msgQ_event_get( queue ));\
117  if ( os_sem_larger_than_zero( sem ) )\
118  os_sem_decrement( sem );\
119  else {\
120  os_task_wait_sem_set( running_tid, sem );\
121  os_task_internal_state_set( running_tid, __LINE__+50000 );\
122  running_tid = NO_TID;\
123  return;\
124  case (__LINE__+50000):\
125  continue;\
126  }\
127  }\
128  else {\
129  ((Msg_t*)pMsg)->signal = NO_MSG_ID;\
130  os_received = MSG_QUEUE_RECEIVED;\
131  }\
132  }\
133  } while ( os_received == MSG_QUEUE_EMPTY );\
134  sem_signal( sem );\
135  } while(0)
136 
137 
138 
139 #define OS_MSG_Q_EVENT_WAIT( task ) do {\
140  OS_SIGNAL_SEM_NO_SCHEDULE(os_msgQ_sem_get(task));\
141  event_wait(os_msgQ_event_get(task));\
142  } while (0)
143 
144 
145 
146 MsgQ_t os_msgQ_create( Msg_t *buffer, uint8_t size, uint16_t msgSize, taskproctype taskproc );
147 MsgQ_t os_msgQ_find( taskproctype taskproc );
148 Sem_t os_msgQ_sem_get( MsgQ_t queue );
149 Evt_t os_msgQ_event_get( MsgQ_t queue );
150 void os_msgQ_tick( MsgQ_t queue );
151 
152 uint8_t os_msg_post( Msg_t *msg, MsgQ_t queue, uint16_t delay, uint16_t period );
153 uint8_t os_msg_receive( Msg_t *msg, MsgQ_t queue );
154 
155 
156 #ifdef __cplusplus
157 }
158 #endif
159 
160 #endif
Definition: os_msgqueue.h:50