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