mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2025-11-16 12:34:48 +00:00
add ARM11
This commit is contained in:
238
ports/arm11/ac5/example_build/build_threadx.bat
Normal file
238
ports/arm11/ac5/example_build/build_threadx.bat
Normal 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
|
||||||
4
ports/arm11/ac5/example_build/build_threadx_sample.bat
Normal file
4
ports/arm11/ac5/example_build/build_threadx_sample.bat
Normal 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
|
||||||
|
|
||||||
369
ports/arm11/ac5/example_build/sample_threadx.c
Normal file
369
ports/arm11/ac5/example_build/sample_threadx.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
444
ports/arm11/ac5/example_build/tx_initialize_low_level.s
Normal file
444
ports/arm11/ac5/example_build/tx_initialize_low_level.s
Normal 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
|
||||||
|
|
||||||
327
ports/arm11/ac5/inc/tx_port.h
Normal file
327
ports/arm11/ac5/inc/tx_port.h
Normal 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
|
||||||
|
|
||||||
534
ports/arm11/ac5/readme_threadx.txt
Normal file
534
ports/arm11/ac5/readme_threadx.txt
Normal 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
|
||||||
|
|
||||||
247
ports/arm11/ac5/src/tx_thread_context_restore.s
Normal file
247
ports/arm11/ac5/src/tx_thread_context_restore.s
Normal 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
|
||||||
|
|
||||||
207
ports/arm11/ac5/src/tx_thread_context_save.s
Normal file
207
ports/arm11/ac5/src/tx_thread_context_save.s
Normal 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
|
||||||
|
|
||||||
259
ports/arm11/ac5/src/tx_thread_fiq_context_restore.s
Normal file
259
ports/arm11/ac5/src/tx_thread_fiq_context_restore.s
Normal 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
|
||||||
|
|
||||||
203
ports/arm11/ac5/src/tx_thread_fiq_context_save.s
Normal file
203
ports/arm11/ac5/src/tx_thread_fiq_context_save.s
Normal 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
|
||||||
|
|
||||||
111
ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s
Normal file
111
ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s
Normal 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
|
||||||
|
|
||||||
104
ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s
Normal file
104
ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s
Normal 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
|
||||||
|
|
||||||
102
ports/arm11/ac5/src/tx_thread_interrupt_control.s
Normal file
102
ports/arm11/ac5/src/tx_thread_interrupt_control.s
Normal 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
|
||||||
|
|
||||||
98
ports/arm11/ac5/src/tx_thread_interrupt_disable.s
Normal file
98
ports/arm11/ac5/src/tx_thread_interrupt_disable.s
Normal 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
|
||||||
|
|
||||||
87
ports/arm11/ac5/src/tx_thread_interrupt_restore.s
Normal file
87
ports/arm11/ac5/src/tx_thread_interrupt_restore.s
Normal 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
|
||||||
|
|
||||||
110
ports/arm11/ac5/src/tx_thread_irq_nesting_end.s
Normal file
110
ports/arm11/ac5/src/tx_thread_irq_nesting_end.s
Normal 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
|
||||||
|
|
||||||
104
ports/arm11/ac5/src/tx_thread_irq_nesting_start.s
Normal file
104
ports/arm11/ac5/src/tx_thread_irq_nesting_start.s
Normal 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
|
||||||
|
|
||||||
172
ports/arm11/ac5/src/tx_thread_schedule.s
Normal file
172
ports/arm11/ac5/src/tx_thread_schedule.s
Normal 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
|
||||||
|
|
||||||
156
ports/arm11/ac5/src/tx_thread_stack_build.s
Normal file
156
ports/arm11/ac5/src/tx_thread_stack_build.s
Normal 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
|
||||||
|
|
||||||
150
ports/arm11/ac5/src/tx_thread_system_return.s
Normal file
150
ports/arm11/ac5/src/tx_thread_system_return.s
Normal 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
|
||||||
|
|
||||||
209
ports/arm11/ac5/src/tx_thread_vectored_context_save.s
Normal file
209
ports/arm11/ac5/src/tx_thread_vectored_context_save.s
Normal 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
|
||||||
|
|
||||||
258
ports/arm11/ac5/src/tx_timer_interrupt.s
Normal file
258
ports/arm11/ac5/src/tx_timer_interrupt.s
Normal 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
|
||||||
|
|
||||||
238
ports/arm11/gnu/example_build/build_threadx.bat
Normal file
238
ports/arm11/gnu/example_build/build_threadx.bat
Normal 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
|
||||||
6
ports/arm11/gnu/example_build/build_threadx_sample.bat
Normal file
6
ports/arm11/gnu/example_build/build_threadx_sample.bat
Normal 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
|
||||||
|
|
||||||
90
ports/arm11/gnu/example_build/crt0.S
Normal file
90
ports/arm11/gnu/example_build/crt0.S
Normal 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
|
||||||
BIN
ports/arm11/gnu/example_build/libc.a
Normal file
BIN
ports/arm11/gnu/example_build/libc.a
Normal file
Binary file not shown.
BIN
ports/arm11/gnu/example_build/libgcc.a
Normal file
BIN
ports/arm11/gnu/example_build/libgcc.a
Normal file
Binary file not shown.
BIN
ports/arm11/gnu/example_build/libnosys.a
Normal file
BIN
ports/arm11/gnu/example_build/libnosys.a
Normal file
Binary file not shown.
76
ports/arm11/gnu/example_build/reset.S
Normal file
76
ports/arm11/gnu/example_build/reset.S
Normal 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
|
||||||
369
ports/arm11/gnu/example_build/sample_threadx.c
Normal file
369
ports/arm11/gnu/example_build/sample_threadx.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
239
ports/arm11/gnu/example_build/sample_threadx.ld
Normal file
239
ports/arm11/gnu/example_build/sample_threadx.ld
Normal 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 . */
|
||||||
|
}
|
||||||
347
ports/arm11/gnu/example_build/tx_initialize_low_level.S
Normal file
347
ports/arm11/gnu/example_build/tx_initialize_low_level.S
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
316
ports/arm11/gnu/inc/tx_port.h
Normal file
316
ports/arm11/gnu/inc/tx_port.h
Normal 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
|
||||||
|
|
||||||
496
ports/arm11/gnu/readme_threadx.txt
Normal file
496
ports/arm11/gnu/readme_threadx.txt
Normal 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
|
||||||
|
|
||||||
241
ports/arm11/gnu/src/tx_thread_context_restore.S
Normal file
241
ports/arm11/gnu/src/tx_thread_context_restore.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
210
ports/arm11/gnu/src/tx_thread_context_save.S
Normal file
210
ports/arm11/gnu/src/tx_thread_context_save.S
Normal 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
|
||||||
|
@
|
||||||
|
@ }
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
256
ports/arm11/gnu/src/tx_thread_fiq_context_restore.S
Normal file
256
ports/arm11/gnu/src/tx_thread_fiq_context_restore.S
Normal 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
|
||||||
|
@
|
||||||
|
@}
|
||||||
|
|
||||||
204
ports/arm11/gnu/src/tx_thread_fiq_context_save.S
Normal file
204
ports/arm11/gnu/src/tx_thread_fiq_context_save.S
Normal 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
|
||||||
|
@
|
||||||
|
@ }
|
||||||
|
@}
|
||||||
|
|
||||||
111
ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S
Normal file
111
ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
104
ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S
Normal file
104
ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
115
ports/arm11/gnu/src/tx_thread_interrupt_control.S
Normal file
115
ports/arm11/gnu/src/tx_thread_interrupt_control.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
116
ports/arm11/gnu/src/tx_thread_interrupt_disable.S
Normal file
116
ports/arm11/gnu/src/tx_thread_interrupt_disable.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
104
ports/arm11/gnu/src/tx_thread_interrupt_restore.S
Normal file
104
ports/arm11/gnu/src/tx_thread_interrupt_restore.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
111
ports/arm11/gnu/src/tx_thread_irq_nesting_end.S
Normal file
111
ports/arm11/gnu/src/tx_thread_irq_nesting_end.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
104
ports/arm11/gnu/src/tx_thread_irq_nesting_start.S
Normal file
104
ports/arm11/gnu/src/tx_thread_irq_nesting_start.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
187
ports/arm11/gnu/src/tx_thread_schedule.S
Normal file
187
ports/arm11/gnu/src/tx_thread_schedule.S
Normal 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
|
||||||
|
@
|
||||||
|
@}
|
||||||
|
@
|
||||||
|
|
||||||
178
ports/arm11/gnu/src/tx_thread_stack_build.S
Normal file
178
ports/arm11/gnu/src/tx_thread_stack_build.S
Normal 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
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
167
ports/arm11/gnu/src/tx_thread_system_return.S
Normal file
167
ports/arm11/gnu/src/tx_thread_system_return.S
Normal 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!
|
||||||
|
@
|
||||||
|
@}
|
||||||
|
|
||||||
199
ports/arm11/gnu/src/tx_thread_vectored_context_save.S
Normal file
199
ports/arm11/gnu/src/tx_thread_vectored_context_save.S
Normal 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
|
||||||
|
@
|
||||||
|
@ }
|
||||||
|
@}
|
||||||
|
|
||||||
279
ports/arm11/gnu/src/tx_timer_interrupt.S
Normal file
279
ports/arm11/gnu/src/tx_timer_interrupt.S
Normal 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
|
||||||
|
@
|
||||||
|
@}
|
||||||
|
|
||||||
13
ports/arm11/iar/example_build/azure_rtos.eww
Normal file
13
ports/arm11/iar/example_build/azure_rtos.eww
Normal 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>
|
||||||
|
|
||||||
|
|
||||||
161
ports/arm11/iar/example_build/cstartup.s
Normal file
161
ports/arm11/iar/example_build/cstartup.s
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
374
ports/arm11/iar/example_build/sample_threadx.c
Normal file
374
ports/arm11/iar/example_build/sample_threadx.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
2974
ports/arm11/iar/example_build/sample_threadx.ewd
Normal file
2974
ports/arm11/iar/example_build/sample_threadx.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2136
ports/arm11/iar/example_build/sample_threadx.ewp
Normal file
2136
ports/arm11/iar/example_build/sample_threadx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
2797
ports/arm11/iar/example_build/sample_threadx.ewt
Normal file
2797
ports/arm11/iar/example_build/sample_threadx.ewt
Normal file
File diff suppressed because it is too large
Load Diff
49
ports/arm11/iar/example_build/sample_threadx.icf
Normal file
49
ports/arm11/iar/example_build/sample_threadx.icf
Normal 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};
|
||||||
535
ports/arm11/iar/example_build/settings/azure_rtos.wsdt
Normal file
535
ports/arm11/iar/example_build/settings/azure_rtos.wsdt
Normal 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><ws></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><Right-click on a symbol in the editor to show a call graph></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>
|
||||||
@@ -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
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
"--endian=little"
|
||||||
|
|
||||||
|
"--cpu=ARM1136J-S"
|
||||||
|
|
||||||
|
"--fpu=None"
|
||||||
|
|
||||||
|
"--semihosting"
|
||||||
|
|
||||||
|
"--multicore_nr_of_cores=1"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
13
ports/arm11/iar/example_build/settings/sample_threadx.crun
Normal file
13
ports/arm11/iar/example_build/settings/sample_threadx.crun
Normal 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>
|
||||||
1685
ports/arm11/iar/example_build/settings/sample_threadx.dbgdt
Normal file
1685
ports/arm11/iar/example_build/settings/sample_threadx.dbgdt
Normal file
File diff suppressed because one or more lines are too long
99
ports/arm11/iar/example_build/settings/sample_threadx.dnx
Normal file
99
ports/arm11/iar/example_build/settings/sample_threadx.dnx
Normal 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>
|
||||||
40
ports/arm11/iar/example_build/settings/tx.Debug.cspy.bat
Normal file
40
ports/arm11/iar/example_build/settings/tx.Debug.cspy.bat
Normal 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
|
||||||
31
ports/arm11/iar/example_build/settings/tx.Debug.cspy.ps1
Normal file
31
ports/arm11/iar/example_build/settings/tx.Debug.cspy.ps1
Normal 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"
|
||||||
|
}
|
||||||
13
ports/arm11/iar/example_build/settings/tx.Debug.driver.xcl
Normal file
13
ports/arm11/iar/example_build/settings/tx.Debug.driver.xcl
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
"--endian=little"
|
||||||
|
|
||||||
|
"--cpu=ARM1136J-S"
|
||||||
|
|
||||||
|
"--fpu=None"
|
||||||
|
|
||||||
|
"--semihosting"
|
||||||
|
|
||||||
|
"--multicore_nr_of_cores=1"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
11
ports/arm11/iar/example_build/settings/tx.Debug.general.xcl
Normal file
11
ports/arm11/iar/example_build/settings/tx.Debug.general.xcl
Normal 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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
13
ports/arm11/iar/example_build/settings/tx.crun
Normal file
13
ports/arm11/iar/example_build/settings/tx.crun
Normal 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>
|
||||||
4
ports/arm11/iar/example_build/settings/tx.dbgdt
Normal file
4
ports/arm11/iar/example_build/settings/tx.dbgdt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Project>
|
||||||
|
<WindowStorage />
|
||||||
|
</Project>
|
||||||
58
ports/arm11/iar/example_build/settings/tx.dnx
Normal file
58
ports/arm11/iar/example_build/settings/tx.dnx
Normal 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>
|
||||||
2974
ports/arm11/iar/example_build/tx.ewd
Normal file
2974
ports/arm11/iar/example_build/tx.ewd
Normal file
File diff suppressed because it is too large
Load Diff
2766
ports/arm11/iar/example_build/tx.ewp
Normal file
2766
ports/arm11/iar/example_build/tx.ewp
Normal file
File diff suppressed because it is too large
Load Diff
3427
ports/arm11/iar/example_build/tx.ewt
Normal file
3427
ports/arm11/iar/example_build/tx.ewt
Normal file
File diff suppressed because it is too large
Load Diff
339
ports/arm11/iar/example_build/tx_initialize_low_level.s
Normal file
339
ports/arm11/iar/example_build/tx_initialize_low_level.s
Normal 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
|
||||||
|
|
||||||
401
ports/arm11/iar/inc/tx_port.h
Normal file
401
ports/arm11/iar/inc/tx_port.h
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
527
ports/arm11/iar/readme_threadx.txt
Normal file
527
ports/arm11/iar/readme_threadx.txt
Normal 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
|
||||||
|
|
||||||
816
ports/arm11/iar/src/tx_iar.c
Normal file
816
ports/arm11/iar/src/tx_iar.c
Normal 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. */
|
||||||
258
ports/arm11/iar/src/tx_thread_context_restore.s
Normal file
258
ports/arm11/iar/src/tx_thread_context_restore.s
Normal 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
|
||||||
|
|
||||||
222
ports/arm11/iar/src/tx_thread_context_save.s
Normal file
222
ports/arm11/iar/src/tx_thread_context_save.s
Normal 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
|
||||||
|
|
||||||
269
ports/arm11/iar/src/tx_thread_fiq_context_restore.s
Normal file
269
ports/arm11/iar/src/tx_thread_fiq_context_restore.s
Normal 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
|
||||||
|
|
||||||
215
ports/arm11/iar/src/tx_thread_fiq_context_save.s
Normal file
215
ports/arm11/iar/src/tx_thread_fiq_context_save.s
Normal 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
|
||||||
|
|
||||||
121
ports/arm11/iar/src/tx_thread_fiq_nesting_end.s
Normal file
121
ports/arm11/iar/src/tx_thread_fiq_nesting_end.s
Normal 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
|
||||||
|
|
||||||
114
ports/arm11/iar/src/tx_thread_fiq_nesting_start.s
Normal file
114
ports/arm11/iar/src/tx_thread_fiq_nesting_start.s
Normal 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
|
||||||
|
|
||||||
115
ports/arm11/iar/src/tx_thread_interrupt_control.s
Normal file
115
ports/arm11/iar/src/tx_thread_interrupt_control.s
Normal 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
|
||||||
113
ports/arm11/iar/src/tx_thread_interrupt_disable.s
Normal file
113
ports/arm11/iar/src/tx_thread_interrupt_disable.s
Normal 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
|
||||||
99
ports/arm11/iar/src/tx_thread_interrupt_restore.s
Normal file
99
ports/arm11/iar/src/tx_thread_interrupt_restore.s
Normal 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
|
||||||
122
ports/arm11/iar/src/tx_thread_irq_nesting_end.s
Normal file
122
ports/arm11/iar/src/tx_thread_irq_nesting_end.s
Normal 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
|
||||||
|
|
||||||
114
ports/arm11/iar/src/tx_thread_irq_nesting_start.s
Normal file
114
ports/arm11/iar/src/tx_thread_irq_nesting_start.s
Normal 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
|
||||||
|
|
||||||
183
ports/arm11/iar/src/tx_thread_schedule.s
Normal file
183
ports/arm11/iar/src/tx_thread_schedule.s
Normal 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
|
||||||
|
|
||||||
170
ports/arm11/iar/src/tx_thread_stack_build.s
Normal file
170
ports/arm11/iar/src/tx_thread_stack_build.s
Normal 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
|
||||||
|
|
||||||
161
ports/arm11/iar/src/tx_thread_system_return.s
Normal file
161
ports/arm11/iar/src/tx_thread_system_return.s
Normal 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
|
||||||
|
|
||||||
207
ports/arm11/iar/src/tx_thread_vectored_context_save.s
Normal file
207
ports/arm11/iar/src/tx_thread_vectored_context_save.s
Normal 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
|
||||||
|
|
||||||
272
ports/arm11/iar/src/tx_timer_interrupt.s
Normal file
272
ports/arm11/iar/src/tx_timer_interrupt.s
Normal 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
|
||||||
|
|
||||||
Reference in New Issue
Block a user