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