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