1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** ThreadX Component */
16 /** */
17 /** Timer */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define TX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "tx_api.h"
28 #include "tx_initialize.h"
29 #include "tx_thread.h"
30 #include "tx_timer.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _txe_timer_create PORTABLE C */
38 /* 6.1 */
39 /* AUTHOR */
40 /* */
41 /* William E. Lamie, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function checks for errors in the create application timer */
46 /* function call. */
47 /* */
48 /* INPUT */
49 /* */
50 /* timer_ptr Pointer to timer control block */
51 /* name_ptr Pointer to timer name */
52 /* expiration_function Application expiration function */
53 /* initial_ticks Initial expiration ticks */
54 /* reschedule_ticks Reschedule ticks */
55 /* auto_activate Automatic activation flag */
56 /* timer_control_block_size Size of timer control block */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* TX_TIMER_ERROR Invalid timer control block */
61 /* TX_TICK_ERROR Invalid initial expiration count */
62 /* TX_ACTIVATE_ERROR Invalid timer activation option */
63 /* TX_CALLER_ERROR Invalid caller of this function */
64 /* status Actual completion status */
65 /* */
66 /* CALLS */
67 /* */
68 /* _tx_thread_system_preempt_check Check for preemption */
69 /* _tx_timer_create Actual timer create function */
70 /* */
71 /* CALLED BY */
72 /* */
73 /* Application Code */
74 /* */
75 /* RELEASE HISTORY */
76 /* */
77 /* DATE NAME DESCRIPTION */
78 /* */
79 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
80 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
81 /* resulting in version 6.1 */
82 /* */
83 /**************************************************************************/
_txe_timer_create(TX_TIMER * timer_ptr,CHAR * name_ptr,VOID (* expiration_function)(ULONG id),ULONG expiration_input,ULONG initial_ticks,ULONG reschedule_ticks,UINT auto_activate,UINT timer_control_block_size)84 UINT _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr,
85 VOID (*expiration_function)(ULONG id), ULONG expiration_input,
86 ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size)
87 {
88
89 TX_INTERRUPT_SAVE_AREA
90
91 UINT status;
92 ULONG i;
93 TX_TIMER *next_timer;
94 #ifndef TX_TIMER_PROCESS_IN_ISR
95 TX_THREAD *thread_ptr;
96 #endif
97
98
99 /* Default status to success. */
100 status = TX_SUCCESS;
101
102 /* Check for a NULL timer pointer. */
103 if (timer_ptr == TX_NULL)
104 {
105
106 /* Timer pointer is invalid, return appropriate error code. */
107 status = TX_TIMER_ERROR;
108 }
109
110 /* Now check for invalid control block size. */
111 else if (timer_control_block_size != (sizeof(TX_TIMER)))
112 {
113
114 /* Timer pointer is invalid, return appropriate error code. */
115 status = TX_TIMER_ERROR;
116 }
117 else
118 {
119
120 /* Disable interrupts. */
121 TX_DISABLE
122
123 /* Increment the preempt disable flag. */
124 _tx_thread_preempt_disable++;
125
126 /* Restore interrupts. */
127 TX_RESTORE
128
129 /* Next see if it is already in the created list. */
130 next_timer = _tx_timer_created_ptr;
131 for (i = ((ULONG) 0); i < _tx_timer_created_count; i++)
132 {
133
134 /* Determine if this timer matches the current timer in the list. */
135 if (timer_ptr == next_timer)
136 {
137
138 break;
139 }
140 else
141 {
142
143 /* Move to next timer. */
144 next_timer = next_timer -> tx_timer_created_next;
145 }
146 }
147
148 /* Disable interrupts. */
149 TX_DISABLE
150
151 /* Decrement the preempt disable flag. */
152 _tx_thread_preempt_disable--;
153
154 /* Restore interrupts. */
155 TX_RESTORE
156
157 /* Check for preemption. */
158 _tx_thread_system_preempt_check();
159
160 /* At this point, check to see if there is a duplicate timer. */
161 if (timer_ptr == next_timer)
162 {
163
164 /* Timer is already created, return appropriate error code. */
165 status = TX_TIMER_ERROR;
166 }
167
168 /* Check for an illegal initial tick value. */
169 else if (initial_ticks == ((ULONG) 0))
170 {
171
172 /* Invalid initial tick value, return appropriate error code. */
173 status = TX_TICK_ERROR;
174 }
175 else
176 {
177
178 /* Check for an illegal activation. */
179 if (auto_activate != TX_AUTO_ACTIVATE)
180 {
181
182 /* And activation is not the other value. */
183 if (auto_activate != TX_NO_ACTIVATE)
184 {
185
186 /* Invalid activation selected, return appropriate error code. */
187 status = TX_ACTIVATE_ERROR;
188 }
189 }
190 }
191 }
192
193 /* Determine if everything is okay. */
194 if (status == TX_SUCCESS)
195 {
196
197 #ifndef TX_TIMER_PROCESS_IN_ISR
198
199 /* Pickup thread pointer. */
200 TX_THREAD_GET_CURRENT(thread_ptr)
201
202 /* Check for invalid caller of this function. First check for a calling thread. */
203 if (thread_ptr == &_tx_timer_thread)
204 {
205
206 /* Invalid caller of this function, return appropriate error code. */
207 status = TX_CALLER_ERROR;
208 }
209 #endif
210
211 /* Check for interrupt call. */
212 if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
213 {
214
215 /* Now, make sure the call is from an interrupt and not initialization. */
216 if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
217 {
218
219 /* Invalid caller of this function, return appropriate error code. */
220 status = TX_CALLER_ERROR;
221 }
222 }
223 }
224
225
226 /* Determine if everything is okay. */
227 if (status == TX_SUCCESS)
228 {
229
230 /* Call actual application timer create function. */
231 status = _tx_timer_create(timer_ptr, name_ptr, expiration_function, expiration_input,
232 initial_ticks, reschedule_ticks, auto_activate);
233 }
234
235 /* Return completion status. */
236 return(status);
237 }
238
239