Skip to content

Commit 6a018a4

Browse files
author
Scott Larson
committed
add ARM11
1 parent 608f55f commit 6a018a4

File tree

95 files changed

+34462
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+34462
-0
lines changed

ports/arm11/ac5/example_build/build_threadx.bat

Lines changed: 238 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
armasm -g --cpu ARM1136J-S --apcs /interwork tx_initialize_low_level.s
2+
armcc -g -c -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc sample_threadx.c
3+
armlink -d -o sample_threadx.axf --elf --ro 0 --first tx_initialize_low_level.o(Init) --remove --map --symbols --list sample_threadx.map tx_initialize_low_level.o sample_threadx.o tx.a
4+
Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
2+
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
3+
byte pool, and block pool. */
4+
5+
#include "tx_api.h"
6+
7+
#define DEMO_STACK_SIZE 1024
8+
#define DEMO_BYTE_POOL_SIZE 9120
9+
#define DEMO_BLOCK_POOL_SIZE 100
10+
#define DEMO_QUEUE_SIZE 100
11+
12+
13+
/* Define the ThreadX object control blocks... */
14+
15+
TX_THREAD thread_0;
16+
TX_THREAD thread_1;
17+
TX_THREAD thread_2;
18+
TX_THREAD thread_3;
19+
TX_THREAD thread_4;
20+
TX_THREAD thread_5;
21+
TX_THREAD thread_6;
22+
TX_THREAD thread_7;
23+
TX_QUEUE queue_0;
24+
TX_SEMAPHORE semaphore_0;
25+
TX_MUTEX mutex_0;
26+
TX_EVENT_FLAGS_GROUP event_flags_0;
27+
TX_BYTE_POOL byte_pool_0;
28+
TX_BLOCK_POOL block_pool_0;
29+
30+
31+
/* Define the counters used in the demo application... */
32+
33+
ULONG thread_0_counter;
34+
ULONG thread_1_counter;
35+
ULONG thread_1_messages_sent;
36+
ULONG thread_2_counter;
37+
ULONG thread_2_messages_received;
38+
ULONG thread_3_counter;
39+
ULONG thread_4_counter;
40+
ULONG thread_5_counter;
41+
ULONG thread_6_counter;
42+
ULONG thread_7_counter;
43+
44+
45+
/* Define thread prototypes. */
46+
47+
void thread_0_entry(ULONG thread_input);
48+
void thread_1_entry(ULONG thread_input);
49+
void thread_2_entry(ULONG thread_input);
50+
void thread_3_and_4_entry(ULONG thread_input);
51+
void thread_5_entry(ULONG thread_input);
52+
void thread_6_and_7_entry(ULONG thread_input);
53+
54+
55+
/* Define main entry point. */
56+
57+
int main()
58+
{
59+
60+
/* Enter the ThreadX kernel. */
61+
tx_kernel_enter();
62+
}
63+
64+
65+
/* Define what the initial system looks like. */
66+
67+
void tx_application_define(void *first_unused_memory)
68+
{
69+
70+
CHAR *pointer = TX_NULL;
71+
72+
73+
/* Create a byte memory pool from which to allocate the thread stacks. */
74+
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
75+
76+
/* Put system definition stuff in here, e.g. thread creates and other assorted
77+
create information. */
78+
79+
/* Allocate the stack for thread 0. */
80+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
81+
82+
/* Create the main thread. */
83+
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
84+
pointer, DEMO_STACK_SIZE,
85+
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
86+
87+
88+
/* Allocate the stack for thread 1. */
89+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
90+
91+
/* Create threads 1 and 2. These threads pass information through a ThreadX
92+
message queue. It is also interesting to note that these threads have a time
93+
slice. */
94+
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
95+
pointer, DEMO_STACK_SIZE,
96+
16, 16, 4, TX_AUTO_START);
97+
98+
/* Allocate the stack for thread 2. */
99+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
100+
101+
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
102+
pointer, DEMO_STACK_SIZE,
103+
16, 16, 4, TX_AUTO_START);
104+
105+
/* Allocate the stack for thread 3. */
106+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
107+
108+
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
109+
An interesting thing here is that both threads share the same instruction area. */
110+
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
111+
pointer, DEMO_STACK_SIZE,
112+
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
113+
114+
/* Allocate the stack for thread 4. */
115+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
116+
117+
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
118+
pointer, DEMO_STACK_SIZE,
119+
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
120+
121+
/* Allocate the stack for thread 5. */
122+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
123+
124+
/* Create thread 5. This thread simply pends on an event flag which will be set
125+
by thread_0. */
126+
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
127+
pointer, DEMO_STACK_SIZE,
128+
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
129+
130+
/* Allocate the stack for thread 6. */
131+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
132+
133+
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
134+
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
135+
pointer, DEMO_STACK_SIZE,
136+
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
137+
138+
/* Allocate the stack for thread 7. */
139+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
140+
141+
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
142+
pointer, DEMO_STACK_SIZE,
143+
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
144+
145+
/* Allocate the message queue. */
146+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
147+
148+
/* Create the message queue shared by threads 1 and 2. */
149+
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
150+
151+
/* Create the semaphore used by threads 3 and 4. */
152+
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
153+
154+
/* Create the event flags group used by threads 1 and 5. */
155+
tx_event_flags_create(&event_flags_0, "event flags 0");
156+
157+
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
158+
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
159+
160+
/* Allocate the memory for a small block pool. */
161+
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
162+
163+
/* Create a block memory pool to allocate a message buffer from. */
164+
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
165+
166+
/* Allocate a block and release the block memory. */
167+
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
168+
169+
/* Release the block back to the pool. */
170+
tx_block_release(pointer);
171+
}
172+
173+
174+
175+
/* Define the test threads. */
176+
177+
void thread_0_entry(ULONG thread_input)
178+
{
179+
180+
UINT status;
181+
182+
183+
/* This thread simply sits in while-forever-sleep loop. */
184+
while(1)
185+
{
186+
187+
/* Increment the thread counter. */
188+
thread_0_counter++;
189+
190+
/* Sleep for 10 ticks. */
191+
tx_thread_sleep(10);
192+
193+
/* Set event flag 0 to wakeup thread 5. */
194+
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
195+
196+
/* Check status. */
197+
if (status != TX_SUCCESS)
198+
break;
199+
}
200+
}
201+
202+
203+
void thread_1_entry(ULONG thread_input)
204+
{
205+
206+
UINT status;
207+
208+
209+
/* This thread simply sends messages to a queue shared by thread 2. */
210+
while(1)
211+
{
212+
213+
/* Increment the thread counter. */
214+
thread_1_counter++;
215+
216+
/* Send message to queue 0. */
217+
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
218+
219+
/* Check completion status. */
220+
if (status != TX_SUCCESS)
221+
break;
222+
223+
/* Increment the message sent. */
224+
thread_1_messages_sent++;
225+
}
226+
}
227+
228+
229+
void thread_2_entry(ULONG thread_input)
230+
{
231+
232+
ULONG received_message;
233+
UINT status;
234+
235+
/* This thread retrieves messages placed on the queue by thread 1. */
236+
while(1)
237+
{
238+
239+
/* Increment the thread counter. */
240+
thread_2_counter++;
241+
242+
/* Retrieve a message from the queue. */
243+
status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
244+
245+
/* Check completion status and make sure the message is what we
246+
expected. */
247+
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
248+
break;
249+
250+
/* Otherwise, all is okay. Increment the received message count. */
251+
thread_2_messages_received++;
252+
}
253+
}
254+
255+
256+
void thread_3_and_4_entry(ULONG thread_input)
257+
{
258+
259+
UINT status;
260+
261+
262+
/* This function is executed from thread 3 and thread 4. As the loop
263+
below shows, these function compete for ownership of semaphore_0. */
264+
while(1)
265+
{
266+
267+
/* Increment the thread counter. */
268+
if (thread_input == 3)
269+
thread_3_counter++;
270+
else
271+
thread_4_counter++;
272+
273+
/* Get the semaphore with suspension. */
274+
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
275+
276+
/* Check status. */
277+
if (status != TX_SUCCESS)
278+
break;
279+
280+
/* Sleep for 2 ticks to hold the semaphore. */
281+
tx_thread_sleep(2);
282+
283+
/* Release the semaphore. */
284+
status = tx_semaphore_put(&semaphore_0);
285+
286+
/* Check status. */
287+
if (status != TX_SUCCESS)
288+
break;
289+
}
290+
}
291+
292+
293+
void thread_5_entry(ULONG thread_input)
294+
{
295+
296+
UINT status;
297+
ULONG actual_flags;
298+
299+
300+
/* This thread simply waits for an event in a forever loop. */
301+
while(1)
302+
{
303+
304+
/* Increment the thread counter. */
305+
thread_5_counter++;
306+
307+
/* Wait for event flag 0. */
308+
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
309+
&actual_flags, TX_WAIT_FOREVER);
310+
311+
/* Check status. */
312+
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
313+
break;
314+
}
315+
}
316+
317+
318+
void thread_6_and_7_entry(ULONG thread_input)
319+
{
320+
321+
UINT status;
322+
323+
324+
/* This function is executed from thread 6 and thread 7. As the loop
325+
below shows, these function compete for ownership of mutex_0. */
326+
while(1)
327+
{
328+
329+
/* Increment the thread counter. */
330+
if (thread_input == 6)
331+
thread_6_counter++;
332+
else
333+
thread_7_counter++;
334+
335+
/* Get the mutex with suspension. */
336+
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
337+
338+
/* Check status. */
339+
if (status != TX_SUCCESS)
340+
break;
341+
342+
/* Get the mutex again with suspension. This shows
343+
that an owning thread may retrieve the mutex it
344+
owns multiple times. */
345+
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
346+
347+
/* Check status. */
348+
if (status != TX_SUCCESS)
349+
break;
350+
351+
/* Sleep for 2 ticks to hold the mutex. */
352+
tx_thread_sleep(2);
353+
354+
/* Release the mutex. */
355+
status = tx_mutex_put(&mutex_0);
356+
357+
/* Check status. */
358+
if (status != TX_SUCCESS)
359+
break;
360+
361+
/* Release the mutex again. This will actually
362+
release ownership since it was obtained twice. */
363+
status = tx_mutex_put(&mutex_0);
364+
365+
/* Check status. */
366+
if (status != TX_SUCCESS)
367+
break;
368+
}
369+
}

0 commit comments

Comments
 (0)