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 /**   Module Manager                                                      */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define TX_SOURCE_CODE
24 
25 #include "tx_api.h"
26 #include "tx_trace.h"
27 #include "tx_thread.h"
28 #include "txm_module.h"
29 
30 /**************************************************************************/
31 /*                                                                        */
32 /*  FUNCTION                                               RELEASE        */
33 /*                                                                        */
34 /*    _txm_module_manager_thread_reset                    PORTABLE C      */
35 /*                                                           6.1          */
36 /*  AUTHOR                                                                */
37 /*                                                                        */
38 /*    Scott Larson, Microsoft Corporation                                 */
39 /*                                                                        */
40 /*  DESCRIPTION                                                           */
41 /*                                                                        */
42 /*    This function prepares the thread to run again from the entry       */
43 /*    point specified during thread creation. The application must        */
44 /*    call tx_thread_resume after this call completes for the thread      */
45 /*    to actually run.                                                    */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    thread_ptr                        Pointer to thread to reset        */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    status                            Service return status             */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    _txm_module_manager_thread_stack_build    Build initial thread      */
58 /*                                                stack                   */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    _txm_module_manager_kernel_dispatch   Kernel dispatch function      */
63 /*                                                                        */
64 /*  RELEASE HISTORY                                                       */
65 /*                                                                        */
66 /*    DATE              NAME                      DESCRIPTION             */
67 /*                                                                        */
68 /*  09-30-2020      Scott Larson            Initial Version 6.1           */
69 /*                                                                        */
70 /**************************************************************************/
_txm_module_manager_thread_reset(TX_THREAD * thread_ptr)71 UINT  _txm_module_manager_thread_reset(TX_THREAD *thread_ptr)
72 {
73 
74 TX_INTERRUPT_SAVE_AREA
75 
76 TX_THREAD       *current_thread;
77 UINT            status;
78 TXM_MODULE_INSTANCE             *module_instance;
79 TXM_MODULE_THREAD_ENTRY_INFO    *thread_entry_info;
80 
81     /* Default a successful completion status.  */
82     status =  TX_SUCCESS;
83 
84     /* Disable interrupts.  */
85     TX_DISABLE
86 
87     /* Pickup thread pointer.  */
88     TX_THREAD_GET_CURRENT(current_thread)
89 
90     /* Check for a call from the current thread, which is not allowed!  */
91     if (current_thread == thread_ptr)
92     {
93 
94         /* Restore interrupts.  */
95         TX_RESTORE
96 
97         /* Thread not completed or terminated - return an error!  */
98         status =  TX_NOT_DONE;
99     }
100     else
101     {
102 
103         /* Check for proper status of this thread to reset.  */
104         if (thread_ptr -> tx_thread_state != TX_COMPLETED)
105         {
106 
107             /* Now check for terminated state.  */
108             if (thread_ptr -> tx_thread_state != TX_TERMINATED)
109             {
110 
111                 /* Thread not completed or terminated - return an error!  */
112                 status =  TX_NOT_DONE;
113             }
114         }
115     }
116 
117     /* Is the request valid?  */
118     if (status == TX_SUCCESS)
119     {
120 
121         /* Modify the thread status to prevent additional reset calls.  */
122         thread_ptr -> tx_thread_state =  TX_NOT_DONE;
123 
124         /* Get the module instance.  */
125         module_instance =  thread_ptr -> tx_thread_module_instance_ptr;
126 
127         /* Execute Port-Specific completion processing. If needed, it is typically defined in txm_module_port.h.  */
128         TXM_MODULE_MANAGER_THREAD_RESET_PORT_COMPLETION(thread_ptr, module_instance)
129 
130         /* Restore interrupts.  */
131         TX_RESTORE
132 
133 #ifndef TX_DISABLE_STACK_FILLING
134 
135         /* Set the thread stack to a pattern prior to creating the initial
136            stack frame.  This pattern is used by the stack checking routines
137            to see how much has been used.  */
138         TX_MEMSET(thread_ptr -> tx_thread_stack_start, ((UCHAR) TX_STACK_FILL), thread_ptr -> tx_thread_stack_size);
139 #endif
140 
141         /* Setup pointer to the thread entry information structure, which will live at the top of each
142            module thread's stack. This will allow the module thread entry function to avoid direct
143            access to the actual thread control block.  */
144         thread_entry_info =  (TXM_MODULE_THREAD_ENTRY_INFO *) (((UCHAR *) thread_ptr -> tx_thread_stack_end) + (2*sizeof(ULONG)) + 1);
145         thread_entry_info =  (TXM_MODULE_THREAD_ENTRY_INFO *) (((ALIGN_TYPE)(thread_entry_info)) & (~0x3));
146 
147         /* Place the thread entry information pointer in the thread control block so it can be picked up
148            in the following stack build function. This is supplied to the module's shell entry function
149            to avoid direct access to the actual thread control block. Note that this is overwritten
150            with the actual stack pointer at the end of stack build.  */
151         thread_ptr -> tx_thread_stack_ptr =  (VOID *) thread_entry_info;
152 
153         /* Call the target specific stack frame building routine to build the
154            thread's initial stack and to setup the actual stack pointer in the
155            control block.  */
156         _txm_module_manager_thread_stack_build(thread_ptr, module_instance -> txm_module_instance_shell_entry_function);
157 
158         /* Disable interrupts.  */
159         TX_DISABLE
160 
161         /* Finally, move into a suspended state to allow for the thread to be resumed.  */
162         thread_ptr -> tx_thread_state =  TX_SUSPENDED;
163 
164         /* If trace is enabled, insert this event into the trace buffer.  */
165         TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_RESET, thread_ptr, thread_ptr -> tx_thread_state, 0, 0, TX_TRACE_THREAD_EVENTS)
166 
167         /* Log this kernel call.  */
168         TX_EL_THREAD_RESET_INSERT
169 
170         /* Log the thread status change.  */
171         TX_EL_THREAD_STATUS_CHANGE_INSERT(thread_ptr, TX_SUSPENDED)
172     }
173 
174     /* Restore interrupts.  */
175     TX_RESTORE
176 
177     /* Return completion status to caller.  */
178     return(status);
179 }
180 
181