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