Release 6.1.7

This commit is contained in:
Bo Chen
2021-06-02 06:45:05 +00:00
parent d759e6bb9e
commit f5056f4923
1269 changed files with 57325 additions and 55178 deletions

View File

@@ -0,0 +1,7 @@
call build_threadx.bat
call build_threadx_module_library.bat
call build_threadx_module_sample.bat
call ..\..\..\..\common_modules\utilities\module_to_c_array.exe sample_threadx_module.axf module_code.c
powershell -Command "(gc module_code.c) -replace 'unsigned', '__align(4096) unsigned' | Out-File module_code.c"
call build_threadx_module_manager_sample.bat

View File

@@ -0,0 +1,290 @@
del tx.a
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork tx_initialize_low_level.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_stack_build.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_schedule.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_system_return.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_context_save.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_context_restore.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_control.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_timer_interrupt.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_context_restore.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_context_save.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_nesting_end.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_nesting_start.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_disable.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_restore.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_irq_nesting_end.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_irq_nesting_start.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_vectored_context_save.s
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_allocate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_cleanup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_release.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_allocate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_cleanup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_search.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_release.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_cleanup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_set.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_set_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_initialize_high_level.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_initialize_kernel_enter.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_initialize_kernel_setup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_cleanup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_priority_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_put.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_cleanup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_flush.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_front_send.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_receive.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_send.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_send_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_ceiling_put.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_cleanup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_put.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_put_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_entry_exit_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_identify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_preemption_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_priority_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_relinquish.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_reset.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_resume.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_shell_entry.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_sleep.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_stack_analyze.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_stack_error_handler.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_stack_error_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_suspend.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_system_preempt_check.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_system_resume.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_system_suspend.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_terminate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_time_slice.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_time_slice_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_timeout.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_wait_abort.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_time_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_time_set.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_activate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_deactivate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_expiration_process.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_performance_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_performance_system_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_system_activate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_system_deactivate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_thread_entry.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_enable.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_disable.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_interrupt_control.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_isr_enter_insert.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_isr_exit_insert.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_object_register.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_object_unregister.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_user_event_insert.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_buffer_full_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_event_filter.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_event_unfilter.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_allocate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_release.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_allocate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_release.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_set.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_set_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_put.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_flush.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_front_send.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_receive.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_send.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_send_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_ceiling_put.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_prioritize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_put.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_put_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_entry_exit_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_preemption_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_priority_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_relinquish.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_reset.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_resume.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_suspend.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_terminate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_time_slice_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_wait_abort.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_activate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_change.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_deactivate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_delete.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_info_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_alignment_adjust.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_application_request.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_callback_request.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_event_flags_notify_trampoline.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_external_memory_enable.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_file_load.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_in_place_load.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_internal_load.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_mm_initialize.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_kernel_dispatch.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_maximum_module_priority_set.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_memory_fault_handler.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_memory_fault_notify.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_memory_load.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_allocate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_deallocate.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_pointer_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_pointer_get_extended.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_pool_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_properties_get.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_queue_notify_trampoline.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_semaphore_notify_trampoline.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_mm_register_setup.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_start.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_stop.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_thread_create.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_thread_notify_trampoline.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_thread_reset.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_timer_notify_trampoline.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_unload.c
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_util.c
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/txm_module_manager_thread_stack_build.s
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/txm_module_manager_user_mode_entry.s
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_initialize_low_level.o tx_thread_fiq_context_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_end.o tx_thread_fiq_nesting_start.o tx_thread_interrupt_disable.o
armar -r tx.a tx_thread_interrupt_restore.o tx_thread_irq_nesting_end.o tx_thread_irq_nesting_start.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
armar -r tx.a txm_module_manager_alignment_adjust.o txm_module_manager_application_request.o txm_module_manager_callback_request.o
armar -r tx.a txm_module_manager_event_flags_notify_trampoline.o txm_module_manager_external_memory_enable.o txm_module_manager_file_load.o
armar -r tx.a txm_module_manager_in_place_load.o txm_module_manager_initialize.o txm_module_manager_mm_initialize.o
armar -r tx.a txm_module_manager_kernel_dispatch.o txm_module_manager_maximum_module_priority_set.o txm_module_manager_memory_fault_handler.o
armar -r tx.a txm_module_manager_memory_fault_notify.o txm_module_manager_memory_load.o txm_module_manager_object_pointer_get.o
armar -r tx.a txm_module_manager_object_pool_create.o txm_module_manager_queue_notify_trampoline.o txm_module_manager_semaphore_notify_trampoline.o
armar -r tx.a txm_module_manager_mm_register_setup.o txm_module_manager_start.o txm_module_manager_stop.o
armar -r tx.a txm_module_manager_thread_create.o txm_module_manager_thread_notify_trampoline.o txm_module_manager_thread_reset.o
armar -r tx.a txm_module_manager_timer_notify_trampoline.o txm_module_manager_unload.o txm_module_manager_thread_stack_build.o
armar -r tx.a txm_module_manager_user_mode_entry.o
armar -r tx.a txm_module_manager_internal_load.o
armar -r tx.a txm_module_manager_object_allocate.o
armar -r tx.a txm_module_manager_object_deallocate.o
armar -r tx.a txm_module_manager_object_pointer_get_extended.o
armar -r tx.a txm_module_manager_properties_get.o
armar -r tx.a txm_module_manager_util.o

View File

@@ -0,0 +1,120 @@
del txm.a
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_allocate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_prioritize.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_release.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_allocate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_prioritize.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_release.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_set.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_set_notify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_application_request.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_callback_request_thread_entry.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_object_allocate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_object_deallocate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_object_pointer_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_lib/src/txm_module_thread_shell_entry.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_thread_system_suspend.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_prioritize.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_put.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_flush.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_front_send.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_prioritize.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_receive.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_send.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_send_notify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_ceiling_put.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_prioritize.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_put.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_put_notify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_entry_exit_notify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_identify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_interrupt_control.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_preemption_change.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_priority_change.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_relinquish.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_reset.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_resume.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_sleep.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_stack_error_notify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_suspend.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_terminate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_time_slice_change.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_wait_abort.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_time_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_time_set.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_activate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_change.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_create.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_deactivate.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_delete.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_performance_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_performance_system_info_get.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_buffer_full_notify.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_disable.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_enable.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_event_filter.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_event_unfilter.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_isr_enter_insert.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_isr_exit_insert.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_user_event_insert.c
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork/ropi/rwpi ../module_lib/src/txm_module_initialize.s
armar --create txm.a txm_block_allocate.o txm_block_pool_create.o txm_block_pool_delete.o txm_block_pool_info_get.o txm_block_pool_performance_info_get.o txm_block_pool_performance_system_info_get.o
armar -r txm.a txm_block_pool_prioritize.o txm_block_release.o
armar -r txm.a txm_byte_allocate.o txm_byte_pool_create.o txm_byte_pool_delete.o txm_byte_pool_info_get.o txm_byte_pool_performance_info_get.o txm_byte_pool_performance_system_info_get.o
armar -r txm.a txm_byte_pool_prioritize.o txm_byte_release.o
armar -r txm.a txm_event_flags_create.o txm_event_flags_delete.o txm_event_flags_get.o txm_event_flags_info_get.o txm_event_flags_performance_info_get.o txm_event_flags_performance_system_info_get.o
armar -r txm.a txm_event_flags_set.o txm_event_flags_set_notify.o
armar -r txm.a txm_module_application_request.o txm_module_callback_request_thread_entry.o txm_module_initialize.o txm_module_object_allocate.o txm_module_object_deallocate.o txm_module_object_pointer_get.o txm_module_thread_shell_entry.o txm_module_thread_system_suspend.o
armar -r txm.a txm_mutex_create.o txm_mutex_delete.o txm_mutex_get.o txm_mutex_info_get.o txm_mutex_performance_info_get.o txm_mutex_performance_system_info_get.o txm_mutex_prioritize.o txm_mutex_put.o
armar -r txm.a txm_queue_create.o txm_queue_delete.o txm_queue_flush.o txm_queue_front_send.o txm_queue_info_get.o txm_queue_performance_info_get.o txm_queue_performance_system_info_get.o
armar -r txm.a txm_queue_prioritize.o txm_queue_receive.o txm_queue_send.o txm_queue_send_notify.o
armar -r txm.a txm_semaphore_ceiling_put.o txm_semaphore_create.o txm_semaphore_delete.o txm_semaphore_get.o txm_semaphore_info_get.o txm_semaphore_performance_info_get.o txm_semaphore_performance_system_info_get.o
armar -r txm.a txm_semaphore_prioritize.o txm_semaphore_put.o txm_semaphore_put_notify.o
armar -r txm.a txm_thread_create.o txm_thread_delete.o txm_thread_entry_exit_notify.o txm_thread_identify.o txm_thread_info_get.o txm_thread_interrupt_control.o txm_thread_performance_info_get.o
armar -r txm.a txm_thread_performance_system_info_get.o txm_thread_preemption_change.o txm_thread_priority_change.o txm_thread_relinquish.o txm_thread_reset.o txm_thread_resume.o
armar -r txm.a txm_thread_sleep.o txm_thread_stack_error_notify.o txm_thread_suspend.o txm_thread_terminate.o txm_thread_time_slice_change.o txm_thread_wait_abort.o
armar -r txm.a txm_time_get.o txm_time_set.o
armar -r txm.a txm_timer_activate.o txm_timer_change.o txm_timer_create.o txm_timer_deactivate.o txm_timer_delete.o txm_timer_info_get.o txm_timer_performance_info_get.o txm_timer_performance_system_info_get.o
armar -r txm.a txm_trace_buffer_full_notify.o txm_trace_disable.o txm_trace_enable.o txm_trace_event_filter.o txm_trace_event_unfilter.o txm_trace_isr_enter_insert.o txm_trace_isr_exit_insert.o txm_trace_user_event_insert.o

View File

@@ -0,0 +1,5 @@
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=interwork tx_initialize_low_level.s
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc sample_threadx_module_manager.c
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c module_code.c
armlink -d -o sample_threadx_module_manager.axf --elf --ro 0x80000000 --first tx_initialize_low_level.o(VECTORS) --remove --map --symbols --list sample_threadx_module_manager.map tx_initialize_low_level.o sample_threadx_module_manager.o module_code.o tx.a

View File

@@ -0,0 +1,4 @@
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork/ropi/rwpi txm_module_preamble.s
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi --lower_ropi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc sample_threadx_module.c
armlink -d -o sample_threadx_module.axf --elf --ro 0 --first txm_module_preamble.o(Init) --entry=_txm_module_thread_shell_entry --ropi --rwpi --remove --map --symbols --list sample_threadx_module.map txm_module_preamble.o sample_threadx_module.o txm.a

Binary file not shown.

View File

@@ -0,0 +1,427 @@
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
event flags group, byte pool, and block pool. */
/* Specify that this is a module! */
#define TXM_MODULE
/* Include the ThreadX module definitions. */
#include "txm_module.h"
/* Define constants. */
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the pool space in the bss section of the module. ULONG is used to
get the word alignment. */
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / 4];
/* 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;
ULONG semaphore_0_puts;
ULONG event_0_sets;
ULONG queue_0_sends;
/* 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);
void semaphore_0_notify(TX_SEMAPHORE *semaphore_ptr)
{
if (semaphore_ptr == semaphore_0)
semaphore_0_puts++;
}
void event_0_notify(TX_EVENT_FLAGS_GROUP *event_flag_group_ptr)
{
if (event_flag_group_ptr == event_flags_0)
event_0_sets++;
}
void queue_0_notify(TX_QUEUE *queue_ptr)
{
if (queue_ptr == queue_0)
queue_0_sends++;
}
/* Define the module start function. */
void demo_module_start(ULONG id)
{
CHAR *pointer;
/* Allocate all the objects. In MMU mode, modules cannot allocate control blocks within
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
the control block(s). */
txm_module_object_allocate((void *) &thread_0, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_1, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_2, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_3, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_4, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_5, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_6, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &thread_7, sizeof(TX_THREAD));
txm_module_object_allocate((void *) &queue_0, sizeof(TX_QUEUE));
txm_module_object_allocate((void *) &semaphore_0, sizeof(TX_SEMAPHORE));
txm_module_object_allocate((void *) &mutex_0, sizeof(TX_MUTEX));
txm_module_object_allocate((void *) &event_flags_0, sizeof(TX_EVENT_FLAGS_GROUP));
txm_module_object_allocate((void *) &byte_pool_0, sizeof(TX_BYTE_POOL));
txm_module_object_allocate((void *) &block_pool_0, sizeof(TX_BLOCK_POOL));
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
tx_queue_send_notify(queue_0, queue_0_notify);
/* Create the semaphore used by threads 3 and 4. */
tx_semaphore_create(semaphore_0, "module semaphore 0", 1);
tx_semaphore_put_notify(semaphore_0, semaphore_0_notify);
/* Create the event flags group used by threads 1 and 5. */
tx_event_flags_create(event_flags_0, "module event flags 0");
tx_event_flags_set_notify(event_flags_0, event_0_notify);
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
tx_mutex_create(mutex_0, "module 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, "module 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;
/* Test external/shared memory. */
*(ULONG *) 0x90000000 = 0xdeadbeef;
*(ULONG *) 0x90000FFC = 0xfeed0add;
*(ULONG *) 0x90001000 = 0xfedcba01;
/* This thread simply sits in while-forever-sleep loop. */
while(1)
{
/* Increment the thread counter. */
thread_0_counter++;
/* Sleep for 10 ticks. */
tx_thread_sleep(10);
/* Set event flag 0 to wakeup thread 5. */
status = tx_event_flags_set(event_flags_0, 0x1, TX_OR);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}
void thread_1_entry(ULONG thread_input)
{
UINT status;
/* This thread simply sends messages to a queue shared by thread 2. */
while(1)
{
/* Increment the thread counter. */
thread_1_counter++;
/* Send message to queue 0. */
status = tx_queue_send(queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
/* Check completion status. */
if (status != TX_SUCCESS)
break;
/* Increment the message sent. */
thread_1_messages_sent++;
}
}
void thread_2_entry(ULONG thread_input)
{
ULONG received_message;
UINT status;
/* This thread retrieves messages placed on the queue by thread 1. */
while(1)
{
/* Increment the thread counter. */
thread_2_counter++;
/* Retrieve a message from the queue. */
status = tx_queue_receive(queue_0, &received_message, TX_WAIT_FOREVER);
/* Check completion status and make sure the message is what we
expected. */
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
break;
/* Otherwise, all is okay. Increment the received message count. */
thread_2_messages_received++;
}
}
void thread_3_and_4_entry(ULONG thread_input)
{
UINT status;
/* This function is executed from thread 3 and thread 4. As the loop
below shows, these function compete for ownership of semaphore_0. */
while(1)
{
/* Increment the thread counter. */
if (thread_input == 3)
thread_3_counter++;
else
thread_4_counter++;
/* Get the semaphore with suspension. */
status = tx_semaphore_get(semaphore_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Sleep for 2 ticks to hold the semaphore. */
tx_thread_sleep(2);
/* Release the semaphore. */
status = tx_semaphore_put(semaphore_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}
void thread_5_entry(ULONG thread_input)
{
UINT status;
ULONG actual_flags;
/* This thread simply waits for an event in a forever loop. */
while(1)
{
/* Increment the thread counter. */
thread_5_counter++;
/* Wait for event flag 0. */
status = tx_event_flags_get(event_flags_0, 0x1, TX_OR_CLEAR,
&actual_flags, TX_WAIT_FOREVER);
/* Check status. */
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
break;
}
}
void thread_6_and_7_entry(ULONG thread_input)
{
UINT status;
/* This function is executed from thread 6 and thread 7. As the loop
below shows, these function compete for ownership of mutex_0. */
while(1)
{
/* Increment the thread counter. */
if (thread_input == 6)
thread_6_counter++;
else
thread_7_counter++;
/* Get the mutex with suspension. */
status = tx_mutex_get(mutex_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Get the mutex again with suspension. This shows
that an owning thread may retrieve the mutex it
owns multiple times. */
status = tx_mutex_get(mutex_0, TX_WAIT_FOREVER);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Sleep for 2 ticks to hold the mutex. */
tx_thread_sleep(2);
/* Release the mutex. */
status = tx_mutex_put(mutex_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
/* Release the mutex again. This will actually
release ownership since it was obtained twice. */
status = tx_mutex_put(mutex_0);
/* Check status. */
if (status != TX_SUCCESS)
break;
}
}

View File

@@ -0,0 +1,132 @@
/* Small demonstration of the ThreadX module manager. This demonstration assumes the program
manager is loaded at 0 and that RAM addresses 0x200000 through 0x400000 are available for
use. */
#include "tx_api.h"
#include "txm_module.h"
#define DEMO_STACK_SIZE 1024
/* Define the ThreadX object control blocks... */
TX_THREAD module_manager;
/* Define thread prototypes. */
void module_manager_entry(ULONG thread_input);
/* Define the module object pool area. */
UCHAR object_memory[16384];
/* Define the module data pool area. */
#define MODULE_DATA_SIZE 65536
unsigned char module_data_area[MODULE_DATA_SIZE];
/* Define a module instance. */
TXM_MODULE_INSTANCE my_module1;
TXM_MODULE_INSTANCE my_module2;
/* Module code is in an array created by module_to_c_array utility. */
extern unsigned char module_code[];
/* Define the count of memory faults. */
ULONG memory_faults;
/* Define fault handler. */
VOID module_fault_handler(TX_THREAD *thread, TXM_MODULE_INSTANCE *module)
{
/* Just increment the fault counter. */
memory_faults++;
}
/* 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)
{
/* Create the module manager thread. */
tx_thread_create(&module_manager, "Module Manager Thread", module_manager_entry, 0,
first_unused_memory, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
}
/* Define the test threads. */
void module_manager_entry(ULONG thread_input)
{
/* Initialize the module manager. */
txm_module_manager_initialize((VOID *) module_data_area, MODULE_DATA_SIZE);
/* Create a pool for module objects. */
txm_module_manager_object_pool_create(object_memory, sizeof(object_memory));
/* Register a fault handler. */
txm_module_manager_memory_fault_notify(module_fault_handler);
/* Initialize MMU. */
txm_module_manager_mm_initialize();
/* Load the module that is already there, in this example it is placed there by the multiple image download. */
txm_module_manager_in_place_load(&my_module1, "my module1", (VOID *) module_code);
/* Load a second instance of the module. */
//txm_module_manager_in_place_load(&my_module2, "my module2", (VOID *) module_code);
/* Enable shared memory regions for one module. */
//txm_module_manager_external_memory_enable(&my_module2, (void*)0x90000000, 0x010000, 0x3F);
/* Start the modules. */
txm_module_manager_start(&my_module1);
//txm_module_manager_start(&my_module2);
/* Sleep for a while and let the modules run.... */
tx_thread_sleep(50);
/* Thread 0 in module1 should be terminated due to violating the MMU. */
/* Stop the modules. */
txm_module_manager_stop(&my_module1);
txm_module_manager_stop(&my_module2);
/* Unload the modules. */
txm_module_manager_unload(&my_module1);
txm_module_manager_unload(&my_module2);
/* Reload the modules. */
txm_module_manager_in_place_load(&my_module2, "my module2", (VOID *) module_code);
txm_module_manager_in_place_load(&my_module1, "my module1", (VOID *) module_code);
/* Give both modules shared memory. */
txm_module_manager_external_memory_enable(&my_module2, (void*)0x90000000, 0x010000, 0x3F);
txm_module_manager_external_memory_enable(&my_module1, (void*)0x90000000, 0x010000, 0x3F);
/* Start the module again. */
txm_module_manager_start(&my_module2);
txm_module_manager_start(&my_module1);
/* Now just spin... */
while(1)
{
tx_thread_sleep(100);
/* Thread 0 and 5 in module1 should not exist because they violate the maximum priority. */
}
}

View File

@@ -0,0 +1,41 @@
;**************************************************
; Copyright (c) 2011 ARM Ltd. All rights reserved.
;**************************************************
; This scatter-file places application code, data, stack and heap at base address 0x80000000.
; Using a scatter-file with ARM_LIB_STACKHEAP eliminates the need to set stack-limit or heap-base in the debugger.
SDRAM 0x80000000
{
VECTORS +0
{
* (VECTORS, +FIRST) ; Vector table and other (assembler) startup code
* (InRoot$$Sections) ; All (library) code that must be in a root region
}
RO_CODE +0
{ * (+RO-CODE) } ; Application RO code (.text)
RO_DATA +0
{ * (+RO-DATA) } ; Application RO data (.constdata)
RW_DATA +0
{ * (+RW) } ; Application RW data (.data)
ZI_DATA +0
{ * (+ZI) } ; Application ZI data (.bss)
ARM_LIB_HEAP 0x80040000 EMPTY 0x00040000 ; Application heap
{ }
ARM_LIB_STACK 0x80090000 EMPTY -0x00010000 ; Application (SVC mode) stack
{ }
IRQ_STACK 0x800A0000 EMPTY -0x00010000 ; IRQ mode stack
{ }
TTB 0x80100000 EMPTY 0x4000 ; Level-1 Translation Table for MMU
{ }
}

View File

@@ -0,0 +1,659 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR
FIQ_MODE EQU 0x11 ; FIQ mode
IRQ_MODE EQU 0x12 ; IRQ mode
SVC_MODE EQU 0x13 ; SVC mode
ABT_MODE EQU 0x17 ; ABT mode
SYS_MODE EQU 0x1F ; SYS mode
HEAP_SIZE EQU 4096 ; Heap size
FIQ_STACK_SIZE EQU 512 ; FIQ stack size
SYS_STACK_SIZE EQU 1024 ; SYS stack size
IRQ_STACK_SIZE EQU 1024 ; IRQ stack size
SVC_STACK_SIZE EQU 512 ; SVC stack size
ABT_STACK_SIZE EQU 512 ; ABT stack size
VFPEnable EQU 0x40000000 ; VFP enable value
;
;
IMPORT __tx_swi_interrupt
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 VECTORS, CODE, READONLY
PRESERVE8
;
;/* Define the default Cortex-A7 vector area. This should be located or copied to 0. */
;
EXPORT __vectors
__vectors
LDR pc,=Reset_Vector ; 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
;
;
EXPORT Reset_Vector
Reset_Vector
IF {TARGET_FPU_VFP} = {TRUE}
MRC p15, 0, r1, c1, c0, 2 ; r1 = Access Control Register
ORR r1, r1, #(0xf << 20) ; Enable full access for p10,11
MCR p15, 0, r1, c1, c0, 2 ; Access Control Register = r1
MOV r1, #0
MCR p15, 0, r1, c7, c5, 4 ; Flush prefetch buffer because of FMXR below and
; CP 10 & 11 were only just enabled
MOV r0, #VFPEnable ; Enable VFP itself
FMXR FPEXC, r0 ; FPEXC = r0
ENDIF
B __main
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_initialize_low_level Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.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. */
;
; Set vector table.
LDR r0, = __vectors
MCR p15, 0, r0, c12, c0, 0
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
MOV r3, lr ; Save LR
LDR r2, =SYS_STACK_SIZE ; Pickup stack size
CPS #SYS_MODE ; 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
MOV lr, r3 ; Restore LR
LDR r2, =SVC_STACK_SIZE ; Pickup SVC stack size
CPS #SVC_MODE ; Enter SVC mode
ADD r1, r1, r2 ; Calculate start of SVC stack
BIC r1, r1, #7 ; Ensure 8-byte alignment
MOV sp, r1 ; Setup SVC stack pointer
LDR r2, =IRQ_STACK_SIZE ; Pickup IRQ stack size
CPS #IRQ_MODE ; 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
LDR r2, =FIQ_STACK_SIZE ; Pickup FIQ stack size
CPS #FIQ_MODE ; 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, =ABT_STACK_SIZE ; Pickup ABT stack size
CPS #ABT_MODE ; Enter ABT mode
ADD r1, r1, r2 ; Calculate start of ABT stack
BIC r1, r1, #7 ; Ensure 8-byte alignment
MOV sp, r1 ; Setup ABT stack pointer
CPS #SYS_MODE ; Enter SYS mode
;
; /* Save the first available memory address. */
; _tx_initialize_unused_memory = (VOID_PTR) |Image$$ZI$$Limit| + HEAP + SYS_STACK + SVC_STACK + IRQ_STACK + FIQ_STACK + ABT_STACK;
;
ADD r0, r1, #4 ; Increment to next free word
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. */
;
GIC1_CPU_INTERFACE_BASE EQU 0x2C002000
GIC1_DIST_INTERFACE_BASE EQU 0x2C001000
PUSH {r4-r12, lr}
ldr r2, =GIC1_CPU_INTERFACE_BASE
ldr r7, =GIC1_DIST_INTERFACE_BASE
; Enable GIC
mov r3, #0x1
str r3, [r2, #0x0000]
; Enable GIC forwarding
str r3, [r7, #0x000]
; Set Binary Point Register to 0
eor r3, r3, r3
str r3, [r2, #0x0008]
; At this point GIC is enabled
; All INTS are disabled / not configured
; r0 - interrupt number
; r1 - priority
; r2 - interrupt type (edge / level trig.)
ldr r0, =34
ldr r1, =0xF0
ldr r2, =1
ldr r7, =GIC1_DIST_INTERFACE_BASE
; enable the interrupt in isenable register
mov r4, #0x100 ; ISEN REG offset base
mov r5, r0, LSR #5 ; Interrupt_Number DIV 5
add r4, r4, r5, LSL #2 ; final offset from GIC DIST BASE
and r5, r0, #31 ; bit number
mov r8, #1
ldr r6, [r7, r4]
orr r6, r6, r8, LSL r5
str r6, [r7, r4]
; setup priority
mov r4, #0x400
mov r5, r0, LSR #2 ; Interrupt_Number DIV 4
add r4, r4, r5, LSL #2 ; final offset from GIC DIST BASE
and r5, r0, #3 ; Int_Num MOD 4
lsl r5, #3
lsl r1, r5
ldr r6, [r7, r4]
orr r1, r6, r1
str r1, [r7, r4]
; set up processor target
mov r4, #0x800
mov r5, r0, LSR #2 ; Interrupt_Number DIV 4
add r4, r4, r5, LSL #2 ; final offset from GIC DIST BASE
and r5, r0, #3 ; Int_Num MOD 4
lsl r5, #3
mov r1, #0xff
lsl r1, r5
ldr r6, [r7, r4]
orr r1, r6, r1
str r1, [r7, r4]
; set up interrupt type
mov r4, #0xC00
mov r5, r0, LSR #4
add r4, r4, r5, LSL #2 ; offset from base
; field
and r5, r0, #15
lsl r5, #1
lsl r2, r5
ldr r6, [r7, r4]
orr r2, r6, r2
str r2, [r7, r4]
ldr r2, =GIC1_CPU_INTERFACE_BASE
; set the interrupt id prio mask
; Max Priorities = 32.
; mask = (32 - 1) << 3
mov r3, #0xF8
str r3, [r2, #0x0004]
CPSIE if
; Timer base
ldr r0, =0x1C110000
; get the timer id
ldr r1, [r0, #0xfe0]
; set count value in load register
ldr r1, =0x00000020
str r1, [r0, #00]
; enable the timer
; periodic mode
mov r1, #0xe2
str r1, [r0, #08]
POP {r4-r12, lr}
;
; /* Done, return to caller. */
;
BX lr ; Return to caller
;}
;
;
;/* 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_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. */
;
;
BL _tx_timer_interrupt ; Timer interrupt handler
; clear timer interrupt
ldr r0, =0x1C110000
eor r1, r1, r1
str r1, [r0, #0x0C]
_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
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* __tx_prefetch_handler & __tx_abort_handler Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function handles MMU exceptions and fills the */
;/* _txm_module_manager_memory_fault_info struct. */
;/* */
;/* INPUT */
;/* */
;/* None */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* _txm_module_manager_memory_fault_handler */
;/* _tx_execution_thread_exit */
;/* _tx_thread_schedule */
;/* */
;/* CALLED BY */
;/* */
;/* MMU exceptions */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
; *******************************************************************
; MMU Exception Handling
; *******************************************************************
EXTERN _tx_thread_system_state
EXTERN _txm_module_manager_memory_fault_info
EXTERN _tx_thread_current_ptr
EXTERN _txm_module_manager_memory_fault_handler
EXTERN _tx_execution_thread_exit
EXTERN _tx_thread_schedule
EXPORT __tx_prefetch_handler
EXPORT __tx_abort_handler
__tx_prefetch_handler
__tx_abort_handler
STMDB sp!, {r0-r3} ; Save some working registers
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
LDR r2, [r3, #0] ; Pickup system state
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
SUB lr, lr, #4 ; Adjust point of exception
;
; /* Now pickup and store all the fault related information. */
;
; Pickup the memory fault info struct
LDR r3, =_txm_module_manager_memory_fault_info
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
LDR r1, [r0] ; Pickup the current thread pointer
STR r1, [r3, #0] ; Save current thread pointer
STR lr, [r3, #4] ; Save point of fault
MRC p15, 0, r0, c6, c0, 0 ; Read DFAR
STR r0, [r3, #8] ; Save DFAR
MRC p15, 0, r0, c5, c0, 0 ; Read DFSR
STR r0, [r3, #12] ; Save DFSR
MRC p15, 0, r0, c6, c0, 2 ; Read IFAR
STR r0, [r3, #16] ; Save IFAR
MRC p15, 0, r0, c5, c0, 1 ; Read IFSR
STR r0, [r3, #20] ; Save IFSR
; Save registers r0-r12
POP {r0-r2}
STR r0, [r3, #28] ; Save r0
STR r1, [r3, #32] ; Save r1
STR r2, [r3, #36] ; Save r2
POP {r0}
STR r0, [r3, #40] ; Save r3
STR r4, [r3, #44] ; Save r4
STR r5, [r3, #48] ; Save r5
STR r6, [r3, #52] ; Save r6
STR r7, [r3, #56] ; Save r7
STR r8, [r3, #60] ; Save r8
STR r9, [r3, #64] ; Save r9
STR r10,[r3, #68] ; Save r10
STR r11,[r3, #72] ; Save r11
STR r12,[r3, #76] ; Save r12
CPS #SYS_MODE ; Enter SYS mode
MOV r0, lr ; Pickup lr
MOV r1, sp ; Pickup sp
CPS #ABT_MODE ; Back to ABT mode
STR r0, [r3, #80] ; Save lr
STR r1, [r3, #24] ; Save sp
MRS r0, SPSR ; Pickup SPSR
STR r0, [r3, #84] ; Save SPSR
ORR r0, r0, #SYS_MODE ; Return into SYS mode
BIC r0, r0, #THUMB_MASK ; Clear THUMB mode
MSR SPSR_c, r0 ; Save SPSR
; Call memory manager fault handler
BL _txm_module_manager_memory_fault_handler
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 r0, =_tx_thread_system_state ; Pickup address of system state
LDR r1, [r0] ; Pickup system state
SUB r1, r1, #1 ; Decrement
STR r1, [r0] ; Store new system state
MOV r1, #0 ; Build NULL value
LDR r0, =_tx_thread_current_ptr ; Pickup address of current thread pointer
STR r1, [r0] ; Clear current thread pointer
; Return from exception
LDR lr, =_tx_thread_schedule ; Load scheduler address
MOVS pc, lr ; Return to scheduler
; *******************************************************************
; End of MMU exception handling.
; *******************************************************************
;
; /* Reference build options and version ID to ensure they come in. */
;
LDR r2, =_tx_build_options ; Pickup build options variable address
LDR r0, [r2, #0] ; Pickup build options content
LDR r2, =_tx_version_id ; Pickup version ID variable address
LDR r0, [r2, #0] ; Pickup version ID content
;
;
END

View File

@@ -0,0 +1,64 @@
AREA Init, CODE, READONLY
; /* Define public symbols. */
EXPORT __txm_module_preamble
; /* Define application-specific start/stop entry points for the module. */
IMPORT demo_module_start
; /* Define common external refrences. */
IMPORT _txm_module_thread_shell_entry
IMPORT _txm_module_callback_request_thread_entry
IMPORT |Image$$ER_RO$$Length|
IMPORT |Image$$ER_RW$$Length|
__txm_module_preamble
DCD 0x4D4F4455 ; Module ID
DCD 0x6 ; Module Major Version
DCD 0x1 ; Module Minor Version
DCD 32 ; Module Preamble Size in 32-bit words
DCD 0x12345678 ; Module ID (application defined)
DCD 0x01000001 ; Module Properties where:
; Bits 31-24: Compiler ID
; 0 -> IAR
; 1 -> RVDS
; 2 -> GNU
; Bits 23-1: Reserved
; Bit 0: 0 -> Privileged mode execution (no MMU protection)
; 1 -> User mode execution (MMU protection)
DCD _txm_module_thread_shell_entry - . + . ; Module Shell Entry Point
DCD demo_module_start - . + . ; Module Start Thread Entry Point
DCD 0 ; Module Stop Thread Entry Point
DCD 1 ; Module Start/Stop Thread Priority
DCD 2046 ; Module Start/Stop Thread Stack Size
DCD _txm_module_callback_request_thread_entry - . + . ; Module Callback Thread Entry
DCD 1 ; Module Callback Thread Priority
DCD 2046 ; Module Callback Thread Stack Size
DCD |Image$$ER_RO$$Length| + |Image$$ER_RW$$Length| ; Module Code Size
DCD 0x4000 ; Module Data Size - default to 16K (need to make sure this is large enough for module's data needs!)
DCD 0 ; Reserved 0
DCD 0 ; Reserved 1
DCD 0 ; Reserved 2
DCD 0 ; Reserved 3
DCD 0 ; Reserved 4
DCD 0 ; Reserved 5
DCD 0 ; Reserved 6
DCD 0 ; Reserved 7
DCD 0 ; Reserved 8
DCD 0 ; Reserved 9
DCD 0 ; Reserved 10
DCD 0 ; Reserved 11
DCD 0 ; Reserved 12
DCD 0 ; Reserved 13
DCD 0 ; Reserved 14
DCD 0 ; Reserved 15
END

View File

@@ -0,0 +1,355 @@
/**************************************************************************/
/* */
/* 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 Cortex-A7/AC5 */
/* 6.1.6 */
/* */
/* 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 */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */
/* macro definition, */
/* resulting in version 6.1.6 */
/* */
/**************************************************************************/
#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 ULONG tx_thread_vfp_enable; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
#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 VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
/* 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 UINT 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 UINT interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
#endif
/* Define VFP extension for the Cortex-A5. Each is assumed to be called in the context of the executing
thread. */
void tx_thread_vfp_enable(void);
void tx_thread_vfp_disable(void);
/* 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 Cortex-A7/AC5 Version 6.1.6 *";
#else
extern CHAR _tx_version_id[];
#endif
#endif

View File

@@ -0,0 +1,413 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Interface (API) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the basic module constants, interface structures, */
/* and function prototypes. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
#ifndef TXM_MODULE_PORT_H
#define TXM_MODULE_PORT_H
/* It is assumed that the base ThreadX tx_port.h file has been modified to add the
following extensions to the ThreadX thread control block (this code should replace
the corresponding macro define in tx_port.h):
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; \
VOID *tx_thread_module_instance_ptr; \
VOID *tx_thread_module_entry_info_ptr; \
ULONG tx_thread_module_current_user_mode; \
ULONG tx_thread_module_user_mode; \
VOID *tx_thread_module_kernel_stack_start; \
VOID *tx_thread_module_kernel_stack_end; \
ULONG tx_thread_module_kernel_stack_size; \
VOID *tx_thread_module_stack_ptr; \
VOID *tx_thread_module_stack_start; \
VOID *tx_thread_module_stack_end; \
ULONG tx_thread_module_stack_size; \
VOID *tx_thread_module_reserved;
The following extensions must also be defined in tx_port.h:
#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
VOID (*tx_timer_module_expiration_function)(ULONG id);
*/
/* Define the kernel stack size for a module thread. */
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
#define TXM_MODULE_KERNEL_STACK_SIZE 512
#endif
/* Defined, this option enables the MMU hardware and requires memory protected
module objects to be allocated from the module manager object pool.
If this is undefined, module objects can be created in the module's data area
or in the module manager object pool. If this is not defined (MMU hardware
is disabled), a module requiring memory protection will not run (the load
functions will return a TXM_MODULE_INVALID_PROPERTIES error).
Default setting for this value is defined. */
#define TXM_MODULE_MEMORY_PROTECTION_ENABLED
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
#define TXM_MODULE_RVDS_COMPILER 0x01000000
#define TXM_MODULE_GNU_COMPILER 0x02000000
#define TXM_MODULE_COMPILER_MASK 0xFF000000
#define TXM_MODULE_OPTIONS_MASK 0x000000FF
/* Define the properties for this particular module port. */
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
#define TXM_MODULE_MEMORY_PROTECTION 0x00000001
#else
#define TXM_MODULE_MEMORY_PROTECTION 0x00000000
#endif
#define TXM_MODULE_USER_MODE 0x00000001
/* Define the supported options for this module. */
#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_MEMORY_PROTECTION)
#define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0
/* Define offset adjustments according to the compiler used to build the module. */
#define TXM_MODULE_IAR_SHELL_ADJUST 24
#define TXM_MODULE_IAR_START_ADJUST 28
#define TXM_MODULE_IAR_STOP_ADJUST 32
#define TXM_MODULE_IAR_CALLBACK_ADJUST 44
#define TXM_MODULE_RVDS_SHELL_ADJUST 0
#define TXM_MODULE_RVDS_START_ADJUST 0
#define TXM_MODULE_RVDS_STOP_ADJUST 0
#define TXM_MODULE_RVDS_CALLBACK_ADJUST 0
#define TXM_MODULE_GNU_SHELL_ADJUST 24
#define TXM_MODULE_GNU_START_ADJUST 28
#define TXM_MODULE_GNU_STOP_ADJUST 32
#define TXM_MODULE_GNU_CALLBACK_ADJUST 44
/* Define other module port-specific constants. */
/* Define INLINE_DECLARE to whitespace for ARM compiler. */
#define INLINE_DECLARE
#define TXM_MAXIMUM_MODULES 16
#define TXM_MODULE_LEVEL1_PAGE_TABLE_SIZE 32
#define TXM_ASID_TABLE_LENGTH 256
#define TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET (TXM_MAXIMUM_MODULES * 0)
#define TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET (TXM_MAXIMUM_MODULES * 1)
#define TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET (TXM_MAXIMUM_MODULES * 2)
#define TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET (TXM_MAXIMUM_MODULES * 3)
#define TXM_MASTER_PAGE_TABLE_INDEX 0
/* 1 entry per 1MB, so this covers 4G address space */
#define TXM_MASTER_PAGE_TABLE_ENTRIES 4096
/* Smallest MMU page size is 4kB. */
#define TXM_MODULE_MEMORY_ALIGNMENT 4096
#define TXM_MMU_LEVEL1_PAGE_SHIFT 20
#define TXM_MMU_LEVEL2_PAGE_SHIFT 12
#define TXM_LEVEL_2_PAGE_TABLE_ENTRIES 256
/* Level 1 section base address mask. */
#define TXM_MMU_LEVEL1_MASK 0xFFF00000
/* Level 2 section base address mask. */
#define TXM_MMU_LEVEL2_MASK 0xFFFFF000
/* Non-global, outer & inner write-back, write-allocate, user read, no write. */
#define TXM_MMU_LEVEL1_CODE_ATTRIBUTES 0x000219EE
/* Non-global, outer & inner write-back, write-allocate, user read, write, no-execute. */
#define TXM_MMU_LEVEL1_DATA_ATTRIBUTES 0x00021DFE
/* Level 1 "level 2 descriptor base address" mask. */
#define TXM_MMU_LEVEL1_SECOND_MASK 0xFFFFFC00
/* Level 1 "level 2 descriptor" attributes. */
#define TXM_MMU_LEVEL1_SECOND_ATTRIBUTES 0x0000001E1
/* Kernel level 2 attributes: global, outer & inner write-back, write-allocate, user read/write */
#define TXM_MMU_KERNEL_LEVEL2_CODE_ATTRIBUTES 0x0000006E
#define TXM_MMU_KERNEL_LEVEL2_DATA_ATTRIBUTES 0x0000005E
/* Module level 2 attributes: non-global, outer & inner write-back, write-allocate, user read, no write. */
#define TXM_MMU_LEVEL2_CODE_ATTRIBUTES 0x0000086E
#define TXM_MMU_LEVEL2_DATA_ATTRIBUTES 0x0000087F
/* Settings the user can use to set up shared memory attributes. */
#define TXM_MMU_ATTRIBUTE_XN 0x00000001
#define TXM_MMU_ATTRIBUTE_B 0x00000002
#define TXM_MMU_ATTRIBUTE_C 0x00000004
#define TXM_MMU_ATTRIBUTE_AP 0x00000018
#define TXM_MMU_ATTRIBUTE_TEX 0x000000E0
/* Masks for each attribute. */
#define TXM_MMU_ATTRIBUTE_XN_MASK 0x00000001
#define TXM_MMU_ATTRIBUTE_B_MASK 0x00000001
#define TXM_MMU_ATTRIBUTE_C_MASK 0x00000001
#define TXM_MMU_ATTRIBUTE_AP_MASK 0x00000003
#define TXM_MMU_ATTRIBUTE_TEX_MASK 0x00000007
/* Shift amounts for bitfields above to correct register locations. */
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_XN_SHIFT 4
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_B_SHIFT 1
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_C_SHIFT 1
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_AP_SHIFT 7
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_TEX_SHIFT 7
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_BASE 0x000201E2
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_XN_SHIFT 0
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_B_SHIFT 1
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_C_SHIFT 1
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_AP_SHIFT 1
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_TEX_SHIFT 1
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE 0x00000802
/* Shift amounts from bit 0 position. */
#define TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT 4
#define TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT 2
#define TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT 3
#define TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT 10
#define TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT 12
#define TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT 0
#define TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT 2
#define TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT 3
#define TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT 4
#define TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT 6
/* Masks for L1 page attributes. */
#define TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK (TXM_MMU_ATTRIBUTE_XN_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT)
#define TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK (TXM_MMU_ATTRIBUTE_B_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT)
#define TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK (TXM_MMU_ATTRIBUTE_C_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT)
#define TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK (TXM_MMU_ATTRIBUTE_AP_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT)
#define TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK (TXM_MMU_ATTRIBUTE_TEX_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT)
/* Masks for L2 page attributes. */
#define TXM_MMU_LEVEL2_ATTRIBUTE_XN_MASK (TXM_MMU_ATTRIBUTE_XN_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT)
#define TXM_MMU_LEVEL2_ATTRIBUTE_B_MASK (TXM_MMU_ATTRIBUTE_B_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT)
#define TXM_MMU_LEVEL2_ATTRIBUTE_C_MASK (TXM_MMU_ATTRIBUTE_C_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT)
#define TXM_MMU_LEVEL2_ATTRIBUTE_AP_MASK (TXM_MMU_ATTRIBUTE_AP_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT)
#define TXM_MMU_LEVEL2_ATTRIBUTE_TEX_MASK (TXM_MMU_ATTRIBUTE_TEX_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT)
#define TXM_ADDRESS_TRANSLATION_FAULT_BIT 1
#define TXM_ASID_RESERVED 0xFFFFFFFF
#define TXM_MODULE_ASID_ERROR 0xF6
#define TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR 0xF7
/* Number of L2 pages each module can have. */
#define TXM_MODULE_LEVEL2_EXTERNAL_PAGES 16
/* Size, in pages, of the L2 page pool. */
#define TXM_LEVEL2_EXTERNAL_POOL_PAGES (TXM_MODULE_LEVEL2_EXTERNAL_PAGES * TXM_MAXIMUM_MODULES)
/* Define the port-extensions to the module manager instance structure. */
#define TXM_MODULE_MANAGER_PORT_EXTENSION \
ULONG txm_module_instance_asid; \
ULONG *txm_external_page_table[TXM_MODULE_LEVEL2_EXTERNAL_PAGES];
/* Define the memory fault information structure that is populated when a memory fault occurs. */
typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT
{
TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr;
VOID *txm_module_manager_memory_fault_info_code_location;
ULONG txm_module_manager_memory_fault_info_dfar;
ULONG txm_module_manager_memory_fault_info_dfsr;
ULONG txm_module_manager_memory_fault_info_ifar;
ULONG txm_module_manager_memory_fault_info_ifsr;
ULONG txm_module_manager_memory_fault_info_sp;
ULONG txm_module_manager_memory_fault_info_r0;
ULONG txm_module_manager_memory_fault_info_r1;
ULONG txm_module_manager_memory_fault_info_r2;
ULONG txm_module_manager_memory_fault_info_r3;
ULONG txm_module_manager_memory_fault_info_r4;
ULONG txm_module_manager_memory_fault_info_r5;
ULONG txm_module_manager_memory_fault_info_r6;
ULONG txm_module_manager_memory_fault_info_r7;
ULONG txm_module_manager_memory_fault_info_r8;
ULONG txm_module_manager_memory_fault_info_r9;
ULONG txm_module_manager_memory_fault_info_r10;
ULONG txm_module_manager_memory_fault_info_r11;
ULONG txm_module_manager_memory_fault_info_r12;
ULONG txm_module_manager_memory_fault_info_lr;
ULONG txm_module_manager_memory_fault_info_cpsr;
} TXM_MODULE_MANAGER_MEMORY_FAULT_INFO;
#define TXM_MODULE_MANAGER_FAULT_INFO \
TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info;
/* Define the macro to check the stack available in dispatch. */
#define TXM_MODULE_MANAGER_CHECK_STACK_AVAILABLE
/* Define the macro to check the code alignment. */
#define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \
{ \
ULONG temp; \
temp = (ULONG) module_location; \
temp = temp & (TXM_MODULE_MEMORY_ALIGNMENT - 1); \
if (temp) \
{ \
_tx_mutex_put(&_txm_module_manager_mutex); \
return(TXM_MODULE_ALIGNMENT_ERROR); \
} \
}
/* Define the macro to adjust the alignment and size for code/data areas. */
#define TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size, data_alignment) _txm_module_manager_alignment_adjust(module_preamble, &code_size, &code_alignment, &data_size, &data_alignment);
/* Define the macro to adjust the symbols in the module preamble. */
#define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \
if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_IAR_START_ADJUST; \
stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST; \
} \
else if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_RVDS_COMPILER) \
{ \
shell_function_adjust = TXM_MODULE_RVDS_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_RVDS_START_ADJUST; \
stop_function_adjust = TXM_MODULE_RVDS_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_RVDS_CALLBACK_ADJUST; \
} \
else \
{ \
shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \
start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \
stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \
callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \
}
/* Define the macro to populate the thread control block with module port-specific information. */
#define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \
thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
if (thread_ptr -> tx_thread_module_user_mode) \
{ \
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \
} \
else \
{ \
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \
}
/* Define the macro to populate the module control block with module port-specific information.
If memory protection is enabled, set up the MMU registers.
*/
#define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \
{ \
_txm_module_manager_mm_register_setup(module_instance); \
} \
else \
{ \
/* Do nothing. */ \
}
/* Define the macro to perform port-specific functions when unloading the module. */
#define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance) \
_txm_level2_page_clear(module_instance); \
_txm_module_manager_remove_asid(module_instance);
/* Define the macros to perform port-specific checks when passing pointers to the kernel. */
/* Define macro to make sure object is inside the module's data or shared memory. */
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
_txm_module_manager_inside_data_check((ULONG) obj_ptr)
/* Define some internal prototypes to this module port. */
#ifndef TX_SOURCE_CODE
#define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify
#define txm_module_manager_mm_initialize _txm_module_manager_mm_initialize
#endif
#define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \
ULONG _txm_module_manager_data_pointer_check(ULONG pointer); \
VOID _txm_module_manager_memory_fault_handler(VOID); \
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \
UINT _txm_module_manager_mm_initialize(VOID); \
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance); \
VOID _txm_level2_page_clear(TXM_MODULE_INSTANCE *module_instance); \
VOID _txm_module_manager_remove_asid(TXM_MODULE_INSTANCE *module_instance); \
UINT _txm_module_manager_inside_data_check(ULONG pointer);
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A7/MMU/AC5 Version 6.1 *";
#endif

View File

@@ -0,0 +1,91 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/** Module */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
;
IMPORT __scatterload
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _txm_module_initialize Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function initializes the module c runtime. */
;/* */
;/* INPUT */
;/* */
;/* None */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* __scatterload Initialize C runtime */
;/* */
;/* CALLED BY */
;/* */
;/* _txm_module_thread_shell_entry Start module thread */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _txm_module_initialize(VOID)
;{
EXPORT _txm_module_initialize
_txm_module_initialize
PUSH {r4-r12,lr} ; Save dregs and LR
B __scatterload ; Call ARM func to initialize variables
;/* Override __rt_exit function. */
EXPORT __rt_exit
__rt_exit
POP {r4-r12,lr} ; Restore dregs and LR
BX lr ; Return to caller
;}
END

View File

@@ -0,0 +1,175 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module */
/** */
/**************************************************************************/
/**************************************************************************/
#ifndef TXM_MODULE
#define TXM_MODULE
#endif
#ifndef TX_SOURCE_CODE
#define TX_SOURCE_CODE
#endif
/* Include necessary system files. */
#include "txm_module.h"
/* Define the global module entry pointer from the start thread of the module. */
TXM_MODULE_THREAD_ENTRY_INFO *_txm_module_entry_info;
/* Define the dispatch function pointer used in the module implementation. */
ULONG (*_txm_module_kernel_call_dispatcher)(ULONG kernel_request, ULONG param_1, ULONG param_2, ULONG param3);
/* Define the RVDS startup code that clears the uninitialized global data and sets up the
preset global variables. */
extern VOID _txm_module_initialize(VOID);
int main(VOID){return 0;}
VOID __user_setup_stackheap(VOID){return;}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calls the specified entry function of the thread. It */
/* also provides a place for the thread's entry function to return. */
/* If the thread returns, this function places the thread in a */
/* "COMPLETED" state. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to current thread */
/* thread_info Pointer to thread entry info */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* __rt_lib_init RVDS global init function */
/* thread_entry Thread's entry function */
/* tx_thread_resume Resume the module callback thread */
/* txm_module_thread_system_suspend Module thread suspension routine */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_thread_shell_entry(TX_THREAD *thread_ptr, TXM_MODULE_THREAD_ENTRY_INFO *thread_info)
{
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
VOID (*entry_exit_notify)(TX_THREAD *, UINT);
#endif
/* Determine if this is the start thread. If so, we must prepare the module for
execution. If not, simply skip the C startup code. */
if (thread_info -> txm_module_thread_entry_info_start_thread)
{
/* Initialize the RVDS C environment. */
_txm_module_initialize();
/* Save the entry info pointer, for later use. */
_txm_module_entry_info = thread_info;
/* Save the kernel function dispatch address. This is used to make all resident calls from
the module. */
_txm_module_kernel_call_dispatcher = thread_info -> txm_module_thread_entry_info_kernel_call_dispatcher;
/* Ensure that we have a valid pointer. */
while (!_txm_module_kernel_call_dispatcher)
{
/* Loop here, if an error is present getting the dispatch function pointer!
An error here typically indicates the resident portion of _tx_thread_schedule
is not supporting the trap to obtain the function pointer. */
}
/* Resume the module's callback thread, already created in the manager. */
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
}
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has been entered! */
(entry_exit_notify)(thread_ptr, TX_THREAD_ENTRY);
}
#endif
/* Call current thread's entry function. */
(thread_info -> txm_module_thread_entry_info_entry) (thread_info -> txm_module_thread_entry_info_parameter);
/* Suspend thread with a "completed" state. */
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Pickup the entry/exit application callback routine again. */
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
/* Determine if an application callback routine is specified. */
if (entry_exit_notify != TX_NULL)
{
/* Yes, notify application that this thread has exited! */
(entry_exit_notify)(thread_ptr, TX_THREAD_EXIT);
}
#endif
/* Call actual thread suspension routine. */
_txm_module_thread_system_suspend(thread_ptr);
#ifdef TX_SAFETY_CRITICAL
/* If we ever get here, raise safety critical exception. */
TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
#endif
}

View File

@@ -0,0 +1,260 @@
;/**************************************************************************/
;/* */
;/* 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 0x12 ; IRQ mode
SVC_MODE EQU 0x13 ; SVC mode
SYS_MODE EQU 0x1F ; SYS mode
THUMB_MASK EQU 0x20 ; Thumb bit mask
IF :DEF:TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
ELSE
DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
ENDIF
;
;
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 Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_context_restore(VOID)
;{
EXPORT _tx_thread_context_restore
_tx_thread_context_restore
;
; /* Lockout interrupts. */
;
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
ELSE
CPSID i ; Disable IRQ interrupts
ENDIF
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)
CPS #SYS_MODE ; Enter SYS mode
STR r1, [sp, #-4]! ; Save point of interrupt on thread's stack
STMDB sp!, {r4-r12, lr} ; Save upper half of registers on thread's stack
MOV r4, r3 ; Save SPSR in r4
CPS #IRQ_MODE ; Enter IRQ mode
LDMIA sp!, {r0-r3} ; Recover r0-r3
CPS #SYS_MODE ; Enter SYS mode
STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1, #0] ; Pickup current thread pointer
IF {TARGET_FPU_VFP} = {TRUE}
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
CMP r2, #0 ; Is the VFP enabled?
BEQ _tx_skip_irq_vfp_save ; No, skip VFP IRQ save
VMRS r2, FPSCR ; Pickup the FPSCR
STR r2, [sp, #-4]! ; Save FPSCR
VSTMDB sp!, {D16-D31} ; Save D16-D31
VSTMDB sp!, {D0-D15} ; Save D0-D15
_tx_skip_irq_vfp_save
ENDIF
MOV r3, #1 ; Build interrupt stack type
STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR
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, #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();
;
CPS #IRQ_MODE ; Enter IRQ mode
MRS r1, SPSR ; Get SPSR
ORR r1, r1, #SYS_MODE ; Change to SYS Mode
BIC r1, r1, #THUMB_MASK ; Clear thumb bit
MSR SPSR_cxsf, r1 ; Put SYS Mode in SPSR
LDR lr, =_tx_thread_schedule ; Load scheduler address
MOVS pc, lr ; Return to scheduler
; }
;
__tx_thread_idle_system_restore
;
; /* Just return back to the scheduler! */
;
LDR lr, =_tx_thread_schedule ; Load scheduler address
MOVS pc, lr ; Return to scheduler
;}
;
END

View File

@@ -0,0 +1,199 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
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 Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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
CPSID if ; Disable FIQ interrupts
ENDIF
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
LDR r2, [r3, #0] ; Pickup system state
CMP r2, #0 ; Is this the first interrupt?
BEQ __tx_thread_not_nested_save ; Yes, not a nested context save
;
; /* Nested interrupt condition. */
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
;
; /* Save the rest of the scratch registers on the stack and return to the
; calling ISR. */
;
MRS r0, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} ; Store other registers
;
; /* Return to the ISR. */
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
B __tx_irq_processing_return ; Continue IRQ processing
;
__tx_thread_not_nested_save
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1, #0] ; Pickup current thread pointer
CMP r0, #0 ; Is it NULL?
BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
; scheduling loop - nothing needs saving!
;
; /* Save minimal context of interrupted thread. */
;
MRS r2, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r2, r10, r12, lr} ; Store other registers
;
; /* Save the current stack pointer in the thread's control block. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
B __tx_irq_processing_return ; Continue IRQ processing
;
; }
; else
; {
;
__tx_thread_idle_system_save
;
; /* Interrupt occurred in the scheduling loop. */
;
; /* Not much to do here, just adjust the stack pointer, and return to IRQ
; processing. */
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
ADD sp, sp, #16 ; Recover saved registers
B __tx_irq_processing_return ; Continue IRQ processing
;
; }
;}
;
END

View File

@@ -0,0 +1,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 */
;/** */
;/** 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
MODE_MASK EQU 0x1F ; Mode mask
IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits
;
;
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 Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_fiq_context_restore(VOID)
;{
EXPORT _tx_thread_fiq_context_restore
_tx_thread_fiq_context_restore
;
; /* Lockout interrupts. */
;
CPSID if ; Disable IRQ and FIQ 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_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, #FIQ_MODE ; Build FIQ mode CPSR
MSR CPSR_c, r2 ; Re-enter FIQ 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
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1] ; Pickup current thread pointer
IF {TARGET_FPU_VFP} = {TRUE}
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
CMP r2, #0 ; Is the VFP enabled?
BEQ _tx_skip_fiq_vfp_save ; No, skip VFP FIQ save
VMRS r2, FPSCR ; Pickup the FPSCR
STR r2, [sp, #-4]! ; Save FPSCR
VSTMDB sp!, {D16-D31} ; Save D16-D31
VSTMDB sp!, {D0-D15} ; Save D0-D15
_tx_skip_fiq_vfp_save
ENDIF
MOV r3, #1 ; Build interrupt stack type
STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR
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_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
MOV r3, #SVC_MODE ; Build SVC mode CPSR
MSR CPSR_c, r3 ; Enter SVC mode
B _tx_thread_schedule ; Return to scheduler
;
;}
;
END

View File

@@ -0,0 +1,203 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
IMPORT _tx_thread_system_state
IMPORT _tx_thread_current_ptr
IMPORT __tx_fiq_processing_return
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
IMPORT _tx_execution_isr_enter
ENDIF
;
;
AREA ||.text||, CODE, READONLY
PRESERVE8
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_context_save Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
; VOID _tx_thread_fiq_context_save(VOID)
;{
EXPORT _tx_thread_fiq_context_save
_tx_thread_fiq_context_save
;
; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
; out, we are in IRQ mode, and all registers are intact. */
;
; /* Check for a nested interrupt condition. */
; if (_tx_thread_system_state++)
; {
;
STMDB sp!, {r0-r3} ; Save some working registers
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
LDR r2, [r3] ; Pickup system state
CMP r2, #0 ; Is this the first interrupt?
BEQ __tx_thread_fiq_not_nested_save ; Yes, not a nested context save
;
; /* Nested interrupt condition. */
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3] ; Store it back in the variable
;
; /* Save the rest of the scratch registers on the stack and return to the
; calling ISR. */
;
MRS r0, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r0, r10, r12, lr} ; Store other registers
;
; /* Return to the ISR. */
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
B __tx_fiq_processing_return ; Continue FIQ processing
;
__tx_thread_fiq_not_nested_save
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3] ; Store it back in the variable
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1] ; Pickup current thread pointer
CMP r0, #0 ; Is it NULL?
BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred in
; ; scheduling loop - nothing needs saving!
;
; /* Save minimal context of interrupted thread. */
;
MRS r2, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r2, lr} ; Store other registers, Note that we don't
; ; need to save sl and ip since FIQ has
; ; copies of these registers. Nested
; ; interrupt processing does need to save
; ; these registers.
;
; /* Save the current stack pointer in the thread's control block. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
B __tx_fiq_processing_return ; Continue FIQ processing
;
; }
; else
; {
;
__tx_thread_fiq_idle_system_save
;
; /* Interrupt occurred in the scheduling loop. */
;
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
;
; /* Not much to do here, save the current SPSR and LR for possible
; use in IRQ interrupted in idle system conditions, and return to
; FIQ interrupt processing. */
;
MRS r0, SPSR ; Pickup saved SPSR
SUB lr, lr, #4 ; Adjust point of interrupt
STMDB sp!, {r0, lr} ; Store other registers that will get used
; ; or stripped off the stack in context
; ; restore
B __tx_fiq_processing_return ; Continue FIQ processing
;
; }
;}
;
END

View File

@@ -0,0 +1,111 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
IF :DEF:TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
ELSE
DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
ENDIF
MODE_MASK EQU 0x1F ; Mode mask
FIQ_MODE_BITS EQU 0x11 ; FIQ mode bits
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_nesting_end Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Re-enter IRQ mode
IF {INTER} = {TRUE}
BX r3 ; Return to caller
ELSE
MOV pc, r3 ; Return to caller
ENDIF
;}
;
END

View File

@@ -0,0 +1,104 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
FIQ_DISABLE EQU 0x40 ; FIQ disable bit
MODE_MASK EQU 0x1F ; Mode mask
SYS_MODE_BITS EQU 0x1F ; System mode bits
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_fiq_nesting_start Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Enter system mode
IF {INTER} = {TRUE}
BX r3 ; Return to caller
ELSE
MOV pc, r3 ; Return to caller
ENDIF
;}
;
END

View File

@@ -0,0 +1,102 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
IF :DEF:TX_ENABLE_FIQ_SUPPORT
INT_MASK EQU 0xC0 ; Interrupt bit mask
ELSE
INT_MASK EQU 0x80 ; Interrupt bit mask
ENDIF
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_control Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, r1 ; Setup new CPSR
AND r0, r3, #INT_MASK ; Return previous interrupt mask
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;
;}
;
END

View File

@@ -0,0 +1,95 @@
;/**************************************************************************/
;/* */
;/* 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_disable Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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. */
;
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ
ELSE
CPSID i ; Disable IRQ
ENDIF
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;}
;
END

View File

@@ -0,0 +1,87 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_interrupt_restore Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, r0 ; Setup new CPSR
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;}
;
END

View File

@@ -0,0 +1,110 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
IF :DEF:TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
ELSE
DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
ENDIF
MODE_MASK EQU 0x1F ; Mode mask
IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_irq_nesting_end Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Re-enter IRQ mode
IF {INTER} = {TRUE}
BX r3 ; Return to caller
ELSE
MOV pc, r3 ; Return to caller
ENDIF
;}
END

View File

@@ -0,0 +1,104 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Thread */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
IRQ_DISABLE EQU 0x80 ; IRQ disable bit
MODE_MASK EQU 0x1F ; Mode mask
SYS_MODE_BITS EQU 0x1F ; System mode bits
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_irq_nesting_start Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Enter system mode
IF {INTER} = {TRUE}
BX r3 ; Return to caller
ELSE
MOV pc, r3 ; Return to caller
ENDIF
;}
;
END

View File

@@ -0,0 +1,458 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
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
IRQ_MODE EQU 0xD2 ; IRQ mode
USR_MODE EQU 0x10 ; USR mode
SVC_MODE EQU 0x13 ; SVC mode
SYS_MODE EQU 0x1F ; SYS mode
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
MODE_MASK EQU 0x1F ; Mode mask
THUMB_MASK EQU 0x20 ; Thumb bit mask
IMPORT _txm_system_mode_enter
IMPORT _txm_system_mode_exit
IMPORT _txm_ttbr1_page_table
;
;
AREA ||.text||, CODE, READONLY
PRESERVE8
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_schedule Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_schedule(VOID)
;{
EXPORT _tx_thread_schedule
_tx_thread_schedule
; Enter the scheduler.
SVC 0
; We should never get here - ever!
_tx_scheduler_fault__
B _tx_scheduler_fault__
;}
; ****************************************************************************
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SWI_Handler
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXPORT __tx_swi_interrupt ; Software interrupt handler
__tx_swi_interrupt
STMFD sp!, {r0-r3, r12, lr} ; Store the registers
MOV r1, sp ; Set pointer to parameters
MRS r0, spsr ; Get spsr
STMFD sp!, {r0, r3} ; Store spsr onto stack and another
; register to maintain 8-byte-aligned stack
TST r0, #THUMB_MASK ; Occurred in Thumb state?
LDRNEH r0, [lr,#-2] ; Yes: Load halfword and...
BICNE r0, r0, #0xFF00 ; ...extract comment field
LDREQ r0, [lr,#-4] ; No: Load word and...
BICEQ r0, r0, #0xFF000000 ; ...extract comment field
; r0 now contains SVC number
; r1 now contains pointer to stacked registers
;
; The service call is handled here
;
CMP r0, #0 ; Is it a schedule request?
BEQ _tx_handler_svc_schedule ; Yes, go there
CMP r0, #1 ; Is it a system mode enter request?
BEQ _tx_handler_svc_super_enter ; Yes, go there
CMP r0, #2 ; Is it a system mode exit request?
BEQ _tx_handler_svc_super_exit ; Yes, go there
LDR r2, =0x123456
CMP r0, r2 ; Is it an ARM request?
BEQ _tx_handler_svc_arm ; Yes, go there
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Unknown SVC argument
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Unrecognized service call
_tx_handler_svc_unrecognized
_tx_handler_svc_unrecognized_loop ; We should never get here
B _tx_handler_svc_unrecognized_loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SVC 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; At this point we have an SVC 1, which means we are entering the system mode to service a kernel call
_tx_handler_svc_super_enter
; Make sure that we have been called from the system mode enter location (security)
LDR r2, =_txm_system_mode_enter ; Load the address of the known call point
SUB r1, lr, #4 ; Calculate the address of the actual call
CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry?
BNE _tx_handler_svc_unrecognized ; Return to where we came
; Clear the user mode flag in the thread structure
LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address
LDR r2, [r1] ; Load current thread location from the pointer (pointer indirection)
MOV r1, #0 ; Load the new user mode flag value (user mode flag clear -> not user mode -> system)
STR r1, [r2, #0x9C] ; Clear tx_thread_module_current_user_mode for thread
; Now we enter the system mode and return
LDMFD sp!, {r0, r3} ; Get spsr from the stack
BIC r0, r0, #MODE_MASK ; clear mode field
ORR r0, r0, #SYS_MODE ; system mode code
MSR SPSR_cxsf, r0 ; Restore the spsr
LDR r1, [r2, #0xA8] ; Load the module kernel stack pointer
CPS #SYS_MODE ; Switch to SYS mode
MOV r3, sp ; Grab thread stack pointer
MOV sp, r1 ; Set SP to kernel stack pointer
CPS #SVC_MODE ; Switch back to SVC mode
STR r3, [r2, #0xB0] ; Save thread stack pointer
IF :DEF:TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
ELSE
LDR r3, [r2, #0xAC] ; Load the module kernel stack size
STR r3, [r2, #20] ; Set stack size
LDRD r0, r1, [r2, #0xA4] ; Load the module kernel stack start and end
STRD r0, r1, [r2, #0x0C] ; Set stack start and end
ENDIF
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SVC 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; At this point we have an SVC 2, which means we are exiting the system mode after servicing a kernel call
_tx_handler_svc_super_exit
; Make sure that we have been called from the system mode exit location (security)
LDR r2, =_txm_system_mode_exit ; Load the address of the known call point
SUB r1, lr, #4 ; Calculate the address of the actual call
CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry?
BNE _tx_handler_svc_unrecognized ; Return to where we came
; Set the user mode flag into the thread structure
LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address
LDR r2, [r1] ; Load the current thread location from the pointer (pointer indirection)
MOV r1, #1 ; Load the new user mode flag value (user mode enabled -> not system anymore)
STR r1, [r2, #0x9C] ; Set tx_thread_module_current_user_mode for thread
; Now we enter user mode (exit the system mode) and return
LDMFD sp!, {r0, r3} ; Get spsr from the stack
BIC r0, r0, #MODE_MASK ; clear mode field
ORR r0, r0, #USR_MODE ; user mode code
MSR SPSR_cxsf, r0 ; Restore the spsr
LDR r1, [r2, #0xB0] ; Load the module thread stack pointer
CPS #SYS_MODE ; Switch to SYS mode
MOV r3, sp ; Grab kernel stack pointer
MOV sp, r1 ; Set SP back to thread stack pointer
CPS #SVC_MODE ; Switch back to SVC mode
IF :DEF:TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
ELSE
LDR r3, [r2, #0xBC] ; Load the module thread stack size
STR r3, [r2, #20] ; Set stack size
LDRD r0, r1, [r2, #0xB4] ; Load the module thread stack start and end
STRD r0, r1, [r2, #0x0C] ; Set stack start and end
ENDIF
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ARM Semihosting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_tx_handler_svc_arm
; *** TODO: handle semihosting requests or ARM angel requests ***
; just return
LDMFD sp!, {r0, r3} ; Get spsr from the stack
MSR SPSR_cxsf, r0 ; Restore the spsr
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SVC 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; At this point we have an SVC 0: enter the scheduler.
_tx_handler_svc_schedule
LDMFD sp!, {r0, r3} ; Get spsr from stack
MSR SPSR_cxsf, r0 ; Restore spsr
LDMFD sp!, {r0-r3, r12, lr} ; Restore the registers
; This code 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.
;
; /* 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
STR r3, [r2, #0] ; Setup time-slice
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the thread entry function to indicate the thread is executing. */
;
MOV r5, r0 ; Save r0
BL _tx_execution_thread_enter ; Call the thread execution enter function
MOV r0, r5 ; Restore r0
ENDIF
; Determine if an interrupt frame or a synchronous task suspension frame is present.
CPS #SYS_MODE ; Enter SYS mode
LDR sp, [r0, #8] ; Switch to thread stack pointer
LDMIA sp!, {r4, r5} ; Pickup the stack type and saved CPSR
CPS #SVC_MODE ; Enter SVC mode
; **************************************************************************
; Set up MMU for module.
LDR r2, [r0, #0x94] ; Pickup the module pointer
CMP r2, #0 ; Valid module pointer?
LDRNE r2, [r2, #0x64] ; Load ASID
; Otherwise, ASID 0 & master table will be loaded.
; Is ASID already loaded?
MRC p15, 0, r1, c13, c0, 1 ; Read CONTEXTIDR into r1
CMP r1, r2
; If so, skip MMU setup.
BEQ _tx_skip_mmu_update
; New ASID & TTBR values to load
DSB
ISB
; Load new ASID and TTBR
LDR r1, =_txm_ttbr1_page_table ; Load master TTBR
ORR r1, r1, #0x48 ; OR it with #TTBR0_ATTRIBUTES
MCR p15, 0, r1, c2, c0, 0 ; Change TTBR to master
ISB
DSB
MCR p15, 0, r2, c13, c0, 1 ; Change ASID to new value
ISB
; Change TTBR to new value
MOV r3, #14
ADD r1, r1, r2, LSL r3
MCR p15, 0, r1, c2, c0, 0 ; Change TTBR to new value
; refresh TLB
MOV r2, #0
DSB
MCR p15, 0, r2, c8, c7, 0 ; Invalidate entire unified TLB
MCR p15, 0, r2, c7, c5, 0 ; Invalidate all instruction caches to PoU
MCR p15, 0, r2, c7, c5, 6 ; Invalidate branch predictor
DSB
ISB
;test address translation
;mcr p15, 0, r0, c7, c8, 0
_tx_skip_mmu_update
; **************************************************************************
CMP r4, #0 ; Check for synchronous context switch
BEQ _tx_solicited_return
MSR SPSR_cxsf, r5 ; Setup SPSR for return
LDR r1, [r0, #8] ; Get thread SP
LDR lr, [r1, #0x40] ; Get thread PC
CPS #SYS_MODE ; Enter SYS mode
IF {TARGET_FPU_VFP} = {TRUE}
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
CMP r2, #0 ; Is the VFP enabled?
BEQ _tx_skip_interrupt_vfp_restore ; No, skip VFP interrupt restore
VLDMIA sp!, {D0-D15} ; Recover D0-D15
VLDMIA sp!, {D16-D31} ; Recover D16-D31
LDR r4, [sp], #4 ; Pickup FPSCR
VMSR FPSCR, r4 ; Restore FPSCR
CPS #SVC_MODE ; Enter SVC mode
LDR lr, [r1, #0x144] ; Get thread PC
CPS #SYS_MODE ; Enter SYS mode
_tx_skip_interrupt_vfp_restore
ENDIF
LDMIA sp!, {r0-r12, lr} ; Restore registers
ADD sp, sp, #4 ; Fix stack pointer
CPS #SVC_MODE ; Enter SVC mode
SUBS pc, lr, #0 ; Return to point of thread interrupt
_tx_solicited_return
MOV r2, r5 ; Move CPSR to scratch register
CPS #SYS_MODE ; Enter SYS mode
IF {TARGET_FPU_VFP} = {TRUE}
LDR r1, [r0, #144] ; Pickup the VFP enabled flag
CMP r1, #0 ; Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_restore ; No, skip VFP solicited restore
VLDMIA sp!, {D8-D15} ; Recover D8-D15
VLDMIA sp!, {D16-D31} ; Recover D16-D31
LDR r4, [sp], #4 ; Pickup FPSCR
VMSR FPSCR, r4 ; Restore FPSCR
_tx_skip_solicited_vfp_restore
ENDIF
LDMIA sp!, {r4-r11, lr} ; Restore registers
MOV r1, lr ; Copy lr to r1 to preserve across mode change
CPS #SVC_MODE ; Enter SVC mode
MSR SPSR_cxsf, r2 ; Recover CPSR
MOV lr, r1 ; Deprecated return via r1, so copy r1 to lr and return via lr
SUBS pc, lr, #0 ; Return to thread synchronously
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; End __tx_handler_swi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IF {TARGET_FPU_VFP} = {TRUE}
EXPORT tx_thread_vfp_enable
tx_thread_vfp_enable
MRS r2, CPSR ; Pickup the CPSR
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
ELSE
CPSID i ; Disable IRQ interrupts
ENDIF
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
LDR r1, [r0] ; Pickup current thread pointer
CMP r1, #0 ; Check for NULL thread pointer
BEQ __tx_no_thread_to_enable ; If NULL, skip VFP enable
MOV r0, #1 ; Build enable value
STR r0, [r1, #144] ; Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
__tx_no_thread_to_enable
MSR CPSR_cxsf, r2 ; Recover CPSR
BX LR ; Return to caller
EXPORT tx_thread_vfp_disable
tx_thread_vfp_disable
MRS r2, CPSR ; Pickup the CPSR
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
ELSE
CPSID i ; Disable IRQ interrupts
ENDIF
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
LDR r1, [r0] ; Pickup current thread pointer
CMP r1, #0 ; Check for NULL thread pointer
BEQ __tx_no_thread_to_disable ; If NULL, skip VFP disable
MOV r0, #0 ; Build disable value
STR r0, [r1, #144] ; Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
__tx_no_thread_to_disable
MSR CPSR_cxsf, r2 ; Recover CPSR
BX LR ; Return to caller
ENDIF
END

View File

@@ -0,0 +1,166 @@
;/**************************************************************************/
;/* */
;/* 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
SYS_MODE EQU 0x1F ; SYS 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
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR
;
;
AREA ||.text||, CODE, READONLY
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_thread_stack_build Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.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 Cortex-A7 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 r3, CPSR ; Pickup CPSR
BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR
ORR r3, r3, #SYS_MODE ; Build CPSR, SYS mode, interrupts enabled
BIC r3, r3, #THUMB_MASK ; Clear Thumb bit by default
AND r1, r1, #1 ; Determine if the entry function is in Thumb mode
CMP r1, #1 ; Is the Thumb bit set?
ORREQ r3, r3, #THUMB_MASK ; Yes, set the Thumb bit
STR r3, [r2, #4] ; Store initial CPSR
;
; /* Setup stack pointer. */
; thread_ptr -> tx_thread_stack_ptr = r2;
;
STR r2, [r0, #8] ; Save stack pointer in thread's
; control block
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;}
END

View File

@@ -0,0 +1,159 @@
;/**************************************************************************/
;/* */
;/* 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"
;
;
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 Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_thread_system_return(VOID)
;{
EXPORT _tx_thread_system_return
_tx_thread_system_return
;
; /* Save minimal context on the stack. */
;
STMDB sp!, {r4-r11, lr} ; Save minimal context
LDR r5, =_tx_thread_current_ptr ; Pickup address of current ptr
LDR r6, [r5, #0] ; Pickup current thread pointer
IF {TARGET_FPU_VFP} = {TRUE}
LDR r0, [r6, #144] ; Pickup the VFP enabled flag
CMP r0, #0 ; Is the VFP enabled?
BEQ _tx_skip_solicited_vfp_save ; No, skip VFP solicited save
VMRS r4, FPSCR ; Pickup the FPSCR
STR r4, [sp, #-4]! ; Save FPSCR
VSTMDB sp!, {D16-D31} ; Save D16-D31
VSTMDB sp!, {D8-D15} ; Save D8-D15
_tx_skip_solicited_vfp_save
ENDIF
MOV r0, #0 ; Build a solicited stack type
MRS r1, CPSR ; Pickup the CPSR
STMDB sp!, {r0-r1} ; Save type and CPSR
;
; /* Lockout interrupts. */
;
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
ELSE
CPSID i ; Disable IRQ interrupts
ENDIF
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 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, [r6, #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 the current remaining 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, [r6, #24] ; Store current time-slice
;
; }
__tx_thread_dont_save_ts
;
; /* Clear the current thread pointer. */
; _tx_thread_current_ptr = TX_NULL;
;
STR r4, [r5, #0] ; Clear current thread pointer
B _tx_thread_schedule ; Jump to scheduler!
;
;}
END

View File

@@ -0,0 +1,200 @@
;/**************************************************************************/
;/* */
;/* 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
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 Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.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
CPSID if ; Disable IRQ and FIQ interrupts
ENDIF
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
LDR r2, [r3, #0] ; Pickup system state
CMP r2, #0 ; Is this the first interrupt?
BEQ __tx_thread_not_nested_save ; Yes, not a nested context save
;
; /* Nested interrupt condition. */
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
;
; /* Note: Minimal context of interrupted thread is already saved. */
;
; /* Return to the ISR. */
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;
__tx_thread_not_nested_save
; }
;
; /* Otherwise, not nested, check to see if a thread was running. */
; else if (_tx_thread_current_ptr)
; {
;
ADD r2, r2, #1 ; Increment the interrupt counter
STR r2, [r3, #0] ; Store it back in the variable
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
LDR r0, [r1, #0] ; Pickup current thread pointer
CMP r0, #0 ; Is it NULL?
BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
; scheduling loop - nothing needs saving!
;
; /* Note: Minimal context of interrupted thread is already saved. */
;
; /* Save the current stack pointer in the thread's control block. */
; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
;
; /* Switch to the system stack. */
; sp = _tx_thread_system_stack_ptr;
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;
; }
; else
; {
;
__tx_thread_idle_system_save
;
; /* Interrupt occurred in the scheduling loop. */
;
; /* Not much to do here, just adjust the stack pointer, and return to IRQ
; processing. */
;
MOV r10, #0 ; Clear stack limit
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
; /* Call the ISR enter function to indicate an ISR is executing. */
;
PUSH {lr} ; Save ISR lr
BL _tx_execution_isr_enter ; Call the ISR enter function
POP {lr} ; Recover ISR lr
ENDIF
ADD sp, sp, #32 ; Recover saved registers
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;
; }
;}
;
END

View File

@@ -0,0 +1,258 @@
;/**************************************************************************/
;/* */
;/* Copyright (c) Microsoft Corporation. All rights reserved. */
;/* */
;/* This software is licensed under the Microsoft Software License */
;/* Terms for Microsoft Azure RTOS. Full text of the license can be */
;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
;/* and in the root directory of this software. */
;/* */
;/**************************************************************************/
;
;
;/**************************************************************************/
;/**************************************************************************/
;/** */
;/** ThreadX Component */
;/** */
;/** Timer */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_timer.h"
;#include "tx_thread.h"
;
;
;Define Assembly language external references...
;
IMPORT _tx_timer_time_slice
IMPORT _tx_timer_system_clock
IMPORT _tx_timer_current_ptr
IMPORT _tx_timer_list_start
IMPORT _tx_timer_list_end
IMPORT _tx_timer_expired_time_slice
IMPORT _tx_timer_expired
IMPORT _tx_thread_time_slice
IMPORT _tx_timer_expiration_process
;
;
AREA ||.text||, CODE, READONLY
PRESERVE8
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _tx_timer_interrupt Cortex-A7/AC5 */
;/* 6.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 */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _tx_timer_interrupt(VOID)
;{
EXPORT _tx_timer_interrupt
_tx_timer_interrupt
;
; /* Upon entry to this routine, it is assumed that context save has already
; been called, and therefore the compiler scratch registers are available
; for use. */
;
; /* Increment the system clock. */
; _tx_timer_system_clock++;
;
LDR r1, =_tx_timer_system_clock ; Pickup address of system clock
LDR r0, [r1, #0] ; Pickup system clock
ADD r0, r0, #1 ; Increment system clock
STR r0, [r1, #0] ; Store new system clock
;
; /* Test for time-slice expiration. */
; if (_tx_timer_time_slice)
; {
;
LDR r3, =_tx_timer_time_slice ; Pickup address of time-slice
LDR r2, [r3, #0] ; Pickup time-slice
CMP r2, #0 ; Is it non-active?
BEQ __tx_timer_no_time_slice ; Yes, skip time-slice processing
;
; /* Decrement the time_slice. */
; _tx_timer_time_slice--;
;
SUB r2, r2, #1 ; Decrement the time-slice
STR r2, [r3, #0] ; Store new time-slice value
;
; /* Check for expiration. */
; if (__tx_timer_time_slice == 0)
;
CMP r2, #0 ; Has it expired?
BNE __tx_timer_no_time_slice ; No, skip expiration processing
;
; /* Set the time-slice expired flag. */
; _tx_timer_expired_time_slice = TX_TRUE;
;
LDR r3, =_tx_timer_expired_time_slice ; Pickup address of expired flag
MOV r0, #1 ; Build expired value
STR r0, [r3, #0] ; Set time-slice expiration flag
;
; }
;
__tx_timer_no_time_slice
;
; /* Test for timer expiration. */
; if (*_tx_timer_current_ptr)
; {
;
LDR r1, =_tx_timer_current_ptr ; Pickup current timer pointer addr
LDR r0, [r1, #0] ; Pickup current timer
LDR r2, [r0, #0] ; Pickup timer list entry
CMP r2, #0 ; Is there anything in the list?
BEQ __tx_timer_no_timer ; No, just increment the timer
;
; /* Set expiration flag. */
; _tx_timer_expired = TX_TRUE;
;
LDR r3, =_tx_timer_expired ; Pickup expiration flag address
MOV r2, #1 ; Build expired value
STR r2, [r3, #0] ; Set expired flag
B __tx_timer_done ; Finished timer processing
;
; }
; else
; {
__tx_timer_no_timer
;
; /* No timer expired, increment the timer pointer. */
; _tx_timer_current_ptr++;
;
ADD r0, r0, #4 ; Move to next timer
;
; /* Check for wrap-around. */
; if (_tx_timer_current_ptr == _tx_timer_list_end)
;
LDR r3, =_tx_timer_list_end ; Pickup addr of timer list end
LDR r2, [r3, #0] ; Pickup list end
CMP r0, r2 ; Are we at list end?
BNE __tx_timer_skip_wrap ; No, skip wrap-around logic
;
; /* Wrap to beginning of list. */
; _tx_timer_current_ptr = _tx_timer_list_start;
;
LDR r3, =_tx_timer_list_start ; Pickup addr of timer list start
LDR r0, [r3, #0] ; Set current pointer to list start
;
__tx_timer_skip_wrap
;
STR r0, [r1, #0] ; Store new current timer pointer
; }
;
__tx_timer_done
;
;
; /* See if anything has expired. */
; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
; {
;
LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of expired flag
LDR r2, [r3, #0] ; Pickup time-slice expired flag
CMP r2, #0 ; Did a time-slice expire?
BNE __tx_something_expired ; If non-zero, time-slice expired
LDR r1, =_tx_timer_expired ; Pickup addr of other expired flag
LDR r0, [r1, #0] ; Pickup timer expired flag
CMP r0, #0 ; Did a timer expire?
BEQ __tx_timer_nothing_expired ; No, nothing expired
;
__tx_something_expired
;
;
STMDB sp!, {r0, lr} ; Save the lr register on the stack
; and save r0 just to keep 8-byte alignment
;
; /* Did a timer expire? */
; if (_tx_timer_expired)
; {
;
LDR r1, =_tx_timer_expired ; Pickup addr of expired flag
LDR r0, [r1, #0] ; Pickup timer expired flag
CMP r0, #0 ; Check for timer expiration
BEQ __tx_timer_dont_activate ; If not set, skip timer activation
;
; /* Process timer expiration. */
; _tx_timer_expiration_process();
;
BL _tx_timer_expiration_process ; Call the timer expiration handling routine
;
; }
__tx_timer_dont_activate
;
; /* Did time slice expire? */
; if (_tx_timer_expired_time_slice)
; {
;
LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of time-slice expired
LDR r2, [r3, #0] ; Pickup the actual flag
CMP r2, #0 ; See if the flag is set
BEQ __tx_timer_not_ts_expiration ; No, skip time-slice processing
;
; /* Time slice interrupted thread. */
; _tx_thread_time_slice();
BL _tx_thread_time_slice ; Call time-slice processing
;
; }
;
__tx_timer_not_ts_expiration
;
LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for
; the 8-byte stack alignment
;
; }
;
__tx_timer_nothing_expired
;
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
MOV pc, lr ; Return to caller
ENDIF
;
;}
END

View File

@@ -0,0 +1,90 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_alignment_adjust Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function adjusts the alignment and size of the code and data */
/* section for a given module implementation. */
/* */
/* INPUT */
/* */
/* code_size Size of the code area (updated) */
/* code_alignment Code area alignment (updated) */
/* data_size Size of data area (updated) */
/* data_alignment Data area alignment (updated) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Initial thread stack frame */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment)
{
ULONG local_code_size;
ULONG local_code_alignment;
ULONG local_data_size;
ULONG local_data_alignment;
/* Copy the input parameters into local variables for ease of use. */
local_code_size = *code_size;
local_code_alignment = TXM_MODULE_MEMORY_ALIGNMENT;
local_data_size = *data_size;
local_data_alignment = TXM_MODULE_MEMORY_ALIGNMENT;
/* Return all the information to the caller. */
*code_size = ((local_code_size + TXM_MODULE_MEMORY_ALIGNMENT - 1)/TXM_MODULE_MEMORY_ALIGNMENT) * TXM_MODULE_MEMORY_ALIGNMENT;
*code_alignment = local_code_alignment;
*data_size = ((local_data_size + TXM_MODULE_MEMORY_ALIGNMENT - 1)/TXM_MODULE_MEMORY_ALIGNMENT) * TXM_MODULE_MEMORY_ALIGNMENT;
*data_alignment = local_data_alignment;
}

View File

@@ -0,0 +1,483 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_mutex.h"
#include "tx_queue.h"
#include "tx_thread.h"
#include "txm_module.h"
/* External page tables. */
extern ULONG _txm_level2_external_page_pool[TXM_LEVEL2_EXTERNAL_POOL_PAGES][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
extern ULONG _txm_ttbr1_page_table[TXM_MAXIMUM_MODULES][TXM_MASTER_PAGE_TABLE_ENTRIES];
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_level2_page_get Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets an available L2 page table and places it in the */
/* module external page table list. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* page_addr Address of L2 page */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_external_memory_enable */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
ULONG _txm_level2_page_get(TXM_MODULE_INSTANCE *module_instance, ULONG *page_addr)
{
UINT i;
UINT status;
UINT table_index;
UINT pool_index;
/* Default status to success. */
status = TX_SUCCESS;
/* Find first free table slot in module control block. */
for(i = 0; i < TXM_MODULE_LEVEL2_EXTERNAL_PAGES; i++)
{
if(module_instance->txm_external_page_table[i] == TX_NULL)
{
table_index = i;
break;
}
}
if(i >= TXM_MODULE_LEVEL2_EXTERNAL_PAGES)
{
status = TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR;
}
else
{
/* Find first free table in pool. */
for(i = 0; i < TXM_LEVEL2_EXTERNAL_POOL_PAGES; i++)
{
if(_txm_level2_external_page_pool[i][0] == (ULONG) TX_NULL)
{
pool_index = i;
break;
}
}
if(i >= TXM_LEVEL2_EXTERNAL_POOL_PAGES)
{
status = TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR;
}
}
if(status == TX_SUCCESS)
{
/* Place page address in table slot. Return page address. */
module_instance->txm_external_page_table[table_index] = _txm_level2_external_page_pool[pool_index];
*page_addr = (ULONG)_txm_level2_external_page_pool[pool_index];
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_level2_page_clear Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function clears the first entry in a L2 page table and clears */
/* the table entry from the module external page table list. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* TXM_MODULE_MANAGER_MODULE_UNLOAD */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_level2_page_clear(TXM_MODULE_INSTANCE *module_instance)
{
UINT i;
/* Clear table slots and zero out L2 entry. */
for(i = 0; i < TXM_MODULE_LEVEL2_EXTERNAL_PAGES; i++)
{
if(module_instance->txm_external_page_table[i])
{
*(ULONG *)module_instance->txm_external_page_table[i] = (ULONG)TX_NULL;
module_instance->txm_external_page_table[i] = TX_NULL;
}
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_external_memory_enable Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates an entry in the MMU table for a shared */
/* memory space. */
/* */
/* INPUT */
/* */
/* module_instance Module instance pointer */
/* start_address Start address of memory */
/* length Length of external memory */
/* attributes Memory attributes */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _tx_mutex_get Get protection mutex */
/* _tx_mutex_put Release protection mutex */
/* TX_MEMSET Fill memory with constant */
/* _txm_level2_page_get Get L2 page table */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_external_memory_enable( TXM_MODULE_INSTANCE *module_instance,
VOID *start_address,
ULONG length,
UINT attributes)
{
ULONG start_addr = (ULONG) start_address;
ULONG end_addr;
ULONG mmu_l1_entries;
ULONG mmu_l2_entries = 0;
ULONG level1_index;
ULONG level2_index;
ULONG temp_index;
ULONG temp_addr;
ULONG page_addr;
ULONG asid;
ULONG level1_attributes;
ULONG level2_attributes;
UINT status;
UINT i;
/* Determine if the module manager has not been initialized yet. */
if (_txm_module_manager_ready != TX_TRUE)
{
/* Module manager has not been initialized. */
return(TX_NOT_AVAILABLE);
}
/* Determine if the module is valid. */
if (module_instance == TX_NULL)
{
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Get module manager protection mutex. */
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
/* Determine if the module instance is valid. */
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Invalid module pointer. */
return(TX_PTR_ERROR);
}
/* Determine if the module instance is in the loaded state. */
if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not ready. */
return(TX_START_ERROR);
}
/* Determine if the module instance is memory protected. */
if (module_instance -> txm_module_instance_asid == 0)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return error if the module is not protected. */
return(TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR);
}
/* Start address must be aligned to MMU block size (4 kB).
Length will be rounded up to 4 kB alignment. */
if(start_addr & ~TXM_MMU_LEVEL2_MASK)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return alignment error. */
return(TXM_MODULE_ALIGNMENT_ERROR);
}
/**************************************************************************/
/* At this point, we have a valid address. Set up MMU. */
/**************************************************************************/
/* Round length up to 4 kB alignment. */
if(length & ~TXM_MMU_LEVEL2_MASK)
{
length = ((length + TXM_MODULE_MEMORY_ALIGNMENT - 1)/TXM_MODULE_MEMORY_ALIGNMENT) * TXM_MODULE_MEMORY_ALIGNMENT;
}
/* Get end address. */
end_addr = start_addr + length - 1;
/* How many level 1 table entries does data span? */
mmu_l1_entries = (end_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1;
/* Add 1 to align. */
end_addr++;
/* How many level 2 table entries does data need?
* 0: start and end addresses both aligned.
* 1: either start or end address aligned.
* 2: start and end addresses both not aligned. */
if(start_addr & ~TXM_MMU_LEVEL1_MASK)
{
/* If start address is not aligned, increment. */
mmu_l2_entries++;
}
if(end_addr & ~TXM_MMU_LEVEL1_MASK)
{
/* If end address is not aligned, increment. */
mmu_l2_entries++;
}
/* Get index into L1 table. */
level1_index = (start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT);
/* Get module ASID. */
asid = module_instance -> txm_module_instance_asid;
/* Do start and end entries need level 2 pages? */
if(mmu_l2_entries > 0)
{
/* Build L2 attributes. */
level2_attributes = ((attributes & TXM_MMU_ATTRIBUTE_XN) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_XN_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_B) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_B_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_C) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_C_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_AP) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_AP_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_TEX) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_TEX_SHIFT) |
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
/* If start_addr is not aligned, we need a L2 page. */
if(start_addr & ~TXM_MMU_LEVEL1_MASK)
{
/* Is there already an L2 page in the L1 table? */
if((_txm_ttbr1_page_table[asid][level1_index] & ~TXM_MMU_LEVEL1_SECOND_MASK) == TXM_MMU_LEVEL1_SECOND_ATTRIBUTES)
{
page_addr = _txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_SECOND_MASK;
}
else
{
/* Get L2 table from pool. */
status = _txm_level2_page_get(module_instance, &page_addr);
if(status != TX_SUCCESS)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
return(TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR);
}
/* Clear L2 table. */
TX_MEMSET((void *)page_addr, 0, TXM_LEVEL_2_PAGE_TABLE_ENTRIES);
/* Put L2 page in L1 table. */
_txm_ttbr1_page_table[asid][level1_index] = (page_addr & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
}
/* Decrement number of L1 entries remaining. */
mmu_l1_entries--;
/* Set up L2 start table. */
/* Determine how many entries in L2 table. */
if((end_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT))
{
/* End address goes to next L1 page (or beyond). */
temp_addr = ((start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1) << (TXM_MMU_LEVEL1_PAGE_SHIFT);
mmu_l2_entries = (temp_addr - start_addr) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
}
else
{
/* End address is on the same L1 page. */
mmu_l2_entries = (end_addr >> TXM_MMU_LEVEL2_PAGE_SHIFT) - (start_addr >> TXM_MMU_LEVEL2_PAGE_SHIFT);
}
/* Insert module settings into start table. */
level2_index = ((start_addr & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
for(i = 0; i < mmu_l2_entries; i++, level2_index++)
{
((ULONG *) page_addr)[level2_index] = (start_addr & TXM_MMU_LEVEL1_MASK) | (level2_index << TXM_MMU_LEVEL2_PAGE_SHIFT) | level2_attributes;
}
level1_index++;
}
/* Does last entry need a level 2 page? */
/* If end_address is not aligned, we need a L2 page. */
if((end_addr & ~TXM_MMU_LEVEL1_MASK) && (mmu_l1_entries != 0))
{
/* Get index into L1 table. */
temp_index = (end_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT);
/* Is there already an L2 page in the L1 table? */
if((_txm_ttbr1_page_table[asid][temp_index] & ~TXM_MMU_LEVEL1_SECOND_MASK) == TXM_MMU_LEVEL1_SECOND_ATTRIBUTES)
{
page_addr = _txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_SECOND_MASK;
}
else
{
/* Get L2 table from pool. */
status = _txm_level2_page_get(module_instance, &page_addr);
if(status != TX_SUCCESS)
{
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
return(TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR);
}
/* Clear L2 table. */
TX_MEMSET((void *)page_addr, 0, TXM_LEVEL_2_PAGE_TABLE_ENTRIES);
/* Put L2 page in L1 table. */
_txm_ttbr1_page_table[asid][temp_index] = (page_addr & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
}
/* Decrement number of L1 entries remaining. */
mmu_l1_entries--;
/* Determine how many entries in L2 table. */
mmu_l2_entries = ((end_addr & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
/* Set up L2 end table. */
for(i = 0; i < mmu_l2_entries; i++)
{
((ULONG *) page_addr)[i] = (end_addr & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | level2_attributes;
}
}
}
/* Fill any L1 entries between start and end pages of module data range. */
for(i = 0; i < mmu_l1_entries; i++, level1_index++)
{
/* Build L1 attributes. */
level1_attributes = ((attributes & TXM_MMU_ATTRIBUTE_XN) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_XN_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_B) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_B_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_C) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_C_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_AP) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_AP_SHIFT) |
((attributes & TXM_MMU_ATTRIBUTE_TEX) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_TEX_SHIFT) |
TXM_MMU_LEVEL1_USER_ATTRIBUTE_BASE;
/* Place address and attributes in table. */
_txm_ttbr1_page_table[asid][level1_index] = (level1_index << TXM_MMU_LEVEL1_PAGE_SHIFT) | level1_attributes;
}
/* Release the protection mutex. */
_tx_mutex_put(&_txm_module_manager_mutex);
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,111 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/* Define a macro that can be used to allocate global variables useful to
store information about the last fault. This macro is defined in
txm_module_port.h and is usually populated in the assembly language
fault handling prior to the code calling _txm_module_manager_memory_fault_handler. */
TXM_MODULE_MANAGER_FAULT_INFO
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_handler Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles a fault associated with a memory protected */
/* module. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_terminate Terminate thread */
/* */
/* CALLED BY */
/* */
/* Fault handler */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_memory_fault_handler(VOID)
{
TXM_MODULE_INSTANCE *module_instance_ptr;
TX_THREAD *thread_ptr;
/* Pickup the current thread. */
thread_ptr = _tx_thread_current_ptr;
/* Initialize the module instance pointer to NULL. */
module_instance_ptr = TX_NULL;
/* Is there a thread? */
if (thread_ptr)
{
/* Pickup the module instance. */
module_instance_ptr = thread_ptr -> tx_thread_module_instance_ptr;
/* Terminate the current thread. */
_tx_thread_terminate(_tx_thread_current_ptr);
}
/* Determine if there is a user memory fault notification callback. */
if (_txm_module_manager_fault_notify)
{
/* Yes, call the user's notification memory fault callback. */
(_txm_module_manager_fault_notify)(thread_ptr, module_instance_ptr);
}
}

View File

@@ -0,0 +1,84 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "txm_module.h"
/* Define the external user's fault notification callback function pointer. This is
setup via the txm_module_manager_memory_fault_notify API. */
extern VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_memory_fault_notify Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers an application callback when/if a memory */
/* fault occurs. The supplied thread is automatically terminated, but */
/* any other threads in the same module may still execute. */
/* */
/* INPUT */
/* */
/* notify_function Memory fault notification */
/* function, NULL disables. */
/* */
/* OUTPUT */
/* */
/* Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *))
{
/* Setup notification function. */
_txm_module_manager_fault_notify = notify_function;
/* Return success. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,301 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
#define CACHE_DISABLED 0x12
#define SDRAM_START 0x00000000
#define SDRAM_END 0x1fffffff
#define CACHE_WRITEBACK 0x1e
#define SECTION_DESCRIPTOR 0x00000002
#define DACR_CLIENT_MODE 0x55555555
/*** Page table attributes TTBR0 ***********************************************
* IRGN = 01 - Normal memory, Inner Write-Back Write-Allocate Cacheable
* S - non-shareable
* RGN = 01 - Normal memory, Outer Write-Back Write-Allocate Cacheable
* NOS - outer-shareable
*******************************************************************************/
#define TTBR0_ATTRIBUTES 0x48
/* ASID table, index is ASID number and contents hold pointer to module. */
TXM_MODULE_INSTANCE *_txm_asid_table[TXM_ASID_TABLE_LENGTH];
/* Master page table, 2^14 (16kB) alignment.
* First table is the master level 1 table, the rest are for each module. */
__align(16384) ULONG _txm_ttbr1_page_table[TXM_MAXIMUM_MODULES][TXM_MASTER_PAGE_TABLE_ENTRIES];
/* Module start and end level 2 page tables, 2^10 (1kB) alignment.
* First set of 4 tables are the master level 2 tables, the rest are for each module.
* Each module needs two L2 tables for code and two L2 tables for data. */
__align(1024) ULONG _txm_level2_module_page_table[TXM_MAXIMUM_MODULES * 4][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
/* Module external memory level 2 page tables, 2^10 (1kB) alignment. */
__align(1024) ULONG _txm_level2_external_page_pool[TXM_LEVEL2_EXTERNAL_POOL_PAGES][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_initialize Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs the initial set up of the the A7 MMU. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_mm_initialize(VOID)
{
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
UINT i;
ULONG cp15reg;
UINT user_mode_index;
UINT counter_limit;
/* Clear ASID table. */
for (i = 0; i < TXM_ASID_TABLE_LENGTH; i++)
{
_txm_asid_table[i] = 0;
}
_txm_asid_table[0] = (TXM_MODULE_INSTANCE *)TXM_ASID_RESERVED;
/********************************************************************************/
/* This is an example showing how to set up the cache attributes. */
/********************************************************************************/
/*******************************************************************************
* PAGE TABLE generation
* Generate the page tables
* Build a flat translation table for the whole address space.
* ie: Create 4096 1MB sections from 0x000xxxxx to 0xFFFxxxxx
* 31 20|19 18|17|16| 15|14 12|11 10|9|8 5|4 |3 2|1 0|
* |base address | 0 0|nG| S|AP2|TEX |AP |P|Domain|XN|CB |1 0|
*
* Bits[31:20] - Top 12 bits of VA is pointer into table
* nG[17]=0 - Non global, enables matching against ASID in the TLB when set.
* S[16]=0 - Indicates normal memory is shared when set.
* AP2[15]=0
* TEX[14:12]=000
* AP[11:10]=11 - Configure for full read/write access in all modes
* IMPP[9]=0 - Ignored
* Domain[5:8]=1111 - Set all pages to use domain 15
* XN[4]=0 - Execute never disabled
* CB[3:2]= 00 - Set attributes to Strongly-ordered memory.
* (except for the descriptor where code segment is based,
* see below)
* Bits[1:0]=10 - Indicate entry is a 1MB section
*******************************************************************************/
/* ---- Parameter setting to level1 descriptor (bits 19:0) ---- */
/* setting for Strongly-ordered memory
B-00000000000000000000010111100010 */
#define TTB_PARA_STRGLY 0x05E2
/* setting for Outer and inner not cache normal memory
B-00000000000000000001010111100010 */
#define TTB_PARA_NORMAL_NOT_CACHE 0x15E2
/* setting for Outer and inner write back, write allocate normal memory
(Cacheable)
B-00000000000000000001010111101110 */
#define TTB_PARA_NORMAL_CACHE 0x15EE //0x15EE
/* In this chip (RZA1) there are the following 12 sections with the defined memory size (MB) */
#define M_SIZE_NOR 128 /* [Area00] CS0, CS1 area (for NOR flash) */
#define M_SIZE_SDRAM 128 /* [Area01] CS2, CS3 area (for SDRAM) */
#define M_SIZE_CS45 128 /* [Area02] CS4, CS5 area */
#define M_SIZE_SPI 128 /* [Area03] SPI, SP2 area (for Serial flash) */
#define M_SIZE_RAM 10 /* [Area04] Internal RAM */
#define M_SIZE_IO_1 502 /* [Area05] I/O area 1 */
#define M_SIZE_NOR_M 128 /* [Area06] CS0, CS1 area (for NOR flash) (mirror) */
#define M_SIZE_SDRAM_M 128 /* [Area07] CS2, CS3 area (for SDRAM) (mirror) */
#define M_SIZE_CS45_M 128 /* [Area08] CS4, CS5 area (mirror) */
#define M_SIZE_SPI_M 128 /* [Area09] SPI, SP2 area (for Serial flash) (mirror) */
#define M_SIZE_RAM_M 10 /* [Area10] Internal RAM (mirror) */
#define M_SIZE_IO_2 2550 /* [Area11] I/O area 2 */
/* Should add to: 4096 */
counter_limit = M_SIZE_NOR;
for (i = 0; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
}
counter_limit += M_SIZE_SDRAM;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
}
counter_limit += M_SIZE_CS45;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
}
counter_limit += M_SIZE_SPI;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
}
counter_limit += M_SIZE_RAM;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
}
counter_limit += M_SIZE_IO_1;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
}
counter_limit += M_SIZE_NOR_M;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
}
counter_limit += M_SIZE_SDRAM_M;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
}
counter_limit += M_SIZE_CS45_M;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
}
counter_limit += M_SIZE_SPI_M;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
}
counter_limit += M_SIZE_RAM_M;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
}
counter_limit += M_SIZE_IO_2;
for (; i < counter_limit; i++)
{
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
}
/********************************************************************************/
/* This is the end of the example showing how to set up the cache attributes. */
/********************************************************************************/
/* Clear ASID. */
cp15reg = 0;
__asm("mcr p15, 0, cp15reg, c13, c0, 1");
__asm("isb");
/* Put the page table address in TTBR. */
cp15reg = (int)(VOID*)_txm_ttbr1_page_table;
cp15reg |= TTBR0_ATTRIBUTES;
__asm("mcr p15, 0, cp15reg, c2, c0, 0");
/* Set the domain to client mode. */
cp15reg = DACR_CLIENT_MODE;
__asm("mcr p15, 0, cp15reg, c3, c0, 0");
/* Level 2 small page attributes: normal memory, cache & buffer enabled, priviledged access. */
#define TTB_LEVEL2_NORMAL_CACHE 0x05E
/* Level 2 clear AP attributes mask. */
#define TTB_LEVEL2_AP_CLEAR_MASK 0xFFFFFFCF
/* Attributes for user mode table entry in level 2 table. */
#define TTB_LEVEL2_USER_MODE_ENTRY 0x06E
/* Set up Level 2 table for user to kernel mode entry trampoline. */
/* Find which table entry _txm_module_manager_user_mode_entry is in. */
user_mode_index = (ULONG)_txm_module_manager_user_mode_entry >> TXM_MMU_LEVEL1_PAGE_SHIFT;
/* Fill table. */
for (i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = ((ULONG)_txm_module_manager_user_mode_entry & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | TTB_LEVEL2_NORMAL_CACHE;
}
/* Enter Level 2 table in to master table. */
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][user_mode_index] = ((ULONG)_txm_level2_module_page_table & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
/* Find level 2 entry that holds _txm_module_manager_user_mode_entry. */
user_mode_index = ((ULONG)_txm_module_manager_user_mode_entry & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
/* Set attribute bits for the user mode entry page. */
_txm_level2_module_page_table[TXM_MASTER_PAGE_TABLE_INDEX][user_mode_index] = (_txm_level2_module_page_table[TXM_MASTER_PAGE_TABLE_INDEX][user_mode_index] & TTB_LEVEL2_AP_CLEAR_MASK) | TTB_LEVEL2_USER_MODE_ENTRY;
/* Enable the MMU. */
__asm("mrc p15, 0, cp15reg, c1, c0, 0");
cp15reg |= 0x1;
__asm("mcr p15, 0, cp15reg, c1, c0, 0");
return(TX_SUCCESS);
#else
return(TX_FEATURE_NOT_ENABLED);
#endif
}

View File

@@ -0,0 +1,589 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "txm_module.h"
extern TXM_MODULE_INSTANCE *_txm_asid_table[TXM_ASID_TABLE_LENGTH];
extern ULONG _txm_level2_module_page_table[TXM_MAXIMUM_MODULES][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
extern ULONG _txm_ttbr1_page_table[TXM_MAXIMUM_MODULES][TXM_MASTER_PAGE_TABLE_ENTRIES];
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_inside_data_check Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function determines if pointer is within the module's data or */
/* shared memory. */
/* */
/* INPUT */
/* */
/* pointer Data pointer */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* TXM_MODULE_MANAGER_DATA_POINTER_CHECK */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_inside_data_check(ULONG pointer)
{
ULONG translation;
/* ATS1CUR operation on address supplied in pointer, Stage 1 unprivileged read. */
__asm("MCR p15, 0, pointer, c7, c8, 2");
__asm("ISB"); /* Ensure completion of the MCR write to CP15. */
__asm("MRC p15, 0, translation, c7, c4, 0"); /* Read result from 32-bit PAR into translation. */
if (translation & TXM_ADDRESS_TRANSLATION_FAULT_BIT)
{
return(TX_FALSE);
}
return(TX_TRUE);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_assign_asid Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function assigns an Application Specific ID (ASID) to a */
/* module. */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_mm_register_setup */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_assign_asid(TXM_MODULE_INSTANCE *module_instance)
{
UINT i = 1;
/* Find first non-zero ASID, starting at index 1. */
while(i < TXM_ASID_TABLE_LENGTH)
{
if(_txm_asid_table[i] != 0)
{
i++;
}
else
{
module_instance -> txm_module_instance_asid = i;
_txm_asid_table[i] = module_instance;
return(TX_SUCCESS);
}
}
return(TXM_MODULE_ASID_ERROR);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_remove_asid Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function removes a module from the ASID list. */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* TXM_MODULE_MANAGER_MODULE_UNLOAD */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_remove_asid(TXM_MODULE_INSTANCE *module_instance)
{
if(module_instance -> txm_module_instance_asid)
{
_txm_asid_table[module_instance -> txm_module_instance_asid] = 0;
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-A7/MMU/AC5 */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets up the Cortex-A7 MMU register definitions based */
/* on the module's memory characteristics. */
/* */
/* INPUT */
/* */
/* module_instance Pointer to module instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _txm_module_manager_assign_asid */
/* */
/* CALLED BY */
/* */
/* TXM_MODULE_MANAGER_MODULE_SETUP */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
{
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
ULONG start_address;
ULONG end_address;
ULONG mmu_l1_entries;
ULONG mmu_l2_entries = 0;
ULONG level1_index;
ULONG level2_index;
ULONG temp_index;
ULONG temp_address;
ULONG l2_address;
ULONG attributes = 0;
ULONG asid;
UINT i;
/* Assign an ASID to this module. */
_txm_module_manager_assign_asid(module_instance);
asid = module_instance -> txm_module_instance_asid;
/* Copy master level 1 page table to module's page table. */
for(i = 0; i < TXM_MASTER_PAGE_TABLE_ENTRIES; i++)
{
_txm_ttbr1_page_table[asid][i] = _txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i];
}
/* Clear level 2 tables. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][i] = 0;
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = 0;
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][i] = 0;
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = 0;
}
/* Get code start and end addresses. */
start_address = (ULONG)module_instance -> txm_module_instance_code_start;
/* Extend end address to end of page (TXM_MODULE_MEMORY_ALIGNMENT-1). */
end_address = ((((ULONG)module_instance -> txm_module_instance_code_end) + TXM_MODULE_MEMORY_ALIGNMENT-1) & ~((ULONG)TXM_MODULE_MEMORY_ALIGNMENT-1)) - 1;
/* How many level 1 table entries does code span? */
mmu_l1_entries = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1;
/* Add 1 to align. */
end_address++;
/* How many level 2 table entries does code need?
* 0: start and end addresses both aligned.
* 1: either start or end address aligned.
* 2: start and end addresses both not aligned. */
if(start_address & ~TXM_MMU_LEVEL1_MASK)
{
/* If start address is not aligned, increment. */
mmu_l2_entries++;
}
if(end_address & ~TXM_MMU_LEVEL1_MASK)
{
/* If end address is not aligned, increment. */
mmu_l2_entries++;
}
/* Get index into L1 table. */
level1_index = (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
/* Set up level 1 table. */
/* Do start and end entries need level 2 pages? */
if(mmu_l2_entries > 0)
{
/* If start_address is not aligned, we need a L2 page. */
if(start_address & ~TXM_MMU_LEVEL1_MASK)
{
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
if(_txm_ttbr1_page_table[asid][level1_index] & 0x01)
{
/* Get L2 page address from L1 table. */
l2_address = _txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_SECOND_MASK;
/* Copy the existing L2 page into the module L2 page. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
}
}
else
{
/* Translate attributes from L1 entry to an L2 entry. */
attributes = (((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
/* Build L2 page with attributes inherited from L1 entry. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
}
}
/* Put L2 page in L1 table. */
_txm_ttbr1_page_table[asid][level1_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
/* Decrement number of L1 entries remaining. */
mmu_l1_entries--;
/* Set up L2 start table. */
/* Determine how many entries in L2 table. */
if((end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT))
{
/* End address goes to next L1 page (or beyond). */
temp_address = ((start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1) << (TXM_MMU_LEVEL1_PAGE_SHIFT);
mmu_l2_entries = (temp_address - start_address) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
}
else
{
/* End address is on the same L1 page. */
mmu_l2_entries = (end_address >> TXM_MMU_LEVEL2_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL2_PAGE_SHIFT);
}
/* Insert module settings into start table. */
level2_index = ((start_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
for(i = 0; i < mmu_l2_entries; i++, level2_index++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][level2_index] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (level2_index << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_CODE_ATTRIBUTES;
}
level1_index++;
}
/* Does last entry need a level 2 page? */
/* If end_address is not aligned, we need a L2 page. */
if((end_address & ~TXM_MMU_LEVEL1_MASK) && (mmu_l1_entries != 0))
{
/* Get index into L1 table. */
temp_index = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
if(_txm_ttbr1_page_table[asid][temp_index] & 0x01)
{
/* Get L2 page address from L1 table. */
l2_address = _txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_SECOND_MASK;
/* Copy the existing L2 page into the module L2 page. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
}
}
else
{
/* Translate attributes from L1 entry to an L2 entry. */
attributes = (((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
/* Build L2 page with attributes inherited from L1 entry. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
}
}
/* Put L2 page in L1 table. */
_txm_ttbr1_page_table[asid][temp_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
/* Decrement number of L1 entries remaining. */
mmu_l1_entries--;
/* Determine how many entries in L2 table. */
mmu_l2_entries = ((end_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
/* Set up L2 end table. */
for(i = 0; i < mmu_l2_entries; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = ((ULONG)end_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_CODE_ATTRIBUTES;
}
}
}
/* Fill any L1 entries between start and end pages of module code range. */
for(i = 0; i < mmu_l1_entries; i++, level1_index++)
{
/* Place address and attributes in table. */
_txm_ttbr1_page_table[asid][level1_index] = (level1_index << TXM_MMU_LEVEL1_PAGE_SHIFT) | TXM_MMU_LEVEL1_CODE_ATTRIBUTES;
}
/**************************************************************************/
/* At this point, code protection is set up. */
/* Data protection is set up below. */
/**************************************************************************/
/* Get data start and end addresses. */
start_address = (ULONG)module_instance -> txm_module_instance_data_start;
end_address = (ULONG)module_instance -> txm_module_instance_data_end;
/* How many level 1 table entries does data span? */
mmu_l1_entries = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1;
/* Add 1 to align. */
end_address++;
/* How many level 2 table entries does data need?
* 0: start and end addresses both aligned.
* 1: either start or end address aligned.
* 2: start and end addresses both not aligned. */
if(start_address & ~TXM_MMU_LEVEL1_MASK)
{
/* If start address is not aligned, increment. */
mmu_l2_entries++;
}
if(end_address & ~TXM_MMU_LEVEL1_MASK)
{
/* If end address is not aligned, increment. */
mmu_l2_entries++;
}
/* Get index into L1 table. */
level1_index = (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
/* Set up level 1 table. */
/* Do start and end entries need level 2 pages? */
if(mmu_l2_entries > 0)
{
/* If start_address is not aligned, we need a L2 page. */
if(start_address & ~TXM_MMU_LEVEL1_MASK)
{
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
if(_txm_ttbr1_page_table[asid][level1_index] & 0x01)
{
/* Get L2 page address from L1 table. */
l2_address = _txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_SECOND_MASK;
/* Copy the existing L2 page into the module L2 page. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
}
}
else
{
/* Translate attributes from L1 entry to an L2 entry. */
attributes = (((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
/* Build L2 page with attributes inherited from L1 entry. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
}
}
/* Put L2 page in L1 table. */
_txm_ttbr1_page_table[asid][level1_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
/* Decrement number of L1 entries remaining. */
mmu_l1_entries--;
/* Set up L2 start table. */
/* Determine how many entries in L2 table. */
if((end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT))
{
/* End address goes to next L1 page (or beyond). */
temp_address = ((start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1) << (TXM_MMU_LEVEL1_PAGE_SHIFT);
mmu_l2_entries = (temp_address - start_address) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
}
else
{
/* End address is on the same L1 page. */
mmu_l2_entries = (end_address >> TXM_MMU_LEVEL2_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL2_PAGE_SHIFT);
}
/* Insert module settings into start table. */
level2_index = ((start_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
for(i = 0; i < mmu_l2_entries; i++, level2_index++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][level2_index] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (level2_index << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_DATA_ATTRIBUTES;
}
level1_index++;
}
/* Does last entry need a level 2 page? */
/* If end_address is not aligned, we need a L2 page. */
if((end_address & ~TXM_MMU_LEVEL1_MASK) && (mmu_l1_entries != 0))
{
/* Get index into L1 table. */
temp_index = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
if(_txm_ttbr1_page_table[asid][temp_index] & 0x01)
{
/* Get L2 page address from L1 table. */
l2_address = _txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_SECOND_MASK;
/* Copy the existing L2 page into the module L2 page. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
}
}
else
{
/* Translate attributes from L1 entry to an L2 entry. */
attributes = (((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
/* Build L2 page with attributes inherited from L1 entry. */
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
}
}
/* Put L2 page in L1 table. */
_txm_ttbr1_page_table[asid][temp_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
/* Decrement number of L1 entries remaining. */
mmu_l1_entries--;
/* Determine how many entries in L2 table. */
mmu_l2_entries = ((end_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
/* Set up L2 end table. */
for(i = 0; i < mmu_l2_entries; i++)
{
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = ((ULONG)end_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_DATA_ATTRIBUTES;
}
}
}
/* Fill any L1 entries between start and end pages of module data range. */
for(i = 0; i < mmu_l1_entries; i++, level1_index++)
{
/* Place address and attributes in table. */
_txm_ttbr1_page_table[asid][level1_index] = (level1_index << TXM_MMU_LEVEL1_PAGE_SHIFT) | TXM_MMU_LEVEL1_DATA_ATTRIBUTES;
}
#endif
}

View File

@@ -0,0 +1,160 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/** Module Manager */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
;
;#define TX_SOURCE_CODE
;
;
;/* Include necessary system files. */
;
;#include "tx_api.h"
;#include "tx_thread.h"
;
;
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR
USR_MODE EQU 0x10 ; USR mode
SYS_MODE EQU 0x1F ; SYS 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 */
;/* */
;/* _txm_module_manager_thread_stack_build Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, 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 */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
;VOID _txm_module_manager_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(TX_THREAD *, TXM_MODULE_INSTANCE *))
;{
EXPORT _txm_module_manager_thread_stack_build
_txm_module_manager_thread_stack_build
;
;
; /* Build a fake interrupt frame. The form of the fake interrupt stack
; on the Cortex-A7 should look like the following after it is built:
;
; Stack Top: 1 Interrupt stack frame type
; CPSR Initial value for CPSR
; r0 Initial value for r0
; r1 Initial value for r1
; r2 Initial value for r2
; r3 Initial value for r3
; r4 Initial value for r4
; r5 Initial value for r5
; r6 Initial value for r6
; r7 Initial value for r7
; r8 Initial value for r8
; r9 Initial value for r9
; r10 Initial value for r10
; r11 Initial value for r11
; r12 Initial value for r12
; lr Initial value for lr (r14)
; pc Initial value for pc (r15)
; 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
STR r0, [r2, #8] ; Store initial r0 (thread pointer)
LDR r3, [r0, #8] ; Pickup thread info pointer (it's in the stack pointer location right now)
STR r3, [r2, #12] ; Store initial r1
LDR r3, [r3, #8] ; Pickup data base register
STR r3, [r2, #44] ; Store initial r9
MOV r3, #0 ; Build initial register value
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
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 r3, CPSR ; Pickup CPSR
BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR
TST r1, #1 ; Test if THUMB bit set in initial PC
ORRNE r3, r3, #THUMB_MASK ; Set T bit if set
LDR r1, [r0, #156] ; Load tx_thread_module_current_user_mode
TST r1, #1 ; Test if the flag is set
ORREQ r3, r3, #SYS_MODE ; Flag not set: Build CPSR, SYS mode, IRQ enabled
ORRNE r3, r3, #USR_MODE ; Flag set: Build CPSR, USR mode, IRQ 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
BX lr ; Return to caller
;}
END

View File

@@ -0,0 +1,92 @@
;/**************************************************************************/
;/* */
;/* 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 */
;/** */
;/** Module Manager */
;/** */
;/**************************************************************************/
;/**************************************************************************/
;
IMPORT _tx_thread_current_ptr
IMPORT _txm_module_manager_kernel_dispatch
AREA ||.text||, CODE, READONLY, ALIGN=12
PRESERVE8
;/**************************************************************************/
;/* */
;/* FUNCTION RELEASE */
;/* */
;/* _txm_module_manager_user_mode_entry Cortex-A7/MMU/AC5 */
;/* 6.1 */
;/* AUTHOR */
;/* */
;/* Scott Larson, Microsoft Corporation */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function allows modules to enter kernel mode. */
;/* */
;/* INPUT */
;/* */
;/* None */
;/* */
;/* OUTPUT */
;/* */
;/* None */
;/* */
;/* CALLS */
;/* */
;/* SVC 1 Enter kernel mode */
;/* SVC 2 Exit kernel mode */
;/* */
;/* CALLED BY */
;/* */
;/* Modules in user mode */
;/* */
;/* RELEASE HISTORY */
;/* */
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
;/* */
;/**************************************************************************/
EXPORT _txm_module_manager_user_mode_entry
EXPORT _txm_system_mode_enter
_txm_module_manager_user_mode_entry
_txm_system_mode_enter
SVC 1 ; Get out of user mode
_txm_module_priv
; At this point, we are in system mode.
; Save LR (and r3 for 8 byte aligned stack) and call the kernel dispatch function.
PUSH {r3, lr}
BL _txm_module_manager_kernel_dispatch
POP {r3, lr}
EXPORT _txm_system_mode_exit
_txm_system_mode_exit
; Trap to restore user mode while inside of ThreadX
SVC 2
BX lr ; Return to the caller
NOP
NOP
; Fill up 4kB page.
ALIGN 4096
_txm_module_manager_user_mode_end
END