ESOS32
ESOSOn32-bitProcessors
esos_mail.h
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2019 J. W. Bruce ("AUTHOR(S)")"
3  * All rights reserved.
4  * (J. W. Bruce, jwbruce_AT_tntech.edu, Tennessee Tech University)
5  *
6  * Permission to use, copy, modify, and distribute this software and its
7  * documentation for any purpose, without fee, and without written agreement is
8  * hereby granted, provided that the above copyright notice, the following
9  * two paragraphs and the authors appear in all copies of this software.
10  *
11  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
12  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
13  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
14  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15  *
16  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
19  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
20  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
21  *
22  * Please maintain this header in its entirety when copying/modifying
23  * these files.
24  *
25  *
26  */
27 
28 
44 #ifndef ESOS_MAIL_H
45 #define ESOS_MAIL_H
46 
47 /* I N C L U D E S **********************************************************/
48 #include "esos.h"
49 #include "esos_cb.h"
50 
51 // TODO we have included esos.h but for some reason the MAX_NUM_USER_TASKS
52 // define is not being found in the declaration of mailboxes below??????
53 
54 /* S T R U C T U R E S ******************************************************/
55 
60 typedef struct __stMAILBOX {
61  CBUFFER* pst_CBuffer; // ptr to structure that describes mailbox circular buffer
62  struct stTask* pst_Task; // ptr to ESOS_TASK_HANDLE that owns mailbox
63 } MAILBOX;
64 
70 /* DEPRECATED MAIL MESSAGE structure
71 typedef struct __stMAILMSG {
72  uint16_t u16_Header; // bits F-C RESERVED; bits B-4 fromTaskHash?; bits 3-0 payload length
73  uint32_t u32_Postmark; // ESOS tick timestamp
74  uint8_t au8_Contents[__MAIL_MSG_MAX_LEN]; // data storage
75 } MAILMSG;
76 */
77 
78 #define __MAIL_MSG_MAX_DATA_LEN 16 // can be no BIGGER than 16 bytes
79 
80 typedef struct __stMAILMESSAGE {
81  uint8_t u8_flags; // various bits to help us decode message
82  uint16_t u16_FromTaskID; // an unique? 16-bit ID number identifying the sender task
83  uint8_t u8_DataLength; // how many bytes in data payload
84  uint32_t u32_Postmark; // ESOS tick timestamp on message
85  union {
86  uint8_t au8_Contents[__MAIL_MSG_MAX_DATA_LEN]; // message contents
87  uint16_t au16_Contents[__MAIL_MSG_MAX_DATA_LEN/2]; // message contents
88  uint32_t au32_Contents[__MAIL_MSG_MAX_DATA_LEN/4]; // message contents
89  char ach_Contents[__MAIL_MSG_MAX_DATA_LEN]; // message contents
90  };
91 } MAILMESSAGE;
92 
93 /* D E F I N E S ************************************************************/
94 // DEFINEs user can NOT change
95 #define ESOS_MAILMESSAGE_STRING 0x0
96 #define ESOS_MAILMESSAGE_UINT8 0x1
97 #define ESOS_MAILMESSAGE_UINT16 0x2
98 #define ESOS_MAILMESSAGE_UINT32 0x4
99 #define ESOS_MAILMESSAGE_REQUEST_ACK 0x8
100 
101 // verify these against the MAILMESSAGE struct above
102 #define __MAIL_MSG_HEADER_LEN (1+2+1+4)
103 #define __MAIL_MSG_MAX_LEN (__MAIL_MSG_HEADER_LEN+__MAIL_MSG_MAX_DATA_LEN)
104 
105 // size of each task's mailbox (in bytes)
106 #define MAX_SIZE_TASK_MAILBOX 5*__MAIL_MSG_MAX_LEN
107 
108 /* M A C R O S ************************************************************/
109 
117 #define ESOS_TASK_HAS_MAIL(pstTask) (__ESOS_CB_IS_NOT_EMPTY((pstTask)->pst_Mailbox->pst_CBuffer))
118 
127 #define ESOS_TASK_IS_WAITING_MAIL_DELIVERY(TaskHandle) IS_BIT_SET_MASK((TaskHandle)->flags, __TASK_MAILNACK_MASK)
128 
139 #define ESOS_TASK_IVE_GOT_MAIL() ESOS_TASK_HAS_MAIL(__pstSelf)
140 
148 #define ESOS_TASK_WAIT_FOR_MAIL() ESOS_TASK_WAIT_UNTIL(ESOS_TASK_IVE_GOT_MAIL())
149 
150 
162 #define ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(pstTask, x) ESOS_TASK_WAIT_UNTIL(ESOS_TASK_MAILBOX_GOT_AT_LEAST_DATA_BYTES((pstTask), ((x)+__MAIL_MSG_HEADER_LEN)))
163 
178 #define ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_ROOM_MESSAGE(pstTask, pstMsg) \
179  ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(pstTask, __MAIL_MSG_MAX_DATA_LEN )
180 
181 
189 #define ESOS_TASK_MAILBOX_GET_AVAILABLE_LEN(pstTask) ((__ESOS_CB_GET_AVAILABLE((pstTask)->pst_Mailbox->pst_CBuffer))-__MAIL_MSG_HEADER_LEN)
190 
201 #define ESOS_TASK_MAILBOX_GOT_EXACTLY_DATA_BYTES(pstTask,x) (ESOS_TASK_MAILBOX_GET_AVAILABLE_LEN((pstTask)) == ((x)+__MAIL_MSG_HEADER_LEN))
202 
214 #define ESOS_TASK_MAILBOX_GOT_AT_LEAST_DATA_BYTES(pstTask, x) (ESOS_TASK_MAILBOX_GET_AVAILABLE_LEN((pstTask)) >= ((x)+__MAIL_MSG_HEADER_LEN))
215 
228 #define ESOS_TASK_FLUSH_TASK_MAILBOX(pstTask) __ESOS_CB_FLUSH((pstTask)->pst_Mailbox->pst_CBuffer)
229 
230 #define ESOS_TASK_SEND_MESSAGE(pst_ToTask, pst_Msg) __esos_SendMailMessage((pst_ToTask),(pst_Msg))
231 
232 #define ESOS_TASK_SEND_MESSAGE_WAIT_DELIVERY(pst_ToTask, pstMsg) ESOS_TASK_WAIT_ON_DELIVERY((pst_ToTask), (pstMsg))
233 
234 #define ESOS_TASK_WAIT_ON_DELIVERY(pst_ToTask, pstMsg) \
235  do{ \
236  (pstMsg)->u8_flags |= ESOS_MAILMESSAGE_REQUEST_ACK; \
237  ESOS_TASK_SEND_MESSAGE((pst_ToTask),(pstMsg)); \
238  __ESOS_SET_TASK_MAILNACK_FLAG((__pstSelf)); \
239  ESOS_TASK_WAIT_WHILE( ESOS_TASK_IS_WAITING_MAIL_DELIVERY( __pstSelf ) ); \
240  } while(0)
241 
242 #define ESOS_TASK_GET_NEXT_MESSAGE(pst_Msg) __esos_ReadMailMessage(__pstSelf, (pst_Msg))
243 
244 #define ESOS_TASK_GET_LAST_MESSAGE(pst_Msg) \
245  do { \
246  while ( ESOS_TASK_IVE_GOT_MAIL() ) { \
247  __esos_ReadMailMessage(__pstSelf, (pst_Msg) ); \
248  } \
249  }while(0)
250 
251 /********************
252 *** QUICKIE MACROS
253 ********************/
254 #define ESOS_IS_TASK_SENDER(hTask, stMsg) (hTask->u16_taskID==stMsg.u16_FromTaskID)
255 
256 #define ESOS_SET_MSG_FLAGS(stMsg, flags) stMsg.u8_flags=(flags)
257 #define ESOS_SET_MSG_FROMTASK(stMsg, pstFromTask) stMsg.u16_FromTaskID=pstFromTask->u16_taskID
258 #define ESOS_SET_MSG_DATA_LENGTH(stMsg, len) stMsg.u8_DataLength=(len)
259 #define ESOS_GET_MSG_FLAGS(stMsg) (stMsg.u8_flags)
260 #define ESOS_GET_MSG_FROMTASK(stMsg) (stMsg.u16_FromTaskID)
261 #define ESOS_GET_MSG_DATA_LENGTH(stMsg) (stMsg.u8_DataLength)
262 #define ESOS_GET_MSG_POSTMARK(stMsg) (stMsg.u32_Postmark)
263 
264 #define ESOS_SET_PMSG_FLAGS(pstMsg, flags) pstMsg->u8_flags=(flags)
265 #define ESOS_SET_PMSG_FROMTASK(pstMsg, pstFromTask) pstMsg->u16_FromTaskID=pstFromTask->u16_taskID
266 #define ESOS_SET_PMSG_DATA_LENGTH(pstMsg, len) pstMsg->u8_DataLength=(len)
267 #define ESOS_GET_PMSG_FLAGS(pstMsg) (pstMsg->u8_flags)
268 #define ESOS_GET_PMSG_FROMTASK(pstMsg) (pstMsg->u16_FromTaskID)
269 #define ESOS_GET_PMSG_DATA_LENGTH(pstMsg) (pstMsg->u8_DataLength)
270 #define ESOS_GET_PMSG_POSTMARK(pstMsg) (pstMsg->u32_Postmark)
271 
272 #define ESOS_TASK_MAKE_MSG_EMPTY(stMsg) \
273  do{ \
274  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT8); \
275  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
276  ESOS_SET_MSG_DATA_LENGTH(stMsg, 0); \
277  } while(0)
278 
279 #define ESOS_TASK_MAKE_MSG_UINT8(stMsg, u8x) \
280  do{ \
281  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT8); \
282  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
283  ESOS_SET_MSG_DATA_LENGTH(stMsg, 1); \
284  stMsg.au8_Contents[0] = (u8x); \
285  } while(0)
286 
287 #define ESOS_TASK_MAKE_MSG_UINT8_X2(stMsg, u8x0, u8x1) \
288  do{ \
289  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT8); \
290  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
291  ESOS_SET_MSG_DATA_LENGTH(stMsg, 2); \
292  stMsg.au8_Contents[0] = (u8x0); \
293  stMsg.au8_Contents[1] = (u8x1); \
294  } while(0)
295 
296 #define ESOS_TASK_MAKE_MSG_UINT8_X3(stMsg, u8x0, u8x1, u8x2) \
297  do{ \
298  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT8); \
299  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
300  ESOS_SET_MSG_DATA_LENGTH(stMsg, 3); \
301  stMsg.au8_Contents[0] = (u8x0); \
302  stMsg.au8_Contents[1] = (u8x1); \
303  stMsg.au8_Contents[2] = (u8x2); \
304  } while(0)
305 
306 #define ESOS_TASK_MAKE_MSG_UINT8_X4(stMsg, u8x0, u8x1, u8x2, u8x3) \
307  do{ \
308  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT8); \
309  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
310  ESOS_SET_MSG_DATA_LENGTH(stMsg, 4); \
311  stMsg.au8_Contents[0] = (u8x0); \
312  stMsg.au8_Contents[1] = (u8x1); \
313  stMsg.au8_Contents[2] = (u8x2); \
314  stMsg.au8_Contents[3] = (u8x3); \
315  } while(0)
316 
317 #define ESOS_TASK_MAKE_MSG_AUINT8(stMsg, pau8x, len) \
318  do{ \
319  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT8); \
320  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
321  ESOS_SET_MSG_DATA_LENGTH(stMsg, len); \
322  for (__u8_esos_mail_routines_dummy_uint8=0; __u8_esos_mail_routines_dummy_uint8<len; __u8_esos_mail_routines_dummy_uint8++) { \
323  stMsg.au8_Contents[__u8_esos_mail_routines_dummy_uint8] = pau8x[__u8_esos_mail_routines_dummy_uint8]; \
324  } \
325  } while(0)
326 
327 #define ESOS_TASK_MAKE_MSG_UINT16(stMsg, u16x) \
328  do{ \
329  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT16); \
330  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
331  ESOS_SET_MSG_DATA_LENGTH(stMsg, 1); \
332  stMsg.au16_Contents[0] = (u16x); \
333  } while(0)
334 
335 #define ESOS_TASK_MAKE_MSG_UINT16_X2(stMsg, u16x0, u16x1) \
336  do{ \
337  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT16); \
338  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
339  ESOS_SET_MSG_DATA_LENGTH(stMsg, 2); \
340  stMsg.au16_Contents[0] = (u16x0); \
341  stMsg.au16_Contents[1] = (u16x1); \
342  } while(0)
343 
344 #define ESOS_TASK_MAKE_MSG_UINT16_X3(stMsg, u16x0, u16x1, u16x2) \
345  do{ \
346  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT16); \
347  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
348  ESOS_SET_MSG_DATA_LENGTH(stMsg, 3); \
349  stMsg.au16_Contents[0] = (u16x0); \
350  stMsg.au16_Contents[1] = (u16x1); \
351  stMsg.au16_Contents[2] = (u16x2); \
352  } while(0)
353 
354 #define ESOS_TASK_MAKE_MSG_UINT16_X4(stMsg, u16x0, u16x1, u16x2, u16x3) \
355  do{ \
356  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT16); \
357  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
358  ESOS_SET_MSG_DATA_LENGTH(stMsg, 4); \
359  stMsg.au16_Contents[0] = (u16x0); \
360  stMsg.au16_Contents[1] = (u16x1); \
361  stMsg.au16_Contents[2] = (u16x2); \
362  stMsg.au16_Contents[3] = (u16x3); \
363  } while(0)
364 
365 #define ESOS_TASK_MAKE_MSG_UINT32(stMsg, u32x) \
366  do{ \
367  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT32); \
368  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
369  ESOS_SET_MSG_DATA_LENGTH(stMsg, 1); \
370  stMsg.au32_Contents[0] = (u32x); \
371  } while(0)
372 
373 #define ESOS_TASK_MAKE_MSG_UINT32_X2(stMsg, u32x0, u32x1) \
374  do{ \
375  ESOS_SET_MSG_FLAGS(stMsg, ESOS_MAILMESSAGE_UINT32); \
376  ESOS_SET_MSG_FROMTASK(stMsg, __pstSelf); \
377  ESOS_SET_MSG_DATA_LENGTH(stMsg, 2); \
378  stMsg.au32_Contents[0] = (u32x0); \
379  stMsg.au32_Contents[1] = (u32x1); \
380  } while(0)
381 
382 
383 #define PRINTF_MESSAGE(stMsg) \
384  do{ \
385  printf("MESSAGE u8_flags = %02X\n",ESOS_GET_MSG_FLAGS(stMsg) ); \
386  printf(" u16_FromTaskID = %d\n",ESOS_GET_MSG_FROMTASK(stMsg) ); \
387  printf(" u8_DataLength = %d\n",ESOS_GET_MSG_DATA_LENGTH(stMsg) ); \
388  printf(" u32_PostMark = %d\n",ESOS_GET_MSG_POSTMARK(stMsg) ); \
389  printf(" first byte = %d\n",stMsg.au8_Contents[0]); \
390  } while(0)
391 
392 /* E X T E R N S ************************************************************/
393 extern MAILBOX __astMailbox[MAX_NUM_USER_TASKS];
394 extern uint8_t __au8_MBData[MAX_NUM_USER_TASKS][MAX_SIZE_TASK_MAILBOX];
395 extern uint8_t __u8_esos_mail_routines_dummy_uint8;
396 
397 /* P U B L I C P R O T O T Y P E S *****************************************/
398 
399 /* P R I V A T E P R O T O T Y P E S ***********************************/
400 
404 void __esos_InitMailbox(MAILBOX* pst_Mailbox, uint8_t* pau8_ptr);
405 
406 //void __esos_WriteMailboxUINT8(MAILBOX* pst_Mailbox, uint8_t u8_x );
407 #define __esos_WriteMailboxUINT8(pstMB, u8x) __esos_CB_WriteUINT8((pstMB)->pst_CBuffer, (u8x) )
408 
409 //uint8_t __esos_ReadMailboxUINT8(MAILBOX* pst_Mailbox );
410 #define __esos_ReadMailboxUINT8(pstMB, u8x) __esos_CB_ReadUINT8((pstMB)->pst_CBuffer )
411 
420 void __esos_SendMailUint8(struct stTask* pst_Task, MAILBOX* pst_Mailbox, uint8_t* pau8_data, uint8_t u8_len );
421 void __esos_ReadMailMessage(struct stTask* pst_Task, MAILMESSAGE* pst_Message );
422 void __esos_SendMailMessage(struct stTask* pst_RcvrTask, MAILMESSAGE* pst_Msg );
423 
426 #endif // ESOS_MAIL_H
__stMAILMESSAGE
Definition: esos_mail.h:80
__esos_SendMailMessage
void __esos_SendMailMessage(ESOS_TASK_HANDLE pst_RcvrTask, MAILMESSAGE *pst_Msg)
Definition: esos_mail.c:60
__MAIL_MSG_MAX_DATA_LEN
#define __MAIL_MSG_MAX_DATA_LEN
Definition: esos_mail.h:78
__stMAILBOX
Definition: esos_mail.h:60
__stCIRCBUFF
Definition: esos_cb.h:56
__esos_ReadMailMessage
void __esos_ReadMailMessage(ESOS_TASK_HANDLE pst_Task, MAILMESSAGE *pst_Message)
Definition: esos_mail.c:98
esos.h
__esos_SendMailUint8
void __esos_SendMailUint8(struct stTask *pst_Task, MAILBOX *pst_Mailbox, uint8_t *pau8_data, uint8_t u8_len)
esos_cb.h
stTask
Definition: esos_task.h:54
MAILBOX
struct __stMAILBOX MAILBOX