1 Microsoft's Azure RTOS ThreadX for Cortex-A8
2
3 Thumb & 32-bit Mode
4
5 Using ARM Compiler 5 (AC5)
6
71. Building the ThreadX run-time Library
8
9First make sure you are in the "example_build" directory. Also, make sure that
10you have setup your path and other environment variables necessary for the ARM
11AC5 development environment. At this point you may run the build_threadx.bat
12batch file. This will build the ThreadX run-time environment in the
13"example_build" directory.
14
15You should observe assembly and compilation of a series of ThreadX source
16files. At the end of the batch file, they are all combined into the
17run-time library file: tx.a. This file must be linked with your
18application in order to use ThreadX.
19
201.1 Building with Project Files
21
22The ThreadX library can also be built via project files. Simply open
23the tx.mcp file with project builder and select make. This will place
24the tx.a library file into the Debug sub-directory.
25
26
272. Demonstration System
28
29The ThreadX demonstration is designed to execute under the ARM
30Windows-based simulator.
31
32Building the demonstration is easy; simply execute the build_threadx_demo.bat
33batch file while inside the "example_build" directory.
34
35You should observe the compilation of sample_threadx.c (which is the demonstration
36application) and linking with tx.a. The resulting file sample_threadx.axf
37is a binary file that can be downloaded and executed on the ARM simulator.
38
392.0.1 Building with Project Files
40
41The ThreadX demonstration can also be built via project files. Simply open
42the sample_threadx.mcp file with project builder and select make. This will place
43the sample_threadx.axf output image into the Debug sub-directory.
44
45
463. System Initialization
47
48The entry point in ThreadX for the Cortex-A8 using AC5 tools is at label
49__main. This is defined within the AC5 compiler's startup code. In
50addition, this is where all static and global pre-set C variable
51initialization processing takes place.
52
53The ThreadX tx_initialize_low_level.s file is responsible for setting up
54various system data structures, the vector area, and a periodic timer interrupt
55source. By default, the vector area is defined to be located in the Init area,
56which is defined at the top of tx_initialize_low_level.s. This area is typically
57located at 0. In situations where this is impossible, the vectors at the beginning
58of the Init area should be copied to address 0.
59
60This is also where initialization of a periodic timer interrupt source
61should take place.
62
63In addition, _tx_initialize_low_level determines the first available
64address for use by the application, which is supplied as the sole input
65parameter to your application definition function, tx_application_define.
66
67
684. Assembler / Compiler Switches
69
70The following are compiler switches used in building the demonstration
71system:
72
73Compiler Switch Meaning
74
75 -g Specifies debug information
76 -c Specifies object code generation
77 --cpu Cortex-A8 Specifies Cortex-A8 instruction set
78 --apcs /interwork Specifies Thumb/32-bit compatibility
79
80Linker Switch Meaning
81
82 -d Specifies to retain debug information in output file
83 -o demo.axf Specifies demo output file name
84 --elf Specifies elf output file format
85 --ro Specifies that Read-Only memory starts at address 0
86 --first tx_initialize_low_level.o(Init)
87 Specifies that the first area loaded is Init
88 --remove Remove unused areas
89 --list Specifies map file name
90 --symbols Specifies symbols for map file
91 --map Creates a map file
92
93Application Defines
94
95 --PD "TX_ENABLE_FIQ_SUPPORT SETL {TRUE}" This assembler define enables FIQ
96 interrupt handling support in the
97 ThreadX assembly files. If used,
98 it should be used on all assembly
99 files and the generic C source of
100 ThreadX should be compiled with
101 TX_ENABLE_FIQ_SUPPORT defined as well.
102 --PD "TX_ENABLE_IRQ_NESTING SETL {TRUE}" This assembler define enables IRQ
103 nested support. If IRQ nested
104 interrupt support is needed, this
105 define should be applied to
106 tx_initialize_low_level.s.
107 --PD "TX_ENABLE_FIQ_NESTING SETL {TRUE}" This assembler define enables FIQ
108 nested support. If FIQ nested
109 interrupt support is needed, this
110 define should be applied to
111 tx_initialize_low_level.s. In addition,
112 IRQ nesting should also be enabled.
113 -DTX_ENABLE_FIQ_SUPPORT This compiler define enables FIQ
114 interrupt handling in the ThreadX
115 generic C source. This define
116 should also be used in conjunction
117 with the corresponding assembler
118 define.
119 -DTX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included,
120 this define causes basic ThreadX error
121 checking to be disabled. Please see
122 Chapter 2 in the "ThreadX User Guide"
123 for more details.
124
125 -DTX_MAX_PRIORITIES Defines the priority levels for ThreadX.
126 Legal values range from 32 through
127 1024 (inclusive) and MUST be evenly divisible
128 by 32. Increasing the number of priority levels
129 supported increases the RAM usage by 128 bytes
130 for every group of 32 priorities. However, there
131 is only a negligible effect on performance. By
132 default, this value is set to 32 priority levels.
133
134 -DTX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is
135 used for error checking when threads are created.
136 The default value is port-specific and is found
137 in tx_port.h.
138
139 -DTX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal
140 ThreadX timer thread. This thread processes all
141 thread sleep requests as well as all service call
142 timeouts. In addition, all application timer callback
143 routines are invoked from this context. The default
144 value is port-specific and is found in tx_port.h.
145
146 -DTX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer
147 thread. The default value is priority 0 - the highest
148 priority in ThreadX. The default value is defined
149 in tx_port.h.
150
151 -DTX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system
152 timer thread for ThreadX. This results in improved
153 performance on timer events and smaller RAM requirements
154 because the timer stack and control block are no
155 longer needed. However, using this option moves all
156 the timer expiration processing to the timer ISR level.
157 By default, this option is not defined.
158
159 -DTX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX
160 timers in-line instead of using a function call. This
161 improves performance but slightly increases code size.
162 By default, this option is not defined.
163
164 -DTX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each
165 thread's stack is disabled. By default, this option is
166 not defined.
167
168 -DTX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking,
169 which includes analysis of how much stack has been used and
170 examination of data pattern "fences" before and after the
171 stack area. If a stack error is detected, the registered
172 application stack error handler is called. This option does
173 result in slightly increased overhead and code size. Please
174 review the tx_thread_stack_error_notify API for more information.
175 By default, this option is not defined.
176
177 -DTX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature
178 and slightly reduces code size and improves performance. Of course,
179 the preemption-threshold capabilities are no longer available.
180 By default, this option is not defined.
181
182 -DTX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX
183 global C data structures to zero. This should only be used if
184 the compiler's initialization code sets all un-initialized
185 C global data to zero. Using this option slightly reduces
186 code size and improves performance during initialization.
187 By default, this option is not defined.
188
189 -DTX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various
190 ThreadX objects. Using this option slightly reduces code size
191 and improves performance.
192
193 -DTX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
194 information on block pools. By default, this option is
195 not defined.
196
197 -DTX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
198 information on byte pools. By default, this option is
199 not defined.
200
201 -DTX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
202 information on event flags groups. By default, this option
203 is not defined.
204
205 -DTX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
206 information on mutexes. By default, this option is
207 not defined.
208
209 -DTX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
210 information on queues. By default, this option is
211 not defined.
212
213 -DTX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
214 information on semaphores. By default, this option is
215 not defined.
216
217 -DTX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
218 information on threads. By default, this option is
219 not defined.
220
221 -DTX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
222 information on timers. By default, this option is
223 not defined.
224
225 -DTX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace
226 feature. The trace buffer is supplied at a later time
227 via an application call to tx_trace_enable.
228
229 -DTX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing.
230 This define is only pertinent if the ThreadX library is
231 built with TX_ENABLE_EVENT_TRACE defined.
232
233 -DTX_TRACE_TIME_MASK This defines the number of valid bits in the event trace
234 time-stamp source defined previously. If the time-stamp
235 source is 16-bits, this value should be 0xFFFF. Alternatively,
236 if the time-stamp source is 32-bits, this value should be
237 0xFFFFFFFF. This define is only pertinent if the ThreadX
238 library is built with TX_ENABLE_EVENT_TRACE defined.
239
240
241
2425. Register Usage and Stack Frames
243
244The AC5 compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch
245registers for each function. All other registers used by a C function must
246be preserved by the function. ThreadX takes advantage of this in situations
247where a context switch happens as a result of making a ThreadX service call
248(which is itself a C function). In such cases, the saved context of a thread
249is only the non-scratch registers.
250
251The following defines the saved context stack frames for context switches
252that occur as a result of interrupt handling or from thread-level API calls.
253All suspended threads have one of these two types of stack frames. The top
254of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
255associated thread control block TX_THREAD.
256
257
258
259 Offset Interrupted Stack Frame Non-Interrupt Stack Frame
260
261 0x00 1 0
262 0x04 CPSR CPSR
263 0x08 r0 (a1) r4 (v1)
264 0x0C r1 (a2) r5 (v2)
265 0x10 r2 (a3) r6 (v3)
266 0x14 r3 (a4) r7 (v4)
267 0x18 r4 (v1) r8 (v5)
268 0x1C r5 (v2) r9 (v6)
269 0x20 r6 (v3) r10 (v7)
270 0x24 r7 (v4) r11 (fp)
271 0x28 r8 (v5) r14 (lr)
272 0x2C r9 (v6)
273 0x30 r10 (v7)
274 0x34 r11 (fp)
275 0x38 r12 (ip)
276 0x3C r14 (lr)
277 0x40 PC
278
279
2806. Improving Performance
281
282The distribution version of ThreadX is built without any compiler
283optimizations. This makes it easy to debug because you can trace or set
284breakpoints inside of ThreadX itself. Of course, this costs some
285performance. To make it run faster, you can change the build_threadx.bat file to
286remove the -g option and enable all compiler optimizations.
287
288In addition, you can eliminate the ThreadX basic API error checking by
289compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
290defined.
291
292
2937. Interrupt Handling
294
295ThreadX provides complete and high-performance interrupt handling for Cortex-A8
296targets. There are a certain set of requirements that are defined in the
297following sub-sections:
298
299
3007.1 Vector Area
301
302The Cortex-A8 vectors start at address zero. The demonstration system startup
303Init area contains the vectors and is loaded at address zero. On actual
304hardware platforms, this area might have to be copied to address 0.
305
306
3077.2 IRQ ISRs
308
309ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports nested
310IRQ interrupts. The following sub-sections define the IRQ capabilities.
311
312
3137.2.1 Standard IRQ ISRs
314
315The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ
316interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following
317is the default IRQ handler defined in tx_initialize_low_level.s:
318
319 EXPORT __tx_irq_handler
320 EXPORT __tx_irq_processing_return
321__tx_irq_handler
322;
323; /* Jump to context save to save system context. */
324 B _tx_thread_context_save ; Jump to the context save
325__tx_irq_processing_return
326;
327; /* At this point execution is still in the IRQ mode. The CPSR, point of
328; interrupt, and all C scratch registers are available for use. Note
329; that IRQ interrupts are still disabled upon return from the context
330; save function. */
331;
332; /* Application ISR call(s) go here! */
333;
334; /* Jump to context restore to restore system context. */
335 B _tx_thread_context_restore
336
337
3387.2.2 Vectored IRQ ISRs
339
340The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified
341by the particular implementation. The following is an example IRQ handler defined in
342tx_initialize_low_level.s:
343
344 EXPORT __tx_irq_example_handler
345__tx_irq_example_handler
346;
347; /* Call context save to save system context. */
348
349 STMDB sp!, {r0-r3} ; Save some scratch registers
350 MRS r0, SPSR ; Pickup saved SPSR
351 SUB lr, lr, #4 ; Adjust point of interrupt
352 STMDB sp!, {r0, r10, r12, lr} ; Store other scratch registers
353 BL _tx_thread_vectored_context_save ; Call the vectored IRQ context save
354;
355; /* At this point execution is still in the IRQ mode. The CPSR, point of
356; interrupt, and all C scratch registers are available for use. Note
357; that IRQ interrupts are still disabled upon return from the context
358; save function. */
359;
360; /* Application ISR call goes here! */
361;
362; /* Jump to context restore to restore system context. */
363 B _tx_thread_context_restore
364
365
3667.2.3 Nested IRQ Support
367
368By default, nested IRQ interrupt support is not enabled. To enable nested
369IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING
370defined. With this defined, two new IRQ interrupt management services are
371available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end.
372These function should be called between the IRQ context save and restore
373calls.
374
375Execution between the calls to _tx_thread_irq_nesting_start and
376_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved
377by switching from IRQ mode to SYS mode and enabling IRQ interrupts.
378The SYS mode stack is used during the SYS mode operation, which was
379setup in tx_initialize_low_level.s. When nested IRQ interrupts are no longer required,
380calling the _tx_thread_irq_nesting_end service disables nesting by disabling
381IRQ interrupts and switching back to IRQ mode in preparation for the IRQ
382context restore service.
383
384The following is an example of enabling IRQ nested interrupts in a standard
385IRQ handler:
386
387 EXPORT __tx_irq_handler
388 EXPORT __tx_irq_processing_return
389__tx_irq_handler
390;
391; /* Jump to context save to save system context. */
392 B _tx_thread_context_save
393__tx_irq_processing_return
394;
395; /* Enable nested IRQ interrupts. NOTE: Since this service returns
396; with IRQ interrupts enabled, all IRQ interrupt sources must be
397; cleared prior to calling this service. */
398 BL _tx_thread_irq_nesting_start
399;
400; /* Application ISR call(s) go here! */
401;
402; /* Disable nested IRQ interrupts. The mode is switched back to
403; IRQ mode and IRQ interrupts are disable upon return. */
404 BL _tx_thread_irq_nesting_end
405;
406; /* Jump to context restore to restore system context. */
407 B _tx_thread_context_restore
408
409
4107.3 FIQ Interrupts
411
412By default, Cortex-A8 FIQ interrupts are left alone by ThreadX. Of course, this
413means that the application is fully responsible for enabling the FIQ interrupt
414and saving/restoring any registers used in the FIQ ISR processing. To globally
415enable FIQ interrupts, the application should enable FIQ interrupts at the
416beginning of each thread or before any threads are created in tx_application_define.
417In addition, the application must ensure that no ThreadX service calls are made
418from default FIQ ISRs, which is located in tx_initialize_low_level.s.
419
420
4217.3.1 Managed FIQ Interrupts
422
423Full ThreadX management of FIQ interrupts is provided if the ThreadX sources
424are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built
425this way, the FIQ interrupt handlers are very similar to the IRQ interrupt
426handlers defined previously. The following is default FIQ handler
427defined in tx_initialize_low_level.s:
428
429
430 EXPORT __tx_fiq_handler
431 EXPORT __tx_fiq_processing_return
432__tx_fiq_handler
433;
434; /* Jump to fiq context save to save system context. */
435 B _tx_thread_fiq_context_save
436__tx_fiq_processing_return:
437;
438; /* At this point execution is still in the FIQ mode. The CPSR, point of
439; interrupt, and all C scratch registers are available for use. */
440;
441; /* Application FIQ handlers can be called here! */
442;
443; /* Jump to fiq context restore to restore system context. */
444 B _tx_thread_fiq_context_restore
445
446
4477.3.1.1 Nested FIQ Support
448
449By default, nested FIQ interrupt support is not enabled. To enable nested
450FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING
451defined. With this defined, two new FIQ interrupt management services are
452available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end.
453These function should be called between the FIQ context save and restore
454calls.
455
456Execution between the calls to _tx_thread_fiq_nesting_start and
457_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved
458by switching from FIQ mode to SYS mode and enabling FIQ interrupts.
459The SYS mode stack is used during the SYS mode operation, which was
460setup in tx_initialize_low_level.s. When nested FIQ interrupts are no longer required,
461calling the _tx_thread_fiq_nesting_end service disables nesting by disabling
462FIQ interrupts and switching back to FIQ mode in preparation for the FIQ
463context restore service.
464
465The following is an example of enabling FIQ nested interrupts in the
466typical FIQ handler:
467
468
469 EXPORT __tx_fiq_handler
470 EXPORT __tx_fiq_processing_return
471__tx_fiq_handler
472;
473; /* Jump to fiq context save to save system context. */
474 B _tx_thread_fiq_context_save
475__tx_fiq_processing_return
476;
477; /* At this point execution is still in the FIQ mode. The CPSR, point of
478; interrupt, and all C scratch registers are available for use. */
479;
480; /* Enable nested FIQ interrupts. NOTE: Since this service returns
481; with FIQ interrupts enabled, all FIQ interrupt sources must be
482; cleared prior to calling this service. */
483 BL _tx_thread_fiq_nesting_start
484;
485; /* Application FIQ handlers can be called here! */
486;
487; /* Disable nested FIQ interrupts. The mode is switched back to
488; FIQ mode and FIQ interrupts are disable upon return. */
489 BL _tx_thread_fiq_nesting_end
490;
491; /* Jump to fiq context restore to restore system context. */
492 B _tx_thread_fiq_context_restore
493
494
4958. ThreadX Timer Interrupt
496
497ThreadX requires a periodic interrupt source to manage all time-slicing,
498thread sleeps, timeouts, and application timers. Without such a timer
499interrupt source, these services are not functional. However, all other
500ThreadX services are operational without a periodic timer source.
501
502To add the timer interrupt processing, simply make a call to
503_tx_timer_interrupt in the IRQ processing. An example of this can be
504found in the file tx_initialize_low_level.s in the Integrator sub-directories.
505
506
5079. Thumb/Cortex-A8 Mixed Mode
508
509By default, ThreadX is setup for running in Cortex-A8 32-bit mode. This is
510also true for the demonstration system. It is possible to build any
511ThreadX file and/or the application in Thumb mode. If any Thumb code
512is used the entire ThreadX source- both C and assembly - should be built
513with the "-apcs /interwork" option.
514
515
51610. VFP Support
517
518By default, VFP support is disabled for each thread. If saving the context of the VFP registers
519is needed, the following API call must be made from the context of the application thread - before
520the VFP usage:
521
522void tx_thread_vfp_enable(void);
523
524After this API is called in the application, VFP registers will be saved/restored for this thread if it
525is preempted via an interrupt. All other suspension of the this thread will not require the VFP registers
526to be saved/restored.
527
528To disable VFP register context saving, simply call the following API:
529
530void tx_thread_vfp_disable(void);
531
532
533
53411. Revision History
535
536For generic code revision information, please refer to the readme_threadx_generic.txt
537file, which is included in your distribution. The following details the revision
538information associated with this specific port of ThreadX:
539
54004-02-2021 Release 6.1.6 changes:
541 tx_port.h Updated macro definition
542
54309-30-2020 Initial ThreadX 6.1 version for Cortex-A8 using AC5 tools.
544
545
546Copyright(c) 1996-2020 Microsoft Corporation
547
548
549https://azure.com/rtos
550
551