summaryrefslogtreecommitdiff
path: root/ports/arm11/ac5
diff options
context:
space:
mode:
authorScott Larson <[email protected]>2020-08-07 17:47:29 -0700
committerScott Larson <[email protected]>2020-08-07 17:47:29 -0700
commit6a018a4cfda937c0d8cbdee761187c5c5843e115 (patch)
treecc9990878ab97ac171a192fe1c2922e752feee99 /ports/arm11/ac5
parent608f55f0d120886e0eddf7e39cf3c3b6f06bd08c (diff)
add ARM11v6.0.1_rel
Diffstat (limited to 'ports/arm11/ac5')
-rw-r--r--ports/arm11/ac5/example_build/build_threadx.bat238
-rw-r--r--ports/arm11/ac5/example_build/build_threadx_sample.bat4
-rw-r--r--ports/arm11/ac5/example_build/sample_threadx.c369
-rw-r--r--ports/arm11/ac5/example_build/tx_initialize_low_level.s444
-rw-r--r--ports/arm11/ac5/inc/tx_port.h327
-rw-r--r--ports/arm11/ac5/readme_threadx.txt534
-rw-r--r--ports/arm11/ac5/src/tx_thread_context_restore.s247
-rw-r--r--ports/arm11/ac5/src/tx_thread_context_save.s207
-rw-r--r--ports/arm11/ac5/src/tx_thread_fiq_context_restore.s259
-rw-r--r--ports/arm11/ac5/src/tx_thread_fiq_context_save.s203
-rw-r--r--ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s111
-rw-r--r--ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s104
-rw-r--r--ports/arm11/ac5/src/tx_thread_interrupt_control.s102
-rw-r--r--ports/arm11/ac5/src/tx_thread_interrupt_disable.s98
-rw-r--r--ports/arm11/ac5/src/tx_thread_interrupt_restore.s87
-rw-r--r--ports/arm11/ac5/src/tx_thread_irq_nesting_end.s110
-rw-r--r--ports/arm11/ac5/src/tx_thread_irq_nesting_start.s104
-rw-r--r--ports/arm11/ac5/src/tx_thread_schedule.s172
-rw-r--r--ports/arm11/ac5/src/tx_thread_stack_build.s156
-rw-r--r--ports/arm11/ac5/src/tx_thread_system_return.s150
-rw-r--r--ports/arm11/ac5/src/tx_thread_vectored_context_save.s209
-rw-r--r--ports/arm11/ac5/src/tx_timer_interrupt.s258
22 files changed, 4493 insertions, 0 deletions
diff --git a/ports/arm11/ac5/example_build/build_threadx.bat b/ports/arm11/ac5/example_build/build_threadx.bat
new file mode 100644
index 00000000..d2abc782
--- /dev/null
+++ b/ports/arm11/ac5/example_build/build_threadx.bat
@@ -0,0 +1,238 @@
+del tx.a
+armasm -g --cpu ARM1136J-S --apcs /interwork tx_initialize_low_level.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_stack_build.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_schedule.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_system_return.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_context_save.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_context_restore.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_interrupt_control.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_timer_interrupt.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_interrupt_disable.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_interrupt_restore.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_context_save.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_nesting_start.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_irq_nesting_start.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_irq_nesting_end.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_nesting_end.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_context_restore.s
+armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_vectored_context_save.s
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c
+armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c
+armar --create tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
+armar -r tx.a tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_start.o tx_thread_irq_nesting_start.o tx_thread_irq_nesting_end.o
+armar -r tx.a tx_thread_fiq_nesting_end.o tx_thread_fiq_context_restore.o tx_thread_vectored_context_save.o tx_initialize_low_level.o
+armar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
+armar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
+armar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
+armar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
+armar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
+armar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
+armar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
+armar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
+armar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
+armar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
+armar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
+armar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
+armar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
+armar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
+armar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
+armar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
+armar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
+armar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
+armar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
+armar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
+armar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
+armar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
+armar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+armar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
+armar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
+armar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
+armar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
+armar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
+armar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
+armar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
+armar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
+armar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
+armar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o
diff --git a/ports/arm11/ac5/example_build/build_threadx_sample.bat b/ports/arm11/ac5/example_build/build_threadx_sample.bat
new file mode 100644
index 00000000..f8fb754b
--- /dev/null
+++ b/ports/arm11/ac5/example_build/build_threadx_sample.bat
@@ -0,0 +1,4 @@
+armasm -g --cpu ARM1136J-S --apcs /interwork tx_initialize_low_level.s
+armcc -g -c -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc sample_threadx.c
+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
+
diff --git a/ports/arm11/ac5/example_build/sample_threadx.c b/ports/arm11/ac5/example_build/sample_threadx.c
new file mode 100644
index 00000000..418ec634
--- /dev/null
+++ b/ports/arm11/ac5/example_build/sample_threadx.c
@@ -0,0 +1,369 @@
+/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
+ threads of different priorities, using a message queue, semaphore, mutex, event flags group,
+ byte pool, and block pool. */
+
+#include "tx_api.h"
+
+#define DEMO_STACK_SIZE 1024
+#define DEMO_BYTE_POOL_SIZE 9120
+#define DEMO_BLOCK_POOL_SIZE 100
+#define DEMO_QUEUE_SIZE 100
+
+
+/* Define the ThreadX object control blocks... */
+
+TX_THREAD thread_0;
+TX_THREAD thread_1;
+TX_THREAD thread_2;
+TX_THREAD thread_3;
+TX_THREAD thread_4;
+TX_THREAD thread_5;
+TX_THREAD thread_6;
+TX_THREAD thread_7;
+TX_QUEUE queue_0;
+TX_SEMAPHORE semaphore_0;
+TX_MUTEX mutex_0;
+TX_EVENT_FLAGS_GROUP event_flags_0;
+TX_BYTE_POOL byte_pool_0;
+TX_BLOCK_POOL block_pool_0;
+
+
+/* Define the counters used in the demo application... */
+
+ULONG thread_0_counter;
+ULONG thread_1_counter;
+ULONG thread_1_messages_sent;
+ULONG thread_2_counter;
+ULONG thread_2_messages_received;
+ULONG thread_3_counter;
+ULONG thread_4_counter;
+ULONG thread_5_counter;
+ULONG thread_6_counter;
+ULONG thread_7_counter;
+
+
+/* Define thread prototypes. */
+
+void thread_0_entry(ULONG thread_input);
+void thread_1_entry(ULONG thread_input);
+void thread_2_entry(ULONG thread_input);
+void thread_3_and_4_entry(ULONG thread_input);
+void thread_5_entry(ULONG thread_input);
+void thread_6_and_7_entry(ULONG thread_input);
+
+
+/* Define main entry point. */
+
+int main()
+{
+
+ /* Enter the ThreadX kernel. */
+ tx_kernel_enter();
+}
+
+
+/* Define what the initial system looks like. */
+
+void tx_application_define(void *first_unused_memory)
+{
+
+CHAR *pointer = TX_NULL;
+
+
+ /* Create a byte memory pool from which to allocate the thread stacks. */
+ tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
+
+ /* Put system definition stuff in here, e.g. thread creates and other assorted
+ create information. */
+
+ /* Allocate the stack for thread 0. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create the main thread. */
+ tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, DEMO_STACK_SIZE,
+ 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+
+ /* Allocate the stack for thread 1. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create threads 1 and 2. These threads pass information through a ThreadX
+ message queue. It is also interesting to note that these threads have a time
+ slice. */
+ tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, DEMO_STACK_SIZE,
+ 16, 16, 4, TX_AUTO_START);
+
+ /* Allocate the stack for thread 2. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, DEMO_STACK_SIZE,
+ 16, 16, 4, TX_AUTO_START);
+
+ /* Allocate the stack for thread 3. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
+ An interesting thing here is that both threads share the same instruction area. */
+ tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 4. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 5. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create thread 5. This thread simply pends on an event flag which will be set
+ by thread_0. */
+ tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, DEMO_STACK_SIZE,
+ 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 6. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
+ tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 7. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the message queue. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
+
+ /* Create the message queue shared by threads 1 and 2. */
+ tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
+
+ /* Create the semaphore used by threads 3 and 4. */
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Create the event flags group used by threads 1 and 5. */
+ tx_event_flags_create(&event_flags_0, "event flags 0");
+
+ /* Create the mutex used by thread 6 and 7 without priority inheritance. */
+ tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Allocate the memory for a small block pool. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
+
+ /* Create a block memory pool to allocate a message buffer from. */
+ tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
+
+ /* Allocate a block and release the block memory. */
+ tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
+
+ /* Release the block back to the pool. */
+ tx_block_release(pointer);
+}
+
+
+
+/* Define the test threads. */
+
+void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This thread simply sits in while-forever-sleep loop. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Sleep for 10 ticks. */
+ tx_thread_sleep(10);
+
+ /* Set event flag 0 to wakeup thread 5. */
+ status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
+
+
+void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This thread simply sends messages to a queue shared by thread 2. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Send message to queue 0. */
+ status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
+
+ /* Check completion status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the message sent. */
+ thread_1_messages_sent++;
+ }
+}
+
+
+void thread_2_entry(ULONG thread_input)
+{
+
+ULONG received_message;
+UINT status;
+
+ /* This thread retrieves messages placed on the queue by thread 1. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Retrieve a message from the queue. */
+ status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
+
+ /* Check completion status and make sure the message is what we
+ expected. */
+ if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
+ break;
+
+ /* Otherwise, all is okay. Increment the received message count. */
+ thread_2_messages_received++;
+ }
+}
+
+
+void thread_3_and_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This function is executed from thread 3 and thread 4. As the loop
+ below shows, these function compete for ownership of semaphore_0. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ if (thread_input == 3)
+ thread_3_counter++;
+ else
+ thread_4_counter++;
+
+ /* Get the semaphore with suspension. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Sleep for 2 ticks to hold the semaphore. */
+ tx_thread_sleep(2);
+
+ /* Release the semaphore. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
+
+
+void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_flags;
+
+
+ /* This thread simply waits for an event in a forever loop. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+
+ /* Wait for event flag 0. */
+ status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
+ &actual_flags, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_flags != 0x1))
+ break;
+ }
+}
+
+
+void thread_6_and_7_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This function is executed from thread 6 and thread 7. As the loop
+ below shows, these function compete for ownership of mutex_0. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ if (thread_input == 6)
+ thread_6_counter++;
+ else
+ thread_7_counter++;
+
+ /* Get the mutex with suspension. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Get the mutex again with suspension. This shows
+ that an owning thread may retrieve the mutex it
+ owns multiple times. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Sleep for 2 ticks to hold the mutex. */
+ tx_thread_sleep(2);
+
+ /* Release the mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Release the mutex again. This will actually
+ release ownership since it was obtained twice. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
diff --git a/ports/arm11/ac5/example_build/tx_initialize_low_level.s b/ports/arm11/ac5/example_build/tx_initialize_low_level.s
new file mode 100644
index 00000000..a7bd0a35
--- /dev/null
+++ b/ports/arm11/ac5/example_build/tx_initialize_low_level.s
@@ -0,0 +1,444 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_initialize.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+SVC_MODE EQU 0xD3 ; Disable IRQ/FIQ SVC mode
+IRQ_MODE EQU 0xD2 ; Disable IRQ/FIQ IRQ mode
+FIQ_MODE EQU 0xD1 ; Disable IRQ/FIQ FIQ mode
+SYS_MODE EQU 0xDF ; Disable IRQ/FIQ SYS mode
+HEAP_SIZE EQU 4096 ; Heap size
+FIQ_STACK_SIZE EQU 512 ; FIQ stack size
+SYS_STACK_SIZE EQU 1024 ; SYS stack size (used for nested interrupts)
+IRQ_STACK_SIZE EQU 1024 ; IRQ stack size
+;
+;
+;/* ARM11 ARMulator Timer and Interrupt controller information. This depends on
+; the ARMulator's Interrupt Controller and Timer being enabled in the default.ami.
+; In addition, the addresses must match those specified in the peripherals.ami file.
+; Please refer to section 2.10 and 4.16 of the Debug Target Guide, version 1.2. */
+;
+IRQStatus EQU 0x0a000000 ; IRQ Status Register
+IRQRawStatus EQU 0x0a000004 ; IRQ Raw Status Register
+IRQEnable EQU 0x0a000008 ; IRQ Enable Set Register
+IRQEnableClear EQU 0x0a00000C ; IRQ Enable Clear Register
+IRQSoft EQU 0x0a000010 ; IRQ Soft
+FIQStatus EQU 0x0a000100 ; FIQ Status Register
+FIQRawStatus EQU 0x0a000104 ; FIQ Raw Status Register
+FIQEnable EQU 0x0a000108 ; FIQ Enable Set Register
+FIQEnableClear EQU 0x0a00010C ; FIQ Enable Clear Register
+
+TIMER1_BIT EQU 0x00000010 ; IRQ/FIQ Timer1 bit
+TIMER2_BIT EQU 0x00000020 ; IRQ/FIQ Timer2 bit
+
+Timer1Load EQU 0x0a800000 ; Timer1 Load Register
+Timer1Value EQU 0x0a800004 ; Timer1 Value Register
+Timer1Control EQU 0x0a800008 ; Timer1 Control Register
+Timer1Clear EQU 0x0a80000C ; Timer1 Clear Register
+
+Timer1Mode EQU 0x000000C0 ; Timer1 Control Value, Timer enable, periodic, no prescaler
+Timer1Period EQU 0x0000FFFF ; Timer1 count-down period, maximum value
+
+Timer2Load EQU 0x0a800020 ; Timer2 Load Register
+Timer2Value EQU 0x0a800024 ; Timer2 Value Register
+Timer2Control EQU 0x0a800028 ; Timer2 Control Register
+Timer2Clear EQU 0x0a80002C ; Timer2 Clear Register
+;
+;
+ IMPORT _tx_thread_system_stack_ptr
+ IMPORT _tx_initialize_unused_memory
+ IMPORT _tx_thread_context_save
+ IMPORT _tx_thread_context_restore
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+ IMPORT _tx_thread_fiq_context_save
+ IMPORT _tx_thread_fiq_context_restore
+ ENDIF
+ IF :DEF:TX_ENABLE_IRQ_NESTING
+ IMPORT _tx_thread_irq_nesting_start
+ IMPORT _tx_thread_irq_nesting_end
+ ENDIF
+ IF :DEF:TX_ENABLE_FIQ_NESTING
+ IMPORT _tx_thread_fiq_nesting_start
+ IMPORT _tx_thread_fiq_nesting_end
+ ENDIF
+ IMPORT _tx_timer_interrupt
+ IMPORT __main
+ IMPORT _tx_version_id
+ IMPORT _tx_build_options
+ IMPORT |Image$$ZI$$Limit|
+;
+;
+ AREA Init, CODE, READONLY
+;
+;/* Define the ARM11 vector area. This should be located or copied to 0. */
+;
+ EXPORT __vectors
+__vectors
+ LDR pc,=__main ; Reset goes to startup function
+ LDR pc,=__tx_undefined ; Undefined handler
+ LDR pc,=__tx_swi_interrupt ; Software interrupt handler
+ LDR pc,=__tx_prefetch_handler ; Prefetch exception handler
+ LDR pc,=__tx_abort_handler ; Abort exception handler
+ LDR pc,=__tx_reserved_handler ; Reserved exception handler
+ LDR pc,=__tx_irq_handler ; IRQ interrupt handler
+ LDR pc,=__tx_fiq_handler ; FIQ interrupt handler
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_initialize_low_level(VOID)
+;{
+ EXPORT _tx_initialize_low_level
+_tx_initialize_low_level
+;
+;
+; /****** NOTE ****** We must be in SVC MODE at this point. Some monitors
+; enter this routine in USER mode and require a software interrupt to
+; change into SVC mode. */
+;
+ LDR r1, =|Image$$ZI$$Limit| ; Get end of non-initialized RAM area
+ LDR r2, =HEAP_SIZE ; Pickup the heap size
+ ADD r1, r2, r1 ; Setup heap limit
+ ADD r1, r1, #4 ; Setup stack limit
+;
+ IF :DEF:TX_ENABLE_IRQ_NESTING
+; /* Setup the system mode stack for nested interrupt support */
+ LDR r2, =SYS_STACK_SIZE ; Pickup stack size
+ MOV r3, #SYS_MODE ; Build SYS mode CPSR
+ MSR CPSR_cxsf, r3 ; Enter SYS mode
+ ADD r1, r1, r2 ; Calculate start of SYS stack
+ BIC r1, r1, #7 ; Ensure 8-byte alignment
+ MOV sp, r1 ; Setup SYS stack pointer
+ ENDIF
+;
+ LDR r2, =FIQ_STACK_SIZE ; Pickup stack size
+ MOV r0, #FIQ_MODE ; Build FIQ mode CPSR
+ MSR CPSR_c, r0 ; Enter FIQ mode
+ ADD r1, r1, r2 ; Calculate start of FIQ stack
+ BIC r1, r1, #7 ; Ensure 8-byte alignment
+ MOV sp, r1 ; Setup FIQ stack pointer
+ MOV sl, #0 ; Clear sl
+ MOV fp, #0 ; Clear fp
+ LDR r2, =IRQ_STACK_SIZE ; Pickup IRQ (system stack size)
+ MOV r0, #IRQ_MODE ; Build IRQ mode CPSR
+ MSR CPSR_c, r0 ; Enter IRQ mode
+ ADD r1, r1, r2 ; Calculate start of IRQ stack
+ BIC r1, r1, #7 ; Ensure 8-byte alignment
+ MOV sp, r1 ; Setup IRQ stack pointer
+ MOV r0, #SVC_MODE ; Build SVC mode CPSR
+ MSR CPSR_c, r0 ; Enter SVC mode
+ LDR r3, =_tx_thread_system_stack_ptr ; Pickup stack pointer
+ STR r1, [r3, #0] ; Save the system stack
+;
+; /* Save the system stack pointer. */
+; _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
+;
+ LDR r1, =_tx_thread_system_stack_ptr ; Pickup address of system stack ptr
+ LDR r0, [r1, #0] ; Pickup system stack
+ ADD r0, r0, #4 ; Increment to next free word
+;
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) |Image$$ZI$$Limit| + HEAP + [SYS_STACK] + FIQ_STACK + IRQ_STACK;
+;
+ LDR r2, =_tx_initialize_unused_memory ; Pickup unused memory ptr address
+ STR r0, [r2, #0] ; Save first free memory address
+;
+; /* Setup Timer for periodic interrupts. */
+;
+; /* Setup ARMulator Timer1 for periodic interrupts. */
+;
+ LDR r0,=IRQEnable ; Build address of IRQ enable register
+ LDR r1,=TIMER1_BIT ; Build value of Timer1 IRQ enable
+ STR r1,[r0] ; Enable IRQ interrupts for Timer1
+
+ LDR r0,=Timer1Load ; Build address of Timer1 load register
+ LDR r1,=Timer1Period ; Build Timer1 periodic value
+ STR r1,[r0] ; Set Timer1 load value
+
+ LDR r0,=Timer1Control ; Build address of Timer1 control register
+ LDR r1,=Timer1Mode ; Build Timer1 control value
+ STR r1,[r0] ; Enable Timer1
+;
+; /* Done, return to caller. */
+;
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;}
+;
+;
+;/* Define initial heap/stack routine for the ARM RealView (and ADS) startup code. This
+; routine will set the initial stack to use the ThreadX IRQ & FIQ &
+; (optionally SYS) stack areas. */
+;
+ EXPORT __user_initial_stackheap
+__user_initial_stackheap
+ LDR r0, =|Image$$ZI$$Limit| ; Get end of non-initialized RAM area
+ LDR r2, =HEAP_SIZE ; Pickup the heap size
+ ADD r2, r2, r0 ; Setup heap limit
+ ADD r3, r2, #4 ; Setup stack limit
+ MOV r1, r3 ; Setup start of stack
+ IF :DEF:TX_ENABLE_IRQ_NESTING
+ LDR r12, =SYS_STACK_SIZE ; Pickup IRQ system stack
+ ADD r1, r1, r12 ; Setup the return system stack
+ BIC r1, r1, #7 ; Ensure 8-byte alignment
+ ENDIF
+ LDR r12, =FIQ_STACK_SIZE ; Pickup FIQ stack size
+ ADD r1, r1, r12 ; Setup the return system stack
+ BIC r1, r1, #7 ; Ensure 8-byte alignment
+ LDR r12, =IRQ_STACK_SIZE ; Pickup IRQ system stack
+ ADD r1, r1, r12 ; Setup the return system stack
+ BIC r1, r1, #7 ; Ensure 8-byte alignment
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+;
+;/* Define shells for each of the interrupt vectors. */
+;
+ EXPORT __tx_undefined
+__tx_undefined
+ B __tx_undefined ; Undefined handler
+;
+ EXPORT __tx_swi_interrupt
+__tx_swi_interrupt
+ B __tx_swi_interrupt ; Software interrupt handler
+;
+ EXPORT __tx_prefetch_handler
+__tx_prefetch_handler
+ B __tx_prefetch_handler ; Prefetch exception handler
+;
+ EXPORT __tx_abort_handler
+__tx_abort_handler
+ B __tx_abort_handler ; Abort exception handler
+;
+ EXPORT __tx_reserved_handler
+__tx_reserved_handler
+ B __tx_reserved_handler ; Reserved exception handler
+;
+;
+ EXPORT __tx_irq_handler
+ EXPORT __tx_irq_processing_return
+__tx_irq_handler
+;
+; /* Jump to context save to save system context. */
+ B _tx_thread_context_save
+__tx_irq_processing_return
+;
+; /* At this point execution is still in the IRQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. In
+; addition, IRQ interrupts may be re-enabled - with certain restrictions -
+; if nested IRQ interrupts are desired. Interrupts may be re-enabled over
+; small code sequences where lr is saved before enabling interrupts and
+; restored after interrupts are again disabled. */
+;
+;
+; /* Check for Timer1 interrupts on the ARMulator. */
+
+ LDR r1,=IRQStatus ; Pickup address of IRQStatus register
+ LDR r2, [r1] ; Read IRQStatus
+ LDR r0,=TIMER1_BIT ; Pickup Timer1 interrupt present bit
+ AND r2, r2, r0 ; Is this a timer interrupt?
+ CMP r2, r0 ;
+ BNE _tx_not_timer_interrupt ; If 0, not a timer interrupt
+
+ LDR r1,=Timer1Clear ; Build address of Timer1 clear register
+ MOV r0,#0 ;
+ STR r0, [r1] ; Clear timer 0 interrupt
+
+ BL _tx_timer_interrupt ; Timer interrupt handler
+_tx_not_timer_interrupt
+;
+; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
+; from IRQ mode with interrupts disabled. This routine switches to the
+; system mode and returns with IRQ interrupts enabled.
+;
+; NOTE: It is very important to ensure all IRQ interrupts are cleared
+; prior to enabling nested IRQ interrupts. */
+ IF :DEF:TX_ENABLE_IRQ_NESTING
+ BL _tx_thread_irq_nesting_start
+ ENDIF
+;
+;
+; /* Application IRQ handlers can be called here! */
+;
+; /* If interrupt nesting was started earlier, the end of interrupt nesting
+; service must be called before returning to _tx_thread_context_restore.
+; This routine returns in processing in IRQ mode with interrupts disabled. */
+ IF :DEF:TX_ENABLE_IRQ_NESTING
+ BL _tx_thread_irq_nesting_end
+ ENDIF
+;
+; /* Jump to context restore to restore system context. */
+ B _tx_thread_context_restore
+;
+;
+; /* This is an example of a vectored IRQ handler. */
+;
+ EXPORT __tx_example_vectored_irq_handler
+__tx_example_vectored_irq_handler
+;
+;
+; /* Save initial context and call context save to prepare for
+; vectored ISR execution. */
+;
+; STMDB sp!, {r0-r3} ; Save some scratch registers
+; MRS r0, SPSR ; Pickup saved SPSR
+; SUB lr, lr, #4 ; Adjust point of interrupt
+; STMDB sp!, {r0, r10, r12, lr} ; Store other scratch registers
+; BL _tx_thread_vectored_context_save ; Vectored context save
+;
+; /* At this point execution is still in the IRQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. In
+; addition, IRQ interrupts may be re-enabled - with certain restrictions -
+; if nested IRQ interrupts are desired. Interrupts may be re-enabled over
+; small code sequences where lr is saved before enabling interrupts and
+; restored after interrupts are again disabled. */
+;
+;
+; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
+; from IRQ mode with interrupts disabled. This routine switches to the
+; system mode and returns with IRQ interrupts enabled.
+;
+; NOTE: It is very important to ensure all IRQ interrupts are cleared
+; prior to enabling nested IRQ interrupts. */
+; IF :DEF:TX_ENABLE_IRQ_NESTING
+; BL _tx_thread_irq_nesting_start
+; ENDIF
+;
+; /* Application IRQ handlers can be called here! */
+;
+; /* If interrupt nesting was started earlier, the end of interrupt nesting
+; service must be called before returning to _tx_thread_context_restore.
+; This routine returns in processing in IRQ mode with interrupts disabled. */
+; IF :DEF:TX_ENABLE_IRQ_NESTING
+; BL _tx_thread_irq_nesting_end
+; ENDIF
+;
+; /* Jump to context restore to restore system context. */
+; B _tx_thread_context_restore
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+ EXPORT __tx_fiq_handler
+ EXPORT __tx_fiq_processing_return
+__tx_fiq_handler
+;
+; /* Jump to fiq context save to save system context. */
+ B _tx_thread_fiq_context_save
+__tx_fiq_processing_return
+;
+; /* At this point execution is still in the FIQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. */
+;
+; /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start
+; from FIQ mode with interrupts disabled. This routine switches to the
+; system mode and returns with FIQ interrupts enabled.
+;
+; NOTE: It is very important to ensure all FIQ interrupts are cleared
+; prior to enabling nested FIQ interrupts. */
+ IF :DEF:TX_ENABLE_FIQ_NESTING
+ BL _tx_thread_fiq_nesting_start
+ ENDIF
+;
+; /* Application FIQ handlers can be called here! */
+;
+; /* If interrupt nesting was started earlier, the end of interrupt nesting
+; service must be called before returning to _tx_thread_fiq_context_restore. */
+ IF :DEF:TX_ENABLE_FIQ_NESTING
+ BL _tx_thread_fiq_nesting_end
+ ENDIF
+;
+; /* Jump to fiq context restore to restore system context. */
+ B _tx_thread_fiq_context_restore
+;
+;
+ ELSE
+ EXPORT __tx_fiq_handler
+__tx_fiq_handler
+ B __tx_fiq_handler ; FIQ interrupt handler
+ ENDIF
+;
+; /* Reference build options and version ID to ensure they come in. */
+;
+ LDR r2, =_tx_build_options ; Pickup build options variable address
+ LDR r0, [r2, #0] ; Pickup build options content
+ LDR r2, =_tx_version_id ; Pickup version ID variable address
+ LDR r0, [r2, #0] ; Pickup version ID content
+;
+;
+ END
+
diff --git a/ports/arm11/ac5/inc/tx_port.h b/ports/arm11/ac5/inc/tx_port.h
new file mode 100644
index 00000000..90145158
--- /dev/null
+++ b/ports/arm11/ac5/inc/tx_port.h
@@ -0,0 +1,327 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h ARM11/AC5 */
+/* 6.0.1 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+
+/* Define compiler library include files. */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+/* Define various constants for the ThreadX ARM port. */
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
+#else
+#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */
+#endif
+#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */
+
+
+/* Define the clock source for trace event entry time stamp. The following two item are port specific.
+ For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
+ source constants would be:
+
+#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
+#define TX_TRACE_TIME_MASK 0x0000FFFFUL
+
+*/
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+#define TX_FIQ_ENABLED 1
+#else
+#define TX_FIQ_ENABLED 0
+#endif
+
+#ifdef TX_ENABLE_IRQ_NESTING
+#define TX_IRQ_NESTING_ENABLED 2
+#else
+#define TX_IRQ_NESTING_ENABLED 0
+#endif
+
+#ifdef TX_ENABLE_FIQ_NESTING
+#define TX_FIQ_NESTING_ENABLED 4
+#else
+#define TX_FIQ_NESTING_ENABLED 0
+#endif
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+
+/* Determine if the ARM architecture has the CLZ instruction. This is available on
+ architectures v5 and above. If available, redefine the macro for calculating the
+ lowest bit set. */
+
+#ifndef __thumb
+
+#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
+ b = (ULONG) __clz((unsigned int) m); \
+ b = 31 - b;
+#endif
+
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+#ifndef __thumb
+
+#define TX_INTERRUPT_SAVE_AREA register unsigned int interrupt_save_disabled;
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+
+/* IRQ and FIQ support. */
+
+#define TX_DISABLE __memory_changed(), interrupt_save_disabled = __disable_irq(); \
+ __disable_fiq();
+
+#define TX_RESTORE if (!interrupt_save_disabled) \
+ { \
+ __enable_irq(); \
+ __enable_fiq(); \
+ }
+
+#else
+
+#define TX_DISABLE __memory_changed(), interrupt_save_disabled = __disable_irq();
+
+#define TX_RESTORE if (!interrupt_save_disabled) \
+ { \
+ __enable_irq(); \
+ }
+#endif
+
+#else
+
+unsigned int _tx_thread_interrupt_disable(void);
+unsigned int _tx_thread_interrupt_restore(UINT old_posture);
+
+
+#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+#endif
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX ARM11/AC5 Version 6.0.1 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+#endif
+
diff --git a/ports/arm11/ac5/readme_threadx.txt b/ports/arm11/ac5/readme_threadx.txt
new file mode 100644
index 00000000..836a2e01
--- /dev/null
+++ b/ports/arm11/ac5/readme_threadx.txt
@@ -0,0 +1,534 @@
+ Microsoft's Azure RTOS ThreadX for ARM11
+
+ Thumb & 32-bit Mode
+
+ Using ARM Compiler 5 (AC5)
+
+1. Building the ThreadX run-time Library
+
+First make sure you are in the "example_build" directory. Also, make sure that
+you have setup your path and other environment variables necessary for the ARM
+AC5 development environment. At this point you may run the build_threadx.bat
+batch file. This will build the ThreadX run-time environment in the
+"example_build" directory.
+
+You should observe assembly and compilation of a series of ThreadX source
+files. At the end of the batch file, they are all combined into the
+run-time library file: tx.a. This file must be linked with your
+application in order to use ThreadX.
+
+
+2. Demonstration System
+
+Since there is no ARM11 FVP, there are no instructions here for running
+the demonstration; users are expected to run the demonstration on their
+platform of choice.
+
+Building the demonstration is easy; simply execute the build_threadx_sample.bat
+batch file while inside the "example_build" directory.
+
+You should observe the compilation of sample_threadx.c (which is the demonstration
+application) and linking with tx.a. The resulting file sample_threadx.axf
+is a binary file that can be downloaded and executed on the user's platform of choice.
+
+
+3. System Initialization
+
+The entry point in ThreadX for the Cortex-A5 using AC5 tools is at label
+__main. This is defined within the AC5 compiler's startup code. In addition,
+this is where all static and global pre-set C variable initialization processing
+takes place.
+
+The ThreadX tx_initialize_low_level.s file is responsible for setting up
+various system data structures, the vector area, and a periodic timer interrupt
+source. By default, the vector area is defined to be located in the Init area,
+which is defined at the top of tx_initialize_low_level.s. This area is typically
+located at 0. In situations where this is impossible, the vectors at the beginning
+of the Init area should be copied to address 0.
+
+This is also where initialization of a periodic timer interrupt source
+should take place.
+
+In addition, _tx_initialize_low_level determines the first available
+address for use by the application, which is supplied as the sole input
+parameter to your application definition function, tx_application_define.
+
+
+4. Assembler / Compiler Switches
+
+The following are compiler switches used in building the demonstration
+system:
+
+Compiler Switch Meaning
+
+ -g Specifies debug information
+ -c Specifies object code generation
+ --cpu Cortex-A5 Specifies Cortex-A5 instruction set
+ --apcs /interwork Specifies Thumb/32-bit compatibility
+
+Linker Switch Meaning
+
+ -d Specifies to retain debug information in output file
+ -o demo.axf Specifies demo output file name
+ --elf Specifies elf output file format
+ --ro Specifies that Read-Only memory starts at address 0
+ --first tx_initialize_low_level.o(Init)
+ Specifies that the first area loaded is Init
+ --remove Remove unused areas
+ --list Specifies map file name
+ --symbols Specifies symbols for map file
+ --map Creates a map file
+
+Application Defines
+
+ --PD "TX_ENABLE_FIQ_SUPPORT SETL {TRUE}" This assembler define enables FIQ
+ interrupt handling support in the
+ ThreadX assembly files. If used,
+ it should be used on all assembly
+ files and the generic C source of
+ ThreadX should be compiled with
+ TX_ENABLE_FIQ_SUPPORT defined as well.
+ --PD "TX_ENABLE_IRQ_NESTING SETL {TRUE}" This assembler define enables IRQ
+ nested support. If IRQ nested
+ interrupt support is needed, this
+ define should be applied to
+ tx_initialize_low_level.s.
+ --PD "TX_ENABLE_FIQ_NESTING SETL {TRUE}" This assembler define enables FIQ
+ nested support. If FIQ nested
+ interrupt support is needed, this
+ define should be applied to
+ tx_initialize_low_level.s. In addition,
+ IRQ nesting should also be enabled.
+ -DTX_ENABLE_FIQ_SUPPORT This compiler define enables FIQ
+ interrupt handling in the ThreadX
+ generic C source. This define
+ should also be used in conjunction
+ with the corresponding assembler
+ define.
+ -DTX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included,
+ this define causes basic ThreadX error
+ checking to be disabled. Please see
+ Chapter 2 in the "ThreadX User Guide"
+ for more details.
+
+ -DTX_MAX_PRIORITIES Defines the priority levels for ThreadX.
+ Legal values range from 32 through
+ 1024 (inclusive) and MUST be evenly divisible
+ by 32. Increasing the number of priority levels
+ supported increases the RAM usage by 128 bytes
+ for every group of 32 priorities. However, there
+ is only a negligible effect on performance. By
+ default, this value is set to 32 priority levels.
+
+ -DTX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is
+ used for error checking when threads are created.
+ The default value is port-specific and is found
+ in tx_port.h.
+
+ -DTX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal
+ ThreadX timer thread. This thread processes all
+ thread sleep requests as well as all service call
+ timeouts. In addition, all application timer callback
+ routines are invoked from this context. The default
+ value is port-specific and is found in tx_port.h.
+
+ -DTX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer
+ thread. The default value is priority 0 - the highest
+ priority in ThreadX. The default value is defined
+ in tx_port.h.
+
+ -DTX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system
+ timer thread for ThreadX. This results in improved
+ performance on timer events and smaller RAM requirements
+ because the timer stack and control block are no
+ longer needed. However, using this option moves all
+ the timer expiration processing to the timer ISR level.
+ By default, this option is not defined.
+
+ -DTX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX
+ timers in-line instead of using a function call. This
+ improves performance but slightly increases code size.
+ By default, this option is not defined.
+
+ -DTX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each
+ thread's stack is disabled. By default, this option is
+ not defined.
+
+ -DTX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking,
+ which includes analysis of how much stack has been used and
+ examination of data pattern "fences" before and after the
+ stack area. If a stack error is detected, the registered
+ application stack error handler is called. This option does
+ result in slightly increased overhead and code size. Please
+ review the tx_thread_stack_error_notify API for more information.
+ By default, this option is not defined.
+
+ -DTX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature
+ and slightly reduces code size and improves performance. Of course,
+ the preemption-threshold capabilities are no longer available.
+ By default, this option is not defined.
+
+ -DTX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX
+ global C data structures to zero. This should only be used if
+ the compiler's initialization code sets all un-initialized
+ C global data to zero. Using this option slightly reduces
+ code size and improves performance during initialization.
+ By default, this option is not defined.
+
+ -DTX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various
+ ThreadX objects. Using this option slightly reduces code size
+ and improves performance.
+
+ -DTX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on block pools. By default, this option is
+ not defined.
+
+ -DTX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on byte pools. By default, this option is
+ not defined.
+
+ -DTX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on event flags groups. By default, this option
+ is not defined.
+
+ -DTX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on mutexes. By default, this option is
+ not defined.
+
+ -DTX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on queues. By default, this option is
+ not defined.
+
+ -DTX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on semaphores. By default, this option is
+ not defined.
+
+ -DTX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on threads. By default, this option is
+ not defined.
+
+ -DTX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on timers. By default, this option is
+ not defined.
+
+ -DTX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace
+ feature. The trace buffer is supplied at a later time
+ via an application call to tx_trace_enable.
+
+ -DTX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing.
+ This define is only pertinent if the ThreadX library is
+ built with TX_ENABLE_EVENT_TRACE defined.
+
+ -DTX_TRACE_TIME_MASK This defines the number of valid bits in the event trace
+ time-stamp source defined previously. If the time-stamp
+ source is 16-bits, this value should be 0xFFFF. Alternatively,
+ if the time-stamp source is 32-bits, this value should be
+ 0xFFFFFFFF. This define is only pertinent if the ThreadX
+ library is built with TX_ENABLE_EVENT_TRACE defined.
+
+
+
+5. Register Usage and Stack Frames
+
+The AC5 compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch
+registers for each function. All other registers used by a C function must
+be preserved by the function. ThreadX takes advantage of this in situations
+where a context switch happens as a result of making a ThreadX service call
+(which is itself a C function). In such cases, the saved context of a thread
+is only the non-scratch registers.
+
+The following defines the saved context stack frames for context switches
+that occur as a result of interrupt handling or from thread-level API calls.
+All suspended threads have one of these two types of stack frames. The top
+of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
+associated thread control block TX_THREAD.
+
+
+
+ Offset Interrupted Stack Frame Non-Interrupt Stack Frame
+
+ 0x00 1 0
+ 0x04 CPSR CPSR
+ 0x08 r0 (a1) r4 (v1)
+ 0x0C r1 (a2) r5 (v2)
+ 0x10 r2 (a3) r6 (v3)
+ 0x14 r3 (a4) r7 (v4)
+ 0x18 r4 (v1) r8 (v5)
+ 0x1C r5 (v2) r9 (v6)
+ 0x20 r6 (v3) r10 (v7)
+ 0x24 r7 (v4) r11 (fp)
+ 0x28 r8 (v5) r14 (lr)
+ 0x2C r9 (v6)
+ 0x30 r10 (v7)
+ 0x34 r11 (fp)
+ 0x38 r12 (ip)
+ 0x3C r14 (lr)
+ 0x40 PC
+
+
+6. Improving Performance
+
+The distribution version of ThreadX is built without any compiler
+optimizations. This makes it easy to debug because you can trace or set
+breakpoints inside of ThreadX itself. Of course, this costs some
+performance. To make it run faster, you can change the build_threadx.bat file to
+remove the -g option and enable all compiler optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by
+compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
+defined.
+
+
+7. Interrupt Handling
+
+ThreadX provides complete and high-performance interrupt handling for Cortex-A5
+targets. There are a certain set of requirements that are defined in the
+following sub-sections:
+
+
+7.1 Vector Area
+
+The Cortex-A5 vectors start at address zero. The demonstration system startup
+Init area contains the vectors and is loaded at address zero. On actual
+hardware platforms, this area might have to be copied to address 0.
+
+
+7.2 IRQ ISRs
+
+ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports nested
+IRQ interrupts. The following sub-sections define the IRQ capabilities.
+
+
+7.2.1 Standard IRQ ISRs
+
+The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ
+interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following
+is the default IRQ handler defined in tx_initialize_low_level.s:
+
+ EXPORT __tx_irq_handler
+ EXPORT __tx_irq_processing_return
+__tx_irq_handler
+;
+; /* Jump to context save to save system context. */
+ B _tx_thread_context_save ; Jump to the context save
+__tx_irq_processing_return
+;
+; /* At this point execution is still in the IRQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. Note
+; that IRQ interrupts are still disabled upon return from the context
+; save function. */
+;
+; /* Application ISR call(s) go here! */
+;
+; /* Jump to context restore to restore system context. */
+ B _tx_thread_context_restore
+
+
+7.2.2 Vectored IRQ ISRs
+
+The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified
+by the particular implementation. The following is an example IRQ handler defined in
+tx_initialize_low_level.s:
+
+ EXPORT __tx_irq_example_handler
+__tx_irq_example_handler
+;
+; /* Call context save to save system context. */
+
+ STMDB sp!, {r0-r3} ; Save some scratch registers
+ MRS r0, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r0, r10, r12, lr} ; Store other scratch registers
+ BL _tx_thread_vectored_context_save ; Call the vectored IRQ context save
+;
+; /* At this point execution is still in the IRQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. Note
+; that IRQ interrupts are still disabled upon return from the context
+; save function. */
+;
+; /* Application ISR call goes here! */
+;
+; /* Jump to context restore to restore system context. */
+ B _tx_thread_context_restore
+
+
+7.2.3 Nested IRQ Support
+
+By default, nested IRQ interrupt support is not enabled. To enable nested
+IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING
+defined. With this defined, two new IRQ interrupt management services are
+available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end.
+These function should be called between the IRQ context save and restore
+calls.
+
+Execution between the calls to _tx_thread_irq_nesting_start and
+_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved
+by switching from IRQ mode to SYS mode and enabling IRQ interrupts.
+The SYS mode stack is used during the SYS mode operation, which was
+setup in tx_initialize_low_level.s. When nested IRQ interrupts are no longer required,
+calling the _tx_thread_irq_nesting_end service disables nesting by disabling
+IRQ interrupts and switching back to IRQ mode in preparation for the IRQ
+context restore service.
+
+The following is an example of enabling IRQ nested interrupts in a standard
+IRQ handler:
+
+ EXPORT __tx_irq_handler
+ EXPORT __tx_irq_processing_return
+__tx_irq_handler
+;
+; /* Jump to context save to save system context. */
+ B _tx_thread_context_save
+__tx_irq_processing_return
+;
+; /* Enable nested IRQ interrupts. NOTE: Since this service returns
+; with IRQ interrupts enabled, all IRQ interrupt sources must be
+; cleared prior to calling this service. */
+ BL _tx_thread_irq_nesting_start
+;
+; /* Application ISR call(s) go here! */
+;
+; /* Disable nested IRQ interrupts. The mode is switched back to
+; IRQ mode and IRQ interrupts are disable upon return. */
+ BL _tx_thread_irq_nesting_end
+;
+; /* Jump to context restore to restore system context. */
+ B _tx_thread_context_restore
+
+
+7.3 FIQ Interrupts
+
+By default, Cortex-A5 FIQ interrupts are left alone by ThreadX. Of course, this
+means that the application is fully responsible for enabling the FIQ interrupt
+and saving/restoring any registers used in the FIQ ISR processing. To globally
+enable FIQ interrupts, the application should enable FIQ interrupts at the
+beginning of each thread or before any threads are created in tx_application_define.
+In addition, the application must ensure that no ThreadX service calls are made
+from default FIQ ISRs, which is located in tx_initialize_low_level.s.
+
+
+7.3.1 Managed FIQ Interrupts
+
+Full ThreadX management of FIQ interrupts is provided if the ThreadX sources
+are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built
+this way, the FIQ interrupt handlers are very similar to the IRQ interrupt
+handlers defined previously. The following is default FIQ handler
+defined in tx_initialize_low_level.s:
+
+
+ EXPORT __tx_fiq_handler
+ EXPORT __tx_fiq_processing_return
+__tx_fiq_handler
+;
+; /* Jump to fiq context save to save system context. */
+ B _tx_thread_fiq_context_save
+__tx_fiq_processing_return:
+;
+; /* At this point execution is still in the FIQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. */
+;
+; /* Application FIQ handlers can be called here! */
+;
+; /* Jump to fiq context restore to restore system context. */
+ B _tx_thread_fiq_context_restore
+
+
+7.3.1.1 Nested FIQ Support
+
+By default, nested FIQ interrupt support is not enabled. To enable nested
+FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING
+defined. With this defined, two new FIQ interrupt management services are
+available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end.
+These function should be called between the FIQ context save and restore
+calls.
+
+Execution between the calls to _tx_thread_fiq_nesting_start and
+_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved
+by switching from FIQ mode to SYS mode and enabling FIQ interrupts.
+The SYS mode stack is used during the SYS mode operation, which was
+setup in tx_initialize_low_level.s. When nested FIQ interrupts are no longer required,
+calling the _tx_thread_fiq_nesting_end service disables nesting by disabling
+FIQ interrupts and switching back to FIQ mode in preparation for the FIQ
+context restore service.
+
+The following is an example of enabling FIQ nested interrupts in the
+typical FIQ handler:
+
+
+ EXPORT __tx_fiq_handler
+ EXPORT __tx_fiq_processing_return
+__tx_fiq_handler
+;
+; /* Jump to fiq context save to save system context. */
+ B _tx_thread_fiq_context_save
+__tx_fiq_processing_return
+;
+; /* At this point execution is still in the FIQ mode. The CPSR, point of
+; interrupt, and all C scratch registers are available for use. */
+;
+; /* Enable nested FIQ interrupts. NOTE: Since this service returns
+; with FIQ interrupts enabled, all FIQ interrupt sources must be
+; cleared prior to calling this service. */
+ BL _tx_thread_fiq_nesting_start
+;
+; /* Application FIQ handlers can be called here! */
+;
+; /* Disable nested FIQ interrupts. The mode is switched back to
+; FIQ mode and FIQ interrupts are disable upon return. */
+ BL _tx_thread_fiq_nesting_end
+;
+; /* Jump to fiq context restore to restore system context. */
+ B _tx_thread_fiq_context_restore
+
+
+8. ThreadX Timer Interrupt
+
+ThreadX requires a periodic interrupt source to manage all time-slicing,
+thread sleeps, timeouts, and application timers. Without such a timer
+interrupt source, these services are not functional. However, all other
+ThreadX services are operational without a periodic timer source.
+
+To add the timer interrupt processing, simply make a call to
+_tx_timer_interrupt in the IRQ processing. An example of this can be
+found in the file tx_initialize_low_level.s in the Integrator sub-directories.
+
+
+9. Thumb/Cortex-A5 Mixed Mode
+
+By default, ThreadX is setup for running in Cortex-A5 32-bit mode. This is
+also true for the demonstration system. It is possible to build any
+ThreadX file and/or the application in Thumb mode. If any Thumb code
+is used the entire ThreadX source- both C and assembly - should be built
+with the "-apcs /interwork" option.
+
+11. VFP Support
+
+By default, VFP support is disabled for each thread. If saving the context of the VFP registers
+is needed, the following API call must be made from the context of the application thread - before
+the VFP usage:
+
+void tx_thread_vfp_enable(void);
+
+After this API is called in the application, VFP registers will be saved/restored for this thread if it
+is preempted via an interrupt. All other suspension of the this thread will not require the VFP registers
+to be saved/restored.
+
+To disable VFP register context saving, simply call the following API:
+
+void tx_thread_vfp_disable(void);
+
+
+12. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+06/30/2020 Initial ThreadX 6.0.1 version for Cortex-A5 using AC5 tools.
+
+
+Copyright(c) 1996-2020 Microsoft Corporation
+
+
+https://azure.com/rtos
+
diff --git a/ports/arm11/ac5/src/tx_thread_context_restore.s b/ports/arm11/ac5/src/tx_thread_context_restore.s
new file mode 100644
index 00000000..1d6cd60f
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_context_restore.s
@@ -0,0 +1,247 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+IRQ_MODE EQU 0xD2 ; IRQ mode
+SVC_MODE EQU 0xD3 ; SVC mode
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
+ ELSE
+DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
+ ENDIF
+MODE_MASK EQU 0x1F ; Mode mask
+THUMB_MASK EQU 0x20 ; Thumb bit mask
+SVC_MODE_BITS EQU 0x13 ; SVC mode value
+;
+;
+ IMPORT _tx_thread_system_state
+ IMPORT _tx_thread_current_ptr
+ IMPORT _tx_thread_execute_ptr
+ IMPORT _tx_timer_time_slice
+ IMPORT _tx_thread_schedule
+ IMPORT _tx_thread_preempt_disable
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_isr_exit
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_restore(VOID)
+;{
+ EXPORT _tx_thread_context_restore
+_tx_thread_context_restore
+;
+; /* Lockout interrupts. */
+;
+ MRS r3, CPSR ; Pickup current CPSR
+ ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value
+ MSR CPSR_cxsf, r0 ; Lockout interrupts
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR exit function to indicate an ISR is complete. */
+;
+ BL _tx_execution_isr_exit ; Call the ISR exit function
+ ENDIF
+;
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+;
+ LDR r3, =_tx_thread_system_state ; Pickup address of system state var
+ LDR r2, [r3, #0] ; Pickup system state
+ SUB r2, r2, #1 ; Decrement the counter
+ STR r2, [r3, #0] ; Store the counter
+ CMP r2, #0 ; Was this the first interrupt?
+ BEQ __tx_thread_not_nested_restore ; If so, not a nested restore
+;
+; /* Interrupts are nested. */
+;
+; /* Just recover the saved registers and return to the point of
+; interrupt. */
+;
+ LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 ; Put SPSR back
+ LDMIA sp!, {r0-r3} ; Recover r0-r3
+ MOVS pc, lr ; Return to point of interrupt
+;
+; }
+__tx_thread_not_nested_restore
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+;
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1, #0] ; Pickup actual current thread pointer
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_idle_system_restore ; Yes, idle system was interrupted
+;
+ LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address
+ LDR r2, [r3, #0] ; Pickup actual preempt disable flag
+ CMP r2, #0 ; Is it set?
+ BNE __tx_thread_no_preempt_restore ; Yes, don't preempt this thread
+ LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr
+ LDR r2, [r3, #0] ; Pickup actual execute thread pointer
+ CMP r0, r2 ; Is the same thread highest priority?
+ BNE __tx_thread_preempt_restore ; No, preemption needs to happen
+;
+;
+__tx_thread_no_preempt_restore
+;
+; /* Restore interrupted thread or ISR. */
+;
+; /* Pickup the saved stack pointer. */
+; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
+;
+; /* Recover the saved context and return to the point of interrupt. */
+;
+ LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 ; Put SPSR back
+ LDMIA sp!, {r0-r3} ; Recover r0-r3
+ MOVS pc, lr ; Return to point of interrupt
+;
+; }
+; else
+; {
+__tx_thread_preempt_restore
+;
+ LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
+ MOV r1, lr ; Save lr (point of interrupt)
+ MOV r2, #SVC_MODE ; Build SVC mode CPSR
+ MSR CPSR_c, r2 ; Enter SVC mode
+ STR r1, [sp, #-4]! ; Save point of interrupt
+ STMDB sp!, {r4-r12, lr} ; Save upper half of registers
+ MOV r4, r3 ; Save SPSR in r4
+ MOV r2, #IRQ_MODE ; Build IRQ mode CPSR
+ MSR CPSR_c, r2 ; Enter IRQ mode
+ LDMIA sp!, {r0-r3} ; Recover r0-r3
+ MOV r5, #SVC_MODE ; Build SVC mode CPSR
+ MSR CPSR_c, r5 ; Enter SVC mode
+ STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack
+ MOV r3, #1 ; Build interrupt stack type
+ STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1, #0] ; Pickup current thread pointer
+ STR sp, [r0, #8] ; Save stack pointer in thread control
+ ; block
+ BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR
+ ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s)
+ MSR CPSR_cxsf, r3 ; Lockout interrupts
+;
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+;
+ LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address
+ LDR r2, [r3, #0] ; Pickup time-slice
+ CMP r2, #0 ; Is it active?
+ BEQ __tx_thread_dont_save_ts ; No, don't save it
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ STR r2, [r0, #24] ; Save thread's time-slice
+ MOV r2, #0 ; Clear value
+ STR r2, [r3, #0] ; Disable global time-slice flag
+;
+; }
+__tx_thread_dont_save_ts
+;
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ MOV r0, #0 ; NULL value
+ STR r0, [r1, #0] ; Clear current thread pointer
+;
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+;
+ B _tx_thread_schedule ; Return to scheduler
+; }
+;
+__tx_thread_idle_system_restore
+;
+; /* Just return back to the scheduler! */
+;
+ MRS r3, CPSR ; Pickup current CPSR
+ BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR
+ ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit
+ MSR CPSR_cxsf, r3 ; Lockout interrupts
+ B _tx_thread_schedule ; Return to scheduler
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_context_save.s b/ports/arm11/ac5/src/tx_thread_context_save.s
new file mode 100644
index 00000000..6ce74590
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_context_save.s
@@ -0,0 +1,207 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled
+ ELSE
+DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled
+ ENDIF
+
+ IMPORT _tx_thread_system_state
+ IMPORT _tx_thread_current_ptr
+ IMPORT __tx_irq_processing_return
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_isr_enter
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ EXPORT _tx_thread_context_save
+_tx_thread_context_save
+;
+; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+; out, we are in IRQ mode, and all registers are intact. */
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+ STMDB sp!, {r0-r3} ; Save some working registers
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+ MRS r0, CPSR ; Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR
+ MSR CPSR_cxsf, r0 ; Disable interrupts
+ ENDIF
+ LDR r3, =_tx_thread_system_state ; Pickup address of system state var
+ LDR r2, [r3, #0] ; Pickup system state
+ CMP r2, #0 ; Is this the first interrupt?
+ BEQ __tx_thread_not_nested_save ; Yes, not a nested context save
+;
+; /* Nested interrupt condition. */
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3, #0] ; Store it back in the variable
+;
+; /* Save the rest of the scratch registers on the stack and return to the
+; calling ISR. */
+;
+ MRS r0, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r0, r10, r12, lr} ; Store other registers
+;
+; /* Return to the ISR. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ B __tx_irq_processing_return ; Continue IRQ processing
+;
+__tx_thread_not_nested_save
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3, #0] ; Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1, #0] ; Pickup current thread pointer
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
+ ; scheduling loop - nothing needs saving!
+;
+; /* Save minimal context of interrupted thread. */
+;
+ MRS r2, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r2, r10, r12, lr} ; Store other registers
+;
+; /* Save the current stack pointer in the thread's control block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+;
+; /* Switch to the system stack. */
+; sp = _tx_thread_system_stack_ptr;
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ B __tx_irq_processing_return ; Continue IRQ processing
+;
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+; /* Not much to do here, just adjust the stack pointer, and return to IRQ
+; processing. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ ADD sp, sp, #16 ; Recover saved registers
+ B __tx_irq_processing_return ; Continue IRQ processing
+;
+; }
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s b/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s
new file mode 100644
index 00000000..a183032b
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s
@@ -0,0 +1,259 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+SVC_MODE EQU 0xD3 ; SVC mode
+FIQ_MODE EQU 0xD1 ; FIQ mode
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
+ ELSE
+DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
+ ENDIF
+MODE_MASK EQU 0x1F ; Mode mask
+THUMB_MASK EQU 0x20 ; Thumb bit mask
+IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits
+SVC_MODE_BITS EQU 0x13 ; SVC mode value
+;
+;
+ IMPORT _tx_thread_system_state
+ IMPORT _tx_thread_current_ptr
+ IMPORT _tx_thread_system_stack_ptr
+ IMPORT _tx_thread_execute_ptr
+ IMPORT _tx_timer_time_slice
+ IMPORT _tx_thread_schedule
+ IMPORT _tx_thread_preempt_disable
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_isr_exit
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_fiq_context_restore ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the fiq interrupt context when processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* FIQ ISR Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_fiq_context_restore(VOID)
+;{
+ EXPORT _tx_thread_fiq_context_restore
+_tx_thread_fiq_context_restore
+;
+; /* Lockout interrupts. */
+;
+ MRS r3, CPSR ; Pickup current CPSR
+ ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value
+ MSR CPSR_cxsf, r0 ; Lockout interrupts
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR exit function to indicate an ISR is complete. */
+;
+ BL _tx_execution_isr_exit ; Call the ISR exit function
+ ENDIF
+;
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+;
+ LDR r3, =_tx_thread_system_state ; Pickup address of system state var
+ LDR r2, [r3] ; Pickup system state
+ SUB r2, r2, #1 ; Decrement the counter
+ STR r2, [r3] ; Store the counter
+ CMP r2, #0 ; Was this the first interrupt?
+ BEQ __tx_thread_fiq_not_nested_restore ; If so, not a nested restore
+;
+; /* Interrupts are nested. */
+;
+; /* Just recover the saved registers and return to the point of
+; interrupt. */
+;
+ LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 ; Put SPSR back
+ LDMIA sp!, {r0-r3} ; Recover r0-r3
+ MOVS pc, lr ; Return to point of interrupt
+;
+; }
+__tx_thread_fiq_not_nested_restore
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+;
+ LDR r1, [sp] ; Pickup the saved SPSR
+ MOV r2, #MODE_MASK ; Build mask to isolate the interrupted mode
+ AND r1, r1, r2 ; Isolate mode bits
+ CMP r1, #IRQ_MODE_BITS ; Was an interrupt taken in IRQ mode before we
+ ; got to context save? */
+ BEQ __tx_thread_fiq_no_preempt_restore ; Yes, just go back to point of interrupt
+
+
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1] ; Pickup actual current thread pointer
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_fiq_idle_system_restore ; Yes, idle system was interrupted
+
+ LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address
+ LDR r2, [r3] ; Pickup actual preempt disable flag
+ CMP r2, #0 ; Is it set?
+ BNE __tx_thread_fiq_no_preempt_restore ; Yes, don't preempt this thread
+ LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr
+ LDR r2, [r3] ; Pickup actual execute thread pointer
+ CMP r0, r2 ; Is the same thread highest priority?
+ BNE __tx_thread_fiq_preempt_restore ; No, preemption needs to happen
+
+
+__tx_thread_fiq_no_preempt_restore
+;
+; /* Restore interrupted thread or ISR. */
+;
+; /* Pickup the saved stack pointer. */
+; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
+;
+; /* Recover the saved context and return to the point of interrupt. */
+;
+ LDMIA sp!, {r0, lr} ; Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 ; Put SPSR back
+ LDMIA sp!, {r0-r3} ; Recover r0-r3
+ MOVS pc, lr ; Return to point of interrupt
+;
+; }
+; else
+; {
+__tx_thread_fiq_preempt_restore
+;
+ LDMIA sp!, {r3, lr} ; Recover temporarily saved registers
+ MOV r1, lr ; Save lr (point of interrupt)
+ MOV r2, #SVC_MODE ; Build SVC mode CPSR
+ MSR CPSR_cxsf, r2 ; Enter SVC mode
+ STR r1, [sp, #-4]! ; Save point of interrupt
+ STMDB sp!, {r4-r12, lr} ; Save upper half of registers
+ MOV r4, r3 ; Save SPSR in r4
+ MOV r2, #FIQ_MODE ; Build FIQ mode CPSR
+ MSR CPSR_cxsf, r2 ; Re-enter FIQ mode
+ LDMIA sp!, {r0-r3} ; Recover r0-r3
+ MOV r5, #SVC_MODE ; Build SVC mode CPSR
+ MSR CPSR_cxsf, r5 ; Enter SVC mode
+ STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack
+ MOV r3, #1 ; Build interrupt stack type
+ STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1] ; Pickup current thread pointer
+ STR sp, [r0, #8] ; Save stack pointer in thread control
+ ; block */
+ BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR
+ ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s)
+ MSR CPSR_cxsf, r3 ; Lockout interrupts
+;
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+;
+ LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address
+ LDR r2, [r3] ; Pickup time-slice
+ CMP r2, #0 ; Is it active?
+ BEQ __tx_thread_fiq_dont_save_ts ; No, don't save it
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ STR r2, [r0, #24] ; Save thread's time-slice
+ MOV r2, #0 ; Clear value
+ STR r2, [r3] ; Disable global time-slice flag
+;
+; }
+__tx_thread_fiq_dont_save_ts
+;
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ MOV r0, #0 ; NULL value
+ STR r0, [r1] ; Clear current thread pointer
+;
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+;
+ B _tx_thread_schedule ; Return to scheduler
+; }
+;
+__tx_thread_fiq_idle_system_restore
+;
+; /* Just return back to the scheduler! */
+;
+ ADD sp, sp, #24 ; Recover FIQ stack space
+ MRS r3, CPSR ; Pickup current CPSR
+ BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR
+ ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit
+ MSR CPSR_cxsf, r3 ; Lockout interrupts
+ B _tx_thread_schedule ; Return to scheduler
+;
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_fiq_context_save.s b/ports/arm11/ac5/src/tx_thread_fiq_context_save.s
new file mode 100644
index 00000000..370e0946
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_fiq_context_save.s
@@ -0,0 +1,203 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IMPORT _tx_thread_system_state
+ IMPORT _tx_thread_current_ptr
+ IMPORT __tx_fiq_processing_return
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_isr_enter
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_fiq_context_save ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+; VOID _tx_thread_fiq_context_save(VOID)
+;{
+ EXPORT _tx_thread_fiq_context_save
+_tx_thread_fiq_context_save
+;
+; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+; out, we are in IRQ mode, and all registers are intact. */
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+ STMDB sp!, {r0-r3} ; Save some working registers
+ LDR r3, =_tx_thread_system_state ; Pickup address of system state var
+ LDR r2, [r3] ; Pickup system state
+ CMP r2, #0 ; Is this the first interrupt?
+ BEQ __tx_thread_fiq_not_nested_save ; Yes, not a nested context save
+;
+; /* Nested interrupt condition. */
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3] ; Store it back in the variable
+;
+; /* Save the rest of the scratch registers on the stack and return to the
+; calling ISR. */
+;
+ MRS r0, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r0, r10, r12, lr} ; Store other registers
+;
+; /* Return to the ISR. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ B __tx_fiq_processing_return ; Continue FIQ processing
+;
+__tx_thread_fiq_not_nested_save
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3] ; Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1] ; Pickup current thread pointer
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred in
+; ; scheduling loop - nothing needs saving!
+;
+; /* Save minimal context of interrupted thread. */
+;
+ MRS r2, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r2, lr} ; Store other registers, Note that we don't
+; ; need to save sl and ip since FIQ has
+; ; copies of these registers. Nested
+; ; interrupt processing does need to save
+; ; these registers.
+;
+; /* Save the current stack pointer in the thread's control block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+;
+; /* Switch to the system stack. */
+; sp = _tx_thread_system_stack_ptr;
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ B __tx_fiq_processing_return ; Continue FIQ processing
+;
+; }
+; else
+; {
+;
+__tx_thread_fiq_idle_system_save
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+;
+; /* Not much to do here, save the current SPSR and LR for possible
+; use in IRQ interrupted in idle system conditions, and return to
+; FIQ interrupt processing. */
+;
+ MRS r0, SPSR ; Pickup saved SPSR
+ SUB lr, lr, #4 ; Adjust point of interrupt
+ STMDB sp!, {r0, lr} ; Store other registers that will get used
+; ; or stripped off the stack in context
+; ; restore
+ B __tx_fiq_processing_return ; Continue FIQ processing
+;
+; }
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s b/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s
new file mode 100644
index 00000000..5d81879d
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s
@@ -0,0 +1,111 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
+ ELSE
+DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
+ ENDIF
+MODE_MASK EQU 0x1F ; Mode mask
+FIQ_MODE_BITS EQU 0x11 ; FIQ mode bits
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_fiq_nesting_end ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is called by the application from FIQ mode after */
+;/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */
+;/* processing from system mode back to FIQ mode prior to the ISR */
+;/* calling _tx_thread_fiq_context_restore. Note that this function */
+;/* assumes the system stack pointer is in the same position after */
+;/* nesting start function was called. */
+;/* */
+;/* This function assumes that the system mode stack pointer was setup */
+;/* during low-level initialization (tx_initialize_low_level.s). */
+;/* */
+;/* This function returns with FIQ interrupts disabled. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_fiq_nesting_end(VOID)
+;{
+ EXPORT _tx_thread_fiq_nesting_end
+_tx_thread_fiq_nesting_end
+ MOV r3,lr ; Save ISR return address
+ MRS r0, CPSR ; Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value
+ MSR CPSR_cxsf, r0 ; Disable interrupts
+ LDMIA sp!, {r1, lr} ; Pickup saved lr (and r1 throw-away for
+ ; 8-byte alignment logic)
+ BIC r0, r0, #MODE_MASK ; Clear mode bits
+ ORR r0, r0, #FIQ_MODE_BITS ; Build IRQ mode CPSR
+ MSR CPSR_cxsf, r0 ; Re-enter IRQ mode
+ IF {INTER} = {TRUE}
+ BX r3 ; Return to caller
+ ELSE
+ MOV pc, r3 ; Return to caller
+ ENDIF
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s b/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s
new file mode 100644
index 00000000..32c1b258
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s
@@ -0,0 +1,104 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+FIQ_DISABLE EQU 0x40 ; FIQ disable bit
+MODE_MASK EQU 0x1F ; Mode mask
+SYS_MODE_BITS EQU 0x1F ; System mode bits
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_fiq_nesting_start ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is called by the application from FIQ mode after */
+;/* _tx_thread_fiq_context_save has been called and switches the FIQ */
+;/* processing to the system mode so nested FIQ interrupt processing */
+;/* is possible (system mode has its own "lr" register). Note that */
+;/* this function assumes that the system mode stack pointer was setup */
+;/* during low-level initialization (tx_initialize_low_level.s). */
+;/* */
+;/* This function returns with FIQ interrupts enabled. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_fiq_nesting_start(VOID)
+;{
+ EXPORT _tx_thread_fiq_nesting_start
+_tx_thread_fiq_nesting_start
+ MOV r3,lr ; Save ISR return address
+ MRS r0, CPSR ; Pickup the CPSR
+ BIC r0, r0, #MODE_MASK ; Clear the mode bits
+ ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR
+ MSR CPSR_cxsf, r0 ; Enter system mode
+ STMDB sp!, {r1, lr} ; Push the system mode lr on the system mode stack
+ ; and push r1 just to keep 8-byte alignment
+ BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR
+ MSR CPSR_cxsf, r0 ; Enter system mode
+ IF {INTER} = {TRUE}
+ BX r3 ; Return to caller
+ ELSE
+ MOV pc, r3 ; Return to caller
+ ENDIF
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_control.s b/ports/arm11/ac5/src/tx_thread_interrupt_control.s
new file mode 100644
index 00000000..f11c820e
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_interrupt_control.s
@@ -0,0 +1,102 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+INT_MASK EQU 0xC0 ; Interrupt bit mask
+ ELSE
+INT_MASK EQU 0x80 ; Interrupt bit mask
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+ EXPORT _tx_thread_interrupt_control
+_tx_thread_interrupt_control
+;
+; /* Pickup current interrupt lockout posture. */
+;
+ MRS r3, CPSR ; Pickup current CPSR
+ BIC r1, r3, #INT_MASK ; Clear interrupt lockout bits
+ ORR r1, r1, r0 ; Or-in new interrupt lockout bits
+;
+; /* Apply the new interrupt posture. */
+;
+ MSR CPSR_cxsf, r1 ; Setup new CPSR
+ AND r0, r3, #INT_MASK ; Return previous interrupt mask
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_disable.s b/ports/arm11/ac5/src/tx_thread_interrupt_disable.s
new file mode 100644
index 00000000..a3145dab
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_interrupt_disable.s
@@ -0,0 +1,98 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled
+ ELSE
+DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_disable ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for disabling interrupts */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_disable(void)
+;{
+ EXPORT _tx_thread_interrupt_disable
+_tx_thread_interrupt_disable
+;
+; /* Pickup current interrupt lockout posture. */
+;
+ MRS r0, CPSR ; Pickup current CPSR
+;
+; /* Mask interrupts. */
+;
+ ORR r1, r0, #DISABLE_INTS ; Mask interrupts
+ MSR CPSR_cxsf, r1 ; Setup new CPSR
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_restore.s b/ports/arm11/ac5/src/tx_thread_interrupt_restore.s
new file mode 100644
index 00000000..aad4e743
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_interrupt_restore.s
@@ -0,0 +1,87 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_restore ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for restoring interrupts to the state */
+;/* returned by a previous _tx_thread_interrupt_disable call. */
+;/* */
+;/* INPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_restore(UINT old_posture)
+;{
+ EXPORT _tx_thread_interrupt_restore
+_tx_thread_interrupt_restore
+;
+; /* Apply the new interrupt posture. */
+;
+ MSR CPSR_cxsf, r0 ; Setup new CPSR
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s b/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s
new file mode 100644
index 00000000..415d6152
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s
@@ -0,0 +1,110 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
+ ELSE
+DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
+ ENDIF
+MODE_MASK EQU 0x1F ; Mode mask
+IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_irq_nesting_end ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is called by the application from IRQ mode after */
+;/* _tx_thread_irq_nesting_start has been called and switches the IRQ */
+;/* processing from system mode back to IRQ mode prior to the ISR */
+;/* calling _tx_thread_context_restore. Note that this function */
+;/* assumes the system stack pointer is in the same position after */
+;/* nesting start function was called. */
+;/* */
+;/* This function assumes that the system mode stack pointer was setup */
+;/* during low-level initialization (tx_initialize_low_level.s). */
+;/* */
+;/* This function returns with IRQ interrupts disabled. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_irq_nesting_end(VOID)
+;{
+ EXPORT _tx_thread_irq_nesting_end
+_tx_thread_irq_nesting_end
+ MOV r3,lr ; Save ISR return address
+ MRS r0, CPSR ; Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value
+ MSR CPSR_cxsf, r0 ; Disable interrupts
+ LDMIA sp!, {r1, lr} ; Pickup saved lr (and r1 throw-away for
+ ; 8-byte alignment logic)
+ BIC r0, r0, #MODE_MASK ; Clear mode bits
+ ORR r0, r0, #IRQ_MODE_BITS ; Build IRQ mode CPSR
+ MSR CPSR_cxsf, r0 ; Re-enter IRQ mode
+ IF {INTER} = {TRUE}
+ BX r3 ; Return to caller
+ ELSE
+ MOV pc, r3 ; Return to caller
+ ENDIF
+;}
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s b/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s
new file mode 100644
index 00000000..417235dd
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s
@@ -0,0 +1,104 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+IRQ_DISABLE EQU 0x80 ; IRQ disable bit
+MODE_MASK EQU 0x1F ; Mode mask
+SYS_MODE_BITS EQU 0x1F ; System mode bits
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_irq_nesting_start ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is called by the application from IRQ mode after */
+;/* _tx_thread_context_save has been called and switches the IRQ */
+;/* processing to the system mode so nested IRQ interrupt processing */
+;/* is possible (system mode has its own "lr" register). Note that */
+;/* this function assumes that the system mode stack pointer was setup */
+;/* during low-level initialization (tx_initialize_low_level.s). */
+;/* */
+;/* This function returns with IRQ interrupts enabled. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_irq_nesting_start(VOID)
+;{
+ EXPORT _tx_thread_irq_nesting_start
+_tx_thread_irq_nesting_start
+ MOV r3,lr ; Save ISR return address
+ MRS r0, CPSR ; Pickup the CPSR
+ BIC r0, r0, #MODE_MASK ; Clear the mode bits
+ ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR
+ MSR CPSR_cxsf, r0 ; Enter system mode
+ STMDB sp!, {r1, lr} ; Push the system mode lr on the system mode stack
+ ; and push r1 just to keep 8-byte alignment
+ BIC r0, r0, #IRQ_DISABLE ; Build enable IRQ CPSR
+ MSR CPSR_cxsf, r0 ; Enter system mode
+ IF {INTER} = {TRUE}
+ BX r3 ; Return to caller
+ ELSE
+ MOV pc, r3 ; Return to caller
+ ENDIF
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_schedule.s b/ports/arm11/ac5/src/tx_thread_schedule.s
new file mode 100644
index 00000000..0347394e
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_schedule.s
@@ -0,0 +1,172 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+ENABLE_INTS EQU 0xC0 ; IRQ & FIQ Interrupts enabled mask
+ ELSE
+ENABLE_INTS EQU 0x80 ; IRQ Interrupts enabled mask
+ ENDIF
+;
+;
+ IMPORT _tx_thread_execute_ptr
+ IMPORT _tx_thread_current_ptr
+ IMPORT _tx_timer_time_slice
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_thread_enter
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ EXPORT _tx_thread_schedule
+_tx_thread_schedule
+;
+; /* Enable interrupts. */
+;
+ MRS r2, CPSR ; Pickup CPSR
+ BIC r0, r2, #ENABLE_INTS ; Clear the disable bit(s)
+ MSR CPSR_cxsf, r0 ; Enable interrupts
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ LDR r1, =_tx_thread_execute_ptr ; Address of thread execute ptr
+;
+__tx_thread_schedule_loop
+;
+ LDR r0, [r1, #0] ; Pickup next thread to execute
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; If so, keep looking for a thread
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ MSR CPSR_cxsf, r2 ; Disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread
+ STR r0, [r1, #0] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ LDR r2, [r0, #4] ; Pickup run counter
+ LDR r3, [r0, #24] ; Pickup time-slice for this thread
+ ADD r2, r2, #1 ; Increment thread run-counter
+ STR r2, [r0, #4] ; Store the new run counter
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ LDR r2, =_tx_timer_time_slice ; Pickup address of time slice
+ ; variable
+ LDR sp, [r0, #8] ; Switch stack pointers
+ STR r3, [r2, #0] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+;
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the thread entry function to indicate the thread is executing. */
+;
+ BL _tx_execution_thread_enter ; Call the thread execution enter function
+ ENDIF
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ LDMIA sp!, {r0, r1} ; Pickup the stack type and saved CPSR
+ CMP r0, #0 ; Check for synchronous context switch
+ MSRNE SPSR_cxsf, r1 ; Setup SPSR for return
+ LDMNEIA sp!, {r0-r12, lr, pc}^ ; Return to point of thread interrupt
+ LDMIA sp!, {r4-r11, lr} ; Return to thread synchronously
+ MSR CPSR_cxsf, r1 ; Recover CPSR
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_stack_build.s b/ports/arm11/ac5/src/tx_thread_stack_build.s
new file mode 100644
index 00000000..d9b68fa9
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_stack_build.s
@@ -0,0 +1,156 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+SVC_MODE EQU 0x13 ; SVC mode
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+CPSR_MASK EQU 0xDF ; Mask initial CPSR, IRQ & FIQ ints enabled
+ ELSE
+CPSR_MASK EQU 0x9F ; Mask initial CPSR, IRQ ints enabled
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+;{
+ EXPORT _tx_thread_stack_build
+_tx_thread_stack_build
+;
+;
+; /* Build a fake interrupt frame. The form of the fake interrupt stack
+; on the ARM11 should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; CPSR Initial value for CPSR
+; a1 (r0) Initial value for a1
+; a2 (r1) Initial value for a2
+; a3 (r2) Initial value for a3
+; a4 (r3) Initial value for a4
+; v1 (r4) Initial value for v1
+; v2 (r5) Initial value for v2
+; v3 (r6) Initial value for v3
+; v4 (r7) Initial value for v4
+; v5 (r8) Initial value for v5
+; sb (r9) Initial value for sb
+; sl (r10) Initial value for sl
+; fp (r11) Initial value for fp
+; ip (r12) Initial value for ip
+; lr (r14) Initial value for lr
+; pc (r15) Initial value for pc
+; 0 For stack backtracing
+;
+; Stack Bottom: (higher memory address) */
+;
+ LDR r2, [r0, #16] ; Pickup end of stack area
+ BIC r2, r2, #7 ; Ensure 8-byte alignment
+ SUB r2, r2, #76 ; Allocate space for the stack frame
+;
+; /* Actually build the stack frame. */
+;
+ MOV r3, #1 ; Build interrupt stack type
+ STR r3, [r2, #0] ; Store stack type
+ MOV r3, #0 ; Build initial register value
+ STR r3, [r2, #8] ; Store initial r0
+ STR r3, [r2, #12] ; Store initial r1
+ STR r3, [r2, #16] ; Store initial r2
+ STR r3, [r2, #20] ; Store initial r3
+ STR r3, [r2, #24] ; Store initial r4
+ STR r3, [r2, #28] ; Store initial r5
+ STR r3, [r2, #32] ; Store initial r6
+ STR r3, [r2, #36] ; Store initial r7
+ STR r3, [r2, #40] ; Store initial r8
+ STR r3, [r2, #44] ; Store initial r9
+ LDR r3, [r0, #12] ; Pickup stack starting address
+ STR r3, [r2, #48] ; Store initial r10 (sl)
+ MOV r3, #0 ; Build initial register value
+ STR r3, [r2, #52] ; Store initial r11
+ STR r3, [r2, #56] ; Store initial r12
+ STR r3, [r2, #60] ; Store initial lr
+ STR r1, [r2, #64] ; Store initial pc
+ STR r3, [r2, #68] ; 0 for back-trace
+ MRS r1, CPSR ; Pickup CPSR
+ BIC r1, r1, #CPSR_MASK ; Mask mode bits of CPSR
+ ORR r3, r1, #SVC_MODE ; Build CPSR, SVC mode, interrupts enabled
+ STR r3, [r2, #4] ; Store initial CPSR
+;
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = r2;
+;
+ STR r2, [r0, #8] ; Save stack pointer in thread's
+ ; control block
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;}
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_system_return.s b/ports/arm11/ac5/src/tx_thread_system_return.s
new file mode 100644
index 00000000..9bfd95d9
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_system_return.s
@@ -0,0 +1,150 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;#include "tx_timer.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled
+ ELSE
+DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled
+ ENDIF
+;
+;
+ IMPORT _tx_thread_current_ptr
+ IMPORT _tx_timer_time_slice
+ IMPORT _tx_thread_schedule
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_thread_exit
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the ThreadX system. Only a */
+;/* minimal context is saved since the compiler assumes temp registers */
+;/* are going to get slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_system_return(VOID)
+;{
+ EXPORT _tx_thread_system_return
+_tx_thread_system_return
+;
+; /* Save minimal context on the stack. */
+;
+ MOV r0, #0 ; Build a solicited stack type
+ MRS r1, CPSR ; Pickup the CPSR
+ STMDB sp!, {r0-r1, r4-r11, lr} ; Save minimal context
+;
+; /* Lockout interrupts. */
+;
+ ORR r2, r1, #DISABLE_INTS ; Build disable interrupt CPSR
+ MSR CPSR_cxsf, r2 ; Disable interrupts
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the thread exit function to indicate the thread is no longer executing. */
+;
+ BL _tx_execution_thread_exit ; Call the thread exit function
+ ENDIF
+
+ LDR r3, =_tx_thread_current_ptr ; Pickup address of current ptr
+ LDR r0, [r3, #0] ; Pickup current thread pointer
+ LDR r2, =_tx_timer_time_slice ; Pickup address of time slice
+ LDR r1, [r2, #0] ; Pickup current time slice
+;
+; /* Save current stack and switch to system stack. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+; sp = _tx_thread_system_stack_ptr;
+;
+ STR sp, [r0, #8] ; Save thread stack pointer
+;
+; /* Determine if the time-slice is active. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV r4, #0 ; Build clear value
+ CMP r1, #0 ; Is a time-slice active?
+ BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice
+;
+; /* Save time-slice for the thread and clear the current time-slice. */
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ STR r4, [r2, #0] ; Clear time-slice
+ STR r1, [r0, #24] ; Save current time-slice
+;
+; }
+__tx_thread_dont_save_ts
+;
+; /* Clear the current thread pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ STR r4, [r3, #0] ; Clear current thread pointer
+ B _tx_thread_schedule ; Jump to scheduler!
+;
+;}
+ END
+
diff --git a/ports/arm11/ac5/src/tx_thread_vectored_context_save.s b/ports/arm11/ac5/src/tx_thread_vectored_context_save.s
new file mode 100644
index 00000000..f318ff3d
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_thread_vectored_context_save.s
@@ -0,0 +1,209 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Thread */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_thread.h"
+;
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled
+ ELSE
+DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled
+ ENDIF
+;
+;
+ IMPORT _tx_thread_system_state
+ IMPORT _tx_thread_current_ptr
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ IMPORT _tx_execution_isr_enter
+ ENDIF
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_vectored_context_save ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_vectored_context_save(VOID)
+;{
+ EXPORT _tx_thread_vectored_context_save
+_tx_thread_vectored_context_save
+;
+; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+; out, we are in IRQ mode, and all registers are intact. */
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+ IF :DEF:TX_ENABLE_FIQ_SUPPORT
+ MRS r0, CPSR ; Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR
+ MSR CPSR_cxsf, r0 ; Disable interrupts
+ ENDIF
+ LDR r3, =_tx_thread_system_state ; Pickup address of system state var
+ LDR r2, [r3, #0] ; Pickup system state
+ CMP r2, #0 ; Is this the first interrupt?
+ BEQ __tx_thread_not_nested_save ; Yes, not a nested context save
+;
+; /* Nested interrupt condition. */
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3, #0] ; Store it back in the variable
+;
+; /* Note: Minimal context of interrupted thread is already saved. */
+;
+; /* Return to the ISR. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+__tx_thread_not_nested_save
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD r2, r2, #1 ; Increment the interrupt counter
+ STR r2, [r3, #0] ; Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
+ LDR r0, [r1, #0] ; Pickup current thread pointer
+ CMP r0, #0 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
+ ; scheduling loop - nothing needs saving!
+;
+; /* Note: Minimal context of interrupted thread is already saved. */
+;
+; /* Save the current stack pointer in the thread's control block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+;
+; /* Switch to the system stack. */
+; sp = _tx_thread_system_stack_ptr;
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+; /* Not much to do here, just adjust the stack pointer, and return to IRQ
+; processing. */
+;
+ MOV r10, #0 ; Clear stack limit
+
+ IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+;
+; /* Call the ISR enter function to indicate an ISR is executing. */
+;
+ PUSH {lr} ; Save ISR lr
+ BL _tx_execution_isr_enter ; Call the ISR enter function
+ POP {lr} ; Recover ISR lr
+ ENDIF
+
+ ADD sp, sp, #32 ; Recover saved registers
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+; }
+;}
+;
+ END
+
diff --git a/ports/arm11/ac5/src/tx_timer_interrupt.s b/ports/arm11/ac5/src/tx_timer_interrupt.s
new file mode 100644
index 00000000..158f6930
--- /dev/null
+++ b/ports/arm11/ac5/src/tx_timer_interrupt.s
@@ -0,0 +1,258 @@
+;/**************************************************************************/
+;/* */
+;/* Copyright (c) Microsoft Corporation. All rights reserved. */
+;/* */
+;/* This software is licensed under the Microsoft Software License */
+;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+;/* and in the root directory of this software. */
+;/* */
+;/**************************************************************************/
+;
+;
+;/**************************************************************************/
+;/**************************************************************************/
+;/** */
+;/** ThreadX Component */
+;/** */
+;/** Timer */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_timer.h"
+;#include "tx_thread.h"
+;
+;
+;Define Assembly language external references...
+;
+ IMPORT _tx_timer_time_slice
+ IMPORT _tx_timer_system_clock
+ IMPORT _tx_timer_current_ptr
+ IMPORT _tx_timer_list_start
+ IMPORT _tx_timer_list_end
+ IMPORT _tx_timer_expired_time_slice
+ IMPORT _tx_timer_expired
+ IMPORT _tx_thread_time_slice
+ IMPORT _tx_timer_expiration_process
+;
+;
+ AREA ||.text||, CODE, READONLY
+ PRESERVE8
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt ARM11/AC5 */
+;/* 6.0.1 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_timer_interrupt(VOID)
+;{
+ EXPORT _tx_timer_interrupt
+_tx_timer_interrupt
+;
+; /* Upon entry to this routine, it is assumed that context save has already
+; been called, and therefore the compiler scratch registers are available
+; for use. */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ LDR r1, =_tx_timer_system_clock ; Pickup address of system clock
+ LDR r0, [r1, #0] ; Pickup system clock
+ ADD r0, r0, #1 ; Increment system clock
+ STR r0, [r1, #0] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ LDR r3, =_tx_timer_time_slice ; Pickup address of time-slice
+ LDR r2, [r3, #0] ; Pickup time-slice
+ CMP r2, #0 ; Is it non-active?
+ BEQ __tx_timer_no_time_slice ; Yes, skip time-slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB r2, r2, #1 ; Decrement the time-slice
+ STR r2, [r3, #0] ; Store new time-slice value
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP r2, #0 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, skip expiration processing
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ LDR r3, =_tx_timer_expired_time_slice ; Pickup address of expired flag
+ MOV r0, #1 ; Build expired value
+ STR r0, [r3, #0] ; Set time-slice expiration flag
+;
+; }
+;
+__tx_timer_no_time_slice
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ LDR r1, =_tx_timer_current_ptr ; Pickup current timer pointer addr
+ LDR r0, [r1, #0] ; Pickup current timer
+ LDR r2, [r0, #0] ; Pickup timer list entry
+ CMP r2, #0 ; Is there anything in the list?
+ BEQ __tx_timer_no_timer ; No, just increment the timer
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ LDR r3, =_tx_timer_expired ; Pickup expiration flag address
+ MOV r2, #1 ; Build expired value
+ STR r2, [r3, #0] ; Set expired flag
+ B __tx_timer_done ; Finished timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+ ADD r0, r0, #4 ; Move to next timer
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ LDR r3, =_tx_timer_list_end ; Pickup addr of timer list end
+ LDR r2, [r3, #0] ; Pickup list end
+ CMP r0, r2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, skip wrap-around logic
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ LDR r3, =_tx_timer_list_start ; Pickup addr of timer list start
+ LDR r0, [r3, #0] ; Set current pointer to list start
+;
+__tx_timer_skip_wrap
+;
+ STR r0, [r1, #0] ; Store new current timer pointer
+; }
+;
+__tx_timer_done
+;
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of expired flag
+ LDR r2, [r3, #0] ; Pickup time-slice expired flag
+ CMP r2, #0 ; Did a time-slice expire?
+ BNE __tx_something_expired ; If non-zero, time-slice expired
+ LDR r1, =_tx_timer_expired ; Pickup addr of other expired flag
+ LDR r0, [r1, #0] ; Pickup timer expired flag
+ CMP r0, #0 ; Did a timer expire?
+ BEQ __tx_timer_nothing_expired ; No, nothing expired
+;
+__tx_something_expired
+;
+;
+ STMDB sp!, {r0, lr} ; Save the lr register on the stack
+ ; and save r0 just to keep 8-byte alignment
+;
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+;
+ LDR r1, =_tx_timer_expired ; Pickup addr of expired flag
+ LDR r0, [r1, #0] ; Pickup timer expired flag
+ CMP r0, #0 ; Check for timer expiration
+ BEQ __tx_timer_dont_activate ; If not set, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BL _tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of time-slice expired
+ LDR r2, [r3, #0] ; Pickup the actual flag
+ CMP r2, #0 ; See if the flag is set
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice processing
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BL _tx_thread_time_slice ; Call time-slice processing
+;
+; }
+;
+__tx_timer_not_ts_expiration
+;
+ LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for
+ ; the 8-byte stack alignment
+;
+; }
+;
+__tx_timer_nothing_expired
+;
+ IF {INTER} = {TRUE}
+ BX lr ; Return to caller
+ ELSE
+ MOV pc, lr ; Return to caller
+ ENDIF
+;
+;}
+ END
+