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 /**   Queue                                                               */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define TX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "tx_api.h"
29 #include "tx_initialize.h"
30 #include "tx_timer.h"
31 #include "tx_thread.h"
32 #include "tx_queue.h"
33 
34 
35 /**************************************************************************/
36 /*                                                                        */
37 /*  FUNCTION                                               RELEASE        */
38 /*                                                                        */
39 /*    _txe_queue_create                                   PORTABLE C      */
40 /*                                                           6.1          */
41 /*  AUTHOR                                                                */
42 /*                                                                        */
43 /*    William E. Lamie, Microsoft Corporation                             */
44 /*                                                                        */
45 /*  DESCRIPTION                                                           */
46 /*                                                                        */
47 /*    This function checks for errors in the queue create function call.  */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    queue_ptr                         Pointer to queue control block    */
52 /*    name_ptr                          Pointer to queue name             */
53 /*    message_size                      Size of each queue message        */
54 /*    queue_start                       Starting address of the queue area*/
55 /*    queue_size                        Number of bytes in the queue      */
56 /*    queue_control_block_size          Size of queue control block       */
57 /*                                                                        */
58 /*  OUTPUT                                                                */
59 /*                                                                        */
60 /*    TX_QUEUE_ERROR                    Invalid queue pointer             */
61 /*    TX_PTR_ERROR                      Invalid starting address of queue */
62 /*    TX_SIZE_ERROR                     Invalid message queue size        */
63 /*    status                            Actual completion status          */
64 /*                                                                        */
65 /*  CALLS                                                                 */
66 /*                                                                        */
67 /*    _tx_queue_create                  Actual queue create function      */
68 /*    _tx_thread_system_preempt_check   Check for preemption              */
69 /*                                                                        */
70 /*  CALLED BY                                                             */
71 /*                                                                        */
72 /*    Application Code                                                    */
73 /*                                                                        */
74 /*  RELEASE HISTORY                                                       */
75 /*                                                                        */
76 /*    DATE              NAME                      DESCRIPTION             */
77 /*                                                                        */
78 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
79 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
80 /*                                            resulting in version 6.1    */
81 /*                                                                        */
82 /**************************************************************************/
_txe_queue_create(TX_QUEUE * queue_ptr,CHAR * name_ptr,UINT message_size,VOID * queue_start,ULONG queue_size,UINT queue_control_block_size)83 UINT  _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size,
84                         VOID *queue_start, ULONG queue_size, UINT queue_control_block_size)
85 {
86 
87 TX_INTERRUPT_SAVE_AREA
88 
89 UINT            status;
90 ULONG           i;
91 TX_QUEUE        *next_queue;
92 #ifndef TX_TIMER_PROCESS_IN_ISR
93 TX_THREAD       *thread_ptr;
94 #endif
95 
96 
97     /* Default status to success.  */
98     status =  TX_SUCCESS;
99 
100     /* Check for an invalid queue pointer.  */
101     if (queue_ptr == TX_NULL)
102     {
103 
104         /* Queue pointer is invalid, return appropriate error code.  */
105         status =  TX_QUEUE_ERROR;
106     }
107 
108     /* Now check for a valid control block size.  */
109     else if (queue_control_block_size != (sizeof(TX_QUEUE)))
110     {
111 
112         /* Queue pointer is invalid, return appropriate error code.  */
113         status =  TX_QUEUE_ERROR;
114     }
115     else
116     {
117 
118         /* Disable interrupts.  */
119         TX_DISABLE
120 
121         /* Increment the preempt disable flag.  */
122         _tx_thread_preempt_disable++;
123 
124         /* Restore interrupts.  */
125         TX_RESTORE
126 
127         /* Next see if it is already in the created list.  */
128         next_queue =   _tx_queue_created_ptr;
129         for (i = ((ULONG) 0); i < _tx_queue_created_count; i++)
130         {
131 
132             /* Determine if this queue matches the queue in the list.  */
133             if (queue_ptr == next_queue)
134             {
135 
136                 break;
137             }
138             else
139             {
140 
141                 /* Move to the next queue.  */
142                 next_queue =  next_queue -> tx_queue_created_next;
143             }
144         }
145 
146         /* Disable interrupts.  */
147         TX_DISABLE
148 
149         /* Decrement the preempt disable flag.  */
150         _tx_thread_preempt_disable--;
151 
152         /* Restore interrupts.  */
153         TX_RESTORE
154 
155         /* Check for preemption.  */
156         _tx_thread_system_preempt_check();
157 
158         /* At this point, check to see if there is a duplicate queue.  */
159         if (queue_ptr == next_queue)
160         {
161 
162             /* Queue is already created, return appropriate error code.  */
163             status =  TX_QUEUE_ERROR;
164         }
165 
166         /* Check the starting address of the queue.  */
167         else if (queue_start == TX_NULL)
168         {
169 
170             /* Invalid starting address of queue.  */
171             status =  TX_PTR_ERROR;
172         }
173 
174         /* Check for an invalid message size - less than 1.  */
175         else if (message_size < TX_1_ULONG)
176         {
177 
178             /* Invalid message size specified.  */
179             status =  TX_SIZE_ERROR;
180         }
181 
182         /* Check for an invalid message size - greater than 16.  */
183         else if (message_size > TX_16_ULONG)
184         {
185 
186             /* Invalid message size specified.  */
187             status =  TX_SIZE_ERROR;
188         }
189 
190         /* Check on the queue size.  */
191         else if ((queue_size/(sizeof(ULONG))) < message_size)
192         {
193 
194             /* Invalid queue size specified.  */
195             status =  TX_SIZE_ERROR;
196         }
197         else
198         {
199 
200 #ifndef TX_TIMER_PROCESS_IN_ISR
201 
202             /* Pickup thread pointer.  */
203             TX_THREAD_GET_CURRENT(thread_ptr)
204 
205             /* Check for invalid caller of this function.  First check for a calling thread.  */
206             if (thread_ptr == &_tx_timer_thread)
207             {
208 
209                 /* Invalid caller of this function, return appropriate error code.  */
210                 status =  TX_CALLER_ERROR;
211             }
212 #endif
213 
214             /* Check for interrupt call.  */
215             if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
216             {
217 
218                 /* Now, make sure the call is from an interrupt and not initialization.  */
219                 if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
220                 {
221 
222                     /* Invalid caller of this function, return appropriate error code.  */
223                     status =  TX_CALLER_ERROR;
224                 }
225             }
226         }
227     }
228 
229     /* Determine if everything is okay.  */
230     if (status == TX_SUCCESS)
231     {
232 
233         /* Call actual queue create function.  */
234         status =  _tx_queue_create(queue_ptr, name_ptr, message_size, queue_start, queue_size);
235     }
236 
237     /* Return completion status.  */
238     return(status);
239 }
240