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 /** Initialize */
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 #if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)
33 extern VOID _tx_execution_initialize(VOID);
34 #endif
35
36 /* Define any port-specific scheduling data structures. */
37
38 TX_PORT_SPECIFIC_DATA
39
40
41 #ifdef TX_SAFETY_CRITICAL
42 TX_SAFETY_CRITICAL_EXCEPTION_HANDLER
43 #endif
44
45
46 /**************************************************************************/
47 /* */
48 /* FUNCTION RELEASE */
49 /* */
50 /* _tx_initialize_kernel_enter PORTABLE C */
51 /* 6.3.0 */
52 /* AUTHOR */
53 /* */
54 /* William E. Lamie, Microsoft Corporation */
55 /* */
56 /* DESCRIPTION */
57 /* */
58 /* This function is the first ThreadX function called during */
59 /* initialization. It is called from the application's "main()" */
60 /* function. It is important to note that this routine never */
61 /* returns. The processing of this function is relatively simple: */
62 /* it calls several ThreadX initialization functions (if needed), */
63 /* calls the application define function, and then invokes the */
64 /* scheduler. */
65 /* */
66 /* INPUT */
67 /* */
68 /* None */
69 /* */
70 /* OUTPUT */
71 /* */
72 /* None */
73 /* */
74 /* CALLS */
75 /* */
76 /* _tx_initialize_low_level Low-level initialization */
77 /* _tx_initialize_high_level High-level initialization */
78 /* tx_application_define Application define function */
79 /* _tx_thread_scheduler ThreadX scheduling loop */
80 /* */
81 /* CALLED BY */
82 /* */
83 /* main Application main program */
84 /* */
85 /* RELEASE HISTORY */
86 /* */
87 /* DATE NAME DESCRIPTION */
88 /* */
89 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
90 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
91 /* resulting in version 6.1 */
92 /* 04-25-2022 Scott Larson Modified comment(s), */
93 /* added EPK initialization, */
94 /* resulting in version 6.1.11 */
95 /* 10-31-2023 Xiuwen Cai Modified comment(s), */
96 /* added random generator */
97 /* initialization, */
98 /* resulting in version 6.3.0 */
99 /* */
100 /**************************************************************************/
_tx_initialize_kernel_enter(VOID)101 VOID _tx_initialize_kernel_enter(VOID)
102 {
103
104 /* Determine if the compiler has pre-initialized ThreadX. */
105 if (_tx_thread_system_state != TX_INITIALIZE_ALMOST_DONE)
106 {
107
108 /* No, the initialization still needs to take place. */
109
110 /* Ensure that the system state variable is set to indicate
111 initialization is in progress. Note that this variable is
112 later used to represent interrupt nesting. */
113 _tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS;
114
115 /* Call any port specific preprocessing. */
116 TX_PORT_SPECIFIC_PRE_INITIALIZATION
117
118 /* Invoke the low-level initialization to handle all processor specific
119 initialization issues. */
120 _tx_initialize_low_level();
121
122 /* Invoke the high-level initialization to exercise all of the
123 ThreadX components and the application's initialization
124 function. */
125 _tx_initialize_high_level();
126
127 /* Call any port specific post-processing. */
128 TX_PORT_SPECIFIC_POST_INITIALIZATION
129 }
130
131 /* Optional processing extension. */
132 TX_INITIALIZE_KERNEL_ENTER_EXTENSION
133
134 /* Ensure that the system state variable is set to indicate
135 initialization is in progress. Note that this variable is
136 later used to represent interrupt nesting. */
137 _tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS;
138
139 /* Optional random number generator initialization. */
140 TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION
141
142 /* Call the application provided initialization function. Pass the
143 first available memory address to it. */
144 tx_application_define(_tx_initialize_unused_memory);
145
146 /* Set the system state in preparation for entering the thread
147 scheduler. */
148 _tx_thread_system_state = TX_INITIALIZE_IS_FINISHED;
149
150 /* Call any port specific pre-scheduler processing. */
151 TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
152
153 #if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)
154 /* Initialize Execution Profile Kit. */
155 _tx_execution_initialize();
156 #endif
157
158 /* Enter the scheduling loop to start executing threads! */
159 _tx_thread_schedule();
160
161 #ifdef TX_SAFETY_CRITICAL
162
163 /* If we ever get here, raise safety critical exception. */
164 TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
165 #endif
166 }
167
168