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