add ARM11

This commit is contained in:
Scott Larson
2020-08-07 17:47:29 -07:00
parent 608f55f0d1
commit 6a018a4cfd
95 changed files with 34462 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,238 @@
del tx.a
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s tx_initialize_low_level.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_stack_build.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_schedule.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_system_return.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_context_save.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_context_restore.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_control.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_timer_interrupt.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_disable.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_restore.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_context_save.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_nesting_start.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_irq_nesting_start.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_irq_nesting_end.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_nesting_end.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_context_restore.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_vectored_context_save.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c
arm-none-eabi-ar -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
arm-none-eabi-ar -r tx.a tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_start.o tx_thread_irq_nesting_start.o tx_thread_irq_nesting_end.o
arm-none-eabi-ar -r tx.a tx_thread_fiq_nesting_end.o tx_thread_fiq_context_restore.o tx_thread_vectored_context_save.o tx_initialize_low_level.o
arm-none-eabi-ar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
arm-none-eabi-ar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
arm-none-eabi-ar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
arm-none-eabi-ar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
arm-none-eabi-ar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
arm-none-eabi-ar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
arm-none-eabi-ar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
arm-none-eabi-ar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
arm-none-eabi-ar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
arm-none-eabi-ar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
arm-none-eabi-ar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
arm-none-eabi-ar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
arm-none-eabi-ar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
arm-none-eabi-ar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
arm-none-eabi-ar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
arm-none-eabi-ar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
arm-none-eabi-ar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
arm-none-eabi-ar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
arm-none-eabi-ar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
arm-none-eabi-ar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
arm-none-eabi-ar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
arm-none-eabi-ar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
arm-none-eabi-ar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
arm-none-eabi-ar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
arm-none-eabi-ar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
arm-none-eabi-ar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
arm-none-eabi-ar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
arm-none-eabi-ar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
arm-none-eabi-ar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
arm-none-eabi-ar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
arm-none-eabi-ar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
arm-none-eabi-ar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o

View File

@@ -0,0 +1,6 @@
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s reset.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s crt0.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s tx_initialize_low_level.S
arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc sample_threadx.c
arm-none-eabi-ld -A arm1136j-s -T sample_threadx.ld reset.o crt0.o tx_initialize_low_level.o sample_threadx.o tx.a libc.a libnosys.a libgcc.a -o sample_threadx.out -M > sample_threadx.map

View File

@@ -0,0 +1,90 @@
/* .text is used instead of .section .text so it works with arm-aout too. */
.text
.code 32
.align 0
.global _mainCRTStartup
.global _start
.global start
start:
_start:
_mainCRTStartup:
/* Start by setting up a stack */
/* Set up the stack pointer to a fixed value */
ldr r3, .LC0
mov sp, r3
/* Setup a default stack-limit in case the code has been
compiled with "-mapcs-stack-check". Hard-wiring this value
is not ideal, since there is currently no support for
checking that the heap and stack have not collided, or that
this default 64k is enough for the program being executed.
However, it ensures that this simple crt0 world will not
immediately cause an overflow event: */
sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
mov a2, #0 /* Second arg: fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */
ldr a1, .LC1 /* First arg: start of memory block */
ldr a3, .LC2
sub a3, a3, a1 /* Third arg: length of block */
bl memset
mov r0, #0 /* no arguments */
mov r1, #0 /* no argv either */
#ifdef __USES_INITFINI__
/* Some arm/elf targets use the .init and .fini sections
to create constructors and destructors, and for these
targets we need to call the _init function and arrange
for _fini to be called at program exit. */
mov r4, r0
mov r5, r1
/* ldr r0, .Lfini */
bl atexit
/* bl init */
mov r0, r4
mov r1, r5
#endif
bl main
bl exit /* Should not return. */
/* For Thumb, constants must be after the code since only
positive offsets are supported for PC relative addresses. */
.align 0
.LC0:
.LC1:
.word __bss_start__
.LC2:
.word __bss_end__
/*
#ifdef __USES_INITFINI__
.Lfini:
.word _fini
#endif */
/* Return ... */
#ifdef __APCS_26__
movs pc, lr
#else
#ifdef __THUMB_INTERWORK
bx lr
#else
mov pc, lr
#endif
#endif
/* Workspace for Angel calls. */
.data
/* Data returned by monitor SWI. */
.global __stack_base__
HeapBase: .word 0
HeapLimit: .word 0
__stack_base__: .word 0
StackLimit: .word 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,76 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Initialize */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_initialize.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
.arm
.global _start
.global __tx_undefined
.global __tx_swi_interrupt
.global __tx_prefetch_handler
.global __tx_abort_handler
.global __tx_reserved_handler
.global __tx_irq_handler
.global __tx_fiq_handler
@
@
@/* Define the vector area. This should be located or copied to 0. */
@
.text
.global __vectors
__vectors:
LDR pc, STARTUP @ Reset goes to startup function
LDR pc, UNDEFINED @ Undefined handler
LDR pc, SWI @ Software interrupt handler
LDR pc, PREFETCH @ Prefetch exception handler
LDR pc, ABORT @ Abort exception handler
LDR pc, RESERVED @ Reserved exception handler
LDR pc, IRQ @ IRQ interrupt handler
LDR pc, FIQ @ FIQ interrupt handler
STARTUP:
.word _start @ Reset goes to C startup function
UNDEFINED:
.word __tx_undefined @ Undefined handler
SWI:
.word __tx_swi_interrupt @ Software interrupt handler
PREFETCH:
.word __tx_prefetch_handler @ Prefetch exception handler
ABORT:
.word __tx_abort_handler @ Abort exception handler
RESERVED:
.word __tx_reserved_handler @ Reserved exception handler
IRQ:
.word __tx_irq_handler @ IRQ interrupt handler
FIQ:
.word __tx_fiq_handler @ FIQ interrupt handler

View File

@@ -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;
}
}

View File

@@ -0,0 +1,239 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
/* ENTRY(_start) */
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
. = 0x00000000;
.vectors : {reset.o(.text) }
/* Read-only sections, merged into text segment: */
. = 0x00001000;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.sdata :
{
*(.rel.sdata)
*(.rel.sdata.*)
*(.rel.gnu.linkonce.s*)
}
.rela.sdata :
{
*(.rela.sdata)
*(.rela.sdata.*)
*(.rela.gnu.linkonce.s*)
}
.rel.sbss : { *(.rel.sbss) }
.rela.sbss : { *(.rela.sbss) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.plt : { *(.plt) }
.text :
{
*(.text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7t) *(.glue_7)
} =0
.init :
{
KEEP (*(.init))
} =0
_etext = .;
PROVIDE (etext = .);
.fini :
{
KEEP (*(.fini))
} =0
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN(256) + (. & (256 - 1));
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.eh_frame : { KEEP (*(.eh_frame)) }
.gcc_except_table : { *(.gcc_except_table) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
}
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
__bss_start__ = .;
.sbss :
{
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_bss_end__ = . ; __bss_end__ = . ;
PROVIDE (end = .);
.stack :
{
_stack_bottom = ABSOLUTE(.) ;
/* Allocate room for stack. This must be big enough for the IRQ, FIQ, and
SYS stack if nested interrupts are enabled. */
. = ALIGN(8) ;
. += 4096 ;
_sp = . - 16 ;
_stack_top = ABSOLUTE(.) ;
}
_end = .; __end__ = . ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}

View File

@@ -0,0 +1,347 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Initialize */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_initialize.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
.arm
SVC_MODE = 0xD3 @ Disable IRQ/FIQ SVC mode
IRQ_MODE = 0xD2 @ Disable IRQ/FIQ IRQ mode
FIQ_MODE = 0xD1 @ Disable IRQ/FIQ FIQ mode
SYS_MODE = 0xDF @ Disable IRQ/FIQ SYS mode
FIQ_STACK_SIZE = 512 @ FIQ stack size
IRQ_STACK_SIZE = 1024 @ IRQ stack size
SYS_STACK_SIZE = 1024 @ System stack size
@
@
.global _tx_thread_system_stack_ptr
.global _tx_initialize_unused_memory
.global _tx_thread_context_save
.global _tx_thread_context_restore
.global _tx_timer_interrupt
.global _end
.global _sp
.global _stack_bottom
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.thumb
.global $_tx_initialize_low_level
.type $_tx_initialize_low_level,function
$_tx_initialize_low_level:
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_initialize_low_level @ Call _tx_initialize_low_level function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_initialize_low_level ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is responsible for any low-level processor */
@/* initialization, including setting up interrupt vectors, setting */
@/* up a periodic timer interrupt source, saving the system stack */
@/* pointer for use in ISR processing later, and finding the first */
@/* available RAM memory address for tx_application_define. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* _tx_initialize_kernel_enter ThreadX entry function */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_initialize_low_level(VOID)
@{
.global _tx_initialize_low_level
.type _tx_initialize_low_level,function
_tx_initialize_low_level:
@
@ /* We must be in SVC mode at this point! */
@
@ /* Setup various stack pointers. */
@
LDR r1, =_sp @ Get pointer to stack area
#ifdef TX_ENABLE_IRQ_NESTING
@
@ /* Setup the system mode stack for nested interrupt support */
@
LDR r2, =SYS_STACK_SIZE @ Pickup stack size
MOV r3, #SYS_MODE @ Build SYS mode CPSR
MSR CPSR_cxsf, r3 @ Enter SYS mode
SUB r1, r1, #1 @ Backup 1 byte
BIC r1, r1, #7 @ Ensure 8-byte alignment
MOV sp, r1 @ Setup SYS stack pointer
SUB r1, r1, r2 @ Calculate start of next stack
#endif
LDR r2, =FIQ_STACK_SIZE @ Pickup stack size
MOV r0, #FIQ_MODE @ Build FIQ mode CPSR
MSR CPSR, r0 @ Enter FIQ mode
SUB r1, r1, #1 @ Backup 1 byte
BIC r1, r1, #7 @ Ensure 8-byte alignment
MOV sp, r1 @ Setup FIQ stack pointer
SUB r1, r1, r2 @ Calculate start of next stack
LDR r2, =IRQ_STACK_SIZE @ Pickup IRQ stack size
MOV r0, #IRQ_MODE @ Build IRQ mode CPSR
MSR CPSR, r0 @ Enter IRQ mode
SUB r1, r1, #1 @ Backup 1 byte
BIC r1, r1, #7 @ Ensure 8-byte alignment
MOV sp, r1 @ Setup IRQ stack pointer
SUB r3, r1, r2 @ Calculate end of IRQ stack
MOV r0, #SVC_MODE @ Build SVC mode CPSR
MSR CPSR, r0 @ Enter SVC mode
LDR r2, =_stack_bottom @ Pickup stack bottom
CMP r3, r2 @ Compare the current stack end with the bottom
_stack_error_loop:
BLT _stack_error_loop @ If the IRQ stack exceeds the stack bottom, just sit here!
@
@ /* Save the system stack pointer. */
@ _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
@
LDR r2, =_tx_thread_system_stack_ptr @ Pickup stack pointer
STR r1, [r2] @ Save the system stack
@
@ /* Save the first available memory address. */
@ _tx_initialize_unused_memory = (VOID_PTR) _end;
@
LDR r1, =_end @ Get end of non-initialized RAM area
LDR r2, =_tx_initialize_unused_memory @ Pickup unused memory ptr address
ADD r1, r1, #8 @ Increment to next free word
STR r1, [r2] @ Save first free memory address
@
@ /* Setup Timer for periodic interrupts. */
@
@ /* Done, return to caller. */
@
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@}
@
@
@/* Define shells for each of the interrupt vectors. */
@
.global __tx_undefined
__tx_undefined:
B __tx_undefined @ Undefined handler
@
.global __tx_swi_interrupt
__tx_swi_interrupt:
B __tx_swi_interrupt @ Software interrupt handler
@
.global __tx_prefetch_handler
__tx_prefetch_handler:
B __tx_prefetch_handler @ Prefetch exception handler
@
.global __tx_abort_handler
__tx_abort_handler:
B __tx_abort_handler @ Abort exception handler
@
.global __tx_reserved_handler
__tx_reserved_handler:
B __tx_reserved_handler @ Reserved exception handler
@
.global __tx_irq_handler
.global __tx_irq_processing_return
__tx_irq_handler:
@
@ /* Jump to context save to save system context. */
B _tx_thread_context_save
__tx_irq_processing_return:
@
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. In
@ addition, IRQ interrupts may be re-enabled - with certain restrictions -
@ if nested IRQ interrupts are desired. Interrupts may be re-enabled over
@ small code sequences where lr is saved before enabling interrupts and
@ restored after interrupts are again disabled. */
@
@ /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
@ from IRQ mode with interrupts disabled. This routine switches to the
@ system mode and returns with IRQ interrupts enabled.
@
@ NOTE: It is very important to ensure all IRQ interrupts are cleared
@ prior to enabling nested IRQ interrupts. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_start
#endif
@
@ /* For debug purpose, execute the timer interrupt processing here. In
@ a real system, some kind of status indication would have to be checked
@ before the timer interrupt handler could be called. */
@
BL _tx_timer_interrupt @ Timer interrupt handler
@
@
@ /* If interrupt nesting was started earlier, the end of interrupt nesting
@ service must be called before returning to _tx_thread_context_restore.
@ This routine returns in processing in IRQ mode with interrupts disabled. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_end
#endif
@
@ /* Jump to context restore to restore system context. */
B _tx_thread_context_restore
@
@
@ /* This is an example of a vectored IRQ handler. */
@
@ .global __tx_example_vectored_irq_handler
@__tx_example_vectored_irq_handler:
@
@
@ /* Save initial context and call context save to prepare for
@ vectored ISR execution. */
@
@ STMDB sp!, {r0-r3} @ Save some scratch registers
@ MRS r0, SPSR @ Pickup saved SPSR
@ SUB lr, lr, #4 @ Adjust point of interrupt
@ STMDB sp!, {r0, r10, r12, lr} @ Store other scratch registers
@ BL _tx_thread_vectored_context_save @ Vectored context save
@
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. In
@ addition, IRQ interrupts may be re-enabled - with certain restrictions -
@ if nested IRQ interrupts are desired. Interrupts may be re-enabled over
@ small code sequences where lr is saved before enabling interrupts and
@ restored after interrupts are again disabled. */
@
@
@ /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
@ from IRQ mode with interrupts disabled. This routine switches to the
@ system mode and returns with IRQ interrupts enabled.
@
@ NOTE: It is very important to ensure all IRQ interrupts are cleared
@ prior to enabling nested IRQ interrupts. */
@#ifdef TX_ENABLE_IRQ_NESTING
@ BL _tx_thread_irq_nesting_start
@#endif
@
@ /* Application IRQ handlers can be called here! */
@
@ /* If interrupt nesting was started earlier, the end of interrupt nesting
@ service must be called before returning to _tx_thread_context_restore.
@ This routine returns in processing in IRQ mode with interrupts disabled. */
@#ifdef TX_ENABLE_IRQ_NESTING
@ BL _tx_thread_irq_nesting_end
@#endif
@
@ /* Jump to context restore to restore system context. */
@ B _tx_thread_context_restore
@
@
#ifdef TX_ENABLE_FIQ_SUPPORT
.global __tx_fiq_handler
.global __tx_fiq_processing_return
__tx_fiq_handler:
@
@ /* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
__tx_fiq_processing_return:
@
@ /* At this point execution is still in the FIQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. */
@
@ /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start
@ from FIQ mode with interrupts disabled. This routine switches to the
@ system mode and returns with FIQ interrupts enabled.
@
@ NOTE: It is very important to ensure all FIQ interrupts are cleared
@ prior to enabling nested FIQ interrupts. */
#ifdef TX_ENABLE_FIQ_NESTING
BL _tx_thread_fiq_nesting_start
#endif
@
@ /* Application FIQ handlers can be called here! */
@
@ /* If interrupt nesting was started earlier, the end of interrupt nesting
@ service must be called before returning to _tx_thread_fiq_context_restore. */
#ifdef TX_ENABLE_FIQ_NESTING
BL _tx_thread_fiq_nesting_end
#endif
@
@ /* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
@
@
#else
.global __tx_fiq_handler
__tx_fiq_handler:
B __tx_fiq_handler @ FIQ interrupt handler
#endif
@
@
BUILD_OPTIONS:
.word _tx_build_options @ Reference to bring in
VERSION_ID:
.word _tx_version_id @ Reference to bring in

View File

@@ -0,0 +1,316 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Port Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h ARM11/GNU */
/* 6.0.1 */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains data type definitions that make the ThreadX */
/* real-time kernel function identically on a variety of different */
/* processor architectures. For example, the size or number of bits */
/* in an "int" data type vary between microprocessor architectures and */
/* even C compilers for the same microprocessor. ThreadX does not */
/* directly use native C data types. Instead, ThreadX creates its */
/* own special types that can be mapped to actual data types by this */
/* file to guarantee consistency in the interface and functionality. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* */
/**************************************************************************/
#ifndef TX_PORT_H
#define TX_PORT_H
/* Determine if the optional ThreadX user define file should be used. */
#ifdef TX_INCLUDE_USER_DEFINE_FILE
/* Yes, include the user defines in tx_user.h. The defines in this file may
alternately be defined on the command line. */
#include "tx_user.h"
#endif
/* Define compiler library include files. */
#include <stdlib.h>
#include <string.h>
/* Define ThreadX basic types for this port. */
#define VOID void
typedef char CHAR;
typedef unsigned char UCHAR;
typedef int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned long ULONG;
typedef short SHORT;
typedef unsigned short USHORT;
/* Define the priority levels for ThreadX. Legal values range
from 32 to 1024 and MUST be evenly divisible by 32. */
#ifndef TX_MAX_PRIORITIES
#define TX_MAX_PRIORITIES 32
#endif
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
thread creation is less than this value, the thread create call will return an error. */
#ifndef TX_MINIMUM_STACK
#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
#endif
/* Define the system timer thread's default stack size and priority. These are only applicable
if TX_TIMER_PROCESS_IN_ISR is not defined. */
#ifndef TX_TIMER_THREAD_STACK_SIZE
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
#endif
#ifndef TX_TIMER_THREAD_PRIORITY
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
/* Define various constants for the ThreadX ARM port. */
#ifdef TX_ENABLE_FIQ_SUPPORT
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
#else
#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */
#endif
#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
#endif
/* Define the port specific options for the _tx_build_options variable. This variable indicates
how the ThreadX library was built. */
#ifdef TX_ENABLE_FIQ_SUPPORT
#define TX_FIQ_ENABLED 1
#else
#define TX_FIQ_ENABLED 0
#endif
#ifdef TX_ENABLE_IRQ_NESTING
#define TX_IRQ_NESTING_ENABLED 2
#else
#define TX_IRQ_NESTING_ENABLED 0
#endif
#ifdef TX_ENABLE_FIQ_NESTING
#define TX_FIQ_NESTING_ENABLED 4
#else
#define TX_FIQ_NESTING_ENABLED 0
#endif
#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED
/* Define the in-line initialization constant so that modules with in-line
initialization capabilities can prevent their initialization from being
a function call. */
#define TX_INLINE_INITIALIZATION
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
logic. */
#ifdef TX_ENABLE_STACK_CHECKING
#undef TX_DISABLE_STACK_FILLING
#endif
/* Define the TX_THREAD control block extensions for this port. The main reason
for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
#define TX_THREAD_EXTENSION_1
#define TX_THREAD_EXTENSION_2
#define TX_THREAD_EXTENSION_3
/* Define the port extensions of the remaining ThreadX objects. */
#define TX_BLOCK_POOL_EXTENSION
#define TX_BYTE_POOL_EXTENSION
#define TX_EVENT_FLAGS_GROUP_EXTENSION
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION
#define TX_SEMAPHORE_EXTENSION
#define TX_TIMER_EXTENSION
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
#define TX_THREAD_USER_EXTENSION
#endif
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
tx_thread_shell_entry, and tx_thread_terminate. */
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
/* Define the ThreadX object creation extensions for the remaining objects. */
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
/* Define the ThreadX object deletion extensions for the remaining objects. */
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
/* Determine if the ARM architecture has the CLZ instruction. This is available on
architectures v5 and above. If available, redefine the macro for calculating the
lowest bit set. */
#if __TARGET_ARCH_ARM > 4
#ifndef __thumb__
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
asm volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); \
b = 31 - b;
#endif
#endif
/* Define ThreadX interrupt lockout and restore macros for protection on
access of critical kernel information. The restore interrupt macro must
restore the interrupt posture of the running thread prior to the value
present prior to the disable macro. In most cases, the save area macro
is used to define a local function save area for the disable and restore
macros. */
#ifdef __thumb__
unsigned int _tx_thread_interrupt_disable(void);
unsigned int _tx_thread_interrupt_restore(UINT old_posture);
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#else
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save, tx_temp;
#ifdef TX_ENABLE_FIQ_SUPPORT
#define TX_DISABLE asm volatile (" MRS %0,CPSR; ORR %1,%0,#0xC0; MSR CPSR_cxsf,%1 ": "=r" (interrupt_save), "=r" (tx_temp) );
#else
#define TX_DISABLE asm volatile (" MRS %0,CPSR; ORR %1,%0,#0x80; MSR CPSR_cxsf,%1 ": "=r" (interrupt_save), "=r" (tx_temp) );
#endif
#define TX_RESTORE asm volatile (" MSR CPSR_cxsf,%0 "::"r" (interrupt_save) );
#endif
/* Define the interrupt lockout macros for each ThreadX object. */
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
#define TX_BYTE_POOL_DISABLE TX_DISABLE
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
#define TX_MUTEX_DISABLE TX_DISABLE
#define TX_QUEUE_DISABLE TX_DISABLE
#define TX_SEMAPHORE_DISABLE TX_DISABLE
/* Define the version ID of ThreadX. This may be utilized by the application. */
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX ARM11/GNU Version 6.0.1 *";
#else
extern CHAR _tx_version_id[];
#endif
#endif

View File

@@ -0,0 +1,496 @@
Microsoft's Azure RTOS ThreadX for ARM11
Using the GNU Tools
1. Building the ThreadX run-time Library
First make sure you are in the "example_build" directory. Also, make sure that
you have setup your path and other environment variables necessary for the GNU
development environment.
At this point you may run the build_threadx.bat batch file. This will build the
ThreadX run-time environment in the "example_build" directory.
You should observe assembly and compilation of a series of ThreadX source
files. At the end of the batch file, they are all combined into the
run-time library file: tx.a. This file must be linked with your
application in order to use ThreadX.
2. Demonstration System
Building the demonstration is easy; simply execute the build_threadx_sample.bat
batch file while inside the "example_build" directory.
You should observe the compilation of sample_threadx.c (which is the demonstration
application) and linking with TX.A. The resulting file DEMO is a binary file
that can be downloaded and executed.
3. System Initialization
The entry point in ThreadX for the ARM11 using GNU tools is at label _start.
This is defined within the modified version of the GNU startup code - crt0.S.
The ThreadX tx_initialize_low_level.S file is responsible for setting up various
system data structures, the interrupt vectors, and a periodic timer interrupt source.
By default, the vector area is defined to be located at the "__vectors" label,
which is defined in reset.S. This area is typically located at 0. In situations
where this is impossible, the vectors at the "__vectors" label should be copied
to address 0.
This is also where initialization of a periodic timer interrupt source should take
place.
In addition, _tx_initialize_low_level defines the first available address
for use by the application, which is supplied as the sole input parameter
to your application definition function, tx_application_define.
4. Assembler / Compiler Switches
The following are compiler switches used in building the demonstration
system:
Compiler/Assembler Meaning
Switches
-g Specifies debug information
-c Specifies object code generation
-mcpu=arm1136j-s Specifies target cpu
Linker Switch Meaning
-o sample_threadx.out Specifies output file
-M > sample_threadx.map Specifies demo map file
-A arm1136j-s Specifies target architecture
-T sample_threadx.ld Specifies the loader control file
Application Defines ( -D option)
TX_ENABLE_FIQ_SUPPORT This assembler define enables FIQ
interrupt handling support in the
ThreadX assembly files. If used,
it should be used on all assembly
files and the generic C source of
ThreadX should be compiled with
TX_ENABLE_FIQ_SUPPORT defined as well.
TX_ENABLE_IRQ_NESTING This assembler define enables IRQ
nested support. If IRQ nested
interrupt support is needed, this
define should be applied to
tx_initialize_low_level.S.
TX_ENABLE_FIQ_NESTING This assembler define enables FIQ
nested support. If FIQ nested
interrupt support is needed, this
define should be applied to
tx_initialize_low_level.S. In addition,
IRQ nesting should also be enabled.
TX_ENABLE_FIQ_SUPPORT This compiler define enables FIQ
interrupt handling in the ThreadX
generic C source. This define
should also be used in conjunction
with the corresponding assembler
define.
TX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included,
this define causes basic ThreadX error
checking to be disabled. Please see
Chapter 2 in the "ThreadX User Guide"
for more details.
TX_MAX_PRIORITIES Defines the priority levels for ThreadX.
Legal values range from 32 through
1024 (inclusive) and MUST be evenly divisible
by 32. Increasing the number of priority levels
supported increases the RAM usage by 128 bytes
for every group of 32 priorities. However, there
is only a negligible effect on performance. By
default, this value is set to 32 priority levels.
TX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is
used for error checking when threads are created.
The default value is port-specific and is found
in tx_port.h.
TX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal
ThreadX timer thread. This thread processes all
thread sleep requests as well as all service call
timeouts. In addition, all application timer callback
routines are invoked from this context. The default
value is port-specific and is found in tx_port.h.
TX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer
thread. The default value is priority 0 - the highest
priority in ThreadX. The default value is defined
in tx_port.h.
TX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system
timer thread for ThreadX. This results in improved
performance on timer events and smaller RAM requirements
because the timer stack and control block are no
longer needed. However, using this option moves all
the timer expiration processing to the timer ISR level.
By default, this option is not defined.
TX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX
timers in-line instead of using a function call. This
improves performance but slightly increases code size.
By default, this option is not defined.
TX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each
thread's stack is disabled. By default, this option is
not defined.
TX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking,
which includes analysis of how much stack has been used and
examination of data pattern "fences" before and after the
stack area. If a stack error is detected, the registered
application stack error handler is called. This option does
result in slightly increased overhead and code size. Please
review the tx_thread_stack_error_notify API for more information.
By default, this option is not defined.
TX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature
and slightly reduces code size and improves performance. Of course,
the preemption-threshold capabilities are no longer available.
By default, this option is not defined.
TX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX
global C data structures to zero. This should only be used if
the compiler's initialization code sets all un-initialized
C global data to zero. Using this option slightly reduces
code size and improves performance during initialization.
By default, this option is not defined.
TX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various
ThreadX objects. Using this option slightly reduces code size
and improves performance.
TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on block pools. By default, this option is
not defined.
TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on byte pools. By default, this option is
not defined.
TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on event flags groups. By default, this option
is not defined.
TX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on mutexes. By default, this option is
not defined.
TX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on queues. By default, this option is
not defined.
TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on semaphores. By default, this option is
not defined.
TX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on threads. By default, this option is
not defined.
TX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on timers. By default, this option is
not defined.
TX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace
feature. The trace buffer is supplied at a later time
via an application call to tx_trace_enable.
TX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing.
This define is only pertinent if the ThreadX library is
built with TX_ENABLE_EVENT_TRACE defined.
TX_TRACE_TIME_MASK This defines the number of valid bits in the event trace
time-stamp source defined previously. If the time-stamp
source is 16-bits, this value should be 0xFFFF. Alternatively,
if the time-stamp source is 32-bits, this value should be
0xFFFFFFFF. This define is only pertinent if the ThreadX
library is built with TX_ENABLE_EVENT_TRACE defined.
5. Register Usage and Stack Frames
The GNU compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch
registers for each function. All other registers used by a C function must
be preserved by the function. ThreadX takes advantage of this in situations
where a context switch happens as a result of making a ThreadX service call
(which is itself a C function). In such cases, the saved context of a thread
is only the non-scratch registers.
The following defines the saved context stack frames for context switches
that occur as a result of interrupt handling or from thread-level API calls.
All suspended threads have one of these two types of stack frames. The top
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
associated thread control block TX_THREAD.
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
0x00 1 0
0x04 CPSR CPSR
0x08 r0 (a1) r4 (v1)
0x0C r1 (a2) r5 (v2)
0x10 r2 (a3) r6 (v3)
0x14 r3 (a4) r7 (v4)
0x18 r4 (v1) r8 (v5)
0x1C r5 (v2) r9 (v6)
0x20 r6 (v3) r10 (v7)
0x24 r7 (v4) r11 (fp)
0x28 r8 (v5) r14 (lr)
0x2C r9 (v6)
0x30 r10 (v7)
0x34 r11 (fp)
0x38 r12 (ip)
0x3C r14 (lr)
0x40 PC
6. Improving Performance
The distribution version of ThreadX is built without any compiler
optimizations. This makes it easy to debug because you can trace or set
In addition, you can eliminate the ThreadX basic API error checking by
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
defined.
7. Interrupt Handling
ThreadX provides complete and high-performance interrupt handling for ARM11
targets. There are a certain set of requirements that are defined in the
following sub-sections:
7.1 Vector Area
The ARM11 vectors start at address zero. The demonstration system startup
reset.S file contains the vectors and is loaded at address zero. On actual
hardware platforms, this area might have to be copied to address 0.
7.2 IRQ ISRs
ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports
nested IRQ interrupts. The following sub-sections define the IRQ capabilities.
7.2.1 Standard IRQ ISRs
The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ
interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following
is the default IRQ handler defined in tx_initialize_low_level.S:
.global __tx_irq_handler
.global __tx_irq_processing_return
__tx_irq_handler:
@
@ /* Jump to context save to save system context. */
B _tx_thread_context_save @ Jump to the context save
__tx_irq_processing_return:
@
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. Note
@ that IRQ interrupts are still disabled upon return from the context
@ save function. */
@
@ /* Application ISR call(s) go here! */
@
@ /* Jump to context restore to restore system context. */
B _tx_thread_context_restore
7.2.2 Vectored IRQ ISRs
The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified
by the particular implementation. The following is an example IRQ handler defined in
tx_initialize_low_level.S:
.global __tx_irq_example_handler
__tx_irq_example_handler:
@
@ /* Call context save to save system context. */
STMDB sp!, {r0-r3} @ Save some scratch registers
MRS r0, SPSR @ Pickup saved SPSR
SUB lr, lr, #4 @ Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} @ Store other scratch registers
BL _tx_thread_vectored_context_save @ Call the vectored IRQ context save
@
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. Note
@ that IRQ interrupts are still disabled upon return from the context
@ save function. */
@
@ /* Application ISR call goes here! */
@
@ /* Jump to context restore to restore system context. */
B _tx_thread_context_restore
7.2.3 Nested IRQ Support
By default, nested IRQ interrupt support is not enabled. To enable nested
IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING
defined. With this defined, two new IRQ interrupt management services are
available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end.
These function should be called between the IRQ context save and restore
calls.
Execution between the calls to _tx_thread_irq_nesting_start and
_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved
by switching from IRQ mode to SYS mode and enabling IRQ interrupts.
The SYS mode stack is used during the SYS mode operation, which was
setup in tx_initialize_low_level.S. When nested IRQ interrupts are no
longer required, calling the _tx_thread_irq_nesting_end service disables
nesting by disabling IRQ interrupts and switching back to IRQ mode in
preparation for the IRQ context restore service.
The following is an example of enabling IRQ nested interrupts in a standard
IRQ handler:
.global __tx_irq_handler
.global __tx_irq_processing_return
__tx_irq_handler:
@
@ /* Jump to context save to save system context. */
B _tx_thread_context_save
__tx_irq_processing_return:
@
@ /* Enable nested IRQ interrupts. NOTE: Since this service returns
@ with IRQ interrupts enabled, all IRQ interrupt sources must be
@ cleared prior to calling this service. */
BL _tx_thread_irq_nesting_start
@
@ /* Application ISR call(s) go here! */
@
@ /* Disable nested IRQ interrupts. The mode is switched back to
@ IRQ mode and IRQ interrupts are disable upon return. */
BL _tx_thread_irq_nesting_end
@
@ /* Jump to context restore to restore system context. */
B _tx_thread_context_restore
7.3 FIQ Interrupts
By default, ARM7 FIQ interrupts are left alone by ThreadX. Of course, this
means that the application is fully responsible for enabling the FIQ interrupt
and saving/restoring any registers used in the FIQ ISR processing. To globally
enable FIQ interrupts, the application should enable FIQ interrupts at the
beginning of each thread or before any threads are created in tx_application_define.
In addition, the application must ensure that no ThreadX service calls are made
from default FIQ ISRs, which is located in tx_initialize_low_level.S.
7.3.1 Managed FIQ Interrupts
Full ThreadX management of FIQ interrupts is provided if the ThreadX sources
are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built
this way, the FIQ interrupt handlers are very similar to the IRQ interrupt
handlers defined previously. The following is default FIQ handler
defined in tx_initialize_low_level.S:
.global __tx_fiq_handler
.global __tx_fiq_processing_return
__tx_fiq_handler:
@
@ /* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
__tx_fiq_processing_return:
@
@ /* At this point execution is still in the FIQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. */
@
@ /* Application FIQ handlers can be called here! */
@
@ /* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
7.3.1.1 Nested FIQ Support
By default, nested FIQ interrupt support is not enabled. To enable nested
FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING
defined. With this defined, two new FIQ interrupt management services are
available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end.
These function should be called between the FIQ context save and restore
calls.
Execution between the calls to _tx_thread_fiq_nesting_start and
_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved
by switching from FIQ mode to SYS mode and enabling FIQ interrupts.
The SYS mode stack is used during the SYS mode operation, which was
setup in tx_initialize_low_level.S. When nested FIQ interrupts are no longer required,
calling the _tx_thread_fiq_nesting_end service disables nesting by disabling
FIQ interrupts and switching back to FIQ mode in preparation for the FIQ
context restore service.
The following is an example of enabling FIQ nested interrupts in the
typical FIQ handler:
.global __tx_fiq_handler
.global __tx_fiq_processing_return
__tx_fiq_handler:
@
@ /* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
__tx_fiq_processing_return:
@
@ /* At this point execution is still in the FIQ mode. The CPSR, point of
@ interrupt, and all C scratch registers are available for use. */
@
@ /* Enable nested FIQ interrupts. NOTE: Since this service returns
@ with FIQ interrupts enabled, all FIQ interrupt sources must be
@ cleared prior to calling this service. */
BL _tx_thread_fiq_nesting_start
@
@ /* Application FIQ handlers can be called here! */
@
@ /* Disable nested FIQ interrupts. The mode is switched back to
@ FIQ mode and FIQ interrupts are disable upon return. */
BL _tx_thread_fiq_nesting_end
@
@ /* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
8. ThreadX Timer Interrupt
ThreadX requires a periodic interrupt source to manage all time-slicing,
thread sleeps, timeouts, and application timers. Without such a timer
interrupt source, these services are not functional but the remainder of
ThreadX will still run.
To add the timer interrupt processing, simply make a call to
_tx_timer_interrupt in the IRQ processing. An example of this can be
found in the file tx_initialize_low_level.S for the demonstration system.
9. Revision History
For generic code revision information, please refer to the readme_threadx_generic.txt
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX:
06/30/2020 Initial ThreadX 6.0.1 version for ARM11 using GNU tools.
Copyright(c) 1996-2020 Microsoft Corporation
https://azure.com/rtos

View File

@@ -0,0 +1,241 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
@
.arm
#ifdef TX_ENABLE_FIQ_SUPPORT
SVC_MODE = 0xD3 @ Disable IRQ/FIQ, SVC mode
IRQ_MODE = 0xD2 @ Disable IRQ/FIQ, IRQ mode
#else
SVC_MODE = 0x93 @ Disable IRQ, SVC mode
IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
#endif
@
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global _tx_thread_execute_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
.global _tx_thread_preempt_disable
.global _tx_execution_isr_exit
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_context_restore ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function restores the interrupt context if it is processing a */
@/* nested interrupt. If not, it returns to the interrupt thread if no */
@/* preemption is necessary. Otherwise, if preemption is necessary or */
@/* if no thread was running, the function returns to the scheduler. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* _tx_thread_schedule Thread scheduling routine */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs Interrupt Service Routines */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_context_restore(VOID)
@{
.global _tx_thread_context_restore
.type _tx_thread_context_restore,function
_tx_thread_context_restore:
@
@ /* Lockout interrupts. */
@
MOV r0, #IRQ_MODE @ Build disable interrupts CPSR
MSR CPSR, r0 @ Lockout interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR exit function to indicate an ISR is complete. */
@
BL _tx_execution_isr_exit @ Call the ISR exit function
#endif
@
@ /* Determine if interrupts are nested. */
@ if (--_tx_thread_system_state)
@ {
@
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
LDR r2, [r3] @ Pickup system state
SUB r2, r2, #1 @ Decrement the counter
STR r2, [r3] @ Store the counter
CMP r2, #0 @ Was this the first interrupt?
BEQ __tx_thread_not_nested_restore @ If so, not a nested restore
@
@ /* Interrupts are nested. */
@
@ /* Just recover the saved registers and return to the point of
@ interrupt. */
@
LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
MSR SPSR, r0 @ Put SPSR back
LDMIA sp!, {r0-r3} @ Recover r0-r3
MOVS pc, lr @ Return to point of interrupt
@
@ }
__tx_thread_not_nested_restore:
@
@ /* Determine if a thread was interrupted and no preemption is required. */
@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
@ || (_tx_thread_preempt_disable))
@ {
@
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1] @ Pickup actual current thread pointer
CMP r0, #0 @ Is it NULL?
BEQ __tx_thread_idle_system_restore @ Yes, idle system was interrupted
@
LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address
LDR r2, [r3] @ Pickup actual preempt disable flag
CMP r2, #0 @ Is it set?
BNE __tx_thread_no_preempt_restore @ Yes, don't preempt this thread
LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr
LDR r2, [r3] @ Pickup actual execute thread pointer
CMP r0, r2 @ Is the same thread highest priority?
BNE __tx_thread_preempt_restore @ No, preemption needs to happen
@
@
__tx_thread_no_preempt_restore:
@
@ /* Restore interrupted thread or ISR. */
@
@ /* Pickup the saved stack pointer. */
@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
@
@ /* Recover the saved context and return to the point of interrupt. */
@
LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
MSR SPSR, r0 @ Put SPSR back
LDMIA sp!, {r0-r3} @ Recover r0-r3
MOVS pc, lr @ Return to point of interrupt
@
@ }
@ else
@ {
__tx_thread_preempt_restore:
@
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
MOV r1, lr @ Save lr (point of interrupt)
MOV r2, #SVC_MODE @ Build SVC mode CPSR
MSR CPSR, r2 @ Enter SVC mode
STR r1, [sp, #-4]! @ Save point of interrupt
STMDB sp!, {r4-r12, lr} @ Save upper half of registers
MOV r4, r3 @ Save SPSR in r4
MOV r2, #IRQ_MODE @ Build IRQ mode CPSR
MSR CPSR, r2 @ Enter IRQ mode
LDMIA sp!, {r0-r3} @ Recover r0-r3
MOV r5, #SVC_MODE @ Build SVC mode CPSR
MSR CPSR, r5 @ Enter SVC mode
STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack
MOV r3, #1 @ Build interrupt stack type
STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1] @ Pickup current thread pointer
STR sp, [r0, #8] @ Save stack pointer in thread control
@ block
@
@ /* Save the remaining time-slice and disable it. */
@ if (_tx_timer_time_slice)
@ {
@
LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address
LDR r2, [r3] @ Pickup time-slice
CMP r2, #0 @ Is it active?
BEQ __tx_thread_dont_save_ts @ No, don't save it
@
@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
@ _tx_timer_time_slice = 0;
@
STR r2, [r0, #24] @ Save thread's time-slice
MOV r2, #0 @ Clear value
STR r2, [r3] @ Disable global time-slice flag
@
@ }
__tx_thread_dont_save_ts:
@
@
@ /* Clear the current task pointer. */
@ _tx_thread_current_ptr = TX_NULL;
@
MOV r0, #0 @ NULL value
STR r0, [r1] @ Clear current thread pointer
@
@ /* Return to the scheduler. */
@ _tx_thread_schedule();
@
B _tx_thread_schedule @ Return to scheduler
@ }
@
__tx_thread_idle_system_restore:
@
@ /* Just return back to the scheduler! */
@
MOV r0, #SVC_MODE @ Build SVC mode CPSR
MSR CPSR, r0 @ Enter SVC mode
B _tx_thread_schedule @ Return to scheduler
@}

View File

@@ -0,0 +1,210 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
@
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 @ IRQ interrupts disabled
#endif
@
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global _tx_irq_processing_return
.global _tx_execution_isr_enter
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_context_save ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function saves the context of an executing thread in the */
@/* beginning of interrupt processing. The function also ensures that */
@/* the system stack is used upon return to the calling ISR. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_context_save(VOID)
@{
.global _tx_thread_context_save
.type _tx_thread_context_save,function
_tx_thread_context_save:
@
@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
@ out, we are in IRQ mode, and all registers are intact. */
@
@ /* Check for a nested interrupt condition. */
@ if (_tx_thread_system_state++)
@ {
@
STMDB sp!, {r0-r3} @ Save some working registers
#ifdef TX_ENABLE_FIQ_SUPPORT
MRS r0, CPSR @ Pickup the CPSR
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt CPSR
MSR CPSR_cxsf, r0 @ Disable interrupts
#endif
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
LDR r2, [r3] @ Pickup system state
CMP r2, #0 @ Is this the first interrupt?
BEQ __tx_thread_not_nested_save @ Yes, not a nested context save
@
@ /* Nested interrupt condition. */
@
ADD r2, r2, #1 @ Increment the interrupt counter
STR r2, [r3] @ Store it back in the variable
@
@ /* Save the rest of the scratch registers on the stack and return to the
@ calling ISR. */
@
MRS r0, SPSR @ Pickup saved SPSR
SUB lr, lr, #4 @ Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} @ Store other registers
@
@ /* Return to the ISR. */
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
B __tx_irq_processing_return @ Continue IRQ processing
@
__tx_thread_not_nested_save:
@ }
@
@ /* Otherwise, not nested, check to see if a thread was running. */
@ else if (_tx_thread_current_ptr)
@ {
@
ADD r2, r2, #1 @ Increment the interrupt counter
STR r2, [r3] @ Store it back in the variable
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1] @ Pickup current thread pointer
CMP r0, #0 @ Is it NULL?
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
@ scheduling loop - nothing needs saving!
@
@ /* Save minimal context of interrupted thread. */
@
MRS r2, SPSR @ Pickup saved SPSR
SUB lr, lr, #4 @ Adjust point of interrupt
STMDB sp!, {r2, r10, r12, lr} @ Store other registers
@
@ /* Save the current stack pointer in the thread's control block. */
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
@
@ /* Switch to the system stack. */
@ sp = _tx_thread_system_stack_ptr@
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
B __tx_irq_processing_return @ Continue IRQ processing
@
@ }
@ else
@ {
@
__tx_thread_idle_system_save:
@
@ /* Interrupt occurred in the scheduling loop. */
@
@ /* Not much to do here, just adjust the stack pointer, and return to IRQ
@ processing. */
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
ADD sp, sp, #16 @ Recover saved registers
B __tx_irq_processing_return @ Continue IRQ processing
@
@ }
@}

View File

@@ -0,0 +1,256 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
@
@
SVC_MODE = 0xD3 @ SVC mode
FIQ_MODE = 0xD1 @ FIQ mode
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
MODE_MASK = 0x1F @ Mode mask
THUMB_MASK = 0x20 @ Thumb bit mask
IRQ_MODE_BITS = 0x12 @ IRQ mode bits
SVC_MODE_BITS = 0x13 @ SVC mode value
@
@
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global _tx_thread_system_stack_ptr
.global _tx_thread_execute_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
.global _tx_thread_preempt_disable
.global _tx_execution_isr_exit
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_fiq_context_restore ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function restores the fiq interrupt context when processing a */
@/* nested interrupt. If not, it returns to the interrupt thread if no */
@/* preemption is necessary. Otherwise, if preemption is necessary or */
@/* if no thread was running, the function returns to the scheduler. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* _tx_thread_schedule Thread scheduling routine */
@/* */
@/* CALLED BY */
@/* */
@/* FIQ ISR Interrupt Service Routines */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_fiq_context_restore(VOID)
@{
.global _tx_thread_fiq_context_restore
.type _tx_thread_fiq_context_restore,function
_tx_thread_fiq_context_restore:
@
@ /* Lockout interrupts. */
@
MRS r3, CPSR @ Pickup current CPSR
ORR r0, r3, #DISABLE_INTS @ Build interrupt disable value
MSR CPSR_cxsf, r0 @ Lockout interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR exit function to indicate an ISR is complete. */
@
BL _tx_execution_isr_exit @ Call the ISR exit function
#endif
@
@ /* Determine if interrupts are nested. */
@ if (--_tx_thread_system_state)
@ {
@
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
LDR r2, [r3] @ Pickup system state
SUB r2, r2, #1 @ Decrement the counter
STR r2, [r3] @ Store the counter
CMP r2, #0 @ Was this the first interrupt?
BEQ __tx_thread_fiq_not_nested_restore @ If so, not a nested restore
@
@ /* Interrupts are nested. */
@
@ /* Just recover the saved registers and return to the point of
@ interrupt. */
@
LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
MSR SPSR_cxsf, r0 @ Put SPSR back
LDMIA sp!, {r0-r3} @ Recover r0-r3
MOVS pc, lr @ Return to point of interrupt
@
@ }
__tx_thread_fiq_not_nested_restore:
@
@ /* Determine if a thread was interrupted and no preemption is required. */
@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
@ || (_tx_thread_preempt_disable))
@ {
@
LDR r1, [sp] @ Pickup the saved SPSR
MOV r2, #MODE_MASK @ Build mask to isolate the interrupted mode
AND r1, r1, r2 @ Isolate mode bits
CMP r1, #IRQ_MODE_BITS @ Was an interrupt taken in IRQ mode before we
@ got to context save? */
BEQ __tx_thread_fiq_no_preempt_restore @ Yes, just go back to point of interrupt
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1] @ Pickup actual current thread pointer
CMP r0, #0 @ Is it NULL?
BEQ __tx_thread_fiq_idle_system_restore @ Yes, idle system was interrupted
LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address
LDR r2, [r3] @ Pickup actual preempt disable flag
CMP r2, #0 @ Is it set?
BNE __tx_thread_fiq_no_preempt_restore @ Yes, don't preempt this thread
LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr
LDR r2, [r3] @ Pickup actual execute thread pointer
CMP r0, r2 @ Is the same thread highest priority?
BNE __tx_thread_fiq_preempt_restore @ No, preemption needs to happen
__tx_thread_fiq_no_preempt_restore:
@
@ /* Restore interrupted thread or ISR. */
@
@ /* Pickup the saved stack pointer. */
@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
@
@ /* Recover the saved context and return to the point of interrupt. */
@
LDMIA sp!, {r0, lr} @ Recover SPSR, POI, and scratch regs
MSR SPSR_cxsf, r0 @ Put SPSR back
LDMIA sp!, {r0-r3} @ Recover r0-r3
MOVS pc, lr @ Return to point of interrupt
@
@ }
@ else
@ {
__tx_thread_fiq_preempt_restore:
@
LDMIA sp!, {r3, lr} @ Recover temporarily saved registers
MOV r1, lr @ Save lr (point of interrupt)
MOV r2, #SVC_MODE @ Build SVC mode CPSR
MSR CPSR_cxsf, r2 @ Enter SVC mode
STR r1, [sp, #-4]! @ Save point of interrupt
STMDB sp!, {r4-r12, lr} @ Save upper half of registers
MOV r4, r3 @ Save SPSR in r4
MOV r2, #FIQ_MODE @ Build FIQ mode CPSR
MSR CPSR_cxsf, r2 @ Reenter FIQ mode
LDMIA sp!, {r0-r3} @ Recover r0-r3
MOV r5, #SVC_MODE @ Build SVC mode CPSR
MSR CPSR_cxsf, r5 @ Enter SVC mode
STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack
MOV r3, #1 @ Build interrupt stack type
STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1] @ Pickup current thread pointer
STR sp, [r0, #8] @ Save stack pointer in thread control
@ block */
BIC r4, r4, #THUMB_MASK @ Clear the Thumb bit of CPSR
ORR r3, r4, #DISABLE_INTS @ Or-in interrupt lockout bit(s)
MSR CPSR_cxsf, r3 @ Lockout interrupts
@
@ /* Save the remaining time-slice and disable it. */
@ if (_tx_timer_time_slice)
@ {
@
LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address
LDR r2, [r3] @ Pickup time-slice
CMP r2, #0 @ Is it active?
BEQ __tx_thread_fiq_dont_save_ts @ No, don't save it
@
@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
@ _tx_timer_time_slice = 0;
@
STR r2, [r0, #24] @ Save thread's time-slice
MOV r2, #0 @ Clear value
STR r2, [r3] @ Disable global time-slice flag
@
@ }
__tx_thread_fiq_dont_save_ts:
@
@
@ /* Clear the current task pointer. */
@ _tx_thread_current_ptr = TX_NULL;
@
MOV r0, #0 @ NULL value
STR r0, [r1] @ Clear current thread pointer
@
@ /* Return to the scheduler. */
@ _tx_thread_schedule();
@
B _tx_thread_schedule @ Return to scheduler
@ }
@
__tx_thread_fiq_idle_system_restore:
@
@ /* Just return back to the scheduler! */
@
ADD sp, sp, #24 @ Recover FIQ stack space
MRS r3, CPSR @ Pickup current CPSR
BIC r3, r3, #MODE_MASK @ Clear the mode portion of the CPSR
ORR r3, r3, #SVC_MODE_BITS @ Or-in new interrupt lockout bit
MSR CPSR_cxsf, r3 @ Lockout interrupts
B _tx_thread_schedule @ Return to scheduler
@
@}

View File

@@ -0,0 +1,204 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global __tx_fiq_processing_return
.global _tx_execution_isr_enter
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_fiq_context_save ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function saves the context of an executing thread in the */
@/* beginning of interrupt processing. The function also ensures that */
@/* the system stack is used upon return to the calling ISR. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@ VOID _tx_thread_fiq_context_save(VOID)
@{
.global _tx_thread_fiq_context_save
.type _tx_thread_fiq_context_save,function
_tx_thread_fiq_context_save:
@
@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
@ out, we are in IRQ mode, and all registers are intact. */
@
@ /* Check for a nested interrupt condition. */
@ if (_tx_thread_system_state++)
@ {
@
STMDB sp!, {r0-r3} @ Save some working registers
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
LDR r2, [r3] @ Pickup system state
CMP r2, #0 @ Is this the first interrupt?
BEQ __tx_thread_fiq_not_nested_save @ Yes, not a nested context save
@
@ /* Nested interrupt condition. */
@
ADD r2, r2, #1 @ Increment the interrupt counter
STR r2, [r3] @ Store it back in the variable
@
@ /* Save the rest of the scratch registers on the stack and return to the
@ calling ISR. */
@
MRS r0, SPSR @ Pickup saved SPSR
SUB lr, lr, #4 @ Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} @ Store other registers
@
@ /* Return to the ISR. */
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
B __tx_fiq_processing_return @ Continue FIQ processing
@
__tx_thread_fiq_not_nested_save:
@ }
@
@ /* Otherwise, not nested, check to see if a thread was running. */
@ else if (_tx_thread_current_ptr)
@ {
@
ADD r2, r2, #1 @ Increment the interrupt counter
STR r2, [r3] @ Store it back in the variable
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1] @ Pickup current thread pointer
CMP r0, #0 @ Is it NULL?
BEQ __tx_thread_fiq_idle_system_save @ If so, interrupt occurred in
@ @ scheduling loop - nothing needs saving!
@
@ /* Save minimal context of interrupted thread. */
@
MRS r2, SPSR @ Pickup saved SPSR
SUB lr, lr, #4 @ Adjust point of interrupt
STMDB sp!, {r2, lr} @ Store other registers, Note that we don't
@ @ need to save sl and ip since FIQ has
@ @ copies of these registers. Nested
@ @ interrupt processing does need to save
@ @ these registers.
@
@ /* Save the current stack pointer in the thread's control block. */
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
@
@ /* Switch to the system stack. */
@ sp = _tx_thread_system_stack_ptr;
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
B __tx_fiq_processing_return @ Continue FIQ processing
@
@ }
@ else
@ {
@
__tx_thread_fiq_idle_system_save:
@
@ /* Interrupt occurred in the scheduling loop. */
@
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
@
@ /* Not much to do here, save the current SPSR and LR for possible
@ use in IRQ interrupted in idle system conditions, and return to
@ FIQ interrupt processing. */
@
MRS r0, SPSR @ Pickup saved SPSR
SUB lr, lr, #4 @ Adjust point of interrupt
STMDB sp!, {r0, lr} @ Store other registers that will get used
@ @ or stripped off the stack in context
@ @ restore
B __tx_fiq_processing_return @ Continue FIQ processing
@
@ }
@}

View File

@@ -0,0 +1,111 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
#else
DISABLE_INTS = 0x80 @ Disable IRQ interrupts
#endif
MODE_MASK = 0x1F @ Mode mask
FIQ_MODE_BITS = 0x11 @ FIQ mode bits
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_fiq_nesting_end ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is called by the application from FIQ mode after */
@/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */
@/* processing from system mode back to FIQ mode prior to the ISR */
@/* calling _tx_thread_fiq_context_restore. Note that this function */
@/* assumes the system stack pointer is in the same position after */
@/* nesting start function was called. */
@/* */
@/* This function assumes that the system mode stack pointer was setup */
@/* during low-level initialization (tx_initialize_low_level.s). */
@/* */
@/* This function returns with FIQ interrupts disabled. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_fiq_nesting_end(VOID)
@{
.global _tx_thread_fiq_nesting_end
.type _tx_thread_fiq_nesting_end,function
_tx_thread_fiq_nesting_end:
MOV r3,lr @ Save ISR return address
MRS r0, CPSR @ Pickup the CPSR
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
MSR CPSR_cxsf, r0 @ Disable interrupts
LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
@ 8-byte alignment logic)
BIC r0, r0, #MODE_MASK @ Clear mode bits
ORR r0, r0, #FIQ_MODE_BITS @ Build IRQ mode CPSR
MSR CPSR_cxsf, r0 @ Reenter IRQ mode
MOV pc, r3 @ Return to caller
@}

View File

@@ -0,0 +1,104 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
FIQ_DISABLE = 0x40 @ FIQ disable bit
MODE_MASK = 0x1F @ Mode mask
SYS_MODE_BITS = 0x1F @ System mode bits
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_fiq_nesting_start ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is called by the application from FIQ mode after */
@/* _tx_thread_fiq_context_save has been called and switches the FIQ */
@/* processing to the system mode so nested FIQ interrupt processing */
@/* is possible (system mode has its own "lr" register). Note that */
@/* this function assumes that the system mode stack pointer was setup */
@/* during low-level initialization (tx_initialize_low_level.s). */
@/* */
@/* This function returns with FIQ interrupts enabled. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_fiq_nesting_start(VOID)
@{
.global _tx_thread_fiq_nesting_start
.type _tx_thread_fiq_nesting_start,function
_tx_thread_fiq_nesting_start:
MOV r3,lr @ Save ISR return address
MRS r0, CPSR @ Pickup the CPSR
BIC r0, r0, #MODE_MASK @ Clear the mode bits
ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR
MSR CPSR_cxsf, r0 @ Enter system mode
STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
@ and push r1 just to keep 8-byte alignment
BIC r0, r0, #FIQ_DISABLE @ Build enable FIQ CPSR
MSR CPSR_cxsf, r0 @ Enter system mode
MOV pc, r3 @ Return to caller
@}

View File

@@ -0,0 +1,115 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h" */
@
INT_MASK = 0x03F
@
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.global $_tx_thread_interrupt_control
$_tx_thread_interrupt_control:
.thumb
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_thread_interrupt_control @ Call _tx_thread_interrupt_control function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_interrupt_control ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is responsible for changing the interrupt lockout */
@/* posture of the system. */
@/* */
@/* INPUT */
@/* */
@/* new_posture New interrupt lockout posture */
@/* */
@/* OUTPUT */
@/* */
@/* old_posture Old interrupt lockout posture */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* Application Code */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@UINT _tx_thread_interrupt_control(UINT new_posture)
@{
.global _tx_thread_interrupt_control
.type _tx_thread_interrupt_control,function
_tx_thread_interrupt_control:
@
@ /* Pickup current interrupt lockout posture. */
@
MRS r3, CPSR @ Pickup current CPSR
MOV r2, #INT_MASK @ Build interrupt mask
AND r1, r3, r2 @ Clear interrupt lockout bits
ORR r1, r1, r0 @ Or-in new interrupt lockout bits
@
@ /* Apply the new interrupt posture. */
@
MSR CPSR, r1 @ Setup new CPSR
BIC r0, r3, r2 @ Return previous interrupt mask
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@}

View File

@@ -0,0 +1,116 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 @ IRQ interrupts disabled
#endif
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.global $_tx_thread_interrupt_disable
$_tx_thread_interrupt_disable:
.thumb
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_thread_interrupt_disable @ Call _tx_thread_interrupt_disable function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_interrupt_disable ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is responsible for disabling interrupts */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* old_posture Old interrupt lockout posture */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* Application Code */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@UINT _tx_thread_interrupt_disable(void)
@{
.global _tx_thread_interrupt_disable
.type _tx_thread_interrupt_disable,function
_tx_thread_interrupt_disable:
@
@ /* Pickup current interrupt lockout posture. */
@
MRS r0, CPSR @ Pickup current CPSR
@
@ /* Mask interrupts. */
@
ORR r1, r0, #DISABLE_INTS @ Mask interrupts
MSR CPSR_cxsf, r1 @ Setup new CPSR
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@}

View File

@@ -0,0 +1,104 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.global $_tx_thread_interrupt_restore
$_tx_thread_interrupt_restore:
.thumb
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_thread_interrupt_restore @ Call _tx_thread_interrupt_restore function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_interrupt_restore ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is responsible for restoring interrupts to the state */
@/* returned by a previous _tx_thread_interrupt_disable call. */
@/* */
@/* INPUT */
@/* */
@/* old_posture Old interrupt lockout posture */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* Application Code */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@UINT _tx_thread_interrupt_restore(UINT old_posture)
@{
.global _tx_thread_interrupt_restore
.type _tx_thread_interrupt_restore,function
_tx_thread_interrupt_restore:
@
@ /* Apply the new interrupt posture. */
@
MSR CPSR_cxsf, r0 @ Setup new CPSR
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@}

View File

@@ -0,0 +1,111 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
#else
DISABLE_INTS = 0x80 @ Disable IRQ interrupts
#endif
MODE_MASK = 0x1F @ Mode mask
IRQ_MODE_BITS = 0x12 @ IRQ mode bits
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_irq_nesting_end ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is called by the application from IRQ mode after */
@/* _tx_thread_irq_nesting_start has been called and switches the IRQ */
@/* processing from system mode back to IRQ mode prior to the ISR */
@/* calling _tx_thread_context_restore. Note that this function */
@/* assumes the system stack pointer is in the same position after */
@/* nesting start function was called. */
@/* */
@/* This function assumes that the system mode stack pointer was setup */
@/* during low-level initialization (tx_initialize_low_level.s). */
@/* */
@/* This function returns with IRQ interrupts disabled. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_irq_nesting_end(VOID)
@{
.global _tx_thread_irq_nesting_end
.type _tx_thread_irq_nesting_end,function
_tx_thread_irq_nesting_end:
MOV r3,lr @ Save ISR return address
MRS r0, CPSR @ Pickup the CPSR
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
MSR CPSR_cxsf, r0 @ Disable interrupts
LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
@ 8-byte alignment logic)
BIC r0, r0, #MODE_MASK @ Clear mode bits
ORR r0, r0, #IRQ_MODE_BITS @ Build IRQ mode CPSR
MSR CPSR_cxsf, r0 @ Reenter IRQ mode
MOV pc, r3 @ Return to caller
@}

View File

@@ -0,0 +1,104 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
IRQ_DISABLE = 0x80 @ IRQ disable bit
MODE_MASK = 0x1F @ Mode mask
SYS_MODE_BITS = 0x1F @ System mode bits
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_irq_nesting_start ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is called by the application from IRQ mode after */
@/* _tx_thread_context_save has been called and switches the IRQ */
@/* processing to the system mode so nested IRQ interrupt processing */
@/* is possible (system mode has its own "lr" register). Note that */
@/* this function assumes that the system mode stack pointer was setup */
@/* during low-level initialization (tx_initialize_low_level.s). */
@/* */
@/* This function returns with IRQ interrupts enabled. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_irq_nesting_start(VOID)
@{
.global _tx_thread_irq_nesting_start
.type _tx_thread_irq_nesting_start,function
_tx_thread_irq_nesting_start:
MOV r3,lr @ Save ISR return address
MRS r0, CPSR @ Pickup the CPSR
BIC r0, r0, #MODE_MASK @ Clear the mode bits
ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR
MSR CPSR_cxsf, r0 @ Enter system mode
STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
@ and push r1 just to keep 8-byte alignment
BIC r0, r0, #IRQ_DISABLE @ Build enable IRQ CPSR
MSR CPSR_cxsf, r0 @ Enter system mode
MOV pc, r3 @ Return to caller
@}

View File

@@ -0,0 +1,187 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
@
#ifdef TX_ENABLE_FIQ_SUPPORT
ENABLE_INTS = 0xC0 @ IRQ & FIQ Interrupts enabled mask
#else
ENABLE_INTS = 0x80 @ IRQ Interrupts enabled mask
#endif
@
@
.global _tx_thread_execute_ptr
.global _tx_thread_current_ptr
.global _tx_timer_time_slice
.global _tx_execution_thread_enter
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.global $_tx_thread_schedule
.type $_tx_thread_schedule,function
$_tx_thread_schedule:
.thumb
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_thread_schedule @ Call _tx_thread_schedule function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_schedule ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function waits for a thread control block pointer to appear in */
@/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
@/* in the variable, the corresponding thread is resumed. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* _tx_initialize_kernel_enter ThreadX entry function */
@/* _tx_thread_system_return Return to system from thread */
@/* _tx_thread_context_restore Restore thread's context */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_schedule(VOID)
@{
.global _tx_thread_schedule
.type _tx_thread_schedule,function
_tx_thread_schedule:
@
@ /* Enable interrupts. */
@
MRS r2, CPSR @ Pickup CPSR
BIC r0, r2, #ENABLE_INTS @ Clear the disable bit(s)
MSR CPSR_cxsf, r0 @ Enable interrupts
@
@ /* Wait for a thread to execute. */
@ do
@ {
LDR r1, =_tx_thread_execute_ptr @ Address of thread execute ptr
@
__tx_thread_schedule_loop:
@
LDR r0, [r1] @ Pickup next thread to execute
CMP r0, #0 @ Is it NULL?
BEQ __tx_thread_schedule_loop @ If so, keep looking for a thread
@
@ }
@ while(_tx_thread_execute_ptr == TX_NULL);
@
@ /* Yes! We have a thread to execute. Lockout interrupts and
@ transfer control to it. */
@
MSR CPSR_cxsf, r2 @ Disable interrupts
@
@ /* Setup the current thread pointer. */
@ _tx_thread_current_ptr = _tx_thread_execute_ptr;
@
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread
STR r0, [r1] @ Setup current thread pointer
@
@ /* Increment the run count for this thread. */
@ _tx_thread_current_ptr -> tx_thread_run_count++;
@
LDR r2, [r0, #4] @ Pickup run counter
LDR r3, [r0, #24] @ Pickup time-slice for this thread
ADD r2, r2, #1 @ Increment thread run-counter
STR r2, [r0, #4] @ Store the new run counter
@
@ /* Setup time-slice, if present. */
@ _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
@
LDR r2, =_tx_timer_time_slice @ Pickup address of time-slice
@ variable
LDR sp, [r0, #8] @ Switch stack pointers
STR r3, [r2] @ Setup time-slice
@
@ /* Switch to the thread's stack. */
@ sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
@
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the thread entry function to indicate the thread is executing. */
@
BL _tx_execution_thread_enter @ Call the thread execution enter function
#endif
@
@ /* Determine if an interrupt frame or a synchronous task suspension frame
@ is present. */
@
LDMIA sp!, {r0, r1} @ Pickup the stack type and saved CPSR
CMP r0, #0 @ Check for synchronous context switch
MSRNE SPSR_cxsf, r1 @ Setup SPSR for return
LDMNEIA sp!, {r0-r12, lr, pc}^ @ Return to point of thread interrupt
LDMIA sp!, {r4-r11, lr} @ Return to thread synchronously
MSR CPSR_cxsf, r1 @ Recover CPSR
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@
@}
@

View File

@@ -0,0 +1,178 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
.arm
SVC_MODE = 0x13 @ SVC mode
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled
#else
CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled
#endif
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.thumb
.global $_tx_thread_stack_build
.type $_tx_thread_stack_build,function
$_tx_thread_stack_build:
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_thread_stack_build @ Call _tx_thread_stack_build function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_stack_build ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function builds a stack frame on the supplied thread's stack. */
@/* The stack frame results in a fake interrupt return to the supplied */
@/* function pointer. */
@/* */
@/* INPUT */
@/* */
@/* thread_ptr Pointer to thread control blk */
@/* function_ptr Pointer to return function */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* _tx_thread_create Create thread service */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
@{
.global _tx_thread_stack_build
.type _tx_thread_stack_build,function
_tx_thread_stack_build:
@
@
@ /* Build a fake interrupt frame. The form of the fake interrupt stack
@ on theARM11 should look like the following after it is built:
@
@ Stack Top: 1 Interrupt stack frame type
@ CPSR Initial value for CPSR
@ a1 (r0) Initial value for a1
@ a2 (r1) Initial value for a2
@ a3 (r2) Initial value for a3
@ a4 (r3) Initial value for a4
@ v1 (r4) Initial value for v1
@ v2 (r5) Initial value for v2
@ v3 (r6) Initial value for v3
@ v4 (r7) Initial value for v4
@ v5 (r8) Initial value for v5
@ sb (r9) Initial value for sb
@ sl (r10) Initial value for sl
@ fp (r11) Initial value for fp
@ ip (r12) Initial value for ip
@ lr (r14) Initial value for lr
@ pc (r15) Initial value for pc
@ 0 For stack backtracing
@
@ Stack Bottom: (higher memory address) */
@
LDR r2, [r0, #16] @ Pickup end of stack area
BIC r2, r2, #7 @ Ensure 8-byte alignment
SUB r2, r2, #76 @ Allocate space for the stack frame
@
@ /* Actually build the stack frame. */
@
MOV r3, #1 @ Build interrupt stack type
STR r3, [r2, #0] @ Store stack type
MOV r3, #0 @ Build initial register value
STR r3, [r2, #8] @ Store initial r0
STR r3, [r2, #12] @ Store initial r1
STR r3, [r2, #16] @ Store initial r2
STR r3, [r2, #20] @ Store initial r3
STR r3, [r2, #24] @ Store initial r4
STR r3, [r2, #28] @ Store initial r5
STR r3, [r2, #32] @ Store initial r6
STR r3, [r2, #36] @ Store initial r7
STR r3, [r2, #40] @ Store initial r8
STR r3, [r2, #44] @ Store initial r9
LDR r3, [r0, #12] @ Pickup stack starting address
STR r3, [r2, #48] @ Store initial r10 (sl)
LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace
STR r3, [r2, #60] @ Store initial r14 (lr)
MOV r3, #0 @ Build initial register value
STR r3, [r2, #52] @ Store initial r11
STR r3, [r2, #56] @ Store initial r12
STR r1, [r2, #64] @ Store initial pc
STR r3, [r2, #68] @ 0 for back-trace
MRS r1, CPSR @ Pickup CPSR
BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR
ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled
STR r3, [r2, #4] @ Store initial CPSR
@
@ /* Setup stack pointer. */
@ thread_ptr -> tx_thread_stack_ptr = r2;
@
STR r2, [r0, #8] @ Save stack pointer in thread's
@ control block
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@}

View File

@@ -0,0 +1,167 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
@
.arm
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 @ IRQ interrupts disabled
#endif
@
@
.global _tx_thread_current_ptr
.global _tx_timer_time_slice
.global _tx_thread_schedule
.global _tx_execution_thread_exit
@
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.global $_tx_thread_system_return
.type $_tx_thread_system_return,function
$_tx_thread_system_return:
.thumb
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_thread_system_return @ Call _tx_thread_system_return function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_system_return ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function is target processor specific. It is used to transfer */
@/* control from a thread back to the ThreadX system. Only a */
@/* minimal context is saved since the compiler assumes temp registers */
@/* are going to get slicked by a function call anyway. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* _tx_thread_schedule Thread scheduling loop */
@/* */
@/* CALLED BY */
@/* */
@/* ThreadX components */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_system_return(VOID)
@{
.global _tx_thread_system_return
.type _tx_thread_system_return,function
_tx_thread_system_return:
@
@ /* Save minimal context on the stack. */
@
MOV r0, #0 @ Build a solicited stack type
MRS r1, CPSR @ Pickup the CPSR
STMDB sp!, {r0-r1, r4-r11, lr} @ Save minimal context
@
@ /* Lockout interrupts. */
@
ORR r2, r1, #DISABLE_INTS @ Build disable interrupt CPSR
MSR CPSR_cxsf, r2 @ Disable interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the thread exit function to indicate the thread is no longer executing. */
@
BL _tx_execution_thread_exit @ Call the thread exit function
#endif
LDR r3, =_tx_thread_current_ptr @ Pickup address of current ptr
LDR r0, [r3] @ Pickup current thread pointer
LDR r2, =_tx_timer_time_slice @ Pickup address of time slice
LDR r1, [r2] @ Pickup current time slice
@
@ /* Save current stack and switch to system stack. */
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
@ sp = _tx_thread_system_stack_ptr;
@
STR sp, [r0, #8] @ Save thread stack pointer
@
@ /* Determine if the time-slice is active. */
@ if (_tx_timer_time_slice)
@ {
@
MOV r4, #0 @ Build clear value
CMP r1, #0 @ Is a time-slice active?
BEQ __tx_thread_dont_save_ts @ No, don't save the time-slice
@
@ /* Save time-slice for the thread and clear the current time-slice. */
@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
@ _tx_timer_time_slice = 0;
@
STR r4, [r2] @ Clear time-slice
STR r1, [r0, #24] @ Save current time-slice
@
@ }
__tx_thread_dont_save_ts:
@
@ /* Clear the current thread pointer. */
@ _tx_thread_current_ptr = TX_NULL;
@
STR r4, [r3] @ Clear current thread pointer
B _tx_thread_schedule @ Jump to scheduler!
@
@}

View File

@@ -0,0 +1,199 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Thread */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_thread.h"
@
@
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled
#else
DISABLE_INTS = 0x80 @ IRQ interrupts disabled
#endif
@
@
.global _tx_thread_system_state
.global _tx_thread_current_ptr
.global _tx_execution_isr_enter
@
@
@
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
@ since it will never be called 16-bit mode. */
@
.arm
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_thread_vectored_context_save ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function saves the context of an executing thread in the */
@/* beginning of interrupt processing. The function also ensures that */
@/* the system stack is used upon return to the calling ISR. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* None */
@/* */
@/* CALLED BY */
@/* */
@/* ISRs */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_thread_vectored_context_save(VOID)
@{
.global _tx_thread_vectored_context_save
.type _tx_thread_vectored_context_save,function
_tx_thread_vectored_context_save:
@
@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
@ out, we are in IRQ mode, and all registers are intact. */
@
@ /* Check for a nested interrupt condition. */
@ if (_tx_thread_system_state++)
@ {
@
#ifdef TX_ENABLE_FIQ_SUPPORT
MRS r0, CPSR @ Pickup the CPSR
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt CPSR
MSR CPSR_cxsf, r0 @ Disable interrupts
#endif
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
LDR r2, [r3, #0] @ Pickup system state
CMP r2, #0 @ Is this the first interrupt?
BEQ __tx_thread_not_nested_save @ Yes, not a nested context save
@
@ /* Nested interrupt condition. */
@
ADD r2, r2, #1 @ Increment the interrupt counter
STR r2, [r3, #0] @ Store it back in the variable
@
@ /* Note: Minimal context of interrupted thread is already saved. */
@
@ /* Return to the ISR. */
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
MOV pc, lr @ Return to caller
@
__tx_thread_not_nested_save:
@ }
@
@ /* Otherwise, not nested, check to see if a thread was running. */
@ else if (_tx_thread_current_ptr)
@ {
@
ADD r2, r2, #1 @ Increment the interrupt counter
STR r2, [r3, #0] @ Store it back in the variable
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
LDR r0, [r1, #0] @ Pickup current thread pointer
CMP r0, #0 @ Is it NULL?
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
@ scheduling loop - nothing needs saving!
@
@ /* Note: Minimal context of interrupted thread is already saved. */
@
@ /* Save the current stack pointer in the thread's control block. */
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
@
@ /* Switch to the system stack. */
@ sp = _tx_thread_system_stack_ptr;
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
MOV pc, lr @ Return to caller
@
@ }
@ else
@ {
@
__tx_thread_idle_system_save:
@
@ /* Interrupt occurred in the scheduling loop. */
@
@ /* Not much to do here, just adjust the stack pointer, and return to IRQ
@ processing. */
@
MOV r10, #0 @ Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
@
@ /* Call the ISR enter function to indicate an ISR is executing. */
@
PUSH {lr} @ Save ISR lr
BL _tx_execution_isr_enter @ Call the ISR enter function
POP {lr} @ Recover ISR lr
#endif
ADD sp, sp, #32 @ Recover saved registers
MOV pc, lr @ Return to caller
@
@ }
@}

View File

@@ -0,0 +1,279 @@
@/**************************************************************************/
@/* */
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
@/* */
@/* This software is licensed under the Microsoft Software License */
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
@/* and in the root directory of this software. */
@/* */
@/**************************************************************************/
@
@
@/**************************************************************************/
@/**************************************************************************/
@/** */
@/** ThreadX Component */
@/** */
@/** Timer */
@/** */
@/**************************************************************************/
@/**************************************************************************/
@
@#define TX_SOURCE_CODE
@
@
@/* Include necessary system files. */
@
@#include "tx_api.h"
@#include "tx_timer.h"
@#include "tx_thread.h"
@
@
.arm
@
@/* Define Assembly language external references... */
@
.global _tx_timer_time_slice
.global _tx_timer_system_clock
.global _tx_timer_current_ptr
.global _tx_timer_list_start
.global _tx_timer_list_end
.global _tx_timer_expired_time_slice
.global _tx_timer_expired
.global _tx_thread_time_slice
@
@
@
@/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for
@ applications calling this function from to 16-bit Thumb mode. */
@
.text
.align 2
.thumb
.global $_tx_timer_interrupt
.type $_tx_timer_interrupt,function
$_tx_timer_interrupt:
BX pc @ Switch to 32-bit mode
NOP @
.arm
STMFD sp!, {lr} @ Save return address
BL _tx_timer_interrupt @ Call _tx_timer_interrupt function
LDMFD sp!, {lr} @ Recover saved return address
BX lr @ Return to 16-bit caller
@
@
.text
.align 2
@/**************************************************************************/
@/* */
@/* FUNCTION RELEASE */
@/* */
@/* _tx_timer_interrupt ARM11/GNU */
@/* 6.0.1 */
@/* AUTHOR */
@/* */
@/* William E. Lamie, Microsoft Corporation */
@/* */
@/* DESCRIPTION */
@/* */
@/* This function processes the hardware timer interrupt. This */
@/* processing includes incrementing the system clock and checking for */
@/* time slice and/or timer expiration. If either is found, the */
@/* interrupt context save/restore functions are called along with the */
@/* expiration functions. */
@/* */
@/* INPUT */
@/* */
@/* None */
@/* */
@/* OUTPUT */
@/* */
@/* None */
@/* */
@/* CALLS */
@/* */
@/* _tx_thread_time_slice Time slice interrupted thread */
@/* _tx_timer_expiration_process Timer expiration processing */
@/* */
@/* CALLED BY */
@/* */
@/* interrupt vector */
@/* */
@/* RELEASE HISTORY */
@/* */
@/* DATE NAME DESCRIPTION */
@/* */
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
@/* */
@/**************************************************************************/
@VOID _tx_timer_interrupt(VOID)
@{
.global _tx_timer_interrupt
.type _tx_timer_interrupt,function
_tx_timer_interrupt:
@
@ /* Upon entry to this routine, it is assumed that context save has already
@ been called, and therefore the compiler scratch registers are available
@ for use. */
@
@ /* Increment the system clock. */
@ _tx_timer_system_clock++;
@
LDR r1, =_tx_timer_system_clock @ Pickup address of system clock
LDR r0, [r1] @ Pickup system clock
ADD r0, r0, #1 @ Increment system clock
STR r0, [r1] @ Store new system clock
@
@ /* Test for time-slice expiration. */
@ if (_tx_timer_time_slice)
@ {
@
LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice
LDR r2, [r3] @ Pickup time-slice
CMP r2, #0 @ Is it non-active?
BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing
@
@ /* Decrement the time_slice. */
@ _tx_timer_time_slice--;
@
SUB r2, r2, #1 @ Decrement the time-slice
STR r2, [r3] @ Store new time-slice value
@
@ /* Check for expiration. */
@ if (__tx_timer_time_slice == 0)
@
CMP r2, #0 @ Has it expired?
BNE __tx_timer_no_time_slice @ No, skip expiration processing
@
@ /* Set the time-slice expired flag. */
@ _tx_timer_expired_time_slice = TX_TRUE;
@
LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag
MOV r0, #1 @ Build expired value
STR r0, [r3] @ Set time-slice expiration flag
@
@ }
@
__tx_timer_no_time_slice:
@
@ /* Test for timer expiration. */
@ if (*_tx_timer_current_ptr)
@ {
@
LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address
LDR r0, [r1] @ Pickup current timer
LDR r2, [r0] @ Pickup timer list entry
CMP r2, #0 @ Is there anything in the list?
BEQ __tx_timer_no_timer @ No, just increment the timer
@
@ /* Set expiration flag. */
@ _tx_timer_expired = TX_TRUE;
@
LDR r3, =_tx_timer_expired @ Pickup expiration flag address
MOV r2, #1 @ Build expired value
STR r2, [r3] @ Set expired flag
B __tx_timer_done @ Finished timer processing
@
@ }
@ else
@ {
__tx_timer_no_timer:
@
@ /* No timer expired, increment the timer pointer. */
@ _tx_timer_current_ptr++;
@
ADD r0, r0, #4 @ Move to next timer
@
@ /* Check for wraparound. */
@ if (_tx_timer_current_ptr == _tx_timer_list_end)
@
LDR r3, =_tx_timer_list_end @ Pickup address of timer list end
LDR r2, [r3] @ Pickup list end
CMP r0, r2 @ Are we at list end?
BNE __tx_timer_skip_wrap @ No, skip wraparound logic
@
@ /* Wrap to beginning of list. */
@ _tx_timer_current_ptr = _tx_timer_list_start;
@
LDR r3, =_tx_timer_list_start @ Pickup address of timer list start
LDR r0, [r3] @ Set current pointer to list start
@
__tx_timer_skip_wrap:
@
STR r0, [r1] @ Store new current timer pointer
@ }
@
__tx_timer_done:
@
@
@ /* See if anything has expired. */
@ if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
@ {
@
LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag
LDR r2, [r3] @ Pickup time-slice expired flag
CMP r2, #0 @ Did a time-slice expire?
BNE __tx_something_expired @ If non-zero, time-slice expired
LDR r1, =_tx_timer_expired @ Pickup address of other expired flag
LDR r0, [r1] @ Pickup timer expired flag
CMP r0, #0 @ Did a timer expire?
BEQ __tx_timer_nothing_expired @ No, nothing expired
@
__tx_something_expired:
@
@
STMDB sp!, {r0, lr} @ Save the lr register on the stack
@ and save r0 just to keep 8-byte alignment
@
@ /* Did a timer expire? */
@ if (_tx_timer_expired)
@ {
@
LDR r1, =_tx_timer_expired @ Pickup address of expired flag
LDR r0, [r1] @ Pickup timer expired flag
CMP r0, #0 @ Check for timer expiration
BEQ __tx_timer_dont_activate @ If not set, skip timer activation
@
@ /* Process timer expiration. */
@ _tx_timer_expiration_process();
@
BL _tx_timer_expiration_process @ Call the timer expiration handling routine
@
@ }
__tx_timer_dont_activate:
@
@ /* Did time slice expire? */
@ if (_tx_timer_expired_time_slice)
@ {
@
LDR r3, =_tx_timer_expired_time_slice @ Pickup address of time-slice expired
LDR r2, [r3] @ Pickup the actual flag
CMP r2, #0 @ See if the flag is set
BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing
@
@ /* Time slice interrupted thread. */
@ _tx_thread_time_slice();
@
BL _tx_thread_time_slice @ Call time-slice processing
@
@ }
@
__tx_timer_not_ts_expiration:
@
LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for
@ the 8-byte stack alignment
@
@ }
@
__tx_timer_nothing_expired:
@
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
@
@}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\sample_threadx.ewp</path>
</project>
<project>
<path>$WS_DIR$\tx.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@@ -0,0 +1,161 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Part one of the system initialization code,
;; contains low-level
;; initialization.
;;
;; Copyright 2007 IAR Systems. All rights reserved.
;;
;; $Revision: 14520 $
;;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION IRQ_STACK:DATA:NOROOT(3)
SECTION FIQ_STACK:DATA:NOROOT(3)
SECTION CSTACK:DATA:NOROOT(3)
;
; The module in this file are included in the libraries, and may be
; replaced by any user-defined modules that define the PUBLIC symbol
; __iar_program_start or a user defined start symbol.
;
; To override the cstartup defined in the library, simply add your
; modified version to the workbench project.
SECTION .intvec:CODE:NOROOT(2)
PUBLIC __vector
PUBLIC __vector_0x14
PUBLIC __iar_program_start
EXTERN __tx_undefined
EXTERN __tx_swi_interrupt
EXTERN __tx_prefetch_handler
EXTERN __tx_abort_handler
EXTERN __tx_irq_handler
EXTERN __tx_fiq_handler
ARM
__vector:
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
LDR PC,Reset_Addr ; Reset
LDR PC,Undefined_Addr ; Undefined instructions
LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
LDR PC,Prefetch_Addr ; Prefetch abort
LDR PC,Abort_Addr ; Data abort
__vector_0x14:
DCD 0 ; RESERVED
LDR PC,IRQ_Addr ; IRQ
LDR PC,FIQ_Addr ; FIQ
Reset_Addr: DCD __iar_program_start
Undefined_Addr: DCD __tx_undefined
SWI_Addr: DCD __tx_swi_interrupt
Prefetch_Addr: DCD __tx_prefetch_handler
Abort_Addr: DCD __tx_abort_handler
IRQ_Addr: DCD __tx_irq_handler
FIQ_Addr: DCD __tx_fiq_handler
; --------------------------------------------------
; ?cstartup -- low-level system initialization code.
;
; After a reser execution starts here, the mode is ARM, supervisor
; with interrupts disabled.
;
SECTION .text:CODE:NOROOT(2)
; PUBLIC ?cstartup
EXTERN ?main
REQUIRE __vector
ARM
__iar_program_start:
?cstartup:
;
; Add initialization needed before setup of stackpointers here.
;
;
; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.
;
; --------------------
; Mode, correspords to bits 0-5 in CPSR
MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR
USR_MODE DEFINE 0x10 ; User mode
FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
SVC_MODE DEFINE 0x13 ; Supervisor mode
ABT_MODE DEFINE 0x17 ; Abort mode
UND_MODE DEFINE 0x1B ; Undefined Instruction mode
SYS_MODE DEFINE 0x1F ; System mode
MRS r0, cpsr ; Original PSR value
;; Set up the interrupt stack pointer.
BIC r0, r0, #MODE_MSK ; Clear the mode bits
ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(IRQ_STACK) ; End of IRQ_STACK
;; Set up the fast interrupt stack pointer.
BIC r0, r0, #MODE_MSK ; Clear the mode bits
ORR r0, r0, #FIQ_MODE ; Set FIR mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK
;; Set up the normal stack pointer.
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #SYS_MODE ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(CSTACK) ; End of CSTACK
#ifdef __ARMVFP__
;; Enable the VFP coprocessor.
MOV r0, #0x40000000 ; Set EN bit in VFP
FMXR fpexc, r0 ; FPEXC, clear others.
;
; Disable underflow exceptions by setting flush to zero mode.
; For full IEEE 754 underflow compliance this code should be removed
; and the appropriate exception handler installed.
;
MOV r0, #0x01000000 ; Set FZ bit in VFP
FMXR fpscr, r0 ; FPSCR, clear others.
#endif
;
; Add more initialization here
;
; Continue to ?main for C-level initialization.
B ?main
END

View File

@@ -0,0 +1,374 @@
/* 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 byte pool memory. */
UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE];
/* 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;
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_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;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x0;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x80;
define symbol __ICFEDIT_region_ROM_end__ = 0x1FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x100000;
define symbol __ICFEDIT_region_RAM_end__ = 0x1FFFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x2000;
define symbol __ICFEDIT_size_svcstack__ = 0x100;
define symbol __ICFEDIT_size_irqstack__ = 0x100;
define symbol __ICFEDIT_size_fiqstack__ = 0x100;
define symbol __ICFEDIT_size_undstack__ = 0x100;
define symbol __ICFEDIT_size_abtstack__ = 0x100;
define symbol __ICFEDIT_size_heap__ = 0x8000;
/**** End of ICF editor section. ###ICF###*/
define symbol __ICFEDIT_size_freemem__ = 0x100000;
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region RAM_freemem = mem:[from 0x200000 to 0x300000];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP};
place in RAM_region { last section FREE_MEM};

View File

@@ -0,0 +1,535 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace>
<ConfigDictionary>
<CurrentConfigs>
<Project>sample_threadx/Debug</Project>
<Project>tx/Debug</Project>
</CurrentConfigs>
<CurrentProj>sample_threadx</CurrentProj>
<OverviewSelected>1</OverviewSelected>
</ConfigDictionary>
<WindowStorage>
<Desktop>
<IarPane-34048>
<ColumnWidth0>21</ColumnWidth0>
<ColumnWidth1>2518</ColumnWidth1>
<FilterLevel>2</FilterLevel>
<LiveFile></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34048>
<IarPane-34049>
<ToolBarCmdIds>
<item>34001</item>
<item>0</item>
</ToolBarCmdIds>
</IarPane-34049>
<IarPane-34050>
<ToolBarCmdIds>
<item>57600</item>
<item>57601</item>
<item>57603</item>
<item>33024</item>
<item>0</item>
<item>57607</item>
<item>0</item>
<item>57635</item>
<item>57634</item>
<item>57637</item>
<item>0</item>
<item>57643</item>
<item>57644</item>
<item>0</item>
<item>33090</item>
<item>33057</item>
<item>57636</item>
<item>57640</item>
<item>57641</item>
<item>33026</item>
<item>33065</item>
<item>33063</item>
<item>33064</item>
<item>33053</item>
<item>33054</item>
<item>0</item>
<item>33035</item>
<item>33036</item>
<item>34399</item>
<item>0</item>
<item>33038</item>
<item>33039</item>
<item>0</item>
</ToolBarCmdIds>
</IarPane-34050>
<IarPane-34065>
<ColumnWidths>
<Column0>359</Column0>
<Column1>30</Column1>
<Column2>30</Column2>
<Column3>30</Column3>
</ColumnWidths>
<NodeDict>
<ExpandedNode>&lt;ws&gt;</ExpandedNode>
</NodeDict>
</IarPane-34065>
<ControlBarVersion>
<Major>14</Major>
<Minor>26</Minor>
</ControlBarVersion>
<MFCToolBarParameters>
<Tooltips>1</Tooltips>
<ShortcutKeys>1</ShortcutKeys>
<LargeIcons>0</LargeIcons>
<MenuAnimation>0</MenuAnimation>
<RecentlyUsedMenus>1</RecentlyUsedMenus>
<MenuShadows>1</MenuShadows>
<ShowAllMenusAfterDelay>1</ShowAllMenusAfterDelay>
<CommandsUsage>010000000D002596000001000000108600000B0000000C8100000300000004860000010000001781000002000000148100000100000003E10000010000000E81000001000000E980000001000000118600000A00000046810000020000000D81000001000000E880000001000000</CommandsUsage>
</MFCToolBarParameters>
<CommandManager>
<CommandsWithoutImages>0F000D8400000F84000008840000FFFFFFFF54840000328100001C81000009840000818400007D8400008284000083840000848400000E84000030840000</CommandsWithoutImages>
<MenuUserImages>0400048400004C000000068400004E0000000B8100001B0000000D8100001D000000</MenuUserImages>
</CommandManager>
<Pane-59393>
<ID>0</ID>
<RectRecentFloat>0A0000000A0000006E0000006E000000</RectRecentFloat>
<RectRecentDocked>000000004E050000000A000061050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-59393>
<BasePane-59393>
<IsVisible>1</IsVisible>
</BasePane-59393>
<Pane-34051>
<ID>34051</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34051>
<BasePane-34051>
<IsVisible>0</IsVisible>
</BasePane-34051>
<IarPane-34051 />
<Pane--1>
<ID>4294967295</ID>
<RectRecentFloat>0000000082040000000A000065050000</RectRecentFloat>
<RectRecentDocked>000000006B040000000A00004E050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane--1>
<BasePane--1>
<IsVisible>1</IsVisible>
</BasePane--1>
<Pane-34052>
<ID>34052</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34052>
<BasePane-34052>
<IsVisible>1</IsVisible>
</BasePane-34052>
<IarPane-34052>
<ColumnWidth0>24</ColumnWidth0>
<ColumnWidth1>1880</ColumnWidth1>
<ColumnWidth2>501</ColumnWidth2>
<ColumnWidth3>125</ColumnWidth3>
<FilterLevel>2</FilterLevel>
<LiveFile>C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\BuildLog.log</LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34052>
<Pane-34048>
<ID>34048</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34048>
<BasePane-34048>
<IsVisible>1</IsVisible>
</BasePane-34048>
<Pane-34056>
<ID>34056</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34056>
<BasePane-34056>
<IsVisible>0</IsVisible>
</BasePane-34056>
<IarPane-34056>
<ColumnWidth0>891</ColumnWidth0>
<ColumnWidth1>127</ColumnWidth1>
<ColumnWidth2>1528</ColumnWidth2>
<FilterLevel>2</FilterLevel>
<LiveFile></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34056>
<Pane-34057>
<ID>34057</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34057>
<BasePane-34057>
<IsVisible>0</IsVisible>
</BasePane-34057>
<IarPane-34057>
<ColumnWidth0>891</ColumnWidth0>
<ColumnWidth1>127</ColumnWidth1>
<ColumnWidth2>1528</ColumnWidth2>
<FilterLevel>2</FilterLevel>
<LiveFile></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34057>
<Pane-34058>
<ID>34058</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34058>
<BasePane-34058>
<IsVisible>0</IsVisible>
</BasePane-34058>
<IarPane-34058>
<ColumnWidth0>764</ColumnWidth0>
<ColumnWidth1>127</ColumnWidth1>
<ColumnWidth2>1146</ColumnWidth2>
<ColumnWidth3>509</ColumnWidth3>
<FilterLevel>2</FilterLevel>
<LiveFile></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34058>
<Pane-34059>
<ID>34059</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34059>
<BasePane-34059>
<IsVisible>0</IsVisible>
</BasePane-34059>
<IarPane-34059>
<ColumnWidth0>891</ColumnWidth0>
<ColumnWidth1>127</ColumnWidth1>
<ColumnWidth2>1528</ColumnWidth2>
<FilterLevel>2</FilterLevel>
<LiveFile></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34059>
<Pane-34062>
<ID>34062</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>0400000083040000FC09000034050000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34062>
<BasePane-34062>
<IsVisible>0</IsVisible>
</BasePane-34062>
<IarPane-34062>
<FilterLevel>2</FilterLevel>
<LiveFile></LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34062>
<Pane-34053>
<ID>34053</ID>
<RectRecentFloat>000000001700000080020000A8000000</RectRecentFloat>
<RectRecentDocked>00000000000000008002000091000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34053>
<BasePane-34053>
<IsVisible>0</IsVisible>
</BasePane-34053>
<IarPane-34053>
<cg_type>
<item>2</item>
</cg_type>
<cg_symbol>
<item></item>
</cg_symbol>
<cg_user>
<item></item>
</cg_user>
<cg_display>
<item>&lt;Right-click on a symbol in the editor to show a call graph&gt;</item>
</cg_display>
<cg_def_file>
<item></item>
</cg_def_file>
<cg_def_line>
<item>0</item>
</cg_def_line>
<cg_def_col>
<item>0</item>
</cg_def_col>
<cg_call_file>
<item></item>
</cg_call_file>
<cg_call_line>
<item>0</item>
</cg_call_line>
<cg_call_col>
<item>0</item>
</cg_call_col>
<col-names>
<item>File</item>
<item>Function</item>
<item>Line</item>
</col-names>
<col-widths>
<item>200</item>
<item>700</item>
<item>100</item>
</col-widths>
</IarPane-34053>
<Pane-34054>
<ID>34054</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34054>
<BasePane-34054>
<IsVisible>0</IsVisible>
</BasePane-34054>
<IarPane-34054 />
<Pane-34055>
<ID>34055</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34055>
<BasePane-34055>
<IsVisible>0</IsVisible>
</BasePane-34055>
<IarPane-34055>
<col-names>
<item>Check</item>
<item>File</item>
<item>Line</item>
<item>Message</item>
<item>Severity</item>
</col-names>
<col-widths>
<item>200</item>
<item>200</item>
<item>100</item>
<item>500</item>
<item>100</item>
</col-widths>
</IarPane-34055>
<Pane-34060>
<ID>34060</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34060>
<BasePane-34060>
<IsVisible>0</IsVisible>
</BasePane-34060>
<IarPane-34060>
<FilterLevel>2</FilterLevel>
<LiveFile>$WS_DIR/SourceBrowseLog.log</LiveFile>
<LiveLogEnabled>0</LiveLogEnabled>
<LiveFilterLevel>-1</LiveFilterLevel>
</IarPane-34060>
<Pane-34061>
<ID>34061</ID>
<RectRecentFloat>000000001700000080020000A8000000</RectRecentFloat>
<RectRecentDocked>00000000000000008002000091000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34061>
<BasePane-34061>
<IsVisible>0</IsVisible>
</BasePane-34061>
<IarPane-34061>
<SB_FileFilter>
<item>2</item>
</SB_FileFilter>
<SB_TypeFilter>
<item>0</item>
</SB_TypeFilter>
<SB_SBW_File>
<item>C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\Debug\Obj\sample_threadx.pbw</item>
</SB_SBW_File>
<col-names>
<item>File</item>
<item>Name</item>
<item>Scope</item>
<item>Symbol type</item>
</col-names>
<col-widths>
<item>300</item>
<item>300</item>
<item>300</item>
<item>300</item>
</col-widths>
</IarPane-34061>
<Pane-34063>
<ID>34063</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34063>
<BasePane-34063>
<IsVisible>0</IsVisible>
</BasePane-34063>
<IarPane-34063 />
<Pane-34064>
<ID>34064</ID>
<RectRecentFloat>000000001700000022010000C8000000</RectRecentFloat>
<RectRecentDocked>000000000000000022010000B1000000</RectRecentDocked>
<RecentFrameAlignment>32768</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34064>
<BasePane-34064>
<IsVisible>0</IsVisible>
</BasePane-34064>
<IarPane-34064 />
<Pane-34065>
<ID>34065</ID>
<RectRecentFloat>00000000170000000601000078010000</RectRecentFloat>
<RectRecentDocked>0000000032000000AF01000067040000</RectRecentDocked>
<RecentFrameAlignment>4096</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>32767</MRUWidth>
<PinState>0</PinState>
</Pane-34065>
<BasePane-34065>
<IsVisible>1</IsVisible>
</BasePane-34065>
<DockingManager-256>
<DockingPaneAndPaneDividers>0000000014000000000000000010000001000000FFFFFFFFFFFFFFFFAF01000032000000B301000067040000010000000200001004000000010000005DFFFFFFBD080000118500000000000000000000000000000000000001000000118500000100000011850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000108500000000000000000000000000000000000001000000108500000100000010850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000001000000FFFFFFFFFFFFFFFF0000000067040000000A00006B040000010000000100001004000000010000009EFBFFFF6F000000FFFFFFFF07000000048500000085000008850000098500000A8500000B8500000E850000FFFF02000B004354616262656450616E6500800000010000000000000082040000000A000065050000000000006B040000000A00004E050000000000004080005607000000FFFEFF054200750069006C006400010000000485000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000085000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0485000001000000FFFFFFFF04850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000038500000000000000000000000000000000000001000000038500000100000003850000000000000000000000000000</DockingPaneAndPaneDividers>
</DockingManager-256>
<MFCToolBar-34049>
<Name>CMSIS-Pack</Name>
<Buttons>00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED1840000000000000C000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000</Buttons>
</MFCToolBar-34049>
<Pane-34049>
<ID>34049</ID>
<RectRecentFloat>0A0000000A0000006E0000006E000000</RectRecentFloat>
<RectRecentDocked>FE020000000000002C0300001A000000</RectRecentDocked>
<RecentFrameAlignment>8192</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>24</MRUWidth>
<PinState>0</PinState>
</Pane-34049>
<BasePane-34049>
<IsVisible>1</IsVisible>
</BasePane-34049>
<MFCToolBar-34050>
<Name>Main</Name>
<Buttons>00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000035000000FFFEFF000000000000000000000000000100000001000000018001E100000000000036000000FFFEFF000000000000000000000000000100000001000000018003E100000000040038000000FFFEFF0000000000000000000000000001000000010000000180008100000000000019000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000004003B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004003D000000FFFEFF000000000000000000000000000100000001000000018022E10000000004003C000000FFFEFF000000000000000000000000000100000001000000018025E10000000004003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040042000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040043000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000400FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004002C000000FFFEFF000000000000000000000000000100000001000000018024E10000000004003E000000FFFEFF000000000000000000000000000100000001000000018028E100000000040040000000FFFEFF000000000000000000000000000100000001000000018029E100000000040041000000FFFEFF000000000000000000000000000100000001000000018002810000000004001B000000FFFEFF0000000000000000000000000001000000010000000180298100000000040030000000FFFEFF000000000000000000000000000100000001000000018027810000000004002E000000FFFEFF000000000000000000000000000100000001000000018028810000000004002F000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040028000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040029000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000004001F000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000020000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000034000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000000000022000000FFFEFF00000000000000000000000000010000000100000001800F8100000000000023000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00E8020000</Buttons>
</MFCToolBar-34050>
<Pane-34050>
<ID>34050</ID>
<RectRecentFloat>0A0000000A0000006E0000006E000000</RectRecentFloat>
<RectRecentDocked>0000000000000000FE0200001A000000</RectRecentDocked>
<RecentFrameAlignment>8192</RecentFrameAlignment>
<RecentRowIndex>0</RecentRowIndex>
<IsFloating>0</IsFloating>
<MRUWidth>744</MRUWidth>
<PinState>0</PinState>
</Pane-34050>
<BasePane-34050>
<IsVisible>1</IsVisible>
</BasePane-34050>
</Desktop>
<ChildIdMap>
<WIN_DEBUG_LOG>34048</WIN_DEBUG_LOG>
<TB_CMSISPACK>34049</TB_CMSISPACK>
<TB_MAIN2>34050</TB_MAIN2>
<WIN_BREAKPOINTS>34051</WIN_BREAKPOINTS>
<WIN_BUILD>34052</WIN_BUILD>
<WIN_CALL_GRAPH>34053</WIN_CALL_GRAPH>
<WIN_CUSTOM_SFR>34054</WIN_CUSTOM_SFR>
<WIN_C_STAT>34055</WIN_C_STAT>
<WIN_FIND_ALL_DECLARATIONS>34056</WIN_FIND_ALL_DECLARATIONS>
<WIN_FIND_ALL_REFERENCES>34057</WIN_FIND_ALL_REFERENCES>
<WIN_FIND_IN_FILES>34058</WIN_FIND_IN_FILES>
<WIN_SELECT_AMBIGUOUS_DEFINITIONS>34059</WIN_SELECT_AMBIGUOUS_DEFINITIONS>
<WIN_SOURCEBROWSE_LOG>34060</WIN_SOURCEBROWSE_LOG>
<WIN_SOURCE_BROWSE2>34061</WIN_SOURCE_BROWSE2>
<WIN_TOOL_OUTPUT>34062</WIN_TOOL_OUTPUT>
<WIN_TS_INTERRUPT_AVAILABLE>34063</WIN_TS_INTERRUPT_AVAILABLE>
<WIN_TS_INTERRUPT_CONFIG>34064</WIN_TS_INTERRUPT_CONFIG>
<WIN_WORKSPACE>34065</WIN_WORKSPACE>
</ChildIdMap>
<MDIWindows>
<MDIClientArea-0>
<MDITabsState>01000000030000000100000000000000000000000100000001000000FFFFFFFF00000000010000000100000000000000280000002800000000000000</MDITabsState>
</MDIClientArea-0>
</MDIWindows>
</WindowStorage>
</Workspace>

View File

@@ -0,0 +1,40 @@
@REM This batch file has been generated by the IAR Embedded Workbench
@REM C-SPY Debugger, as an aid to preparing a command line for running
@REM the cspybat command line utility using the appropriate settings.
@REM
@REM Note that this file is generated every time a new debug session
@REM is initialized, so you may want to move or rename the file before
@REM making changes.
@REM
@REM You can launch cspybat by typing the name of this batch file followed
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
@REM
@REM Read about available command line parameters in the C-SPY Debugging
@REM Guide. Hints about additional command line parameters that may be
@REM useful in specific cases:
@REM --download_only Downloads a code image without starting a debug
@REM session afterwards.
@REM --silent Omits the sign-on message.
@REM --timeout Limits the maximum allowed execution time.
@REM
@echo off
if not "%~1" == "" goto debugFile
@echo on
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
@echo off
goto end
:debugFile
@echo on
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
@echo off
:end

View File

@@ -0,0 +1,31 @@
param([String]$debugfile = "");
# This powershell file has been generated by the IAR Embedded Workbench
# C - SPY Debugger, as an aid to preparing a command line for running
# the cspybat command line utility using the appropriate settings.
#
# Note that this file is generated every time a new debug session
# is initialized, so you may want to move or rename the file before
# making changes.
#
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
#
# Read about available command line parameters in the C - SPY Debugging
# Guide. Hints about additional command line parameters that may be
# useful in specific cases :
# --download_only Downloads a code image without starting a debug
# session afterwards.
# --silent Omits the sign - on message.
# --timeout Limits the maximum allowed execution time.
#
if ($debugfile -eq "")
{
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
}
else
{
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl"
}

View File

@@ -0,0 +1,13 @@
"--endian=little"
"--cpu=ARM1136J-S"
"--fpu=None"
"--semihosting"
"--multicore_nr_of_cores=1"

View File

@@ -0,0 +1,11 @@
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armproc.dll"
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armsim2.dll"
"C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\Debug\Exe\sample_threadx.out"
--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll"

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<crun>
<version>1</version>
<filter_entries>
<filter index="0" type="default">
<type>*</type>
<start_file>*</start_file>
<end_file>*</end_file>
<action_debugger>0</action_debugger>
<action_log>1</action_log>
</filter>
</filter_entries>
</crun>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,99 @@
<?xml version="1.0"?>
<settings>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<DebugChecksum>
<Checksum>1018058853</Checksum>
</DebugChecksum>
<CodeCoverage>
<Enabled>0</Enabled>
<ShowSource>0</ShowSource>
<HideCovered>0</HideCovered>
</CodeCoverage>
<Disassembly>
<InstrCount>0</InstrCount>
</Disassembly>
<Exceptions>
<StopOnUncaught>_ 0</StopOnUncaught>
<StopOnThrow>_ 0</StopOnThrow>
</Exceptions>
<CallStack>
<ShowArgs>0</ShowArgs>
</CallStack>
<DriverProfiling>
<Enabled>0</Enabled>
<Mode>1</Mode>
<Graph>0</Graph>
<Symbiont>0</Symbiont>
</DriverProfiling>
<CallStackLog>
<Enabled>0</Enabled>
</CallStackLog>
<CallStackStripe>
<ShowTiming>1</ShowTiming>
</CallStackStripe>
<TermIOLog>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
</TermIOLog>
<LogFile>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
<Category>_ 0</Category>
</LogFile>
<InterruptLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
<SumSortOrder>0</SumSortOrder>
</InterruptLog>
<DataLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
</DataLog>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Interrupts>
<Enabled>1</Enabled>
<Irq0>_ 0 9999 0 9999 1 0 0 100 0 1 "IRQ 1 0x18 CPSR.I"</Irq0>
<Count>1</Count>
</Interrupts>
<MemConfig>
<Base>1</Base>
<Manual>0</Manual>
<Ddf>1</Ddf>
<TypeViol>0</TypeViol>
<Stop>1</Stop>
</MemConfig>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
<Simulator>
<Freq>10000000</Freq>
<FreqHi>0</FreqHi>
<MultiCoreRunAll>1</MultiCoreRunAll>
</Simulator>
</settings>

View File

@@ -0,0 +1,40 @@
@REM This batch file has been generated by the IAR Embedded Workbench
@REM C-SPY Debugger, as an aid to preparing a command line for running
@REM the cspybat command line utility using the appropriate settings.
@REM
@REM Note that this file is generated every time a new debug session
@REM is initialized, so you may want to move or rename the file before
@REM making changes.
@REM
@REM You can launch cspybat by typing the name of this batch file followed
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
@REM
@REM Read about available command line parameters in the C-SPY Debugging
@REM Guide. Hints about additional command line parameters that may be
@REM useful in specific cases:
@REM --download_only Downloads a code image without starting a debug
@REM session afterwards.
@REM --silent Omits the sign-on message.
@REM --timeout Limits the maximum allowed execution time.
@REM
@echo off
if not "%~1" == "" goto debugFile
@echo on
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
@echo off
goto end
:debugFile
@echo on
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
@echo off
:end

View File

@@ -0,0 +1,31 @@
param([String]$debugfile = "");
# This powershell file has been generated by the IAR Embedded Workbench
# C - SPY Debugger, as an aid to preparing a command line for running
# the cspybat command line utility using the appropriate settings.
#
# Note that this file is generated every time a new debug session
# is initialized, so you may want to move or rename the file before
# making changes.
#
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
#
# Read about available command line parameters in the C - SPY Debugging
# Guide. Hints about additional command line parameters that may be
# useful in specific cases :
# --download_only Downloads a code image without starting a debug
# session afterwards.
# --silent Omits the sign - on message.
# --timeout Limits the maximum allowed execution time.
#
if ($debugfile -eq "")
{
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
}
else
{
& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl"
}

View File

@@ -0,0 +1,13 @@
"--endian=little"
"--cpu=ARM1136J-S"
"--fpu=None"
"--semihosting"
"--multicore_nr_of_cores=1"

View File

@@ -0,0 +1,11 @@
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\arm\bin\armproc.dll"
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\arm\bin\armsim2.dll"
"C:\release\threadx\Debug\Exe\tx.out"
--plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\arm\bin\armbat.dll"

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<crun>
<version>1</version>
<filter_entries>
<filter index="0" type="default">
<type>*</type>
<start_file>*</start_file>
<end_file>*</end_file>
<action_debugger>0</action_debugger>
<action_log>1</action_log>
</filter>
</filter_entries>
</crun>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project>
<WindowStorage />
</Project>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0"?>
<settings>
<InterruptLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
<SumSortOrder>0</SumSortOrder>
</InterruptLog>
<DataLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
</DataLog>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Interrupts>
<Enabled>1</Enabled>
</Interrupts>
<MemConfig>
<Base>1</Base>
<Manual>0</Manual>
<Ddf>1</Ddf>
<TypeViol>0</TypeViol>
<Stop>1</Stop>
</MemConfig>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
<Simulator>
<Freq>10000000</Freq>
<FreqHi>0</FreqHi>
<MultiCoreRunAll>1</MultiCoreRunAll>
</Simulator>
</settings>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,339 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** 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 DEFINE 0xD3 ; Disable irq,fiq SVC mode
IRQ_MODE DEFINE 0xD2 ; Disable irq,fiq IRQ mode
FIQ_MODE DEFINE 0xD1 ; Disable irq,fiq FIQ mode
SYS_MODE DEFINE 0xDF ; Disable irq,fiq SYS mode
;
;
EXTERN _tx_thread_system_stack_ptr
EXTERN _tx_initialize_unused_memory
EXTERN _tx_thread_context_save
; EXTERN _tx_thread_vectored_context_save
EXTERN _tx_thread_context_restore
#ifdef TX_ENABLE_FIQ_SUPPORT
EXTERN _tx_thread_fiq_context_save
EXTERN _tx_thread_fiq_context_restore
#endif
#ifdef TX_ENABLE_IRQ_NESTING
EXTERN _tx_thread_irq_nesting_start
EXTERN _tx_thread_irq_nesting_end
#endif
#ifdef TX_ENABLE_FIQ_NESTING
EXTERN _tx_thread_fiq_nesting_start
EXTERN _tx_thread_fiq_nesting_end
#endif
EXTERN _tx_timer_interrupt
EXTERN ?cstartup
EXTERN _tx_build_options
EXTERN _tx_version_id
;
;
;
;/* Define the FREE_MEM segment that will specify where free memory is
; defined. This must also be located in at the end of other RAM segments
; in the linker control file. The value of this segment is what is passed
; to tx_application_define. */
;
RSEG FREE_MEM:DATA
PUBLIC __tx_free_memory_start
__tx_free_memory_start
DS32 4
;
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_initialize_low_level ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
CODE32
PUBLIC _tx_initialize_low_level
_tx_initialize_low_level
;
; /****** NOTE ****** The IAR 4.11a and above releases call main in SYS mode. */
;
; /* Remember the stack pointer, link register, and switch to SVC mode. */
;
MOV r0, sp ; Remember the SP
MOV r1, lr ; Remember the LR
MOV r3, #SVC_MODE ; Build SVC mode CPSR
MSR CPSR_cxsf, r3 ; Switch to SVC mode
MOV sp, r0 ; Inherit the stack pointer setup by cstartup
MOV lr, r1 ; Inherit the link register
;
; /* Pickup the start of free memory. */
;
LDR r0, =__tx_free_memory_start ; Get end of non-initialized RAM area
;
; /* Save the system stack pointer. */
; _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
;
; /* Save the first available memory address. */
; _tx_initialize_unused_memory = (VOID_PTR) FREE_MEM;
;
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. */
;
; /* Done, return to caller. */
;
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;}
;
;/* Define shells for each of the interrupt vectors. */
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_undefined
__tx_undefined
B __tx_undefined ; Undefined handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_swi_interrupt
__tx_swi_interrupt
B __tx_swi_interrupt ; Software interrupt handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_prefetch_handler
__tx_prefetch_handler
B __tx_prefetch_handler ; Prefetch exception handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_abort_handler
__tx_abort_handler
B __tx_abort_handler ; Abort exception handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_reserved_handler
__tx_reserved_handler
B __tx_reserved_handler ; Reserved exception handler
;
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_irq_handler
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_irq_processing_return
__tx_irq_handler
;
; /* Jump to context save to save system context. */
B _tx_thread_context_save
__tx_irq_processing_return
;
; /* At this point execution is still in the IRQ mode. The CPSR, point of
; interrupt, and all C scratch registers are available for use. In
; addition, IRQ interrupts may be re-enabled - with certain restrictions -
; if nested IRQ interrupts are desired. Interrupts may be re-enabled over
; small code sequences where lr is saved before enabling interrupts and
; restored after interrupts are again disabled. */
;
; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
; from IRQ mode with interrupts disabled. This routine switches to the
; system mode and returns with IRQ interrupts enabled.
;
; NOTE: It is very important to ensure all IRQ interrupts are cleared
; prior to enabling nested IRQ interrupts. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_start
#endif
;
; /* For debug purpose, execute the timer interrupt processing here. In
; a real system, some kind of status indication would have to be checked
; before the timer interrupt handler could be called. */
;
BL _tx_timer_interrupt ; Timer interrupt handler
;
; /* Application IRQ handlers can be called here! */
;
; /* If interrupt nesting was started earlier, the end of interrupt nesting
; service must be called before returning to _tx_thread_context_restore.
; This routine returns in processing in IRQ mode with interrupts disabled. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_end
#endif
;
; /* Jump to context restore to restore system context. */
B _tx_thread_context_restore
;
;
; /* This is an example of a vectored IRQ handler. */
;
; RSEG .text:CODE:NOROOT(2)
; PUBLIC __tx_example_vectored_irq_handler
;__tx_example_vectored_irq_handler
;
; /* Jump to 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 registers
; BL _tx_thread_vectored_context_save
;
; /* At this point execution is still in the IRQ mode. The CPSR, point of
; interrupt, and all C scratch registers are available for use. In
; addition, IRQ interrupts may be re-enabled - with certain restrictions -
; if nested IRQ interrupts are desired. Interrupts may be re-enabled over
; small code sequences where lr is saved before enabling interrupts and
; restored after interrupts are again disabled. */
;
; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
; from IRQ mode with interrupts disabled. This routine switches to the
; system mode and returns with IRQ interrupts enabled.
;
; NOTE: It is very important to ensure all IRQ interrupts are cleared
; prior to enabling nested IRQ interrupts. */
;#ifdef TX_ENABLE_IRQ_NESTING
; BL _tx_thread_irq_nesting_start
;#endif
;
; /* Application IRQ handler is called here! */
;
; /* If interrupt nesting was started earlier, the end of interrupt nesting
; service must be called before returning to _tx_thread_context_restore.
; This routine returns in processing in IRQ mode with interrupts disabled. */
;#ifdef TX_ENABLE_IRQ_NESTING
; BL _tx_thread_irq_nesting_end
;#endif
;
; /* Jump to context restore to restore system context. */
; B _tx_thread_context_restore
;
;
#ifdef TX_ENABLE_FIQ_SUPPORT
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_fiq_handler
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_fiq_processing_return
__tx_fiq_handler
;
; /* Jump to fiq context save to save system context. */
B _tx_thread_fiq_context_save
__tx_fiq_processing_return
;
; /* At this point execution is still in the FIQ mode. The CPSR, point of
; interrupt, and all C scratch registers are available for use. */
;
; /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start
; from FIQ mode with interrupts disabled. This routine switches to the
; system mode and returns with FIQ interrupts enabled.
;
; NOTE: It is very important to ensure all FIQ interrupts are cleared
; prior to enabling nested FIQ interrupts. */
#ifdef TX_ENABLE_FIQ_NESTING
BL _tx_thread_fiq_nesting_start
#endif
;
; /* Application FIQ handlers can be called here! */
;
; /* If interrupt nesting was started earlier, the end of interrupt nesting
; service must be called before returning to _tx_thread_fiq_context_restore. */
#ifdef TX_ENABLE_FIQ_NESTING
BL _tx_thread_fiq_nesting_end
#endif
;
; /* Jump to fiq context restore to restore system context. */
B _tx_thread_fiq_context_restore
;
;
#else
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_fiq_handler
__tx_fiq_handler
B __tx_fiq_handler ; FIQ interrupt handler
#endif
;
;
BUILD_OPTIONS
DC32 _tx_build_options ; Reference to ensure it comes in
VERSION_ID
DC32 _tx_version_id ; Reference to ensure it comes in
END

View File

@@ -0,0 +1,401 @@
/**************************************************************************/
/* */
/* Copyright (c) 1996-2018 by Express Logic Inc. */
/* */
/* This software is copyrighted by and is the sole property of Express */
/* Logic, Inc. All rights, title, ownership, or other interests */
/* in the software remain the property of Express Logic, Inc. This */
/* software may only be used in accordance with the corresponding */
/* license agreement. Any unauthorized use, duplication, transmission, */
/* distribution, or disclosure of this software is expressly forbidden. */
/* */
/* This Copyright notice may not be removed or modified without prior */
/* written consent of Express Logic, Inc. */
/* */
/* Express Logic, Inc. reserves the right to modify this software */
/* without notice. */
/* */
/* Express Logic, Inc. info@expresslogic.com */
/* 11423 West Bernardo Court http://www.expresslogic.com */
/* San Diego, CA 92127 */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Port Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h ARM11/IAR */
/* 6.0.1 */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Express Logic, Inc. */
/* */
/* 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 ARM11 IAR */
/* Support 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>
#include <intrinsics.h>
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
/* 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_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
#endif
#else
ULONG _tx_misra_time_stamp_get(VOID);
#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get()
#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. */
#ifdef TX_MISRA_ENABLE
#define TX_DISABLE_INLINE
#else
#define TX_INLINE_INITIALIZATION
#endif
/* 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. */
#ifndef TX_MISRA_ENABLE
#ifdef TX_ENABLE_STACK_CHECKING
#undef TX_DISABLE_STACK_FILLING
#endif
#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
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#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. */
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#if (__VER__ < 8000000)
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
#else
void *_tx_iar_create_per_thread_tls_area(void);
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
void __iar_Initlocks(void);
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
#endif
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
#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 TX_DISABLE_INLINE
#if __CORE__ > __ARM4TM__
#if __CPU_MODE__ == 2
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
b = (UINT) __CLZ(m); \
b = 31 - b;
#endif
#endif
#endif
/* Define ThreadX interrupt lockout and restore macros for protection on
access of critical kernel information. The restore interrupt macro must
restore the interrupt posture of the running thread prior to the value
present prior to the disable macro. In most cases, the save area macro
is used to define a local function save area for the disable and restore
macros. */
/* First, check and see what mode the file is being compiled in. The IAR compiler
defines __CPU_MODE__ to 1, if the Thumb mode is present, and 2 if ARM 32-bit mode
is present. If ARM 32-bit mode is present, the fast CPSR manipulation macros
are available. Otherwise, if Thumb mode is present, we must use function calls. */
#ifdef TX_DISABLE_INLINE
UINT _tx_thread_interrupt_disable(void);
void _tx_thread_interrupt_restore(UINT old_posture);
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#else
#if __CPU_MODE__ == 2
#if (__VER__ < 8002000)
__intrinsic unsigned long __get_CPSR();
__intrinsic void __set_CPSR( unsigned long );
#endif
#if (__VER__ < 8002000)
#define TX_INTERRUPT_SAVE_AREA unsigned long interrupt_save;
#else
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
#endif
#define TX_DISABLE interrupt_save = __get_CPSR(); \
__set_CPSR(interrupt_save | TX_INT_DISABLE);
#define TX_RESTORE __set_CPSR(interrupt_save);
#else
UINT _tx_thread_interrupt_disable(void);
void _tx_thread_interrupt_restore(UINT old_posture);
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#endif
#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/IAR Version 6.0.1 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
#else
extern CHAR _tx_version_id[];
#endif
#endif
#endif

View File

@@ -0,0 +1,527 @@
Microsoft's Azure RTOS ThreadX for ARM11
Thumb & 32-bit Mode
Using the IAR Tools
1. Building the ThreadX run-time Library
Building the ThreadX library is easy. First, open the Azure RTOS workspace
azure_rtos.eww. Next, make the TX project the "active project" in the
IAR Embedded Workbench and select the "Make" button. You should observe
assembly and compilation of a series of ThreadX source files. This
results in the ThreadX run-time library file tx.a, which is needed by
the application.
2. Demonstration System
The ThreadX demonstration is designed to execute under the IAR
Windows-based ARM11 simulator.
Building the demonstration is easy; simply make the sample_threadx.ewp project
the "active project" in the IAR Embedded Workbench and select the
"Make" button.
You should observe the compilation of sample_threadx.c (which is the demonstration
application) and linking with tx.a. The resulting file sample_threadx.out is a
binary file that can be downloaded and executed on IAR's ARM11 simulator.
A SPECIAL NOTE: The IAR ARM simulator does simulate interrupts. In order
for the ThreadX demonstration to run properly, a periodic IRQ interrupt must
be setup in the IAR debugging environment. We recommend setting an IRQ
interrupt to execute every 9999 cycles.
3. System Initialization
The entry point in ThreadX for the ARM11 using IAR tools is at label
?cstartup. This is defined within the IAR compiler's startup code. In
addition, this is where all static and global preset C variable
initialization processing takes place.
The ThreadX tx_initialize_low_level.s file is responsible for setting up
various system data structures, and a periodic timer interrupt source.
By default, the vector area is defined at the top of cstartup.s, which is
a slightly modified from the base IAR file.
The _tx_initialize_low_level function inside of tx_initialize_low_level.s
also 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. To accomplish this, a section is created in
tx_initialize_low_level.s called FREE_MEM, which must be located after all
other RAM sections in memory.
4. Register Usage and Stack Frames
The IAR ARM 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
5. Conditional Compilation Switches
The following are conditional compilation options for building the ThreadX library
and application:
TX_ENABLE_FIQ_SUPPORT This assembler/compiler define enables
FIQ interrupt handling support in the
ThreadX assembly files. If used,
it should be used on all assembly
files and the generic C source of
ThreadX should be compiled with
TX_ENABLE_FIQ_SUPPORT defined as well.
TX_ENABLE_IRQ_NESTING This assembler define enables IRQ
nested support. If IRQ nested
interrupt support is needed, this
define should be applied to
tx_initialize_low_level.s.
TX_ENABLE_FIQ_NESTING This assembler define enables FIQ
nested support. If FIQ nested
interrupt support is needed, this
define should be applied to
tx_initialize_low_level.s. In addition,
IRQ nesting should also be enabled.
TX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included,
this define causes basic ThreadX error
checking to be disabled. Please see
Chapter 2 in the "ThreadX User Guide"
for more details.
TX_MAX_PRIORITIES Defines the priority levels for ThreadX.
Legal values range from 32 through
1024 (inclusive) and MUST be evenly divisible
by 32. Increasing the number of priority levels
supported increases the RAM usage by 128 bytes
for every group of 32 priorities. However, there
is only a negligible effect on performance. By
default, this value is set to 32 priority levels.
TX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is
used for error checking when threads are created.
The default value is port-specific and is found
in tx_port.h.
TX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal
ThreadX timer thread. This thread processes all
thread sleep requests as well as all service call
timeouts. In addition, all application timer callback
routines are invoked from this context. The default
value is port-specific and is found in tx_port.h.
TX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer
thread. The default value is priority 0 - the highest
priority in ThreadX. The default value is defined
in tx_port.h.
TX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system
timer thread for ThreadX. This results in improved
performance on timer events and smaller RAM requirements
because the timer stack and control block are no
longer needed. However, using this option moves all
the timer expiration processing to the timer ISR level.
By default, this option is not defined.
TX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX
timers in-line instead of using a function call. This
improves performance but slightly increases code size.
By default, this option is not defined.
TX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each
thread's stack is disabled. By default, this option is
not defined.
TX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking,
which includes analysis of how much stack has been used and
examination of data pattern "fences" before and after the
stack area. If a stack error is detected, the registered
application stack error handler is called. This option does
result in slightly increased overhead and code size. Please
review the tx_thread_stack_error_notify API for more information.
By default, this option is not defined.
TX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature
and slightly reduces code size and improves performance. Of course,
the preemption-threshold capabilities are no longer available.
By default, this option is not defined.
TX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX
global C data structures to zero. This should only be used if
the compiler's initialization code sets all un-initialized
C global data to zero. Using this option slightly reduces
code size and improves performance during initialization.
By default, this option is not defined.
TX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various
ThreadX objects. Using this option slightly reduces code size
and improves performance.
TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on block pools. By default, this option is
not defined.
TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on byte pools. By default, this option is
not defined.
TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on event flags groups. By default, this option
is not defined.
TX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on mutexes. By default, this option is
not defined.
TX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on queues. By default, this option is
not defined.
TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on semaphores. By default, this option is
not defined.
TX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on threads. By default, this option is
not defined.
TX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance
information on timers. By default, this option is
not defined.
TX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace
feature. The trace buffer is supplied at a later time
via an application call to tx_trace_enable.
TX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing.
This define is only pertinent if the ThreadX library is
built with TX_ENABLE_EVENT_TRACE defined.
TX_TRACE_TIME_MASK This defines the number of valid bits in the event trace
time-stamp source defined previously. If the time-stamp
source is 16-bits, this value should be 0xFFFF. Alternatively,
if the time-stamp source is 32-bits, this value should be
0xFFFFFFFF. This define is only pertinent if the ThreadX
library is built with TX_ENABLE_EVENT_TRACE defined.
TX_THUMB Defined, this option enables the BX LR calling return sequence
in assembly files, to ensure correct operation on systems that
use both ARM and Thumb mode. By default, this option is
not defined
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 ThreadX library
project to enable various 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 ARM11
targets. There are a certain set of requirements that are defined in the
following sub-sections:
7.1 Vector Area
The ARM11 vectors start at address zero. The demonstration system startup
cstartup.s file contains the vectors and is loaded at address zero.
On actual hardware platforms, this area might have to be copied to address 0.
7.2 IRQ ISRs
ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports nested
IRQ interrupts. The following sub-sections define the IRQ capabilities.
7.2.1 Standard IRQ ISRs
The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ
interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following
is the default IRQ handler defined in tx_initialize_low_level.s:
PUBLIC __tx_irq_handler
PUBLIC __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. Note
; that IRQ interrupts are still disabled upon return from the context
; save function. */
;
; /* Application ISR dispatch call goes 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:
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_example_vectored_irq_handler
__tx_example_vectored_irq_handler
;
; /* Jump to 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 registers
BL _tx_thread_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. Note
; that IRQ interrupts are still disabled upon return from the context
; save function. */
;
; /* Application ISR dispatch 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:
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_irq_handler
RSEG .text:CODE:NOROOT(2)
PUBLIC __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. Note
; that IRQ interrupts are still disabled upon return from the context
; save function. */
;
; /* 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. */
;
BL _tx_thread_irq_nesting_start
; /* Application ISR dispatch call goes 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. */
;
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, ARM11 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:
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_fiq_handler
RSEG .text:CODE:NOROOT(2)
PUBLIC __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 dispatch call goes 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:
RSEG .text:CODE:NOROOT(2)
PUBLIC __tx_fiq_handler
RSEG .text:CODE:NOROOT(2)
PUBLIC __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 dispatch call goes 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.
9. Thumb/ARM11 Mixed Mode
By default, ThreadX is setup for running in ARM11 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. The only exception
to this is the file tx_thread_shell_entry.c. This file must always be
built in 32-bit mode. In addition, if any Thumb code is used the entire
ThreadX assembly source should be built with TX_THUMB defined.
10. IAR Thread-safe Library Support
Thread-safe support for the IAR tools is easily enabled by building the ThreadX library
and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file
should have the following line added (if not already in place):
initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
The project options "General Options -> Library Configuration" should also have the
"Enable thread support in library" box selected.
11. Revision History
06/30/2020 Initial ThreadX 6.0.1 version for ARM11 using IAR's ARM tools.
Copyright(c) 1996-2020 Microsoft Corporation
https://azure.com/rtos

View File

@@ -0,0 +1,816 @@
/**************************************************************************/
/* */
/* Copyright (c) 1996-2018 by Express Logic Inc. */
/* */
/* This software is copyrighted by and is the sole property of Express */
/* Logic, Inc. All rights, title, ownership, or other interests */
/* in the software remain the property of Express Logic, Inc. This */
/* software may only be used in accordance with the corresponding */
/* license agreement. Any unauthorized use, duplication, transmission, */
/* distribution, or disclosure of this software is expressly forbidden. */
/* */
/* This Copyright notice may not be removed or modified without prior */
/* written consent of Express Logic, Inc. */
/* */
/* Express Logic, Inc. reserves the right to modify this software */
/* without notice. */
/* */
/* Express Logic, Inc. info@expresslogic.com */
/* 11423 West Bernardo Court www.expresslogic.com */
/* San Diego, CA 92127 */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** IAR Multithreaded Library Support */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Define IAR library for tools prior to version 8. */
#if (__VER__ < 8000000)
/* IAR version 7 and below. */
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_mutex.h"
/* This implementation requires that the following macros are defined in the
tx_port.h file and <yvals.h> is included with the following code segments:
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL;
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
application.
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
*/
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#if _MULTI_THREAD
TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK];
UINT __tx_iar_system_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_system_lock_no_mutexes;
UINT __tx_iar_system_lock_internal_errors;
UINT __tx_iar_system_lock_isr_caller;
/* Define the TLS access function for the IAR library. */
void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
{
char _DLIB_TLS_MEMORY *p = 0;
/* Is there a current thread? */
if (_tx_thread_current_ptr)
p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer;
else
p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD");
p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
return (void _DLIB_TLS_MEMORY *) p;
}
/* Define mutexes for IAR library. */
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_LOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_system_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_system_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_system_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
#if _DLIB_FILE_DESCRIPTOR
TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK];
UINT __tx_iar_file_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_file_lock_no_mutexes;
UINT __tx_iar_file_lock_internal_errors;
UINT __tx_iar_file_lock_isr_caller;
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_FLOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_file_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_file_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_file_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
#endif /* _DLIB_FILE_DESCRIPTOR */
#endif /* _MULTI_THREAD */
#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
#else /* IAR version 8 and above. */
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_mutex.h"
/* This implementation requires that the following macros are defined in the
tx_port.h file and <yvals.h> is included with the following code segments:
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
void *_tx_iar_create_per_thread_tls_area(void);
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
void __iar_Initlocks(void);
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0);
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
application.
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
*/
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <DLib_threads.h>
void * __aeabi_read_tp();
void* _tx_iar_create_per_thread_tls_area();
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
#pragma section="__iar_tls$$DATA"
/* Define the TLS access function for the IAR library. */
void * __aeabi_read_tp(void)
{
void *p = 0;
TX_THREAD *thread_ptr = _tx_thread_current_ptr;
if (thread_ptr)
{
p = thread_ptr->tx_thread_iar_tls_pointer;
}
else
{
p = __section_begin("__iar_tls$$DATA");
}
return p;
}
/* Define the TLS creation and destruction to use malloc/free. */
void* _tx_iar_create_per_thread_tls_area()
{
UINT tls_size = __iar_tls_size();
/* Get memory for TLS. */
void *p = malloc(tls_size);
/* Initialize TLS-area and run constructors for objects in TLS */
__iar_tls_init(p);
return p;
}
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr)
{
/* Destroy objects living in TLS */
__call_thread_dtors();
free(tls_ptr);
}
#ifndef _MAX_LOCK
#define _MAX_LOCK 4
#endif
static TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK];
static UINT __tx_iar_system_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_system_lock_no_mutexes;
UINT __tx_iar_system_lock_internal_errors;
UINT __tx_iar_system_lock_isr_caller;
/* Define mutexes for IAR library. */
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_LOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_system_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_system_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_system_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
if (*m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
if (*m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_system_lock_isr_caller++;
}
}
}
#if _DLIB_FILE_DESCRIPTOR
#include <stdio.h> /* Added to get access to FOPEN_MAX */
#ifndef _MAX_FLOCK
#define _MAX_FLOCK FOPEN_MAX /* Define _MAX_FLOCK as the maximum number of open files */
#endif
TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK];
UINT __tx_iar_file_lock_next_free_mutex = 0;
/* Define error counters, just for debug purposes. */
UINT __tx_iar_file_lock_no_mutexes;
UINT __tx_iar_file_lock_internal_errors;
UINT __tx_iar_file_lock_isr_caller;
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list. */
for (i = 0; i < _MAX_FLOCK; i++)
{
/* Setup a pointer to the start of the next free mutex. */
mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
/* Check for wrap-around on the next free mutex. */
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0. */
__tx_iar_file_lock_next_free_mutex = 0;
}
/* Is this mutex free? */
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop! */
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error! No more free mutexes! */
/* Increment the no mutexes error counter. */
__tx_iar_file_lock_no_mutexes++;
/* Set return pointer to NULL. */
*m = TX_NULL;
/* Return. */
return;
}
/* Now create the ThreadX mutex for the IAR library. */
status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful. */
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer. */
*m = (VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter. */
__tx_iar_file_lock_internal_errors++;
/* Return a NULL pointer to indicate an error. */
*m = TX_NULL;
}
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex. */
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex. */
status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads. */
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex. */
status = _tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release. */
if (status)
{
/* Internal error, increment the counter. */
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error. */
__tx_iar_file_lock_isr_caller++;
}
}
#endif /* _DLIB_FILE_DESCRIPTOR */
#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */
#endif /* IAR version 8 and above. */

View File

@@ -0,0 +1,258 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** 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 DEFINE 0xD3 ; SVC mode
IRQ_MODE DEFINE 0xD2 ; IRQ mode
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; Disable IRQ interrupts
#else
DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts
#endif
MODE_MASK DEFINE 0x1F ; Mode mask
THUMB_MASK DEFINE 0x20 ; Thumb bit mask
SVC_MODE_BITS DEFINE 0x13 ; SVC mode value
;
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN _tx_thread_execute_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_thread_schedule
EXTERN _tx_thread_preempt_disable
EXTERN _tx_execution_isr_exit
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_restore ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_context_restore
CODE32
_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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR exit function to indicate an ISR is complete. */
;
BL _tx_execution_isr_exit ; Call the ISR exit function
#endif
;
; /* Determine if interrupts are nested. */
; if (--_tx_thread_system_state)
; {
;
LDR r3, =_tx_thread_system_state ; Pickup address of system state 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

View File

@@ -0,0 +1,222 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled
#else
DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled
#endif
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN __tx_irq_processing_return
EXTERN _tx_execution_isr_enter
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_context_save ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_context_save
CODE32
_tx_thread_context_save
;
; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
; out, we are in IRQ mode, and all registers are intact. */
;
; /* Check for a nested interrupt condition. */
; if (_tx_thread_system_state++)
; {
;
STMDB sp!, {r0-r3} ; Save some working registers
#ifdef TX_ENABLE_FIQ_SUPPORT
MRS r0, CPSR ; Pickup the CPSR
ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR
MSR CPSR_cxsf, r0 ; Disable interrupts
#endif
LDR r3, =_tx_thread_system_state ; Pickup address of system state 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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
B __tx_irq_processing_return ; Continue IRQ processing
;
__tx_thread_not_nested_save
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #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 occured in
; scheduling loop - nothing needs saving!
;
; /* Save minimal context of interrupted thread. */
;
MRS r2, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r2, r10, r12, lr} ; Store other registers
;
; /* Save the current stack pointer in the thread's control block. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
MOV r10, #0 ; Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
B __tx_irq_processing_return ; Continue IRQ processing
;
; }
; else
; {
;
__tx_thread_idle_system_save
;
; /* Interrupt occurred in the scheduling loop. */
;
; /* Not much to do here, just adjust the stack pointer, and return to IRQ
; processing. */
;
MOV r10, #0 ; Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
ADD sp, sp, #16 ; Recover saved registers
B __tx_irq_processing_return ; Continue IRQ processing
;
; }
;}
;
;
;
END

View File

@@ -0,0 +1,269 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** 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 DEFINE 0xD3 ; SVC mode
FIQ_MODE DEFINE 0xD1 ; FIQ mode
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts
#else
DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts
#endif
MODE_MASK DEFINE 0x1F ; Mode mask
THUMB_MASK DEFINE 0x20 ; Thumb bit mask
IRQ_MODE_BITS DEFINE 0x12 ; IRQ mode bits
SVC_MODE_BITS DEFINE 0x13 ; SVC mode value
;
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN _tx_thread_execute_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_thread_schedule
EXTERN _tx_thread_preempt_disable
EXTERN _tx_execution_isr_exit
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_context_restore ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_fiq_context_restore
CODE32
_tx_thread_fiq_context_restore
;
; /* Lockout interrupts. */
;
MRS r3, CPSR ; Pickup current CPSR
ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value
MSR CPSR_cxsf, r0 ; Lockout interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR exit function to indicate an ISR is complete. */
;
BL _tx_execution_isr_exit ; Call the ISR exit function
#endif
;
; /* Determine if interrupts are nested. */
; if (--_tx_thread_system_state)
; {
;
LDR r3, =_tx_thread_system_state ; Pickup address of system state 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

View File

@@ -0,0 +1,215 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN __tx_fiq_processing_return
EXTERN _tx_execution_isr_enter
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_context_save ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_fiq_context_save
CODE32
_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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
B __tx_fiq_processing_return ; Continue FIQ processing
;
__tx_thread_fiq_not_nested_save
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3] ; Store it back in the variable
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1] ; Pickup current thread pointer
CMP r0, #0 ; Is it NULL?
BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred in
; ; scheduling loop - nothing needs saving!
;
; /* Save minimal context of interrupted thread. */
;
MRS r2, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r2, lr} ; Store other registers, Note that we don't
; ; need to save sl and ip since FIQ has
; ; copies of these registers. Nested
; ; interrupt processing does need to save
; ; these registers.
;
; /* Save the current stack pointer in the thread's control block. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
MOV r10, #0 ; Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
B __tx_fiq_processing_return ; Continue FIQ processing
;
; }
; else
; {
;
__tx_thread_fiq_idle_system_save
;
; /* Interrupt occurred in the scheduling loop. */
;
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
;
; /* Not much to do here, save the current SPSR and LR for possible
; use in IRQ interrupted in idle system conditions, and return to
; FIQ interrupt processing. */
;
MRS r0, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r0, lr} ; Store other registers that will get used
; ; or stripped off the stack in context
; ; restore
B __tx_fiq_processing_return ; Continue FIQ processing
;
; }
;}
;
;
END

View File

@@ -0,0 +1,121 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts
#else
DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts
#endif
MODE_MASK DEFINE 0x1F ; Mode mask
FIQ_MODE_BITS DEFINE 0x11 ; FIQ mode bits
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_nesting_end ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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.s79). */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_fiq_nesting_end
CODE32
_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
LDR lr, [sp] ; Pickup saved lr
ADD sp, sp, #4 ; Adjust stack pointer
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
MOV pc, r3 ; Return to ISR
;}
;
;
END

View File

@@ -0,0 +1,114 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
FIQ_DISABLE DEFINE 0x40 ; FIQ disable bit
MODE_MASK DEFINE 0x1F ; Mode mask
SYS_MODE_BITS DEFINE 0x1F ; System mode bits
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_nesting_start ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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.s79). */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_fiq_nesting_start
CODE32
_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
STR lr, [sp, #-4]! ; Push the system mode lr on the system mode stack
BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR
MSR CPSR_cxsf, r0 ; Enter system mode
MOV pc, r3 ; Return to ISR
;}
;
;
END

View File

@@ -0,0 +1,115 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
#ifdef TX_ENABLE_FIQ_SUPPORT
INT_MASK DEFINE 0xC0 ; Interrupt bit mask
#else
INT_MASK DEFINE 0x80 ; Interrupt bit mask
#endif
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_control ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_interrupt_control
CODE32
_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
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;
;}
;
;
END

View File

@@ -0,0 +1,113 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled
#else
DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled
#endif
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_disable ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_interrupt_disable
CODE32
_tx_thread_interrupt_disable??rA
_tx_thread_interrupt_disable
;
; /* Pickup current interrupt lockout posture. */
;
MRS r0, CPSR ; Pickup current CPSR
;
; /* Mask interrupts. */
;
ORR r1, r0, #DISABLE_INTS ; Mask interrupts
MSR CPSR_cxsf, r1 ; Setup new CPSR
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;}
;
;
END

View File

@@ -0,0 +1,99 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_restore ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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 */
;/* */
;/**************************************************************************/
;void _tx_thread_interrupt_restore(UINT old_posture)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_interrupt_restore
CODE32
_tx_thread_interrupt_restore
;
; /* Apply the new interrupt posture. */
;
MSR CPSR_cxsf, r0 ; Setup new CPSR
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;}
;
END

View File

@@ -0,0 +1,122 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts
#else
DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts
#endif
MODE_MASK DEFINE 0x1F ; Mode mask
IRQ_MODE_BITS DEFINE 0x12 ; IRQ mode bits
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_irq_nesting_end ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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.s79). */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_irq_nesting_end
CODE32
_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
LDR lr, [sp] ; Pickup saved lr
ADD sp, sp, #4 ; Adjust stack pointer
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
MOV pc, r3 ; Return to ISR
;}
;
;
END

View File

@@ -0,0 +1,114 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
IRQ_DISABLE DEFINE 0x80 ; IRQ disable bit
MODE_MASK DEFINE 0x1F ; Mode mask
SYS_MODE_BITS DEFINE 0x1F ; System mode bits
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_irq_nesting_start ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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.s79). */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_irq_nesting_start
CODE32
_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
STR lr, [sp, #-4]! ; Push the system mode lr on the system mode stack
BIC r0, r0, #IRQ_DISABLE ; Build enable IRQ CPSR
MSR CPSR_cxsf, r0 ; Enter system mode
MOV pc, r3 ; Return to ISR
;}
;
;
END

View File

@@ -0,0 +1,183 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
#ifdef TX_ENABLE_FIQ_SUPPORT
ENABLE_INTS DEFINE 0xC0 ; IRQ & FIQ Interrupts enabled mask
#else
ENABLE_INTS DEFINE 0x80 ; IRQ Interrupts enabled mask
#endif
;
;
EXTERN _tx_thread_execute_ptr
EXTERN _tx_thread_current_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_execution_thread_enter
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_schedule ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_schedule
CODE32
_tx_thread_schedule??rA
_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;
;
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the thread entry function to indicate the thread is executing. */
;
BL _tx_execution_thread_enter ; Call the thread execution enter function
#endif
;
; /* Determine if an interrupt frame or a synchronous task suspension frame
; is present. */
;
LDMIA sp!, {r0, r1} ; Pickup the stack type and saved CPSR
CMP r0, #0 ; Check for synchronous context switch
MSRNE SPSR_cxsf, r1 ; Setup SPSR for return
LDMNEIA sp!, {r0-r12, lr, pc}^ ; Return to point of thread interrupt
LDMIA sp!, {r4-r11, lr} ; Return to thread synchronously
MSR CPSR_cxsf, r1 ; Recover CPSR
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;
;}
;
END

View File

@@ -0,0 +1,170 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
SVC_MODE DEFINE 0x13 ; SVC mode
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSR_MASK DEFINE 0xDF ; Mask initial CPSR, IRQ & FIQ ints enabled
#else
CPSR_MASK DEFINE 0x9F ; Mask initial CPSR, IRQ ints enabled
#endif
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_stack_build ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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))
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_stack_build
CODE32
_tx_thread_stack_build
;
;
; /* Build a fake interrupt frame. The form of the fake interrupt stack
; on the ARM9 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 long-word 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
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;}
END

View File

@@ -0,0 +1,161 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled
#else
DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled
#endif
;
;
EXTERN _tx_thread_current_ptr
EXTERN _tx_timer_time_slice
EXTERN _tx_thread_schedule
EXTERN _tx_execution_thread_exit
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_system_return ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_system_return
CODE32
_tx_thread_system_return??rA
_tx_thread_system_return
;
; /* Save minimal context on the stack. */
;
MOV r0, #0 ; Build a solicited stack type
MRS r1, CPSR ; Pickup the CPSR
STMDB sp!, {r0-r1, r4-r11, lr} ; Save minimal context
;
; /* Lockout interrupts. */
;
ORR r2, r1, #DISABLE_INTS ; Build disable interrupt CPSR
MSR CPSR_cxsf, r2 ; Disable interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the thread exit function to indicate the thread is no longer executing. */
;
BL _tx_execution_thread_exit ; Call the thread exit function
#endif
LDR r3, =_tx_thread_current_ptr ; Pickup address of current ptr
LDR r0, [r3, #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

View File

@@ -0,0 +1,207 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;#include "tx_timer.h"
;
;
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled
#else
DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled
#endif
EXTERN _tx_thread_system_state
EXTERN _tx_thread_current_ptr
EXTERN _tx_execution_isr_enter
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_vectored_context_save ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_thread_vectored_context_save
CODE32
_tx_thread_vectored_context_save
;
; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
; out, we are in IRQ mode, the minimal context is already saved, and the
; lr register contains the return ISR address. */
;
; /* Check for a nested interrupt condition. */
; if (_tx_thread_system_state++)
; {
;
#ifdef TX_ENABLE_FIQ_SUPPORT
MRS r0, CPSR ; Pickup the CPSR
ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR
MSR CPSR_cxsf, r0 ; Disable interrupts
#endif
LDR r3, =_tx_thread_system_state ; Pickup address of system state 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
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
MOV pc, lr ; Return to caller
;
__tx_thread_not_nested_save
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1, #0] ; Pickup current thread pointer
CMP r0, #0 ; Is it NULL?
BEQ __tx_thread_idle_system_save ; If so, interrupt occured 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_stack_ptr = sp;
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
MOV r10, #0 ; Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
MOV pc, lr ; Return to caller
;
; }
; else
; {
;
__tx_thread_idle_system_save
;
; /* Interrupt occurred in the scheduling loop. */
;
; /* Not much to do here, just adjust the stack pointer, and return to IRQ
; processing. */
;
MOV r10, #0 ; Clear stack limit
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
#endif
ADD sp, sp, #32 ; Recover saved registers
MOV pc, lr ; Return to caller
;
; }
;}
END

View File

@@ -0,0 +1,272 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) 1996-2018 by Express Logic Inc. */
;/* */
;/* This software is copyrighted by and is the sole property of Express */
;/* Logic, Inc. All rights, title, ownership, or other interests */
;/* in the software remain the property of Express Logic, Inc. This */
;/* software may only be used in accordance with the corresponding */
;/* license agreement. Any unauthorized use, duplication, transmission, */
;/* distribution, or disclosure of this software is expressly forbidden. */
;/* */
;/* This Copyright notice may not be removed or modified without prior */
;/* written consent of Express Logic, Inc. */
;/* */
;/* Express Logic, Inc. reserves the right to modify this software */
;/* without notice. */
;/* */
;/* Express Logic, Inc. info@expresslogic.com */
;/* 11423 West Bernardo Court http://www.expresslogic.com */
;/* San Diego, CA 92127 */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** 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...
;
EXTERN _tx_timer_time_slice
EXTERN _tx_timer_system_clock
EXTERN _tx_timer_current_ptr
EXTERN _tx_timer_list_start
EXTERN _tx_timer_list_end
EXTERN _tx_timer_expired_time_slice
EXTERN _tx_timer_expired
EXTERN _tx_thread_time_slice
EXTERN _tx_timer_expiration_process
;
;
;
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_timer_interrupt ARM11/IAR */
;/* 6.0.1 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Express Logic, Inc. */
;/* */
;/* 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)
;{
RSEG .text:CODE:NOROOT(2)
PUBLIC _tx_timer_interrupt
CODE32
_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
;
#ifdef TX_THUMB
BX lr ; Return to caller
#else
MOV pc, lr ; Return to caller
#endif
;
;}
END