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 /** Port Specific */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 23 /**************************************************************************/ 24 /* */ 25 /* PORT SPECIFIC C INFORMATION RELEASE */ 26 /* */ 27 /* tx_port.h Win32/Visual */ 28 /* 6.1 */ 29 /* */ 30 /* AUTHOR */ 31 /* */ 32 /* William E. Lamie, Microsoft Corporation */ 33 /* */ 34 /* DESCRIPTION */ 35 /* */ 36 /* This file contains data type definitions that make the ThreadX */ 37 /* real-time kernel function identically on a variety of different */ 38 /* processor architectures. For example, the size or number of bits */ 39 /* in an "int" data type vary between microprocessor architectures and */ 40 /* even C compilers for the same microprocessor. ThreadX does not */ 41 /* directly use native C data types. Instead, ThreadX creates its */ 42 /* own special types that can be mapped to actual data types by this */ 43 /* file to guarantee consistency in the interface and functionality. */ 44 /* */ 45 /* RELEASE HISTORY */ 46 /* */ 47 /* DATE NAME DESCRIPTION */ 48 /* */ 49 /* 09-30-2020 William E. Lamie Initial Version 6.1 */ 50 /* */ 51 /**************************************************************************/ 52 53 #ifndef TX_PORT_H 54 #define TX_PORT_H 55 56 57 /* Determine if the optional ThreadX user define file should be used. */ 58 59 #ifdef TX_INCLUDE_USER_DEFINE_FILE 60 61 62 /* Yes, include the user defines in tx_user.h. The defines in this file may 63 alternately be defined on the command line. */ 64 65 #include "tx_user.h" 66 #endif 67 68 69 /* Define compiler library include files. */ 70 71 #include <stdlib.h> 72 #include <string.h> 73 74 75 /* Define performance metric symbols. */ 76 77 #ifndef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO 78 #define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO 79 #endif 80 81 #ifndef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO 82 #define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO 83 #endif 84 85 #ifndef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO 86 #define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO 87 #endif 88 89 #ifndef TX_MUTEX_ENABLE_PERFORMANCE_INFO 90 #define TX_MUTEX_ENABLE_PERFORMANCE_INFO 91 #endif 92 93 #ifndef TX_QUEUE_ENABLE_PERFORMANCE_INFO 94 #define TX_QUEUE_ENABLE_PERFORMANCE_INFO 95 #endif 96 97 #ifndef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO 98 #define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO 99 #endif 100 101 #ifndef TX_THREAD_ENABLE_PERFORMANCE_INFO 102 #define TX_THREAD_ENABLE_PERFORMANCE_INFO 103 #endif 104 105 #ifndef TX_TIMER_ENABLE_PERFORMANCE_INFO 106 #define TX_TIMER_ENABLE_PERFORMANCE_INFO 107 #endif 108 109 110 /* Enable trace info. */ 111 112 #ifndef TX_ENABLE_EVENT_TRACE 113 #define TX_ENABLE_EVENT_TRACE 114 #endif 115 116 117 /* Define ThreadX basic types for this port. */ 118 119 #define VOID void 120 typedef char CHAR; 121 typedef unsigned char UCHAR; 122 typedef int INT; 123 typedef unsigned int UINT; 124 typedef long LONG; 125 typedef unsigned long ULONG; 126 typedef short SHORT; 127 typedef unsigned short USHORT; 128 129 130 /* Add Win32 debug insert prototype. */ 131 132 void _tx_win32_debug_entry_insert(char *action, char *file, unsigned long line); 133 134 #ifndef TX_WIN32_DEBUG_ENABLE 135 136 /* If Win32 debug is not enabled, turn logging into white-space. */ 137 138 #define _tx_win32_debug_entry_insert(a, b, c) 139 140 #endif 141 142 143 144 /* Define the TX_MEMSET macro to remove library reference. */ 145 146 #define TX_MEMSET(a,b,c) { \ 147 UCHAR *ptr; \ 148 UCHAR value; \ 149 UINT i, size; \ 150 ptr = (UCHAR *) ((VOID *) a); \ 151 value = (UCHAR) b; \ 152 size = (UINT) c; \ 153 for (i = 0; i < size; i++) \ 154 { \ 155 *ptr++ = value; \ 156 } \ 157 } 158 159 160 /* Include windows include file. */ 161 162 #include <windows.h> 163 164 165 /* Define the priority levels for ThreadX. Legal values range 166 from 32 to 1024 and MUST be evenly divisible by 32. */ 167 168 #ifndef TX_MAX_PRIORITIES 169 #define TX_MAX_PRIORITIES 32 170 #endif 171 172 173 /* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during 174 thread creation is less than this value, the thread create call will return an error. */ 175 176 #ifndef TX_MINIMUM_STACK 177 #define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ 178 #endif 179 180 181 /* Define the system timer thread's default stack size and priority. These are only applicable 182 if TX_TIMER_PROCESS_IN_ISR is not defined. */ 183 184 #ifndef TX_TIMER_THREAD_STACK_SIZE 185 #define TX_TIMER_THREAD_STACK_SIZE 400 /* Default timer thread stack size - Not used in Win32 port! */ 186 #endif 187 188 #ifndef TX_TIMER_THREAD_PRIORITY 189 #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ 190 #endif 191 192 193 /* Define various constants for the ThreadX port. */ 194 195 #define TX_INT_DISABLE 1 /* Disable interrupts */ 196 #define TX_INT_ENABLE 0 /* Enable interrupts */ 197 198 199 /* Define the clock source for trace event entry time stamp. The following two item are port specific. 200 For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock 201 source constants would be: 202 203 #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) 204 #define TX_TRACE_TIME_MASK 0x0000FFFFUL 205 206 */ 207 208 #ifndef TX_TRACE_TIME_SOURCE 209 #define TX_TRACE_TIME_SOURCE ((ULONG) (_tx_win32_time_stamp.LowPart)); 210 #endif 211 #ifndef TX_TRACE_TIME_MASK 212 #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL 213 #endif 214 215 216 /* Define the port-specific trace extension to pickup the Windows timer. */ 217 218 #define TX_TRACE_PORT_EXTENSION QueryPerformanceCounter((LARGE_INTEGER *)&_tx_win32_time_stamp); 219 220 221 /* Define the port specific options for the _tx_build_options variable. This variable indicates 222 how the ThreadX library was built. */ 223 224 #define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 225 226 227 /* Define the in-line initialization constant so that modules with in-line 228 initialization capabilities can prevent their initialization from being 229 a function call. */ 230 231 #define TX_INLINE_INITIALIZATION 232 233 234 /* Define the Win32-specific initialization code that is expanded in the generic source. */ 235 236 void _tx_initialize_start_interrupts(void); 237 238 #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION _tx_initialize_start_interrupts(); 239 240 241 /* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is 242 disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack 243 checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING 244 define is negated, thereby forcing the stack fill which is necessary for the stack checking 245 logic. */ 246 247 #ifdef TX_ENABLE_STACK_CHECKING 248 #undef TX_DISABLE_STACK_FILLING 249 #endif 250 251 252 /* Define the TX_THREAD control block extensions for this port. The main reason 253 for the multiple macros is so that backward compatibility can be maintained with 254 existing ThreadX kernel awareness modules. */ 255 256 #define TX_THREAD_EXTENSION_0 HANDLE tx_thread_win32_thread_handle; \ 257 DWORD tx_thread_win32_thread_id; \ 258 HANDLE tx_thread_win32_thread_run_semaphore; \ 259 UINT tx_thread_win32_suspension_type; \ 260 UINT tx_thread_win32_int_disabled_flag; 261 #define TX_THREAD_EXTENSION_1 262 #define TX_THREAD_EXTENSION_2 263 #define TX_THREAD_EXTENSION_3 264 265 266 /* Define the port extensions of the remaining ThreadX objects. */ 267 268 #define TX_BLOCK_POOL_EXTENSION 269 #define TX_BYTE_POOL_EXTENSION 270 #define TX_EVENT_FLAGS_GROUP_EXTENSION 271 #define TX_MUTEX_EXTENSION 272 #define TX_QUEUE_EXTENSION 273 #define TX_SEMAPHORE_EXTENSION 274 #define TX_TIMER_EXTENSION 275 276 277 /* Define the user extension field of the thread control block. Nothing 278 additional is needed for this port so it is defined as white space. */ 279 280 #ifndef TX_THREAD_USER_EXTENSION 281 #define TX_THREAD_USER_EXTENSION 282 #endif 283 284 285 /* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, 286 tx_thread_shell_entry, and tx_thread_terminate. */ 287 288 289 #define TX_THREAD_CREATE_EXTENSION(thread_ptr) 290 #define TX_THREAD_DELETE_EXTENSION(thread_ptr) 291 #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) 292 #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) 293 294 295 /* Define the ThreadX object creation extensions for the remaining objects. */ 296 297 #define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) 298 #define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) 299 #define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) 300 #define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) 301 #define TX_QUEUE_CREATE_EXTENSION(queue_ptr) 302 #define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) 303 #define TX_TIMER_CREATE_EXTENSION(timer_ptr) 304 305 306 /* Define the ThreadX object deletion extensions for the remaining objects. */ 307 308 #define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) 309 #define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) 310 #define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) 311 #define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) 312 #define TX_QUEUE_DELETE_EXTENSION(queue_ptr) 313 #define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) 314 #define TX_TIMER_DELETE_EXTENSION(timer_ptr) 315 316 317 struct TX_THREAD_STRUCT; 318 319 /* Define the Win32 critical section data structure. */ 320 321 typedef struct TX_WIN32_CRITICAL_SECTION_STRUCT 322 { 323 HANDLE tx_win32_critical_section_mutex_handle; 324 DWORD tx_win32_critical_section_owner; 325 ULONG tx_win32_critical_section_nested_count; 326 } TX_WIN32_CRITICAL_SECTION; 327 328 329 /* Define Win32-specific critical section APIs. */ 330 331 void _tx_win32_critical_section_obtain(TX_WIN32_CRITICAL_SECTION *critical_section); 332 void _tx_win32_critical_section_release(TX_WIN32_CRITICAL_SECTION *critical_section); 333 void _tx_win32_critical_section_release_all(TX_WIN32_CRITICAL_SECTION *critical_section); 334 335 336 /* Define post completion processing for tx_thread_delete, so that the Win32 thread resources are properly removed. */ 337 338 #define TX_THREAD_DELETE_PORT_COMPLETION(thread_ptr) \ 339 { \ 340 BOOL win32_status; \ 341 DWORD exitcode; \ 342 HANDLE threadrunsemaphore; \ 343 HANDLE threadhandle; \ 344 threadhandle = thread_ptr -> tx_thread_win32_thread_handle; \ 345 threadrunsemaphore = thread_ptr -> tx_thread_win32_thread_run_semaphore; \ 346 _tx_thread_interrupt_restore(tx_saved_posture); \ 347 do \ 348 { \ 349 win32_status = GetExitCodeThread(threadhandle, &exitcode); \ 350 if ((win32_status) && (exitcode != STILL_ACTIVE)) \ 351 { \ 352 break; \ 353 } \ 354 ResumeThread(threadhandle); \ 355 ReleaseSemaphore(threadrunsemaphore, 1, NULL); \ 356 Sleep(1); \ 357 } while (1); \ 358 CloseHandle(threadhandle); \ 359 tx_saved_posture = _tx_thread_interrupt_disable(); \ 360 } 361 362 363 /* Define post completion processing for tx_thread_reset, so that the Win32 thread resources are properly removed. */ 364 365 #define TX_THREAD_RESET_PORT_COMPLETION(thread_ptr) \ 366 { \ 367 BOOL win32_status; \ 368 DWORD exitcode; \ 369 HANDLE threadrunsemaphore; \ 370 HANDLE threadhandle; \ 371 threadhandle = thread_ptr -> tx_thread_win32_thread_handle; \ 372 threadrunsemaphore = thread_ptr -> tx_thread_win32_thread_run_semaphore; \ 373 _tx_thread_interrupt_restore(tx_saved_posture); \ 374 do \ 375 { \ 376 win32_status = GetExitCodeThread(threadhandle, &exitcode); \ 377 if ((win32_status) && (exitcode != STILL_ACTIVE)) \ 378 { \ 379 break; \ 380 } \ 381 ResumeThread(threadhandle); \ 382 ReleaseSemaphore(threadrunsemaphore, 1, NULL); \ 383 Sleep(1); \ 384 } while (1); \ 385 CloseHandle(threadhandle); \ 386 tx_saved_posture = _tx_thread_interrupt_disable(); \ 387 } 388 389 390 /* Define ThreadX interrupt lockout and restore macros for protection on 391 access of critical kernel information. The restore interrupt macro must 392 restore the interrupt posture of the running thread prior to the value 393 present prior to the disable macro. In most cases, the save area macro 394 is used to define a local function save area for the disable and restore 395 macros. */ 396 397 UINT _tx_thread_interrupt_disable(void); 398 VOID _tx_thread_interrupt_restore(UINT previous_posture); 399 400 #define TX_INTERRUPT_SAVE_AREA UINT tx_saved_posture; 401 402 #define TX_DISABLE tx_saved_posture = _tx_thread_interrupt_disable(); 403 404 #define TX_RESTORE _tx_thread_interrupt_restore(tx_saved_posture); 405 406 407 /* Define the interrupt lockout macros for each ThreadX object. */ 408 409 #define TX_BLOCK_POOL_DISABLE TX_DISABLE 410 #define TX_BYTE_POOL_DISABLE TX_DISABLE 411 #define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE 412 #define TX_MUTEX_DISABLE TX_DISABLE 413 #define TX_QUEUE_DISABLE TX_DISABLE 414 #define TX_SEMAPHORE_DISABLE TX_DISABLE 415 416 417 /* Define the version ID of ThreadX. This may be utilized by the application. */ 418 419 #ifdef TX_THREAD_INIT 420 CHAR _tx_version_id[] = 421 "Copyright (c) 2024 Microsoft Corporation. * ThreadX Win32/Visual Studio Version 6.4.1 *"; 422 #else 423 extern CHAR _tx_version_id[]; 424 #endif 425 426 427 /* Define externals for the Win32 port of ThreadX. */ 428 429 extern TX_WIN32_CRITICAL_SECTION _tx_win32_critical_section; 430 extern HANDLE _tx_win32_scheduler_semaphore; 431 extern DWORD _tx_win32_scheduler_id; 432 extern ULONG _tx_win32_global_int_disabled_flag; 433 extern LARGE_INTEGER _tx_win32_time_stamp; 434 extern ULONG _tx_win32_system_error; 435 extern HANDLE _tx_win32_timer_handle; 436 extern UINT _tx_win32_timer_id; 437 extern LARGE_INTEGER _tx_win32_time_stamp; 438 439 440 #ifndef TX_WIN32_MEMORY_SIZE 441 #define TX_WIN32_MEMORY_SIZE 64000 442 #endif 443 444 #ifndef TX_TIMER_PERIODIC 445 #define TX_TIMER_PERIODIC 10 446 #endif 447 448 #endif 449 450 451 452 453