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 #include <unistd.h>
33
34
35 /* Prototype for new thread entry function. */
36
37 void *_tx_linux_thread_entry(void *ptr);
38
39
40 /**************************************************************************/
41 /* */
42 /* FUNCTION RELEASE */
43 /* */
44 /* _tx_thread_stack_build Linux/GNU */
45 /* 6.1 */
46 /* AUTHOR */
47 /* */
48 /* William E. Lamie, Microsoft Corporation */
49 /* */
50 /* DESCRIPTION */
51 /* */
52 /* This function builds a stack frame on the supplied thread's stack. */
53 /* The stack frame results in a fake interrupt return to the supplied */
54 /* function pointer. */
55 /* */
56 /* INPUT */
57 /* */
58 /* thread_ptr Pointer to thread control blk */
59 /* function_ptr Pointer to return function */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* None */
64 /* */
65 /* CALLS */
66 /* */
67 /* pthread_create */
68 /* pthread_setschedparam */
69 /* _tx_linux_thread_suspend */
70 /* sem_init */
71 /* printf */
72 /* _tx_linux_thread_resume */
73 /* */
74 /* CALLED BY */
75 /* */
76 /* _tx_thread_create Create thread service */
77 /* _tx_thread_reset Reset thread service */
78 /* */
79 /* RELEASE HISTORY */
80 /* */
81 /* DATE NAME DESCRIPTION */
82 /* */
83 /* 09-30-2020 William E. Lamie Initial Version 6.1 */
84 /* */
85 /**************************************************************************/
_tx_thread_stack_build(TX_THREAD * thread_ptr,VOID (* function_ptr)(VOID))86 VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
87 {
88 struct sched_param sp;
89
90 (VOID)function_ptr;
91
92 /* Create the run semaphore for the thread. This will allow the scheduler
93 control over when the thread actually runs. */
94 if(sem_init(&thread_ptr -> tx_thread_linux_thread_run_semaphore, 0, 0))
95 {
96
97 /* Display an error message. */
98 printf("ThreadX Linux error creating thread running semaphore!\n");
99 while(1)
100 {
101 }
102 }
103
104 /* Create a Linux thread for the application thread. */
105 if(pthread_create(&thread_ptr -> tx_thread_linux_thread_id, NULL, _tx_linux_thread_entry, thread_ptr))
106 {
107
108 /* Display an error message. */
109 printf("ThreadX Linux error creating thread!\n");
110 while(1)
111 {
112 }
113 }
114
115 /* Otherwise, we have a good thread create. */
116 sp.sched_priority = TX_LINUX_PRIORITY_USER_THREAD;
117 pthread_setschedparam(thread_ptr -> tx_thread_linux_thread_id, SCHED_FIFO, &sp);
118
119 /* Setup the thread suspension type to solicited thread suspension.
120 Pseudo interrupt handlers will suspend with this field set to 1. */
121 thread_ptr -> tx_thread_linux_suspension_type = 0;
122
123 /* Clear the disabled count that will keep track of the
124 tx_interrupt_control nesting. */
125 thread_ptr -> tx_thread_linux_int_disabled_flag = 0;
126
127 /* Setup a fake thread stack pointer. */
128 thread_ptr -> tx_thread_stack_ptr = (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);
129
130 /* Clear the first word of the stack. */
131 *(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) = 0;
132 }
133
134
_tx_linux_thread_entry(void * ptr)135 void *_tx_linux_thread_entry(void *ptr)
136 {
137
138 TX_THREAD *thread_ptr;
139
140 /* Pickup the current thread pointer. */
141 thread_ptr = (TX_THREAD *) ptr;
142 _tx_linux_threadx_thread = 1;
143 nice(20);
144
145 /* Now suspend the thread initially. If the thread has already
146 been scheduled, this will return immediately. */
147 tx_linux_sem_wait(&thread_ptr -> tx_thread_linux_thread_run_semaphore);
148 tx_linux_sem_post_nolock(&_tx_linux_semaphore);
149
150 /* Call ThreadX thread entry point. */
151 _tx_thread_shell_entry();
152
153 return EXIT_SUCCESS;
154 }
155
156