ESOS32
ESOSOn32-bitProcessors
esos_task.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 
29 /*
30  * This file defines the macros and structures needed to implement the
31  * ESOS cooperative mulitasking. It relies heavily on the PROTOTHREADS
32  * library created by Adam Dunkels at SICS. The SICS notices are
33  * found at the EOF.
34  */
35 
48 #ifndef __ESOS_TASK_H__
49 #define __ESOS_TASK_H__
50 
51 #include "lc.h"
52 #include "esos_mail.h"
53 
54 struct stTask {
55  lc_t lc;
56  uint8_t flags;
57  uint8_t (*pfn) (struct stTask *pst_Task);
58  uint32_t u32_savedTick;
59  uint32_t u32_waitLen;
60  uint16_t u16_taskID;
61  MAILBOX* pst_Mailbox;
62 };
63 
73 typedef struct stTask* ESOS_TASK_HANDLE;
74 
75 /******************************
76 ** create a typedef to represent pointers to ESOS
77 ** user task functions
78 *******************************/
79 // typedef uint8_t (*pfn_ESOS_USER_TASK)(struct stTask *pst_Task);
80 //#define __MAKE_UINT16_TASK_ID(pfn) esos_taskname_hash_u16( (pfn), sizeof((pfn)) )
81 //#define ESOS_DOES_TASK_HAVE_ID(pfn,taskID) ((taskID)==__MAKE_UINT16_TASK_ID((pfn)))
82 
83 /* Task "return" values. Used by scheduler to determine what to do with task **/
84 #define ESOS_TASK_WAITING 0
85 #define ESOS_TASK_ENDED 3
86 
87 
88 /* Task flag : task is waiting on ACK from other task reading mail */
89 #define __TASK_MAILNACK_MASK ESOS_BIT5
90 /* Task flag : task has mail needing to be read */
91 #define __TASK_HASMAIL_MASK ESOS_BIT4
92 
93 /* Task flag : task has ended (hit ESOS_TASK_END) */
94 #define __TASK_ENDED_MASK ESOS_BIT3
95 /* Task flag : task has been flagged to be killed (will exit on next block/wait/yield) */
96 #define __TASK_KILLED_MASK ESOS_BIT2
97 /* Task flag : task is sleeping */
98 #define __TASK_SLEEPING_MASK ESOS_BIT1
99 /* Task flag : task is waiting */
100 #define __TASK_WAITING_MASK ESOS_BIT0
101 /* Task flag : task has been called by scheduler */
102 #define __TASK_CALLED_MASK ESOS_BIT7
103 
104 /* some helper macros to manage Task states **/
105 #define __ESOS_SET_TASK_SLEEPING_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_SLEEPING_MASK)
106 #define __ESOS_CLEAR_TASK_SLEEPING_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_SLEEPING_MASK)
107 #define __ESOS_SET_TASK_KILLED_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_KILLED_MASK)
108 #define __ESOS_CLEAR_TASK_KILLED_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_KILLED_MASK)
109 #define __ESOS_SET_TASK_WAITING_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_WAITING_MASK)
110 #define __ESOS_CLEAR_TASK_WAITING_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_WAITING_MASK)
111 #define __ESOS_SET_TASK_CALLED_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_CALLED_MASK)
112 #define __ESOS_CLEAR_TASK_CALLED_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_CALLED_MASK)
113 #define __ESOS_IS_TASK_CALLED(TaskHandle) IS_BIT_SET_MASK((TaskHandle)->flags, __TASK_CALLED_MASK)
114 #define __ESOS_SET_TASK_ENDED_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_ENDED_MASK)
115 #define __ESOS_CLEAR_TASK_ENDED_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_ENDED_MASK)
116 
117 /* mailbox task flags */
118 #define __ESOS_SET_TASK_HASMAIL_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_HASMAIL_MASK)
119 #define __ESOS_CLEAR_TASK_HASMAIL_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_HASMAIL_MASK)
120 #define __ESOS_SET_TASK_MAILNACK_FLAG(TaskHandle) BIT_SET_MASK((TaskHandle)->flags, __TASK_MAILNACK_MASK)
121 #define __ESOS_CLEAR_TASK_MAILNACK_FLAG(TaskHandle) BIT_CLEAR_MASK((TaskHandle)->flags, __TASK_MAILNACK_MASK)
122 
123 
142 #define __ESOS_INIT_TASK(TaskHandle) \
143  LC_INIT((TaskHandle)->lc);
144 
166 #define ESOS_IS_TASK_INITED(TaskHandle) LC_IS_INITED((TaskHandle)->lc)
167 
175 #define ESOS_IS_TASK_SLEEPING(TaskHandle) IS_BIT_SET_MASK((TaskHandle)->flags, __TASK_SLEEPING_MASK)
176 
184 #define ESOS_IS_TASK_KILLED(TaskHandle) IS_BIT_SET_MASK((TaskHandle)->flags, __TASK_KILLED_MASK)
185 
193 #define ESOS_IS_TASK_WAITING(TaskHandle) IS_BIT_SET_MASK((TaskHandle)->flags, __TASK_WAITING_MASK)
194 
204 #define ESOS_IS_TASK_ENDED(TaskHandle) IS_BIT_SET_MASK((TaskHandle)->flags, __TASK_ENDED_MASK)
205 
227 #define ESOS_USER_TASK(taskname) uint8_t taskname(ESOS_TASK_HANDLE __pstSelf)
228 
246 #define ESOS_CHILD_TASK(taskname, ...) uint8_t taskname(ESOS_TASK_HANDLE __pstSelf, ##__VA_ARGS__)
247 
259 #define ESOS_TASK_BEGIN() \
260  { __ESOS_SET_TASK_CALLED_FLAG(__pstSelf); \
261  LC_RESUME(__pstSelf->lc)
262 
271 #define ESOS_TASK_END() \
272  LC_END(__pstSelf->lc); \
273  __pstSelf->flags = __TASK_ENDED_MASK; \
274  __ESOS_INIT_TASK(__pstSelf); \
275  return ESOS_TASK_ENDED; }
276 
277 
289 #define ESOS_TASK_GET_TASK_HANDLE() __pstSelf
290 
313 #define ESOS_SCHEDULE_TASK(pfnThread) ( (pfnThread) < ESOS_TASK_ENDED )
314 
335 #define ESOS_TASK_WAIT_UNTIL(condition) \
336  do { \
337  LC_SET(__pstSelf->lc); \
338  if(ESOS_IS_TASK_KILLED(__pstSelf)) { \
339  __pstSelf->flags = __TASK_KILLED_MASK; \
340  return ESOS_TASK_ENDED; \
341  } \
342  if((condition)) { \
343  __ESOS_CLEAR_TASK_WAITING_FLAG(__pstSelf); \
344  } \
345  else { \
346  __ESOS_SET_TASK_WAITING_FLAG(__pstSelf); \
347  } \
348  if(ESOS_IS_TASK_WAITING(__pstSelf)) { \
349  return ESOS_TASK_WAITING; \
350  } \
351  } while(0)
352 
363 #define ESOS_TASK_WAIT_WHILE(cond) ESOS_TASK_WAIT_UNTIL(!(cond))
364 
375 #define ESOS_TASK_WAIT_TICKS(u32_duration) \
376 do { \
377  __pstSelf->u32_savedTick = esos_GetSystemTick(); \
378  __pstSelf->u32_waitLen = (u32_duration); \
379  ESOS_TASK_WAIT_UNTIL(__esos_hasTickDurationPassed(__pstSelf->u32_savedTick, __pstSelf->u32_waitLen) ); \
380 } while(0);
381 
384 /* helper function to spawn child tasks */
385 #define __ESOS_TASK_SPAWN(pstChild, fcnCallWithArgs) \
386  do { \
387  __ESOS_INIT_TASK((pstChild)); \
388  ESOS_TASK_WAIT_THREAD((fcnCallWithArgs)); \
389  } while(0)
390 
418 #define ESOS_TASK_WAIT_THREAD(pfnChild, ...) ESOS_TASK_WAIT_WHILE(ESOS_SCHEDULE_TASK(pfnChild,##__VA_ARGS__ ))
419 
435 #define ESOS_TASK_SPAWN_AND_WAIT(pstChild, pfnChild, ...) \
436  __ESOS_TASK_SPAWN((pstChild), (pfnChild)( (pstChild), ##__VA_ARGS__) )
437 
447 #define ESOS_ALLOCATE_CHILD_TASK(pstName) (pstName)=esos_GetFreeChildTaskStruct()
448 
449 /*
450  do { \
451  static ESOS_TASK_HANDLE pstName; \
452  pstName=esos_GetFreeChildTaskStruct(); \
453 } while(0)
454 */
455 
478 #define ESOS_TASK_SLEEP() \
479  do { \
480  __ESOS_SET_TASK_SLEEPING_FLAG(__pstSelf); \
481  ESOS_TASK_WAIT_WHILE(ESOS_IS_TASK_SLEEPING(__pstSelf)); \
482  } while(0)
483 
493 #define ESOS_TASK_RESTART() \
494  do { \
495  __pstSelf->flags = 0; \
496  __ESOS_INIT_TASK(__pstSelf); \
497  return ESOS_TASK_WAITING; \
498  } while(0)
499 
512 #define ESOS_TASK_EXIT() \
513  do { \
514  __pstSelf->flags = __TASK_ENDED_MASK; \
515  return ESOS_TASK_ENDED; \
516  } while(0)
517 
518 
533 #define ESOS_WAKE_TASK(TaskHandle) __ESOS_TASK_CLEAR_SLEEPING_FLAG((TaskHandle))
534 
546 #define ESOS_KILL_TASK(TaskHandle) __ESOS_TASK_SET_KILLED_FLAG((TaskHandle))
547 
548 
564 #define ESOS_RESTART_TASK(TaskHandle) \
565  do { \
566  (TaskHandle)->flags = 0; \
567  __ESOS_INIT_TASK((TaskHandle)); \
568 } while(0)
569 
570 
589 #define ESOS_TASK_YIELD() \
590  do { \
591  __ESOS_CLEAR_TASK_CALLED_FLAG(__pstSelf); \
592  ESOS_TASK_WAIT_UNTIL(__ESOS_IS_TASK_CALLED(__pstSelf)); \
593  } while(0)
594 
604 struct stSemaphore {
605  int16_t i16_cnt;
606 };
607 
608 
609 /* Not using these with this definition of semaphores */
610 // #define _SEMNAME_CAT( name, line ) name##line
611 // #define _SEMNAME( name, line ) _SEMNAME_CAT( name, line )
612 // #define SEMNAME( name ) _SEMNAME( name, __LINE__ )
613 
631 #define ESOS_SEMAPHORE(semaphoreName) struct stSemaphore (semaphoreName)
632 
649 #define ESOS_INIT_SEMAPHORE(semaphoreName, i16_val) (semaphoreName).i16_cnt=(i16_val)
650 
666 #define ESOS_TASK_WAIT_SEMAPHORE(semaphoreName, i16_val) \
667  do { \
668  ESOS_TASK_WAIT_UNTIL((semaphoreName).i16_cnt >= (i16_val) ); \
669  (semaphoreName).i16_cnt -= (i16_val); \
670  } while(0)
671 
686 #define ESOS_SIGNAL_SEMAPHORE(semaphoreName, i16_val) (semaphoreName).i16_cnt+=(i16_val)
687 
688 /* @} */
689 
690 
691 #endif /* __ESOS_TASK_H__ */
692 
695 /***********************************************************************
696  *
697  * MUCH OF THIS CODE IS BASED ON PROTOTHREADS BY ADAM DUNKELS
698  * AT THE SWEDISH INSTITUTE OF COMPUTER SCIENCE
699  *
700  ***********************************************************************
701  *
702  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
703  * All rights reserved.
704  *
705  * Redistribution and use in source and binary forms, with or without
706  * modification, are permitted provided that the following conditions
707  * are met:
708  * 1. Redistributions of source code must retain the above copyright
709  * notice, this list of conditions and the following disclaimer.
710  * 2. Redistributions in binary form must reproduce the above copyright
711  * notice, this list of conditions and the following disclaimer in the
712  * documentation and/or other materials provided with the distribution.
713  * 3. Neither the name of the Institute nor the names of its contributors
714  * may be used to endorse or promote products derived from this software
715  * without specific prior written permission.
716  *
717  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
718  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
719  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
720  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
721  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
722  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
723  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
724  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
725  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
726  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
727  * SUCH DAMAGE.
728  *
729  * This file is part of the Contiki operating system.
730  *
731  * Author: Adam Dunkels <adam@sics.se>
732  *
733  */
esos_mail.h
stSemaphore
Definition: esos_task.h:604
__stMAILBOX
Definition: esos_mail.h:60
ESOS_TASK_HANDLE
stTask
Definition: esos_task.h:54