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