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