EVE 1.0
uwork.h
Go to the documentation of this file.
1 #ifndef EVE_UWORK_H_INCLUDED
2 #define EVE_UWORK_H_INCLUDED
3 
4 /**********************************************************************/
5 /*
6  * Copyright (c) 2014-2015, Jetro AS
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modification,
10  * are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  * derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
21  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
23  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29  * OF SUCH DAMAGE.
30  *
31  * This file is part of the EVE platform.
32  */
33 
34 /**
35  * \file
36  * \brief Header file for the EVE microsecond-scale work scheduling.
37  *
38  * \author DT, Jetro AS
39  */ /******************************************************************/
40 
41 #include <stdbool.h>
42 #include <lib/dlist.h>
43 #include <core/work.h>
44 
45 /**
46  * \defgroup eve_uwork usec work scheduler
47  * \ingroup eve_scheduling
48  * \{
49  */
50 
51 /**********************************************************************/
52 /**
53  * Converts a time interval, given in number of microseconds, to the number of microticks.
54  *
55  * \param us duration of the time interval, microseconds
56  * \return number of microticks in the time interval
57  */
58 #define UWORK_USEC(us) (us)
59 
60 /**********************************************************************/
61 /**
62  * Initializes a microwork structure.
63  *
64  * The macro is used to initialize a microsecond-scale work (microwork) structure instance.
65  *
66  * \param x microwork structure
67  * \param callback microwork callback
68  *
69  * Usage:
70  * \code
71  static void MyWorkCallback(struct uwork_t *Work);
72  struct uwork_t MyWork = UWORK_INIT(MyWork, MyWorkCallback);
73  * \endcode
74  */
75 #define UWORK_INIT(x, callback) \
76  { \
77  .work.link.next = &(x).work.link, \
78  .work.link.prev = &(x).work.link, \
79  .work.cb = (work_cb_t) (callback), \
80  }
81 
82 /**********************************************************************/
83 /**
84  * Initializes a microwork structure. Typed version of \ref UWORK_INIT
85  */
86 #define UWORK_INIT_TYPED(x, callback) \
87  (struct uwork_t) UWORK_INIT(x, callback)
88 
89 /**********************************************************************/
90 /**
91  * Instantiates a microwork structure.
92  *
93  * The macro is used to instantiate a work structure.
94  *
95  * \param x name of the microwork structure
96  * \param callback the microwork callback
97  *
98  * Usage:
99  * \code
100  static void MyWorkCallback(struct uwork_t *Work);
101  DECLARE_UWORK(MyWork, MyWorkCallback);
102  * \endcode
103  */
104 #define DECLARE_UWORK(x, callback) \
105  struct uwork_t x = UWORK_INIT(x, callback)
106 
107 /* Forward declaration */
108 struct uwork_t;
109 
110 /**********************************************************************/
111 /**
112  * Microwork time type.
113  *
114  * MSB is used as a sign bit, so, the max interval for the microwork
115  * is 2^(32-1)-1 = 2147483647 us, or ~35 min. Please use OS etimer for
116  * longer intervals.
117  * Note that system holds high-frequency clock on if a microwork is scheduled.
118  */
119 typedef int32_t uwork_time_t;
120 
121 /**********************************************************************/
122 /**
123  * Microwork callback type.
124  *
125  * \param work pointer to the microwork structure
126  */
127 typedef void (*uwork_cb_t)(struct uwork_t *work);
128 
129 /**********************************************************************/
130 /**
131  * Microwork structure.
132  *
133  * EVE microsecond-scale work or `microwork` is a function with an associated data structure,
134  * which can be scheduled for execution at specified time in future. The function is executed
135  * at the hardware interrupt execution level.
136  *
137  * The structure represents the microwork instance.
138  *
139  * The structure must be instantiated in the RAM memory using
140  * one of \ref UWORK_INIT() or \ref DECLARE_UWORK().
141  */
142 struct uwork_t {
143  struct work_t work; /**< Underlaying work structure */
144  uwork_time_t at; /**< Point in time the microwork is scheduled for */
145 };
146 
147 /**********************************************************************/
148 /**
149  * Returns the current timestamp, which can be used as a time reference in struct uwork_t::at
150  *
151  * Usage:
152  * \code
153  MyWork.at = uwork_now() + UWORK_USEC(300);
154  uwork_schedule(&MyWork);
155  // The work is scheduled and will be executed 300 µs later.
156  * \endcode
157  *
158  * \return current timestamp in microsecond-scale `microticks`
159  */
160 uwork_time_t uwork_now(void);
161 
162 /**********************************************************************/
163 /**
164  * Schedules a microwork.
165  *
166  * The function schedules a microwork for execution at the specified point in time.
167  * The microwork will be executed at the hardware interrupt level. It is allowed to
168  * schedule a microwork in the past. In this case it is triggered for execution
169  * immediately.
170  *
171  * If two or more microworks are scheduled for the same tick, they will be executed
172  * in the same order as thay were scheduled. As hardware interrupt routines,
173  * microworks preempt software interrupts (that implies also works and milliworks)
174  * and OS processes. A microwork selv can be preempted by high-priority low-level BLE
175  * radio interrupts.
176  *
177  * If the microwork structure, pointed by the `work` parameter is already scheduled
178  * for execution, then it is re-scheduled at the new time.
179  *
180  * A scheduled microwork holds system at PM_LEVEL_CONSTLAT power level.
181  *
182  * \param work pointer to the microwork structure
183  */
184 void uwork_schedule(struct uwork_t *work);
185 
186 /**********************************************************************/
187 /**
188  * Cancels a scheduled microwork.
189  *
190  * The function cancels a previously scheduled work.
191  *
192  * \param work pointer to the microwork structure
193  */
194 void uwork_cancel(struct uwork_t *work);
195 
196 /**********************************************************************/
197 /**
198  * Checks if the microwork is scheduled and pending execution.
199  *
200  * The function checks if the microwork is scheduled for execution.
201  *
202  * \param work pointer to the microwork structure
203  * \return true if the microwork is scheduled for execution
204  * \return false if the microwork is not scheduled
205  * \return false if the microwork is being executed
206  */
207 static inline bool uwork_pending(struct uwork_t *work)
208 {
209  return !dlist_is_empty(&work->work.link);
210 }
211 
212 /**********************************************************************/
213 /**
214  * \internal
215  *
216  */ /******************************************************************/
217 
218 
219 /**********************************************************************/
220 /**
221  * Initializes the microwork framework
222  */
223 void uwork_init(void);
224 
225 /** \} eve_uwork */
226 
227 #endif /* EVE_UWORK_H_INCLUDED */
struct work_t work
Definition: uwork.h:143
struct dlist_t link
Definition: work.h:141
The code implements Dummy Headed Doubly Linked Circularlist (DHDLC) primitive.
void uwork_schedule(struct uwork_t *work)
int32_t uwork_time_t
Definition: uwork.h:108
static int dlist_is_empty(struct dlist_t *list)
Definition: dlist.h:125
void uwork_init(void)
void uwork_cancel(struct uwork_t *work)
Header file for the EVE work scheduling.
uwork_time_t at
Definition: uwork.h:144
static bool uwork_pending(struct uwork_t *work)
Definition: uwork.h:207
void(* uwork_cb_t)(struct uwork_t *work)
Definition: uwork.h:127
Definition: uwork.h:142
uwork_time_t uwork_now(void)
Definition: work.h:140