summaryrefslogtreecommitdiff
path: root/ports/arm11/gnu
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/gnu
parent608f55f0d120886e0eddf7e39cf3c3b6f06bd08c (diff)
add ARM11v6.0.1_rel
Diffstat (limited to 'ports/arm11/gnu')
-rw-r--r--ports/arm11/gnu/example_build/build_threadx.bat238
-rw-r--r--ports/arm11/gnu/example_build/build_threadx_sample.bat6
-rw-r--r--ports/arm11/gnu/example_build/crt0.S90
-rw-r--r--ports/arm11/gnu/example_build/libc.abin0 -> 1207876 bytes
-rw-r--r--ports/arm11/gnu/example_build/libgcc.abin0 -> 261004 bytes
-rw-r--r--ports/arm11/gnu/example_build/libnosys.abin0 -> 29354 bytes
-rw-r--r--ports/arm11/gnu/example_build/reset.S76
-rw-r--r--ports/arm11/gnu/example_build/sample_threadx.c369
-rw-r--r--ports/arm11/gnu/example_build/sample_threadx.ld239
-rw-r--r--ports/arm11/gnu/example_build/tx_initialize_low_level.S347
-rw-r--r--ports/arm11/gnu/inc/tx_port.h316
-rw-r--r--ports/arm11/gnu/readme_threadx.txt496
-rw-r--r--ports/arm11/gnu/src/tx_thread_context_restore.S241
-rw-r--r--ports/arm11/gnu/src/tx_thread_context_save.S210
-rw-r--r--ports/arm11/gnu/src/tx_thread_fiq_context_restore.S256
-rw-r--r--ports/arm11/gnu/src/tx_thread_fiq_context_save.S204
-rw-r--r--ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S111
-rw-r--r--ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S104
-rw-r--r--ports/arm11/gnu/src/tx_thread_interrupt_control.S115
-rw-r--r--ports/arm11/gnu/src/tx_thread_interrupt_disable.S116
-rw-r--r--ports/arm11/gnu/src/tx_thread_interrupt_restore.S104
-rw-r--r--ports/arm11/gnu/src/tx_thread_irq_nesting_end.S111
-rw-r--r--ports/arm11/gnu/src/tx_thread_irq_nesting_start.S104
-rw-r--r--ports/arm11/gnu/src/tx_thread_schedule.S187
-rw-r--r--ports/arm11/gnu/src/tx_thread_stack_build.S178
-rw-r--r--ports/arm11/gnu/src/tx_thread_system_return.S167
-rw-r--r--ports/arm11/gnu/src/tx_thread_vectored_context_save.S199
-rw-r--r--ports/arm11/gnu/src/tx_timer_interrupt.S279
28 files changed, 4863 insertions, 0 deletions
diff --git a/ports/arm11/gnu/example_build/build_threadx.bat b/ports/arm11/gnu/example_build/build_threadx.bat
new file mode 100644
index 00000000..812a730e
--- /dev/null
+++ b/ports/arm11/gnu/example_build/build_threadx.bat
@@ -0,0 +1,238 @@
+del tx.a
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s tx_initialize_low_level.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_stack_build.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_schedule.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_system_return.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_context_save.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_context_restore.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_control.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_timer_interrupt.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_disable.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_restore.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_context_save.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_nesting_start.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_irq_nesting_start.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_irq_nesting_end.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_nesting_end.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_context_restore.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_vectored_context_save.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c
+arm-none-eabi-ar -r 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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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
+arm-none-eabi-ar -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/gnu/example_build/build_threadx_sample.bat b/ports/arm11/gnu/example_build/build_threadx_sample.bat
new file mode 100644
index 00000000..e67e3c20
--- /dev/null
+++ b/ports/arm11/gnu/example_build/build_threadx_sample.bat
@@ -0,0 +1,6 @@
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s reset.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s crt0.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s tx_initialize_low_level.S
+arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc sample_threadx.c
+arm-none-eabi-ld -A arm1136j-s -T sample_threadx.ld reset.o crt0.o tx_initialize_low_level.o sample_threadx.o tx.a libc.a libnosys.a libgcc.a -o sample_threadx.out -M > sample_threadx.map
+
diff --git a/ports/arm11/gnu/example_build/crt0.S b/ports/arm11/gnu/example_build/crt0.S
new file mode 100644
index 00000000..aa0f3239
--- /dev/null
+++ b/ports/arm11/gnu/example_build/crt0.S
@@ -0,0 +1,90 @@
+
+/* .text is used instead of .section .text so it works with arm-aout too. */
+ .text
+ .code 32
+ .align 0
+
+ .global _mainCRTStartup
+ .global _start
+ .global start
+start:
+_start:
+_mainCRTStartup:
+
+/* Start by setting up a stack */
+ /* Set up the stack pointer to a fixed value */
+ ldr r3, .LC0
+ mov sp, r3
+ /* Setup a default stack-limit in case the code has been
+ compiled with "-mapcs-stack-check". Hard-wiring this value
+ is not ideal, since there is currently no support for
+ checking that the heap and stack have not collided, or that
+ this default 64k is enough for the program being executed.
+ However, it ensures that this simple crt0 world will not
+ immediately cause an overflow event: */
+ sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
+ mov a2, #0 /* Second arg: fill value */
+ mov fp, a2 /* Null frame pointer */
+ mov r7, a2 /* Null frame pointer for Thumb */
+
+ ldr a1, .LC1 /* First arg: start of memory block */
+ ldr a3, .LC2
+ sub a3, a3, a1 /* Third arg: length of block */
+
+
+
+ bl memset
+ mov r0, #0 /* no arguments */
+ mov r1, #0 /* no argv either */
+#ifdef __USES_INITFINI__
+ /* Some arm/elf targets use the .init and .fini sections
+ to create constructors and destructors, and for these
+ targets we need to call the _init function and arrange
+ for _fini to be called at program exit. */
+ mov r4, r0
+ mov r5, r1
+/* ldr r0, .Lfini */
+ bl atexit
+/* bl init */
+ mov r0, r4
+ mov r1, r5
+#endif
+ bl main
+
+ bl exit /* Should not return. */
+
+
+ /* For Thumb, constants must be after the code since only
+ positive offsets are supported for PC relative addresses. */
+
+ .align 0
+.LC0:
+.LC1:
+ .word __bss_start__
+.LC2:
+ .word __bss_end__
+/*
+#ifdef __USES_INITFINI__
+.Lfini:
+ .word _fini
+#endif */
+ /* Return ... */
+#ifdef __APCS_26__
+ movs pc, lr
+#else
+#ifdef __THUMB_INTERWORK
+ bx lr
+#else
+ mov pc, lr
+#endif
+#endif
+
+
+/* Workspace for Angel calls. */
+ .data
+/* Data returned by monitor SWI. */
+.global __stack_base__
+HeapBase: .word 0
+HeapLimit: .word 0
+__stack_base__: .word 0
+StackLimit: .word 0
diff --git a/ports/arm11/gnu/example_build/libc.a b/ports/arm11/gnu/example_build/libc.a
new file mode 100644
index 00000000..b03b1626
--- /dev/null
+++ b/ports/arm11/gnu/example_build/libc.a
Binary files differ
diff --git a/ports/arm11/gnu/example_build/libgcc.a b/ports/arm11/gnu/example_build/libgcc.a
new file mode 100644
index 00000000..da2319e0
--- /dev/null
+++ b/ports/arm11/gnu/example_build/libgcc.a
Binary files differ
diff --git a/ports/arm11/gnu/example_build/libnosys.a b/ports/arm11/gnu/example_build/libnosys.a
new file mode 100644
index 00000000..b70de481
--- /dev/null
+++ b/ports/arm11/gnu/example_build/libnosys.a
Binary files differ
diff --git a/ports/arm11/gnu/example_build/reset.S b/ports/arm11/gnu/example_build/reset.S
new file mode 100644
index 00000000..856e31eb
--- /dev/null
+++ b/ports/arm11/gnu/example_build/reset.S
@@ -0,0 +1,76 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+
+ .arm
+
+ .global _start
+ .global __tx_undefined
+ .global __tx_swi_interrupt
+ .global __tx_prefetch_handler
+ .global __tx_abort_handler
+ .global __tx_reserved_handler
+ .global __tx_irq_handler
+ .global __tx_fiq_handler
+@
+@
+@/* Define the vector area. This should be located or copied to 0. */
+@
+ .text
+ .global __vectors
+__vectors:
+
+ LDR pc, STARTUP @ Reset goes to startup function
+ LDR pc, UNDEFINED @ Undefined handler
+ LDR pc, SWI @ Software interrupt handler
+ LDR pc, PREFETCH @ Prefetch exception handler
+ LDR pc, ABORT @ Abort exception handler
+ LDR pc, RESERVED @ Reserved exception handler
+ LDR pc, IRQ @ IRQ interrupt handler
+ LDR pc, FIQ @ FIQ interrupt handler
+
+STARTUP:
+ .word _start @ Reset goes to C startup function
+UNDEFINED:
+ .word __tx_undefined @ Undefined handler
+SWI:
+ .word __tx_swi_interrupt @ Software interrupt handler
+PREFETCH:
+ .word __tx_prefetch_handler @ Prefetch exception handler
+ABORT:
+ .word __tx_abort_handler @ Abort exception handler
+RESERVED:
+ .word __tx_reserved_handler @ Reserved exception handler
+IRQ:
+ .word __tx_irq_handler @ IRQ interrupt handler
+FIQ:
+ .word __tx_fiq_handler @ FIQ interrupt handler
diff --git a/ports/arm11/gnu/example_build/sample_threadx.c b/ports/arm11/gnu/example_build/sample_threadx.c
new file mode 100644
index 00000000..418ec634
--- /dev/null
+++ b/ports/arm11/gnu/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/gnu/example_build/sample_threadx.ld b/ports/arm11/gnu/example_build/sample_threadx.ld
new file mode 100644
index 00000000..3dea4e1c
--- /dev/null
+++ b/ports/arm11/gnu/example_build/sample_threadx.ld
@@ -0,0 +1,239 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+/* ENTRY(_start) */
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ . = 0x00000000;
+
+ .vectors : {reset.o(.text) }
+
+ /* Read-only sections, merged into text segment: */
+ . = 0x00001000;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.text :
+ {
+ *(.rel.text)
+ *(.rel.text.*)
+ *(.rel.gnu.linkonce.t*)
+ }
+ .rela.text :
+ {
+ *(.rela.text)
+ *(.rela.text.*)
+ *(.rela.gnu.linkonce.t*)
+ }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.rodata :
+ {
+ *(.rel.rodata)
+ *(.rel.rodata.*)
+ *(.rel.gnu.linkonce.r*)
+ }
+ .rela.rodata :
+ {
+ *(.rela.rodata)
+ *(.rela.rodata.*)
+ *(.rela.gnu.linkonce.r*)
+ }
+ .rel.data :
+ {
+ *(.rel.data)
+ *(.rel.data.*)
+ *(.rel.gnu.linkonce.d*)
+ }
+ .rela.data :
+ {
+ *(.rela.data)
+ *(.rela.data.*)
+ *(.rela.gnu.linkonce.d*)
+ }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.sdata :
+ {
+ *(.rel.sdata)
+ *(.rel.sdata.*)
+ *(.rel.gnu.linkonce.s*)
+ }
+ .rela.sdata :
+ {
+ *(.rela.sdata)
+ *(.rela.sdata.*)
+ *(.rela.gnu.linkonce.s*)
+ }
+ .rel.sbss : { *(.rel.sbss) }
+ .rela.sbss : { *(.rela.sbss) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ *(.glue_7t) *(.glue_7)
+ } =0
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(256) + (. & (256 - 1));
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ .eh_frame : { KEEP (*(.eh_frame)) }
+ .gcc_except_table : { *(.gcc_except_table) }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata :
+ {
+ *(.sdata)
+ *(.sdata.*)
+ *(.gnu.linkonce.s.*)
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .sbss :
+ {
+ *(.dynsbss)
+ *(.sbss)
+ *(.sbss.*)
+ *(.scommon)
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+
+ _bss_end__ = . ; __bss_end__ = . ;
+ PROVIDE (end = .);
+
+ .stack :
+ {
+
+ _stack_bottom = ABSOLUTE(.) ;
+
+ /* Allocate room for stack. This must be big enough for the IRQ, FIQ, and
+ SYS stack if nested interrupts are enabled. */
+ . = ALIGN(8) ;
+ . += 4096 ;
+ _sp = . - 16 ;
+ _stack_top = ABSOLUTE(.) ;
+ }
+
+ _end = .; __end__ = . ;
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /* These must appear regardless of . */
+}
diff --git a/ports/arm11/gnu/example_build/tx_initialize_low_level.S b/ports/arm11/gnu/example_build/tx_initialize_low_level.S
new file mode 100644
index 00000000..1cce43f6
--- /dev/null
+++ b/ports/arm11/gnu/example_build/tx_initialize_low_level.S
@@ -0,0 +1,347 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+
+ .arm
+
+SVC_MODE = 0xD3 @ Disable IRQ/FIQ SVC mode
+IRQ_MODE = 0xD2 @ Disable IRQ/FIQ IRQ mode
+FIQ_MODE = 0xD1 @ Disable IRQ/FIQ FIQ mode
+SYS_MODE = 0xDF @ Disable IRQ/FIQ SYS mode
+FIQ_STACK_SIZE = 512 @ FIQ stack size
+IRQ_STACK_SIZE = 1024 @ IRQ stack size
+SYS_STACK_SIZE = 1024 @ System stack size
+@
+@
+ .global _tx_thread_system_stack_ptr
+ .global _tx_initialize_unused_memory
+ .global _tx_thread_context_save
+ .global _tx_thread_context_restore
+ .global _tx_timer_interrupt
+ .global _end
+ .global _sp
+ .global _stack_bottom
+
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .thumb
+ .global $_tx_initialize_low_level
+ .type $_tx_initialize_low_level,function
+$_tx_initialize_low_level:
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_initialize_low_level @ Call _tx_initialize_low_level function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_initialize_low_level ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_initialize_low_level
+ .type _tx_initialize_low_level,function
+_tx_initialize_low_level:
+@
+@ /* We must be in SVC mode at this point! */
+@
+@ /* Setup various stack pointers. */
+@
+ LDR r1, =_sp @ Get pointer to stack area
+
+#ifdef 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
+ SUB r1, r1, #1 @ Backup 1 byte
+ BIC r1, r1, #7 @ Ensure 8-byte alignment
+ MOV sp, r1 @ Setup SYS stack pointer
+ SUB r1, r1, r2 @ Calculate start of next stack
+#endif
+
+ LDR r2, =FIQ_STACK_SIZE @ Pickup stack size
+ MOV r0, #FIQ_MODE @ Build FIQ mode CPSR
+ MSR CPSR, r0 @ Enter FIQ mode
+ SUB r1, r1, #1 @ Backup 1 byte
+ BIC r1, r1, #7 @ Ensure 8-byte alignment
+ MOV sp, r1 @ Setup FIQ stack pointer
+ SUB r1, r1, r2 @ Calculate start of next stack
+ LDR r2, =IRQ_STACK_SIZE @ Pickup IRQ stack size
+ MOV r0, #IRQ_MODE @ Build IRQ mode CPSR
+ MSR CPSR, r0 @ Enter IRQ mode
+ SUB r1, r1, #1 @ Backup 1 byte
+ BIC r1, r1, #7 @ Ensure 8-byte alignment
+ MOV sp, r1 @ Setup IRQ stack pointer
+ SUB r3, r1, r2 @ Calculate end of IRQ stack
+ MOV r0, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR, r0 @ Enter SVC mode
+ LDR r2, =_stack_bottom @ Pickup stack bottom
+ CMP r3, r2 @ Compare the current stack end with the bottom
+_stack_error_loop:
+ BLT _stack_error_loop @ If the IRQ stack exceeds the stack bottom, just sit here!
+@
+@ /* Save the system stack pointer. */
+@ _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
+@
+ LDR r2, =_tx_thread_system_stack_ptr @ Pickup stack pointer
+ STR r1, [r2] @ Save the system stack
+@
+@ /* Save the first available memory address. */
+@ _tx_initialize_unused_memory = (VOID_PTR) _end;
+@
+ LDR r1, =_end @ Get end of non-initialized RAM area
+ LDR r2, =_tx_initialize_unused_memory @ Pickup unused memory ptr address
+ ADD r1, r1, #8 @ Increment to next free word
+ STR r1, [r2] @ Save first free memory address
+@
+@ /* Setup Timer for periodic interrupts. */
+@
+@ /* Done, return to caller. */
+@
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+@
+@
+@/* Define shells for each of the interrupt vectors. */
+@
+ .global __tx_undefined
+__tx_undefined:
+ B __tx_undefined @ Undefined handler
+@
+ .global __tx_swi_interrupt
+__tx_swi_interrupt:
+ B __tx_swi_interrupt @ Software interrupt handler
+@
+ .global __tx_prefetch_handler
+__tx_prefetch_handler:
+ B __tx_prefetch_handler @ Prefetch exception handler
+@
+ .global __tx_abort_handler
+__tx_abort_handler:
+ B __tx_abort_handler @ Abort exception handler
+@
+ .global __tx_reserved_handler
+__tx_reserved_handler:
+ B __tx_reserved_handler @ Reserved exception handler
+@
+ .global __tx_irq_handler
+ .global __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. */
+@
+@ /* 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. */
+#ifdef TX_ENABLE_IRQ_NESTING
+ BL _tx_thread_irq_nesting_start
+#endif
+@
+@ /* For debug purpose, execute the timer interrupt processing here. In
+@ a real system, some kind of status indication would have to be checked
+@ before the timer interrupt handler could be called. */
+@
+ BL _tx_timer_interrupt @ Timer interrupt handler
+@
+@
+@ /* 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. */
+#ifdef 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. */
+@
+@ .global __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. */
+@#ifdef 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. */
+@#ifdef TX_ENABLE_IRQ_NESTING
+@ BL _tx_thread_irq_nesting_end
+@#endif
+@
+@ /* Jump to context restore to restore system context. */
+@ B _tx_thread_context_restore
+@
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ .global __tx_fiq_handler
+ .global __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. */
+#ifdef 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. */
+#ifdef 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
+ .global __tx_fiq_handler
+__tx_fiq_handler:
+ B __tx_fiq_handler @ FIQ interrupt handler
+#endif
+@
+@
+BUILD_OPTIONS:
+ .word _tx_build_options @ Reference to bring in
+VERSION_ID:
+ .word _tx_version_id @ Reference to bring in
+
+
+
diff --git a/ports/arm11/gnu/inc/tx_port.h b/ports/arm11/gnu/inc/tx_port.h
new file mode 100644
index 00000000..3b8e85bf
--- /dev/null
+++ b/ports/arm11/gnu/inc/tx_port.h
@@ -0,0 +1,316 @@
+/**************************************************************************/
+/* */
+/* 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/GNU */
+/* 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. */
+
+#if __TARGET_ARCH_ARM > 4
+
+#ifndef __thumb__
+
+#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
+ asm volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); \
+ b = 31 - b;
+#endif
+#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. */
+
+#ifdef __thumb__
+
+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);
+
+#else
+
+#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save, tx_temp;
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+#define TX_DISABLE asm volatile (" MRS %0,CPSR; ORR %1,%0,#0xC0; MSR CPSR_cxsf,%1 ": "=r" (interrupt_save), "=r" (tx_temp) );
+#else
+#define TX_DISABLE asm volatile (" MRS %0,CPSR; ORR %1,%0,#0x80; MSR CPSR_cxsf,%1 ": "=r" (interrupt_save), "=r" (tx_temp) );
+#endif
+
+#define TX_RESTORE asm volatile (" MSR CPSR_cxsf,%0 "::"r" (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/GNU Version 6.0.1 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+#endif
+
diff --git a/ports/arm11/gnu/readme_threadx.txt b/ports/arm11/gnu/readme_threadx.txt
new file mode 100644
index 00000000..5f36d8ed
--- /dev/null
+++ b/ports/arm11/gnu/readme_threadx.txt
@@ -0,0 +1,496 @@
+ Microsoft's Azure RTOS ThreadX for ARM11
+
+ Using the GNU Tools
+
+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 GNU
+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
+
+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 DEMO is a binary file
+that can be downloaded and executed.
+
+
+3. System Initialization
+
+The entry point in ThreadX for the ARM11 using GNU tools is at label _start.
+This is defined within the modified version of the GNU startup code - crt0.S.
+
+The ThreadX tx_initialize_low_level.S file is responsible for setting up various
+system data structures, the interrupt vectors, and a periodic timer interrupt source.
+By default, the vector area is defined to be located at the "__vectors" label,
+which is defined in reset.S. This area is typically located at 0. In situations
+where this is impossible, the vectors at the "__vectors" label 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 defines 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/Assembler Meaning
+ Switches
+
+ -g Specifies debug information
+ -c Specifies object code generation
+ -mcpu=arm1136j-s Specifies target cpu
+
+Linker Switch Meaning
+
+ -o sample_threadx.out Specifies output file
+ -M > sample_threadx.map Specifies demo map file
+ -A arm1136j-s Specifies target architecture
+ -T sample_threadx.ld Specifies the loader control file
+
+Application Defines ( -D option)
+
+ TX_ENABLE_FIQ_SUPPORT 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.
+
+ TX_ENABLE_IRQ_NESTING 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.
+
+ TX_ENABLE_FIQ_NESTING 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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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.
+
+ TX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various
+ ThreadX objects. Using this option slightly reduces code size
+ and improves performance.
+
+ TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on block pools. By default, this option is
+ not defined.
+
+ TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on byte pools. By default, this option is
+ not defined.
+
+ TX_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.
+
+ TX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on mutexes. By default, this option is
+ not defined.
+
+ TX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on queues. By default, this option is
+ not defined.
+
+ TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on semaphores. By default, this option is
+ not defined.
+
+ TX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on threads. By default, this option is
+ not defined.
+
+ TX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
+ information on timers. By default, this option is
+ not defined.
+
+ TX_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.
+
+ TX_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.
+
+ TX_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 GNU 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
+
+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 ARM11
+targets. There are a certain set of requirements that are defined in the
+following sub-sections:
+
+
+7.1 Vector Area
+
+The ARM11 vectors start at address zero. The demonstration system startup
+reset.S file 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:
+
+ .global __tx_irq_handler
+ .global __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:
+
+ .global __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:
+
+ .global __tx_irq_handler
+ .global __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, ARM7 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:
+
+
+ .global __tx_fiq_handler
+ .global __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:
+
+
+ .global __tx_fiq_handler
+ .global __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 but the remainder of
+ThreadX will still run.
+
+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 for the demonstration system.
+
+
+9. 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 ARM11 using GNU tools.
+
+
+Copyright(c) 1996-2020 Microsoft Corporation
+
+
+https://azure.com/rtos
+
diff --git a/ports/arm11/gnu/src/tx_thread_context_restore.S b/ports/arm11/gnu/src/tx_thread_context_restore.S
new file mode 100644
index 00000000..9e116197
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_context_restore.S
@@ -0,0 +1,241 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+ .arm
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+SVC_MODE = 0xD3 @ Disable IRQ/FIQ, SVC mode
+IRQ_MODE = 0xD2 @ Disable IRQ/FIQ, IRQ mode
+#else
+SVC_MODE = 0x93 @ Disable IRQ, SVC mode
+IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
+#endif
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_thread_execute_ptr
+ .global _tx_timer_time_slice
+ .global _tx_thread_schedule
+ .global _tx_thread_preempt_disable
+ .global _tx_execution_isr_exit
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_context_restore ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_context_restore
+ .type _tx_thread_context_restore,function
+_tx_thread_context_restore:
+@
+@ /* Lockout interrupts. */
+@
+ MOV r0, #IRQ_MODE @ Build disable interrupts CPSR
+ MSR CPSR, r0 @ Lockout interrupts
+
+#ifdef 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 variable
+ 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_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, 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] @ 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] @ 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] @ 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, 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, 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, r2 @ Enter IRQ mode
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOV r5, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR, 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
+@
+@ /* 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_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_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_idle_system_restore:
+@
+@ /* Just return back to the scheduler! */
+@
+ MOV r0, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR, r0 @ Enter SVC mode
+ B _tx_thread_schedule @ Return to scheduler
+@}
+
+
+
diff --git a/ports/arm11/gnu/src/tx_thread_context_save.S b/ports/arm11/gnu/src/tx_thread_context_save.S
new file mode 100644
index 00000000..8a072cf5
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_context_save.S
@@ -0,0 +1,210 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
+#else
+DISABLE_INTS = 0x80 @ IRQ interrupts disabled
+#endif
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_irq_processing_return
+ .global _tx_execution_isr_enter
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_context_save ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_context_save
+ .type _tx_thread_context_save,function
+_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
+#ifdef 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 variable
+ LDR r2, [r3] @ 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] @ 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
+
+#ifdef 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] @ 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_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
+
+#ifdef 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
+
+#ifdef 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
+@
+@ }
+@}
+
+
+
diff --git a/ports/arm11/gnu/src/tx_thread_fiq_context_restore.S b/ports/arm11/gnu/src/tx_thread_fiq_context_restore.S
new file mode 100644
index 00000000..44acd526
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_fiq_context_restore.S
@@ -0,0 +1,256 @@
+@/**************************************************************************/
+@/* */
+@/* 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 = 0xD3 @ SVC mode
+FIQ_MODE = 0xD1 @ FIQ mode
+DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
+MODE_MASK = 0x1F @ Mode mask
+THUMB_MASK = 0x20 @ Thumb bit mask
+IRQ_MODE_BITS = 0x12 @ IRQ mode bits
+SVC_MODE_BITS = 0x13 @ SVC mode value
+@
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_thread_system_stack_ptr
+ .global _tx_thread_execute_ptr
+ .global _tx_timer_time_slice
+ .global _tx_thread_schedule
+ .global _tx_thread_preempt_disable
+ .global _tx_execution_isr_exit
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_context_restore ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_fiq_context_restore
+ .type _tx_thread_fiq_context_restore,function
+_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
+
+#ifdef 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 variable
+ 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 @ Reenter 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
+@
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_fiq_context_save.S b/ports/arm11/gnu/src/tx_thread_fiq_context_save.S
new file mode 100644
index 00000000..53b12f9b
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_fiq_context_save.S
@@ -0,0 +1,204 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global __tx_fiq_processing_return
+ .global _tx_execution_isr_enter
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_context_save ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_fiq_context_save
+ .type _tx_thread_fiq_context_save,function
+_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 variable
+ 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
+
+#ifdef 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
+
+#ifdef 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. */
+@
+#ifdef 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
+@
+@ }
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S b/ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S
new file mode 100644
index 00000000..cc0d4991
--- /dev/null
+++ b/ports/arm11/gnu/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"
+@
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
+#else
+DISABLE_INTS = 0x80 @ Disable IRQ interrupts
+#endif
+MODE_MASK = 0x1F @ Mode mask
+FIQ_MODE_BITS = 0x11 @ FIQ mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_nesting_end ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_fiq_nesting_end
+ .type _tx_thread_fiq_nesting_end,function
+_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 @ Reenter IRQ mode
+ MOV pc, r3 @ Return to caller
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S b/ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S
new file mode 100644
index 00000000..b9dda19e
--- /dev/null
+++ b/ports/arm11/gnu/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 = 0x40 @ FIQ disable bit
+MODE_MASK = 0x1F @ Mode mask
+SYS_MODE_BITS = 0x1F @ System mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_nesting_start ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_fiq_nesting_start
+ .type _tx_thread_fiq_nesting_start,function
+_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
+ MOV pc, r3 @ Return to caller
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_interrupt_control.S b/ports/arm11/gnu/src/tx_thread_interrupt_control.S
new file mode 100644
index 00000000..4cf397c9
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_interrupt_control.S
@@ -0,0 +1,115 @@
+@/**************************************************************************/
+@/* */
+@/* 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" */
+@
+
+INT_MASK = 0x03F
+
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_interrupt_control
+$_tx_thread_interrupt_control:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_interrupt_control @ Call _tx_thread_interrupt_control function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_interrupt_control ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_interrupt_control
+ .type _tx_thread_interrupt_control,function
+_tx_thread_interrupt_control:
+@
+@ /* Pickup current interrupt lockout posture. */
+@
+ MRS r3, CPSR @ Pickup current CPSR
+ MOV r2, #INT_MASK @ Build interrupt mask
+ AND r1, r3, r2 @ Clear interrupt lockout bits
+ ORR r1, r1, r0 @ Or-in new interrupt lockout bits
+@
+@ /* Apply the new interrupt posture. */
+@
+ MSR CPSR, r1 @ Setup new CPSR
+ BIC r0, r3, r2 @ Return previous interrupt mask
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_interrupt_disable.S b/ports/arm11/gnu/src/tx_thread_interrupt_disable.S
new file mode 100644
index 00000000..9d460e24
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_interrupt_disable.S
@@ -0,0 +1,116 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
+#else
+DISABLE_INTS = 0x80 @ IRQ interrupts disabled
+#endif
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_interrupt_disable
+$_tx_thread_interrupt_disable:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_interrupt_disable @ Call _tx_thread_interrupt_disable function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_interrupt_disable ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_interrupt_disable
+ .type _tx_thread_interrupt_disable,function
+_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
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
+
diff --git a/ports/arm11/gnu/src/tx_thread_interrupt_restore.S b/ports/arm11/gnu/src/tx_thread_interrupt_restore.S
new file mode 100644
index 00000000..0a06d5ea
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_interrupt_restore.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"
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_interrupt_restore
+$_tx_thread_interrupt_restore:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_interrupt_restore @ Call _tx_thread_interrupt_restore function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_interrupt_restore ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_interrupt_restore
+ .type _tx_thread_interrupt_restore,function
+_tx_thread_interrupt_restore:
+@
+@ /* Apply the new interrupt posture. */
+@
+ MSR CPSR_cxsf, r0 @ Setup new CPSR
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_irq_nesting_end.S b/ports/arm11/gnu/src/tx_thread_irq_nesting_end.S
new file mode 100644
index 00000000..3fda4dae
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_irq_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"
+@
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
+#else
+DISABLE_INTS = 0x80 @ Disable IRQ interrupts
+#endif
+MODE_MASK = 0x1F @ Mode mask
+IRQ_MODE_BITS = 0x12 @ IRQ mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_irq_nesting_end ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_irq_nesting_end
+ .type _tx_thread_irq_nesting_end,function
+_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 @ Reenter IRQ mode
+ MOV pc, r3 @ Return to caller
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_irq_nesting_start.S b/ports/arm11/gnu/src/tx_thread_irq_nesting_start.S
new file mode 100644
index 00000000..f8e4a134
--- /dev/null
+++ b/ports/arm11/gnu/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 = 0x80 @ IRQ disable bit
+MODE_MASK = 0x1F @ Mode mask
+SYS_MODE_BITS = 0x1F @ System mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_irq_nesting_start ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_irq_nesting_start
+ .type _tx_thread_irq_nesting_start,function
+_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
+ MOV pc, r3 @ Return to caller
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_schedule.S b/ports/arm11/gnu/src/tx_thread_schedule.S
new file mode 100644
index 00000000..09692e98
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_schedule.S
@@ -0,0 +1,187 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ENABLE_INTS = 0xC0 @ IRQ & FIQ Interrupts enabled mask
+#else
+ENABLE_INTS = 0x80 @ IRQ Interrupts enabled mask
+#endif
+@
+@
+ .global _tx_thread_execute_ptr
+ .global _tx_thread_current_ptr
+ .global _tx_timer_time_slice
+ .global _tx_execution_thread_enter
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_schedule
+ .type $_tx_thread_schedule,function
+$_tx_thread_schedule:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_schedule @ Call _tx_thread_schedule function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_schedule ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_schedule
+ .type _tx_thread_schedule,function
+_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] @ 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] @ 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] @ Setup time-slice
+@
+@ /* Switch to the thread's stack. */
+@ sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+@
+#ifdef 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
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@
+@}
+@
+
diff --git a/ports/arm11/gnu/src/tx_thread_stack_build.S b/ports/arm11/gnu/src/tx_thread_stack_build.S
new file mode 100644
index 00000000..ea34e6c2
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_stack_build.S
@@ -0,0 +1,178 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+ .arm
+
+SVC_MODE = 0x13 @ SVC mode
+#ifdef TX_ENABLE_FIQ_SUPPORT
+CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled
+#else
+CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled
+#endif
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .thumb
+ .global $_tx_thread_stack_build
+ .type $_tx_thread_stack_build,function
+$_tx_thread_stack_build:
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_stack_build @ Call _tx_thread_stack_build function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_stack_build ARM11/GNU */
+@/* 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))
+@{
+ .global _tx_thread_stack_build
+ .type _tx_thread_stack_build,function
+_tx_thread_stack_build:
+@
+@
+@ /* Build a fake interrupt frame. The form of the fake interrupt stack
+@ on theARM11 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)
+ LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace
+ STR r3, [r2, #60] @ Store initial r14 (lr)
+ MOV r3, #0 @ Build initial register value
+ STR r3, [r2, #52] @ Store initial r11
+ STR r3, [r2, #56] @ Store initial r12
+ 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
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
+
diff --git a/ports/arm11/gnu/src/tx_thread_system_return.S b/ports/arm11/gnu/src/tx_thread_system_return.S
new file mode 100644
index 00000000..87bef5aa
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_system_return.S
@@ -0,0 +1,167 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+ .arm
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
+#else
+DISABLE_INTS = 0x80 @ IRQ interrupts disabled
+#endif
+@
+@
+ .global _tx_thread_current_ptr
+ .global _tx_timer_time_slice
+ .global _tx_thread_schedule
+ .global _tx_execution_thread_exit
+@
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_system_return
+ .type $_tx_thread_system_return,function
+$_tx_thread_system_return:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_system_return @ Call _tx_thread_system_return function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_system_return ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_system_return
+ .type _tx_thread_system_return,function
+_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
+
+#ifdef 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] @ Pickup current thread pointer
+ LDR r2, =_tx_timer_time_slice @ Pickup address of time slice
+ LDR r1, [r2] @ 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] @ 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] @ Clear current thread pointer
+ B _tx_thread_schedule @ Jump to scheduler!
+@
+@}
+
diff --git a/ports/arm11/gnu/src/tx_thread_vectored_context_save.S b/ports/arm11/gnu/src/tx_thread_vectored_context_save.S
new file mode 100644
index 00000000..3ac517ac
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_thread_vectored_context_save.S
@@ -0,0 +1,199 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
+#else
+DISABLE_INTS = 0x80 @ IRQ interrupts disabled
+#endif
+@
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_execution_isr_enter
+@
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_vectored_context_save ARM11/GNU */
+@/* 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)
+@{
+ .global _tx_thread_vectored_context_save
+ .type _tx_thread_vectored_context_save,function
+_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++)
+@ {
+@
+#ifdef 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 variable
+ 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
+
+#ifdef 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
+
+ MOV pc, lr @ Return to caller
+@
+__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
+
+#ifdef 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
+
+ MOV pc, lr @ Return to caller
+@
+@ }
+@ 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
+
+#ifdef 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
+ MOV pc, lr @ Return to caller
+@
+@ }
+@}
+
diff --git a/ports/arm11/gnu/src/tx_timer_interrupt.S b/ports/arm11/gnu/src/tx_timer_interrupt.S
new file mode 100644
index 00000000..60632a32
--- /dev/null
+++ b/ports/arm11/gnu/src/tx_timer_interrupt.S
@@ -0,0 +1,279 @@
+@/**************************************************************************/
+@/* */
+@/* 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"
+@
+@
+ .arm
+
+@
+@/* Define Assembly language external references... */
+@
+ .global _tx_timer_time_slice
+ .global _tx_timer_system_clock
+ .global _tx_timer_current_ptr
+ .global _tx_timer_list_start
+ .global _tx_timer_list_end
+ .global _tx_timer_expired_time_slice
+ .global _tx_timer_expired
+ .global _tx_thread_time_slice
+@
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .thumb
+ .global $_tx_timer_interrupt
+ .type $_tx_timer_interrupt,function
+$_tx_timer_interrupt:
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_timer_interrupt @ Call _tx_timer_interrupt function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_timer_interrupt ARM11/GNU */
+@/* 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_thread_time_slice Time slice interrupted thread */
+@/* _tx_timer_expiration_process Timer expiration processing */
+@/* */
+@/* 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)
+@{
+ .global _tx_timer_interrupt
+ .type _tx_timer_interrupt,function
+_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] @ Pickup system clock
+ ADD r0, r0, #1 @ Increment system clock
+ STR r0, [r1] @ 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] @ 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] @ 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] @ 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 address
+ LDR r0, [r1] @ Pickup current timer
+ LDR r2, [r0] @ 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] @ 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 wraparound. */
+@ if (_tx_timer_current_ptr == _tx_timer_list_end)
+@
+ LDR r3, =_tx_timer_list_end @ Pickup address of timer list end
+ LDR r2, [r3] @ Pickup list end
+ CMP r0, r2 @ Are we at list end?
+ BNE __tx_timer_skip_wrap @ No, skip wraparound logic
+@
+@ /* Wrap to beginning of list. */
+@ _tx_timer_current_ptr = _tx_timer_list_start;
+@
+ LDR r3, =_tx_timer_list_start @ Pickup address of timer list start
+ LDR r0, [r3] @ Set current pointer to list start
+@
+__tx_timer_skip_wrap:
+@
+ STR r0, [r1] @ 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 address of expired flag
+ LDR r2, [r3] @ 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 address of other expired flag
+ LDR r0, [r1] @ 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 address of expired flag
+ LDR r0, [r1] @ 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 address of time-slice expired
+ LDR r2, [r3] @ 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:
+@
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@
+@}
+