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 #ifdef FX_FILEX_PRESENT
23
24 #define TX_SOURCE_CODE
25
26 #include "tx_api.h"
27 #include "tx_initialize.h"
28 #include "tx_mutex.h"
29 #include "tx_thread.h"
30 #include "tx_byte_pool.h"
31 #include "fx_api.h"
32 #include "txm_module.h"
33 #include "txm_module_manager_util.h"
34
35
36 /**************************************************************************/
37 /* */
38 /* FUNCTION RELEASE */
39 /* */
40 /* _txm_module_manager_file_load PORTABLE C */
41 /* 6.1 */
42 /* AUTHOR */
43 /* */
44 /* Scott Larson, Microsoft Corporation */
45 /* */
46 /* DESCRIPTION */
47 /* */
48 /* This function reads the module preamble, allocates memory for */
49 /* module code, loads the module code from the file, and calls */
50 /* _txm_module_manager_internal_load to load the data and prepare the */
51 /* module for execution. */
52 /* */
53 /* INPUT */
54 /* */
55 /* module_instance Module instance pointer */
56 /* module_name Name of module */
57 /* media_ptr FileX media pointer */
58 /* file_name Name of module binary file */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* status Completion status */
63 /* */
64 /* CALLS */
65 /* */
66 /* fx_file_close Close file */
67 /* fx_file_open Open file */
68 /* fx_file_read File read */
69 /* fx_file_seek File seek */
70 /* _tx_byte_allocate Allocate data area */
71 /* _txm_module_manager_internal_load Load data and prepare module for */
72 /* execution */
73 /* */
74 /* CALLED BY */
75 /* */
76 /* Application code */
77 /* */
78 /* RELEASE HISTORY */
79 /* */
80 /* DATE NAME DESCRIPTION */
81 /* */
82 /* 09-30-2020 Scott Larson Initial Version 6.1 */
83 /* */
84 /**************************************************************************/
_txm_module_manager_file_load(TXM_MODULE_INSTANCE * module_instance,CHAR * module_name,FX_MEDIA * media_ptr,CHAR * file_name)85 UINT _txm_module_manager_file_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, FX_MEDIA *media_ptr, CHAR *file_name)
86 {
87
88
89 TXM_MODULE_PREAMBLE *module_preamble;
90 FX_FILE module_file;
91 TXM_MODULE_PREAMBLE preamble;
92 ULONG code_start;
93 ULONG code_size;
94 ULONG code_alignment;
95 ULONG code_allocation_size;
96 CHAR *code_memory_ptr;
97 UCHAR *destination_ptr;
98 ULONG actual_size;
99 UINT status;
100
101
102 /* Attempt to open the file. */
103 status = fx_file_open(media_ptr, &module_file, file_name, FX_OPEN_FOR_READ);
104
105 /* Check the file open status. */
106 if (status == FX_SUCCESS)
107 {
108
109 /* Read the preamble of the module. */
110 status = fx_file_read(&module_file, (VOID *) &preamble, sizeof(TXM_MODULE_PREAMBLE), &actual_size);
111
112 /* Check the file read status. */
113 if (status == FX_SUCCESS)
114 {
115
116 /* Check the number of bytes read. */
117 if (actual_size == sizeof(TXM_MODULE_PREAMBLE))
118 {
119
120 /* Pickup the module's information. */
121 module_preamble = (TXM_MODULE_PREAMBLE *) &preamble;
122
123 /* Pickup the module code size. */
124 code_size = module_preamble -> txm_module_preamble_code_size;
125
126 /* Check for valid sizes. */
127 if (code_size != 0)
128 {
129
130 /* Initialize module control block to all zeros. */
131 TX_MEMSET(module_instance, 0, sizeof(TXM_MODULE_INSTANCE));
132
133 /* Get the amount of the bytes we need to allocate for the module's code as well as the required alignment. */
134 status = _txm_module_manager_util_code_allocation_size_and_alignment_get(module_preamble, &code_alignment, &code_allocation_size);
135 if (status == TX_SUCCESS)
136 {
137
138 /* Allocate code memory for the module. */
139 status = _tx_byte_allocate(&_txm_module_manager_byte_pool, (VOID **) &code_memory_ptr, code_allocation_size, TX_NO_WAIT);
140
141 /* Determine if the module's code memory allocation was successful. */
142 if (status == TX_SUCCESS)
143 {
144
145 /* Prepare to read the module code into memory. */
146 code_start = (ULONG) code_memory_ptr;
147 code_start = (code_start + (code_alignment - 1)) & ~(code_alignment - 1);
148 destination_ptr = (UCHAR *) code_start;
149
150 /* Seek back to the beginning of the file. */
151 status = fx_file_seek(&module_file, 0);
152 if (status == FX_SUCCESS)
153 {
154
155 /* Read the module into memory. */
156 status = fx_file_read(&module_file, (VOID *) destination_ptr, code_size, &actual_size);
157 if (status == FX_SUCCESS)
158 {
159
160 /* Check the actual size read. */
161 if (actual_size == code_size)
162 {
163
164 /* At this point, the module's instruction area is now in the RAM code area. */
165
166 /* Now load it in-place. */
167 status = _txm_module_manager_internal_load(module_instance, module_name, (VOID *) code_start,
168 code_size, code_memory_ptr, code_allocation_size);
169 if (status == TX_SUCCESS)
170 {
171
172 /* Close the file. */
173 fx_file_close(&module_file);
174
175 /* Return success. */
176 return(TX_SUCCESS);
177 }
178 }
179 else
180 {
181
182 /* Invalid number of bytes read. */
183 status = TXM_MODULE_FILEX_INVALID_BYTES_READ;
184 }
185 }
186 }
187
188 /* Release the memory. */
189 _tx_byte_release(code_memory_ptr);
190 }
191 }
192 }
193 else
194 {
195
196 /* Invalid module preamble. */
197 status = TXM_MODULE_INVALID;
198 }
199 }
200 else
201 {
202
203 /* Invalid number of bytes read. */
204 status = TXM_MODULE_FILEX_INVALID_BYTES_READ;
205 }
206 }
207
208 /* Close the file. */
209 fx_file_close(&module_file);
210 }
211
212 /* Return success. */
213 return(status);
214 }
215
216 #endif
217