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