1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
|
/**
******************************************************************************
* @file stm32_seq.h
* @author MCD Application Team
* @brief sequencer interface
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32_SEQ_H
#define STM32_SEQ_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stdint.h"
/** @defgroup SEQUENCER sequencer utilities
* @{
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup SEQUENCER_Exported_type SEQUENCER exported types
* @{
*/
/**
* @brief bit mapping of the task.
* this value is used to represent a list of task (each corresponds to a task).
*/
typedef uint32_t UTIL_SEQ_bm_t;
/**
* @brief lits of the warning of the sequencer.
* this value is used to indicate warning detected during the sequencer execution.
*/
typedef enum {
UTIL_SEQ_WARNING_INVALIDTASKID,
}UTIL_SEQ_WARNING;
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup SEQUENCER_Exported_const SEQUENCER exported constants
* @{
*/
/**
* @brief This provides a default value for unused parameter
*
*/
#define UTIL_SEQ_RFU 0
/**
* @brief Default value used to start the scheduling.
*
* This informs the sequencer that all tasks registered shall be considered
*
* @note
* This should be used in the application\n
* while(1)\n
* {\n
* UTIL_SEQ_Run( UTIL_SEQ_DEFAULT );\n
* }\n
*
*/
#define UTIL_SEQ_DEFAULT (~0U)
/**
* @}
*/
/* External variables --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/** @defgroup SEQUENCER_Exported_macro SEQUENCER exported macros
* @{
*/
/**
* @brief This macro can be used to define a task with one parameter
*
* @note this is an example of using this macro
*
* task prototype definition
* void FUNCTION_NAME(void *Instance)
* {
* uint8_t _instance = *(uint8_t*) Instance;
* }
*
* task declaration in the application for two instances
* const uint8_t instance1 = 1;
* const uint8_t instance2 = 2;
* UTIL_SEQ_TaskParamDef(FUNCTION_NAME, instance1)
* UTIL_SEQ_TaskParamDef(FUNCTION_NAME, instance2)
*
* task initialization
* UTIL_SEQ_RegTask(1 << 1, 0, UTIL_SEQ_TaskFunction(FUNCTION_NAME,instance2));
* UTIL_SEQ_RegTask(1 << 10, 0, UTIL_SEQ_TaskFunction(FUNCTION_NAME,instance3));
*
* Then no change on the management of the task within the application, the instance being managed within the overloaded function
*
*/
#define UTIL_SEQ_TaskParamDef(_FUNC_,_PARAM_VAL_) \
static void SEQ_FUNC_##_FUNC_##_PARAM_VAL_(void); \
static void SEQ_FUNC_##_FUNC_##_PARAM_VAL_(void) \
{ \
static void *SEQ_PARAM_##_FUNC_ = (void*)&_PARAM_VAL_;\
_FUNC_(SEQ_PARAM_##_FUNC_); \
}
/**
* @brief This macro is used to retrieve the function name of the task
*/
#define UTIL_SEQ_TaskFunction(_FUNC_,_PARAM_VAL_) SEQ_FUNC_##_FUNC_##_PARAM_VAL_
/**
* @}
*/
/* Exported functions ------------------------------------------------------- */
/** @defgroup SEQUENCER_Exported_function SEQUENCER exported functions
* @{
*/
/**
* @brief This function initializes the sequencer resources.
*
* @note It shall not be called from an ISR.
*
*/
void UTIL_SEQ_Init( void );
/**
* @brief This function un-initializes the sequencer resources.
*
* @note It shall not be called from an ISR
*
*/
void UTIL_SEQ_DeInit( void );
/**
* @brief This function is called by the sequencer in critical section (PRIMASK bit) when
* - there are no more tasks to be executed
* AND
* - there are no pending event or the pending event is still not set
* @note The application should enter low power mode in this function
* When this function is not implemented by the application, the sequencer keeps running a while loop (RUN MODE).
* It shall be called only by the sequencer.
*
*/
void UTIL_SEQ_Idle( void );
/**
* @brief This function is called by the sequencer outside critical section just before calling UTIL_SEQ_Idle( )
* UTIL_SEQ_PreIdle() is considered as the last task executed before calling UTIL_SEQ_Idle( )
* In case a task or an event is set from an interrupt handler just after UTIL_SEQ_PreIdle() is called,
* UTIL_SEQ_Idle() will not be called.
*
* @note It shall be called only by the sequencer.
*
*/
void UTIL_SEQ_PreIdle( void );
/**
* @brief This function is called by the sequencer outside critical section either
* - after calling UTIL_SEQ_Idle( )
* OR
* - after calling UTIL_SEQ_PreIdle( ) without call to UTIL_SEQ_Idle() due to an incoming task set or event
* requested after UTIL_SEQ_PreIdle() has been called.
*
* @note UTIL_SEQ_PostIdle() is always called if UTIL_SEQ_PreIdle() has been called and never called otherwise.
* It shall be called only by the sequencer.
*
*/
void UTIL_SEQ_PostIdle( void );
/**
* @brief This function requests the sequencer to execute all pending tasks using round robin mechanism.
* When no task are pending, it calls UTIL_SEQ_Idle();
* This function should be called in a while loop in the application
*
* @param Mask_bm list of task (bit mapping) that is be kept in the sequencer list.
*
* @note It shall not be called from an ISR.
* @note The construction of the task must take into account the fact that there is no counting / protection
* on the activation of the task. Thus, when the task is running, it must perform all the operations
* in progress programmed before its call or manage a reprogramming of the task.
*
*/
void UTIL_SEQ_Run( UTIL_SEQ_bm_t Mask_bm );
/**
* @brief This function registers a task in the sequencer.
*
* @param TaskId_bm The Id of the task
* @param Flags Flags are reserved param for future use
* @param Task Reference of the function to be executed
*
* @note It may be called from an ISR.
*
*/
void UTIL_SEQ_RegTask( UTIL_SEQ_bm_t TaskId_bm, uint32_t Flags, void (*Task)( void ) );
/**
* @brief This function checks if a task is registered
*
* @param TaskId_bm The Id of the task
* It shall be (1<<task_id) where task_id is the number assigned when the task has been registered
* @retval 0 if not 1 if true
*/
uint32_t UTIL_SEQ_IsRegisteredTask( UTIL_SEQ_bm_t TaskId_bm );
/**
* @brief This function requests a task to be executed
*
* @param TaskId_bm The Id of the task
* It shall be (1<<task_id) where task_id is the number assigned when the task has been registered
* @param Task_Prio The priority of the task
* It shall a number from 0 (high priority) to 31 (low priority)
* The priority is checked each time the sequencer needs to select a new task to execute
* It does not permit to preempt a running task with lower priority
*
* @note It may be called from an ISR
*
*/
void UTIL_SEQ_SetTask( UTIL_SEQ_bm_t TaskId_bm, uint32_t Task_Prio );
/**
* @brief This function checks if a task could be scheduled.
*
* @param TaskId_bm The Id of the task
* It shall be (1<<task_id) where task_id is the number assigned when the task has been registered
* @retval 0 if not 1 if true
*
* @note It may be called from an ISR.
*
*/
uint32_t UTIL_SEQ_IsSchedulableTask( UTIL_SEQ_bm_t TaskId_bm);
/**
* @brief This function prevents a task to be called by the sequencer even when set with UTIL_SEQ_SetTask()
* By default, all tasks are executed by the sequencer when set with UTIL_SEQ_SetTask()
* When a task is paused, it is moved out from the sequencer list
*
* @param TaskId_bm The Id of the task
* It shall be (1<<task_id) where task_id is the number assigned when the task has been registered
*
* @note It may be called from an ISR.
*
*/
void UTIL_SEQ_PauseTask( UTIL_SEQ_bm_t TaskId_bm );
/**
* @brief This function allows to know if the task has been put in pause.
* By default, all tasks are executed by the sequencer when set with UTIL_SEQ_SetTask()
* The exit of the pause shall be done by the function UTIL_SEQ_ResumeTask.
*
* @param TaskId_bm The Id of the task
* It shall be (1<<task_id) where task_id is the number assigned when the task has been registered
*
* @note It may be called from an ISR.
*
*/
uint32_t UTIL_SEQ_IsPauseTask( UTIL_SEQ_bm_t TaskId_bm );
/**
* @brief This function allows again a task to be called by the sequencer if set with UTIL_SEQ_SetTask()
* This is used in relation with UTIL_SEQ_PauseTask()
*
* @param TaskId_bm The Id of the task
* It shall be (1<<task_id) where task_id is the number assigned when the task has been registered
*
* @note It may be called from an ISR.
*
*/
void UTIL_SEQ_ResumeTask( UTIL_SEQ_bm_t TaskId_bm );
/**
* @brief This function sets an event that is waited with UTIL_SEQ_WaitEvt()
*
* @param EvtId_bm event id bit mask
*
* @note An event shall be a 32 bit mapping where only 1 bit is set
* It may be called from an ISR.
*
*/
void UTIL_SEQ_SetEvt( UTIL_SEQ_bm_t EvtId_bm );
/**
* @brief This function may be used to clear the event before calling UTIL_SEQ_WaitEvt()
* This API may be useful when the UTIL_SEQ_SetEvt() is called several time to notify the same event.
* Due to Software Architecture where the timings are hard to control, this may be an unwanted case.
*
* @param EvtId_bm event id bm
* It shall be a bit mapping where only 1 bit is set
*
* @note It may be called from an ISR.
*
*/
void UTIL_SEQ_ClrEvt( UTIL_SEQ_bm_t EvtId_bm );
/**
* @brief This function waits for a specific event to be set. The sequencer loops UTIL_SEQ_EvtIdle() until the event is set
* When called recursively, it acts as a First in / Last out mechanism. The sequencer waits for the
* last event requested to be set even though one of the already requested event has been set.
*
* @param EvtId_bm event id bit mask
* It shall be a bit mapping where only 1 bit is set
*
* @note It shall not be called from an ISR.
* @note The construction of the task must take into account the fact that there is no counting / protection on the
* event. Thus, when the task is running, it must perform all the operations in progress programmed before its call
* or manage a reprogramming of the task.
*/
void UTIL_SEQ_WaitEvt( UTIL_SEQ_bm_t EvtId_bm );
/**
* @brief This function returns whether the waited event is pending or not
* It is useful only when the UTIL_SEQ_EvtIdle() is overloaded by the application. In that case, when the low
* power mode needs to be executed, the application shall first check whether the waited event is pending
* or not. Both the event checking and the low power mode processing should be done in critical section
*
* @retval 0 when the waited event is not there or the evt_id when the waited event is pending
*
* @note It may be called from an ISR.
*
*/
UTIL_SEQ_bm_t UTIL_SEQ_IsEvtPend( void );
/**
* @brief This function loops until the waited event is set
* @param TaskId_bm The task id that is currently running. When task_id_bm = 0, it means UTIL_SEQ_WaitEvt( )
* has been called outside a registered task (ie at startup before UTIL_SEQ_Run( ) has been called
* @param EvtWaited_bm The event id that is waited.
*
* @note When not implemented by the application, it calls UTIL_SEQ_Run(~TaskId_bm) which means the waited
* task is suspended until the waited event and the other tasks are running or the application enter
* low power mode.
* Else the user can redefine his own function for example call sequencer UTIL_SEQ_Run(0) to suspend all
* the task and let the sequencer enter the low power mode.
* It shall be called only by the sequencer.
*
*/
void UTIL_SEQ_EvtIdle( UTIL_SEQ_bm_t TaskId_bm, UTIL_SEQ_bm_t EvtWaited_bm );
/**
* @brief This function is call before a task execution
* @param TaskId The task id.
*
* @note the function is provided to help the debug and
* the default implementation does nothing
*
*/
void UTIL_SEQ_PreTask( uint32_t TaskId );
/**
* @brief This function is called after a task execution
* @param TaskId The task id.
*
* @note the function is provided to help the debug and
* the default implementation does nothing
*
*/
void UTIL_SEQ_PostTask( uint32_t TaskId );
/**
* @brief This function is called when a warning is detected
* @param WarningId The warning id.
*
* @note the function is provided to help the debug and
* the default implementation does nothing
*/
void UTIL_SEQ_CatchWarning(UTIL_SEQ_WARNING WarningId);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__STM32_SEQ_H */
|