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 /** Thread */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 #define TX_SOURCE_CODE
25
26
27 /* Include necessary system files. */
28
29 #include "tx_api.h"
30 #include "tx_thread.h"
31 #include <stdio.h>
32
33
34 /* Prototype for new thread entry function. */
35
36 DWORD WINAPI _tx_win32_thread_entry(LPVOID p);
37
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _tx_thread_stack_build Win32/Visual */
44 /* 6.1 */
45 /* AUTHOR */
46 /* */
47 /* William E. Lamie, Microsoft Corporation */
48 /* */
49 /* DESCRIPTION */
50 /* */
51 /* This function builds a stack frame on the supplied thread's stack. */
52 /* The stack frame results in a fake interrupt return to the supplied */
53 /* function pointer. */
54 /* */
55 /* INPUT */
56 /* */
57 /* thread_ptr Pointer to thread control blk */
58 /* function_ptr Pointer to return function */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* None */
63 /* */
64 /* CALLS */
65 /* */
66 /* CreateThread Win32 create thread */
67 /* ResumeThread Win32 resume thread */
68 /* SetThreadPriority Win32 set thread priority */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* _tx_thread_create Create thread service */
73 /* _tx_thread_reset Reset thread service */
74 /* */
75 /* RELEASE HISTORY */
76 /* */
77 /* DATE NAME DESCRIPTION */
78 /* */
79 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
80 /* */
81 /**************************************************************************/
_tx_thread_stack_build(TX_THREAD * thread_ptr,VOID (* function_ptr)(VOID))82 VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
83 {
84
85 /* Create a Win32 thread for the application thread. */
86 thread_ptr -> tx_thread_win32_thread_handle =
87 CreateThread(NULL, 0, _tx_win32_thread_entry, (LPVOID) thread_ptr, CREATE_SUSPENDED,
88 &(thread_ptr -> tx_thread_win32_thread_id));
89
90 /* Check for a good thread create. */
91 if (!thread_ptr -> tx_thread_win32_thread_handle)
92 {
93
94 /* Display an error message. */
95 printf("ThreadX Win32 error creating thread!\n");
96 while(1)
97 {
98 }
99 }
100
101 /* Otherwise, we have a good thread create. Now set the priority to
102 a lower level. */
103 SetThreadPriority(thread_ptr -> tx_thread_win32_thread_handle, THREAD_PRIORITY_LOWEST);
104
105 /* Create the run semaphore for the thread. This will allow the scheduler
106 control over when the thread actually runs. */
107 thread_ptr -> tx_thread_win32_thread_run_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
108
109 /* Determine if the run semaphore was created successfully. */
110 if (!thread_ptr -> tx_thread_win32_thread_run_semaphore)
111 {
112
113 /* Display an error message. */
114 printf("ThreadX Win32 error creating thread running semaphore!\n");
115 while(1)
116 {
117 }
118 }
119
120 /* Setup the thread suspension type to solicited thread suspension.
121 Pseudo interrupt handlers will suspend with this field set to 1. */
122 thread_ptr -> tx_thread_win32_suspension_type = 0;
123
124 /* Clear the disabled count that will keep track of the
125 tx_interrupt_control nesting. */
126 thread_ptr -> tx_thread_win32_int_disabled_flag = 0;
127
128 /* Setup a fake thread stack pointer. */
129 thread_ptr -> tx_thread_stack_ptr = (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);
130
131 /* Clear the first word of the stack. */
132 *(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) = 0;
133
134 /* Make the thread initially ready so it will run to the initial wait on
135 its run semaphore. */
136 ResumeThread(thread_ptr -> tx_thread_win32_thread_handle);
137 }
138
139
_tx_win32_thread_entry(LPVOID ptr)140 DWORD WINAPI _tx_win32_thread_entry(LPVOID ptr)
141 {
142
143 TX_THREAD *thread_ptr;
144
145 /* Pickup the current thread pointer. */
146 thread_ptr = (TX_THREAD *) ptr;
147
148 /* Now suspend the thread initially. If the thread has already
149 been scheduled, this will return immediately. */
150 WaitForSingleObject(thread_ptr -> tx_thread_win32_thread_run_semaphore, INFINITE);
151
152 /* Call ThreadX thread entry point. */
153 _tx_thread_shell_entry();
154
155 return EXIT_SUCCESS;
156 }
157
158