diff options
| author | Scott Larson <[email protected]> | 2020-08-07 17:47:29 -0700 |
|---|---|---|
| committer | Scott Larson <[email protected]> | 2020-08-07 17:47:29 -0700 |
| commit | 6a018a4cfda937c0d8cbdee761187c5c5843e115 (patch) | |
| tree | cc9990878ab97ac171a192fe1c2922e752feee99 /ports/arm11/gnu | |
| parent | 608f55f0d120886e0eddf7e39cf3c3b6f06bd08c (diff) | |
add ARM11v6.0.1_rel
Diffstat (limited to 'ports/arm11/gnu')
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 Binary files differnew file mode 100644 index 00000000..b03b1626 --- /dev/null +++ b/ports/arm11/gnu/example_build/libc.a diff --git a/ports/arm11/gnu/example_build/libgcc.a b/ports/arm11/gnu/example_build/libgcc.a Binary files differnew file mode 100644 index 00000000..da2319e0 --- /dev/null +++ b/ports/arm11/gnu/example_build/libgcc.a diff --git a/ports/arm11/gnu/example_build/libnosys.a b/ports/arm11/gnu/example_build/libnosys.a Binary files differnew file mode 100644 index 00000000..b70de481 --- /dev/null +++ b/ports/arm11/gnu/example_build/libnosys.a 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 +@ +@} + |
