Azure RTOSでRXマイコンが使えるようになったのですね

こんにちは。NoMaYです。

Azure RTOSでRXマイコンが使えるようになったのですね。コンパイラはGNURXが使われていました。

Getting started with the Renesas Starter Kit+ for RX65N-2MB (英文です。)
02/05/2021 Ryan Winter
docs.microsoft.com/ja-jp/samples/azure-rtos/getting-started/getting-started-with-the-renesas-starter-kit-for-rx65n-2mb/
 

  • カーネル内でTX_DISABLEをgrepしてみると以下の通りでした。やはりそれなりにあちらこちらにありますね。

    続く。

    カーネル内でTX_DISABLEをgrep (カーネル内ということでlibs/threadx/フォルダ内のみです)

    libs/threadx/common/inc/tx_thread.h(228):         TX_DISABLE                                                                                                              /
    libs/threadx/common/inc/tx_thread.h(241):                 TX_DISABLE                                                                                                      /
    libs/threadx/common/inc/tx_thread.h(247):                 TX_DISABLE                                                                                                      /
    libs/threadx/common/src/txe_block_pool_create.c(121):         TX_DISABLE
    libs/threadx/common/src/txe_block_pool_create.c(148):         TX_DISABLE
    libs/threadx/common/src/txe_byte_pool_create.c(119):         TX_DISABLE
    libs/threadx/common/src/txe_byte_pool_create.c(147):         TX_DISABLE
    libs/threadx/common/src/txe_event_flags_create.c(116):         TX_DISABLE
    libs/threadx/common/src/txe_event_flags_create.c(144):         TX_DISABLE
    libs/threadx/common/src/txe_mutex_create.c(117):         TX_DISABLE
    libs/threadx/common/src/txe_mutex_create.c(145):         TX_DISABLE
    libs/threadx/common/src/txe_queue_create.c(119):         TX_DISABLE
    libs/threadx/common/src/txe_queue_create.c(147):         TX_DISABLE
    libs/threadx/common/src/txe_semaphore_create.c(116):         TX_DISABLE
    libs/threadx/common/src/txe_semaphore_create.c(144):         TX_DISABLE
    libs/threadx/common/src/txe_thread_create.c(132):         TX_DISABLE
    libs/threadx/common/src/txe_thread_create.c(202):         TX_DISABLE
    libs/threadx/common/src/txe_timer_create.c(122):         TX_DISABLE
    libs/threadx/common/src/txe_timer_create.c(150):         TX_DISABLE
    libs/threadx/common/src/tx_block_allocate.c(106):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_cleanup.c(94):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_cleanup.c(201):                             TX_DISABLE
    libs/threadx/common/src/tx_block_pool_create.c(153):         TX_DISABLE
    libs/threadx/common/src/tx_block_pool_delete.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_delete.c(156):         TX_DISABLE
    libs/threadx/common/src/tx_block_pool_delete.c(195):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_info_get.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_performance_info_get.c(112):         TX_DISABLE
    libs/threadx/common/src/tx_block_pool_performance_system_info_get.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_prioritize.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_block_pool_prioritize.c(162):             TX_DISABLE
    libs/threadx/common/src/tx_block_release.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_byte_allocate.c(110):     TX_DISABLE
    libs/threadx/common/src/tx_byte_allocate.c(179):         TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_cleanup.c(94):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_cleanup.c(200):                             TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_create.c(147):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_delete.c(94):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_delete.c(160):         TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_delete.c(199):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_info_get.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_performance_info_get.c(121):         TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_performance_system_info_get.c(98):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_prioritize.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_prioritize.c(162):             TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_search.c(106):     TX_DISABLE
    libs/threadx/common/src/tx_byte_pool_search.c(261):             TX_DISABLE
    libs/threadx/common/src/tx_byte_release.c(106):     TX_DISABLE
    libs/threadx/common/src/tx_byte_release.c(240):                 TX_DISABLE
    libs/threadx/common/src/tx_byte_release.c(328):                         TX_DISABLE
    libs/threadx/common/src/tx_event_flags_cleanup.c(95):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_cleanup.c(225):                             TX_DISABLE
    libs/threadx/common/src/tx_event_flags_create.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_delete.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_delete.c(156):         TX_DISABLE
    libs/threadx/common/src/tx_event_flags_delete.c(195):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_get.c(108):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_get.c(386):                 TX_DISABLE
    libs/threadx/common/src/tx_event_flags_info_get.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_performance_info_get.c(113):         TX_DISABLE
    libs/threadx/common/src/tx_event_flags_performance_system_info_get.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_set.c(114):     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_set.c(312):                     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_set.c(355):                     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_set.c(554):                     TX_DISABLE
    libs/threadx/common/src/tx_event_flags_set.c(580):                 TX_DISABLE
    libs/threadx/common/src/tx_event_flags_set_notify.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_misra.c(280):     TX_DISABLE
    libs/threadx/common/src/tx_misra.c(293):             TX_DISABLE
    libs/threadx/common/src/tx_misra.c(299):             TX_DISABLE
    libs/threadx/common/src/tx_mutex_cleanup.c(94):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_cleanup.c(202):                             TX_DISABLE
    libs/threadx/common/src/tx_mutex_cleanup.c(271):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_cleanup.c(304):             TX_DISABLE
    libs/threadx/common/src/tx_mutex_create.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_delete.c(94):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_delete.c(177):         TX_DISABLE
    libs/threadx/common/src/tx_mutex_delete.c(192):         TX_DISABLE
    libs/threadx/common/src/tx_mutex_delete.c(231):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_get.c(92):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_info_get.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_performance_info_get.c(118):         TX_DISABLE
    libs/threadx/common/src/tx_mutex_performance_system_info_get.c(95):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_prioritize.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_prioritize.c(165):             TX_DISABLE
    libs/threadx/common/src/tx_mutex_priority_change.c(110):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_priority_change.c(206):         TX_DISABLE
    libs/threadx/common/src/tx_mutex_priority_change.c(241):         TX_DISABLE
    libs/threadx/common/src/tx_mutex_put.c(104):     TX_DISABLE
    libs/threadx/common/src/tx_mutex_put.c(296):                             TX_DISABLE
    libs/threadx/common/src/tx_mutex_put.c(355):                                 TX_DISABLE
    libs/threadx/common/src/tx_mutex_put.c(396):                             TX_DISABLE
    libs/threadx/common/src/tx_mutex_put.c(604):                                     TX_DISABLE
    libs/threadx/common/src/tx_queue_cleanup.c(94):     TX_DISABLE
    libs/threadx/common/src/tx_queue_cleanup.c(213):                             TX_DISABLE
    libs/threadx/common/src/tx_queue_create.c(120):     TX_DISABLE
    libs/threadx/common/src/tx_queue_delete.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_queue_delete.c(155):         TX_DISABLE
    libs/threadx/common/src/tx_queue_delete.c(194):     TX_DISABLE
    libs/threadx/common/src/tx_queue_flush.c(92):     TX_DISABLE
    libs/threadx/common/src/tx_queue_flush.c(159):             TX_DISABLE
    libs/threadx/common/src/tx_queue_flush.c(192):         TX_DISABLE
    libs/threadx/common/src/tx_queue_front_send.c(102):     TX_DISABLE
    libs/threadx/common/src/tx_queue_info_get.c(88):     TX_DISABLE
    libs/threadx/common/src/tx_queue_performance_info_get.c(114):         TX_DISABLE
    libs/threadx/common/src/tx_queue_performance_system_info_get.c(95):     TX_DISABLE
    libs/threadx/common/src/tx_queue_prioritize.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_queue_prioritize.c(162):             TX_DISABLE
    libs/threadx/common/src/tx_queue_receive.c(101):     TX_DISABLE
    libs/threadx/common/src/tx_queue_receive.c(283):                 TX_DISABLE
    libs/threadx/common/src/tx_queue_send.c(102):     TX_DISABLE
    libs/threadx/common/src/tx_queue_send_notify.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_ceiling_put.c(97):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_cleanup.c(95):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_cleanup.c(203):                             TX_DISABLE
    libs/threadx/common/src/tx_semaphore_create.c(92):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_delete.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_delete.c(156):         TX_DISABLE
    libs/threadx/common/src/tx_semaphore_delete.c(195):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_get.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_info_get.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_performance_info_get.c(112):         TX_DISABLE
    libs/threadx/common/src/tx_semaphore_performance_system_info_get.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_prioritize.c(90):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_prioritize.c(162):             TX_DISABLE
    libs/threadx/common/src/tx_semaphore_put.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_semaphore_put_notify.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_thread_create.c(219):     TX_DISABLE
    libs/threadx/common/src/tx_thread_create.c(360):         TX_DISABLE
    libs/threadx/common/src/tx_thread_delete.c(88):     TX_DISABLE
    libs/threadx/common/src/tx_thread_entry_exit_notify.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_thread_identify.c(85):     TX_DISABLE
    libs/threadx/common/src/tx_thread_info_get.c(92):     TX_DISABLE
    libs/threadx/common/src/tx_thread_performance_info_get.c(130):         TX_DISABLE
    libs/threadx/common/src/tx_thread_performance_system_info_get.c(112):     TX_DISABLE
    libs/threadx/common/src/tx_thread_preemption_change.c(114):     TX_DISABLE
    libs/threadx/common/src/tx_thread_preemption_change.c(270):                     TX_DISABLE
    libs/threadx/common/src/tx_thread_priority_change.c(100):     TX_DISABLE
    libs/threadx/common/src/tx_thread_priority_change.c(234):         TX_DISABLE
    libs/threadx/common/src/tx_thread_relinquish.c(97):     TX_DISABLE
    libs/threadx/common/src/tx_thread_reset.c(88):     TX_DISABLE
    libs/threadx/common/src/tx_thread_reset.c(144):         TX_DISABLE
    libs/threadx/common/src/tx_thread_resume.c(111):     TX_DISABLE
    libs/threadx/common/src/tx_thread_resume.c(191):         TX_DISABLE
    libs/threadx/common/src/tx_thread_shell_entry.c(96):     TX_DISABLE
    libs/threadx/common/src/tx_thread_shell_entry.c(128):     TX_DISABLE
    libs/threadx/common/src/tx_thread_sleep.c(84):     TX_DISABLE
    libs/threadx/common/src/tx_thread_stack_analyze.c(85):     TX_DISABLE
    libs/threadx/common/src/tx_thread_stack_analyze.c(149):                     TX_DISABLE
    libs/threadx/common/src/tx_thread_stack_error_handler.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_thread_stack_error_handler.c(113):         TX_DISABLE
    libs/threadx/common/src/tx_thread_stack_error_notify.c(117):     TX_DISABLE
    libs/threadx/common/src/tx_thread_suspend.c(91):     TX_DISABLE
    libs/threadx/common/src/tx_thread_suspend.c(165):             TX_DISABLE
    libs/threadx/common/src/tx_thread_suspend.c(244):     TX_DISABLE
    libs/threadx/common/src/tx_thread_suspend.c(564):                     TX_DISABLE
    libs/threadx/common/src/tx_thread_suspend.c(808):             TX_DISABLE
    libs/threadx/common/src/tx_thread_system_resume.c(112):     TX_DISABLE
    libs/threadx/common/src/tx_thread_system_resume.c(552):     TX_DISABLE
    libs/threadx/common/src/tx_thread_system_suspend.c(121):     TX_DISABLE
    libs/threadx/common/src/tx_thread_system_suspend.c(429):                 TX_DISABLE
    libs/threadx/common/src/tx_thread_system_suspend.c(660):     TX_DISABLE
    libs/threadx/common/src/tx_thread_terminate.c(97):     TX_DISABLE
    libs/threadx/common/src/tx_thread_terminate.c(192):             TX_DISABLE
    libs/threadx/common/src/tx_thread_terminate.c(239):             TX_DISABLE
    libs/threadx/common/src/tx_thread_terminate.c(268):             TX_DISABLE
    libs/threadx/common/src/tx_thread_terminate.c(290):         TX_DISABLE
    libs/threadx/common/src/tx_thread_timeout.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_thread_time_slice.c(106):     TX_DISABLE
    libs/threadx/common/src/tx_thread_time_slice_change.c(87):     TX_DISABLE
    libs/threadx/common/src/tx_thread_wait_abort.c(87):     TX_DISABLE
    libs/threadx/common/src/tx_thread_wait_abort.c(219):             TX_DISABLE
    libs/threadx/common/src/tx_timer_activate.c(83):     TX_DISABLE
    libs/threadx/common/src/tx_timer_change.c(82):     TX_DISABLE
    libs/threadx/common/src/tx_timer_create.c(100):     TX_DISABLE
    libs/threadx/common/src/tx_timer_deactivate.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_timer_delete.c(82):     TX_DISABLE
    libs/threadx/common/src/tx_timer_expiration_process.c(112):     TX_DISABLE
    libs/threadx/common/src/tx_timer_expiration_process.c(140):     TX_DISABLE
    libs/threadx/common/src/tx_timer_expiration_process.c(196):                 TX_DISABLE
    libs/threadx/common/src/tx_timer_expiration_process.c(361):                     TX_DISABLE
    libs/threadx/common/src/tx_timer_info_get.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_timer_performance_info_get.c(115):         TX_DISABLE
    libs/threadx/common/src/tx_timer_performance_system_info_get.c(93):     TX_DISABLE
    libs/threadx/common/src/tx_timer_thread_entry.c(114):             TX_DISABLE
    libs/threadx/common/src/tx_timer_thread_entry.c(146):             TX_DISABLE
    libs/threadx/common/src/tx_timer_thread_entry.c(311):                 TX_DISABLE
    libs/threadx/common/src/tx_timer_thread_entry.c(424):                 TX_DISABLE
    libs/threadx/common/src/tx_time_get.c(87):     TX_DISABLE
    libs/threadx/common/src/tx_time_set.c(80):     TX_DISABLE
    libs/threadx/common/src/tx_trace_enable.c(223):         TX_DISABLE
    libs/threadx/common/src/tx_trace_enable.c(383):         TX_DISABLE
    libs/threadx/common/src/tx_trace_interrupt_control.c(82):     TX_DISABLE
    libs/threadx/common/src/tx_trace_isr_enter_insert.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_trace_isr_enter_insert.c(105):         TX_DISABLE
    libs/threadx/common/src/tx_trace_isr_exit_insert.c(89):     TX_DISABLE
    libs/threadx/common/src/tx_trace_isr_exit_insert.c(105):         TX_DISABLE
    libs/threadx/common/src/tx_trace_object_register.c(293):                         TX_DISABLE
    libs/threadx/common/src/tx_trace_object_unregister.c(128):         TX_DISABLE
    libs/threadx/common/src/tx_trace_user_event_insert.c(86):     TX_DISABLE
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(243): #define TX_DISABLE                              interrupt_save =  _tx_thread_interrupt_disable();
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(265): #define TX_BLOCK_POOL_DISABLE                   TX_DISABLE
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(266): #define TX_BYTE_POOL_DISABLE                    TX_DISABLE
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(267): #define TX_EVENT_FLAGS_GROUP_DISABLE            TX_DISABLE
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(268): #define TX_MUTEX_DISABLE                        TX_DISABLE
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(269): #define TX_QUEUE_DISABLE                        TX_DISABLE
    libs/threadx/ports/rxv3/ccrx/inc/tx_port.h(270): #define TX_SEMAPHORE_DISABLE                    TX_DISABLE
    libs/threadx/utility/low_power/tx_low_power.c(96):     TX_DISABLE
    libs/threadx/utility/low_power/tx_low_power.c(300):     TX_DISABLE
    libs/threadx/utility/low_power/tx_low_power.c(431):     TX_DISABLE

     

  • 試しに libs/threadx/common/src/tx_semaphore_get.c を覗いてみました。やはり割り込み禁止にした状態でゴソゴソそれなりにやっていることがありますね。

    続く。

    libs/threadx/common/src/tx_semaphore_get.c (正直なところ何をやっているのかは分かりません)

    UINT  _tx_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option)
    {

    TX_INTERRUPT_SAVE_AREA

    TX_THREAD       *thread_ptr;
    TX_THREAD       *next_thread;
    TX_THREAD       *previous_thread;
    UINT            status;


        /* Default the status to TX_SUCCESS.  */
        status =  TX_SUCCESS;

        /* Disable interrupts to get an instance from the semaphore.  */
        TX_DISABLE

    #ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO

        /* Increment the total semaphore get counter.  */
        _tx_semaphore_performance_get_count++;

        /* Increment the number of attempts to get this semaphore.  */
        semaphore_ptr -> tx_semaphore_performance_get_count++;
    #endif

        /* If trace is enabled, insert this event into the trace buffer.  */
        TX_TRACE_IN_LINE_INSERT(TX_TRACE_SEMAPHORE_GET, semaphore_ptr, wait_option, semaphore_ptr -> tx_semaphore_count, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), TX_TRACE_SEMAPHORE_EVENTS)

        /* Log this kernel call.  */
        TX_EL_SEMAPHORE_GET_INSERT

        /* Determine if there is an instance of the semaphore.  */
        if (semaphore_ptr -> tx_semaphore_count != ((ULONG) 0))
        {

            /* Decrement the semaphore count.  */
            semaphore_ptr -> tx_semaphore_count--;

            /* Restore interrupts.  */
            TX_RESTORE
        }

        /* Determine if the request specifies suspension.  */
        else if (wait_option != TX_NO_WAIT)
        {

            /* Determine if the preempt disable flag is non-zero.  */
            if (_tx_thread_preempt_disable != ((UINT) 0))
            {

                /* Restore interrupts.  */
                TX_RESTORE

                /* Suspension is not allowed if the preempt disable flag is non-zero at this point - return error completion.  */
                status =  TX_NO_INSTANCE;
            }
            else
            {

                /* Prepare for suspension of this thread.  */

    #ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO

                /* Increment the total semaphore suspensions counter.  */
                _tx_semaphore_performance_suspension_count++;

                /* Increment the number of suspensions on this semaphore.  */
                semaphore_ptr -> tx_semaphore_performance_suspension_count++;
    #endif

                /* Pickup thread pointer.  */
                TX_THREAD_GET_CURRENT(thread_ptr)

                /* Setup cleanup routine pointer.  */
                thread_ptr -> tx_thread_suspend_cleanup =  &(_tx_semaphore_cleanup);

                /* Setup cleanup information, i.e. this semaphore control
                   block.  */
                thread_ptr -> tx_thread_suspend_control_block =  (VOID *) semaphore_ptr;

    #ifndef TX_NOT_INTERRUPTABLE

                /* Increment the suspension sequence number, which is used to identify
                   this suspension event.  */
                thread_ptr -> tx_thread_suspension_sequence++;
    #endif

                /* Setup suspension list.  */
                if (semaphore_ptr -> tx_semaphore_suspended_count == TX_NO_SUSPENSIONS)
                {

                    /* No other threads are suspended.  Setup the head pointer and
                       just setup this threads pointers to itself.  */
                    semaphore_ptr -> tx_semaphore_suspension_list =         thread_ptr;
                    thread_ptr -> tx_thread_suspended_next =                thread_ptr;
                    thread_ptr -> tx_thread_suspended_previous =            thread_ptr;
                }
                else
                {

                    /* This list is not NULL, add current thread to the end. */
                    next_thread =                                   semaphore_ptr -> tx_semaphore_suspension_list;
                    thread_ptr -> tx_thread_suspended_next =        next_thread;
                    previous_thread =                               next_thread -> tx_thread_suspended_previous;
                    thread_ptr -> tx_thread_suspended_previous =    previous_thread;
                    previous_thread -> tx_thread_suspended_next =   thread_ptr;
                    next_thread -> tx_thread_suspended_previous =   thread_ptr;
                }

                /* Increment the number of suspensions.  */
                semaphore_ptr -> tx_semaphore_suspended_count++;

                /* Set the state to suspended.  */
                thread_ptr -> tx_thread_state =    TX_SEMAPHORE_SUSP;

    #ifdef TX_NOT_INTERRUPTABLE

                /* Call actual non-interruptable thread suspension routine.  */
                _tx_thread_system_ni_suspend(thread_ptr, wait_option);

                /* Restore interrupts.  */
                TX_RESTORE
    #else

                /* Set the suspending flag.  */
                thread_ptr -> tx_thread_suspending =  TX_TRUE;

                /* Setup the timeout period.  */
                thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks =  wait_option;

                /* Temporarily disable preemption.  */
                _tx_thread_preempt_disable++;

                /* Restore interrupts.  */
                TX_RESTORE

                /* Call actual thread suspension routine.  */
                _tx_thread_system_suspend(thread_ptr);
    #endif

                /* Return the completion status.  */
                status =  thread_ptr -> tx_thread_suspend_status;
            }
        }
        else
        {

            /* Restore interrupts.  */
            TX_RESTORE

            /* Immediate return, return error completion.  */
            status =  TX_NO_INSTANCE;
        }

        /* Return completion status.  */
        return(status);
    }

     

  • 今度はTick割り込みとContext Switching割り込みを覗いてみました。割り込みルーチン先頭で割り込み許可にしているわけではありませんでした。(なお、Context Switching割り込みは、あくまでContext Switchingする処理なので、例えば、ユーザがセマフォを操作して、RTOSがセマフォを制御して、RTOSがタスクの優先度を変化させて、RTOSがタスクを実行可能状態へ遷移させ、RTOSが実行可能タスクのリストに追加して、といった処理の流れの部分は含んで無いです。)

    続く。

    libs/threadx/ports/rxv3/ccrx/src/tx_timer_interrupt.src (FITのCMTモジュールと結合する都合によりサブルーチンです)

    ;VOID   _tx_timer_interrupt(VOID)
    ;{
        .GLB __tx_timer_interrupt
    __tx_timer_interrupt:
    ;
    ;    /* Upon entry to this routine, it is assumed that all interrupts are locked
    ;       out and the stack looks like the following:
    ;                            SP+4 ->   Interrupted PC
    ;                            SP+8->    Interrupted SR
    ;   */
    ;
    ;    /* Increment the system clock.  */
    ;    _tx_timer_system_clock++;
    ;
        PUSHM    R14-R15
        PUSHM    R1-R5

        MOV.L    #__tx_timer_system_clock, R1       ; Pickup address of system clock
        MOV.L    [R1], R2                           ; Pickup system clock
        ADD      #1, R2                             ; Increment system clock
        MOV.L    R2,[R1]                            ; Store new system clock
    ;
    ;    /* Test for time-slice expiration.  */
    ;    if (_tx_timer_time_slice)
    ;    {
    ;
        MOV.L   #__tx_timer_time_slice, R1          ; Pickup address of time slice
        MOV.L   [R1], R2                            ; Pickup the current time slice
        CMP     #0, R2                              ; Is a time slice active?
        BEQ     __tx_timer_no_time_slice            ; No, skip timer slice processing
    ;
    ;       /* Decrement the time_slice.  */
    ;       _tx_timer_time_slice--;
    ;
        SUB     #1, R2                              ; Decrement the time-slice
        MOV.L   R2, [R1]                            ; Store time-slice
    ;
    ;       /* Check for expiration.  */
    ;       if (__tx_timer_time_slice == 0)
    ;
        CMP     #0, R2                              ; Has it expired?
        BNE     __tx_timer_no_time_slice            ; No, time-slice has not expired
    ;
    ;       /* Set the time-slice expired flag.  */
    ;       _tx_timer_expired_time_slice =  TX_TRUE;
    ;
        MOV.L   #__tx_timer_expired_time_slice, R1  ; Pickup address of expired time-slice
        MOV.L   #1, R2                              ; Build expired value
        MOV.L   R2, [R1]                            ; Set expired time slice variable
    ;    }
    ;
    __tx_timer_no_time_slice:
    ;
    ;    /* Test for timer expiration.  */
    ;    if (*_tx_timer_current_ptr)
    ;    {
    ;
        MOV.L   #__tx_timer_current_ptr, R1         ; Pickup address of current timer ptr
        MOV.L   [R1], R2                            ; Pickup current pointer
        MOV.L   [R2+], R1                           ; Pickup timer list entry, _tx_timer_current_ptr++
        CMP     #0, R1                              ; Is timer pointer NULL?
        BEQ     __tx_timer_no_timer                 ; Yes, no timer has expired
            
    ;
    ;        /* Set expiration flag.  */
    ;        _tx_timer_expired =  TX_TRUE;
    ;
        MOV.L   #__tx_timer_expired,R2              ; Build address of expired flag
        MOV.L   #1, R1                              ; Build expired value
        MOV.L   R1, [R2]    
        BRA     __tx_timer_done                     ; Finished with timer processing
    ;
    ;    }
    ;    else
    ;    {
    __tx_timer_no_timer:
    ;
    ;        /* No timer expired, increment the timer pointer.  */
    ;        _tx_timer_current_ptr++;
    ;
    ;       /* R2 already contains __tx_timer_current_ptr++ */                         
    ;
    ;        /* Check for wrap-around.  */
    ;        if (_tx_timer_current_ptr == _tx_timer_list_end)
    ;
        MOV.L   #__tx_timer_list_end, R1            ; Pickup the timer list end ptr
        MOV.L   [R1], R1                            ; Pickup actual timer list end
        CMP     R1, R2                              ; Are we at list end?
        BNE     __tx_timer_skip_wrap                ; No, don't move pointer to the
                                                    ;   top of the list
    ;
    ;            /* Wrap to beginning of list.  */
    ;            _tx_timer_current_ptr =  _tx_timer_list_start;
    ;
        MOV.L   #__tx_timer_list_start, R2          ; Pickup the timer list start ptr
        MOV.L   [R2], R2                            ; Pickup the start of the list
    ;    }
    ;
    __tx_timer_skip_wrap:
        MOV.L   #__tx_timer_current_ptr,R1     
        MOV.L   R2, [R1]                            ; Store in updated pointer in  _tx_timer_current_ptr  
        
    __tx_timer_done:
    ;
    ;    /* See if anything has expired.  */
    ;    if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
    ;    {
    ;
        MOV.L  #__tx_timer_expired_time_slice, R1   ; Pickup expired time slice addr
        MOV.L  [R1], R1                             ; Pickup expired time slice
        MOV.L   #__tx_timer_expired, R2             ; Pickup expired timer flag address
        MOV.L   [R2], R2                            ; Pickup actual flag
        OR      R1, R2                              ; Or flags together
        BEQ     __tx_timer_nothing_expired          ; If Z set, nothing has expired

    __tx_something_expired:
    ;    /* Did a timer expire?  */
    ;    if (_tx_timer_expired)
    ;    {
        MOV.L   #__tx_timer_expired,R1              ; Pickup expired flag address
        MOV.L   [R1], R1                            ; Pickup expired flag
        CMP     #0,R1                               ; Is the expired timer flag set?
        BEQ     __tx_timer_dont_activate            ; No, skip timer activation
    ;
    ;        /* Process timer expiration.  */
    ;        _tx_timer_expiration_process();
    ;
        BSR    __tx_timer_expiration_process        ; Call the timer expiration handling routine
    ;
    ;    }
    __tx_timer_dont_activate:
    ;
    ;    /* Did time slice expire?  */
    ;    if (_tx_timer_expired_time_slice)
    ;    {
    ;
        MOV.L   #__tx_timer_expired_time_slice, R1  ; Pickup time-slice expired flag addr
        MOV.L   [R1], R1                            ; Pickup actual flag
        CMP     #0,R1                               ; Has time-slice expired?
        BEQ      __tx_timer_not_ts_expiration       ; No, skip time-slice expiration
    ;
    ;        /* Time slice interrupted thread.  */
    ;        _tx_thread_time_slice();

        BSR     __tx_thread_time_slice              ; Call time-slice processing

    ;   /* Check if we must trigger a context switch. */
        MOV.L   #__tx_thread_preempt_disable, R1     ; Load prempt disable flag.
        MOV.L  [R1], R1
        CMP    #0, R1
        BNE    __tx_timer_not_ts_expiration          ; Skip if prempt disabled.

        MOV.L   #__tx_thread_execute_ptr, R1
        MOV.L  [R1], R1
        MOV.L   #__tx_thread_current_ptr, R2
        MOV.L  [R2], R2
        CMP    R1, R2
        BEQ    __tx_timer_not_ts_expiration

        MOV.L   #SWI0, R1
        MOV.L   #1, [R1]

    ;    }
    ;
    __tx_timer_not_ts_expiration:

    __tx_timer_nothing_expired:

        POPM R1-R5
        POPM R14-R15
    ;
        RTS                                         ; Return to point of interrupt
    ;
    ;}

     
    src/hardware_setup.c (FITのCMTモジュールと結合する都合によりコールバックルーチンです)

    /* CMT Timer callback used as the system tick. */
    void timer_callback(void * pdata)
    {
        _tx_timer_interrupt();
    }

    void platform_setup(void)
    {
        uint32_t chan;

        /* Create periodic timer for the system tick. */
        R_CMT_CreatePeriodic(TX_TIMER_TICKS_PER_SECOND, timer_callback, &chan);
        
    }

     
    libs/threadx/ports/rxv3/ccrx/src/tx_thread_schedule.src (こちらは割り込みルーチンです)

    ; Software triggered interrupt used to perform context switches.
    ; The priority of this interrupt is set to the lowest priority within
    ; tx_initialize_low_level() and triggered by ThreadX when calling
    ; _tx_thread_system_return().
    .RVECTOR 27, _tx_software_interrupt_entry
    .GLB _tx_software_interrupt_entry
    _tx_software_interrupt_entry:

        PUSHM R1-R2

        BSR __tx_thread_context_save

        BRA __tx_thread_context_restore

     

  • libs/threadx/ports/rxv3/ccrx/src/tx_thread_contex_save.src

    ;VOID   _tx_thread_context_save(VOID)
    ;{
        .GLB __tx_thread_context_save
    __tx_thread_context_save:
    ;
    ;    /* Upon entry to this routine, it is assumed that interrupts are locked
    ;       out and the (interrupt) stack frame looks like the following:
    ;
    ;           (lower address) SP   ->     [return address of this call]
    ;                           SP+4 ->     Saved R1
    ;                           SP+8 ->     Saved R2
    ;                           SP+12->     Interrupted PC
    ;                           SP+16->     Interrupted PSW
    ;
    ;    /* Check for a nested interrupt condition.  */
    ;    if (_tx_thread_system_state++)
    ;    {
    ;

        MOV.L   #__tx_thread_system_state, R1       ; Pick up address of system state
        MOV.L   [R1], R2                            ; Pick up system state
        CMP     #0, R2                              ; 0 -> no nesting
        BEQ     __tx_thread_not_nested_save
    ;
    ;    /* Nested interrupt condition.  */
    ;   
        ADD   #1, r2                                ; _tx_thread_system_state++
        MOV.L   r2, [r1]

    ;
    ;   /* Save the rest of the scratch registers on the interrupt stack and return to the
    ;       calling ISR.  */
        POP R1                                      ; Recuperate return address from stack
        PUSHM   R3-R5
        PUSHM   R14-R15
        PUSHC   FPSW                                ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
        JMP     R1                                  ; Return address was preserved in R1

    ;
    __tx_thread_not_nested_save:
    ;    }
    ;
    ;    /* Otherwise, not nested, check to see if a thread was running.  */
    ;    else if (_tx_thread_current_ptr)
    ;    {
    ;
        ADD     #1, R2                              ; _tx_thread_system_state++
        MOV.L   R2, [R1]

        MOV.L   #__tx_thread_current_ptr, R2        ; Pickup current thread pointer
        MOV.L   [R2], R2
        CMP     #0,R2                               ; Is it NULL?  
        BEQ      __tx_thread_idle_system_save       ; Yes, idle system is running - idle restore
    ;
    ;    /* Move stack frame over to the current threads stack.  */
    ;    /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW)   */
    ;
        MVFC    USP, R1                             ; Pick up user stack pointer
        MOV.L   16[R0], R2
        MOV.L   R2, [-R1]                           ; Save PSW on thread stack
        MOV.L   12[R0], R2
        MOV.L   R2, [-R1]                           ; Save PC on thread stack
        MOV.L   8[R0], R2
        MOV.L   R2, [-R1]                           ; Save R2 on thread stack
        MOV.L   4[R0], R2
        MOV.L   R2, [-R1]                           ; Save R1 on thread stack
        MOV.L   R5, [-R1]                           ; Save R5 on thread stack
        MOV.L   R4, [-R1]                           ; Save R4 on thread stack
        MOV.L   R3, [-R1]                           ; Save R3 on thread stack
        MOV.L   R15, [-R1]                          ; Save R15 on thread stack
        MOV.L   R14, [-R1]                          ; Save R14 on thread stack
        MVFC    FPSW, R3
        MOV.L   R3, [-R1]                           ; Save FPSW on thread stack
        
        POP     R2                                  ; Pick up return address from interrupt stack
        ADD     #16, R0, R0                         ; Correct interrupt stack pointer back to the bottom   
        MVTC    R1, USP                             ; Set user/thread stack pointer
        JMP     R2                                  ; Return to ISR

    ;    }
    ;    else
    ;    {
    ;
    __tx_thread_idle_system_save:
    ;
    ;        /* Interrupt occurred in the scheduling loop.  */
    ;
        POP     R1                                  ; Pick up return address
        ADD     #16, R0, R0                         ; Correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
        JMP     R1                                  ; Return to caller
    ;
    ;    }
    ;}

     
    libs/threadx/ports/rxv3/ccrx/src/tx_thread_contex_restore.src

    ;VOID   _tx_thread_context_restore(VOID)
    ;{
        .GLB __tx_thread_context_restore
    __tx_thread_context_restore:
    ;
    ;    /* Lockout interrupts.  */

         CLRPSW I                                   ; Disable interrupts

    ;    /* Determine if interrupts are nested.  */
    ;    if (--_tx_thread_system_state)
    ;    {

         MOV.L    #__tx_thread_system_state, R1
         MOV.L    [R1], R2
         SUB      #1, R2
         MOV.L    R2,[R1]
         BEQ      __tx_thread_not_nested_restore

    ;
    ;    /* Interrupts are nested.  */
    ;
    ;    /* Recover the saved registers from the interrupt stack
    ;       and return to the point of interrupt.  */
    ;
    __tx_thread_nested_restore:
         POPC    FPSW                               ; Restore FPU status   
         POPM    R14-R15                            ; Restore R14-R15
         POPM    R3-R5                              ; Restore R3-R5
         POPM    R1-R2                              ; Restore R1-R2
         RTE                                        ; Return to point of interrupt, restore PSW including IPL
    ;    }

    __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))
    ;    {
        
         MOV.L    #__tx_thread_current_ptr, R1      ; Pickup current thread ptr address
         MOV.L    [R1], R2
         CMP      #0, R2
         BEQ      __tx_thread_idle_system_restore
         
         MOV.L    #__tx_thread_preempt_disable, R3  ; Pick up preempt disable flag
         MOV.L    [R3], R3
         CMP      #0, R3
         BNE      __tx_thread_no_preempt_restore    ; If pre-empt disable flag set, we simply return to the original point of interrupt regardless
         
         MOV.L    #__tx_thread_execute_ptr, R3      ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
         CMP      [R3], R2
         BNE      __tx_thread_preempt_restore       ; Jump to pre-empt restoring
    ;
    __tx_thread_no_preempt_restore:
         SETPSW  U                                  ; User stack
         POPC    FPSW                               ; Restore FPU status
         POPM    R14-R15                            ; Restore R14-R15
         POPM    R3-R5                              ; Restore R3-R5
         POPM    R1-R2                              ; Restore R1-R2
         RTE                                        ; Return to point of interrupt, restore PSW including IPL

    ;    }
    ;    else
    ;    {

    __tx_thread_preempt_restore:

    ;    /* Save the remaining time-slice and disable it.  */
    ;    if (_tx_timer_time_slice)
    ;    {

         MOV.L    #__tx_timer_time_slice, R3        ; Pickup time-slice address
         MOV.L    [R3],R4                           ; Pickup actual time-slice
         CMP      #0, R4
         BEQ      __tx_thread_dont_save_ts          ; No time-slice to save
    ;
    ;        _tx_thread_current_ptr -> tx_thread_time_slice =  _tx_timer_time_slice;
    ;        _tx_timer_time_slice =  0;
    ;
         MOV.L    R4,24[R2]                         ; Save thread's time slice
         MOV.L    #0,R4                             ; Clear value
         MOV.L    R4,[R3]                           ; Disable global time slice flag
    ;    }
    __tx_thread_dont_save_ts:
    ;
    ;   /* Now store the remaining registers!   */

         SETPSW   U                                 ; User stack
         PUSHM    R6-R13

         MVFACGU   #0, A1, R4                       ; Save accumulators.
         MVFACHI   #0, A1, R5
         MVFACLO   #0, A1, R6
         PUSHM     R4-R6
         MVFACGU   #0, A0, R4
         MVFACHI   #0, A0, R5
         MVFACLO   #0, A0, R6
         PUSHM     R4-R6

    .IF __DPFPU == 1
        MOV.L   144[R2], R4                         ; Get tx_thread_fpu_enable.
        CMP     #0, R4
        BEQ     __tx_thread_preempt_restore_fpu_skip

        DPUSHM.D DR0-DR15                           ; Save FPU register bank if tx_thread_fpu_enable is not 0.
        DPUSHM.L DPSW-DECNT

    __tx_thread_preempt_restore_fpu_skip:
    .ENDIF

    ;
    ;    /* Clear the current task pointer.  */
    ;    _tx_thread_current_ptr =  TX_NULL;
    ;    R1 ->  _tx_thread_current_ptr
    ;    R2 -> *_tx_thread_current_ptr

         MOV.L   R0,8[R2]                           ; Save thread's stack pointer in thread control block
         MOV.L   #0,R2                              ; Build NULL value
         MOV.L   R2,[R1]                            ; Set current thread to NULL

    ;    /* Return to the scheduler.  */
    ;    _tx_thread_schedule();

    __tx_thread_idle_system_restore:
         MVTC    #0, PSW                            ; Reset interrupt priority level to 0
         BRA     __tx_thread_schedule               ; Jump to scheduler
    ;    }
    ;
    ;}

     
    libs/threadx/ports/rxv3/ccrx/src/tx_thread_schedule.src

    ;VOID   _tx_thread_schedule(VOID)
    ;{
        .GLB __tx_thread_schedule
    __tx_thread_schedule:
    ;
    ;
    ;    /* Wait for a thread to execute.  */
    ;    do
    ;    {
        MOV.L    #__tx_thread_execute_ptr, R1        ; Address of thread to executer ptr
    __tx_thread_schedule_loop:
        SETPSW I                                     ; Enable interrupts
        CLRPSW I                                     ; Disable interrupts
        MOV.L    [R1],R2                             ; Pickup next thread to execute
        CMP      #0,R2                               ; Is it NULL?
        BNE      __tx_thread_thread_ready            ; Not NULL, schedule the thread
                                                     ; Idle system - no thread is ready    
    .IF TX_LOW_POWER==1
        MOV.L    #__tx_thread_preempt_disable, R1    ; Load prempt disable flag.
        MOV.L    [R1], R2
        ADD         #1, R2                              ; Disable preemption while enter/exit
        MOV.L    R2, [R1]
        BSR      _tx_low_power_enter                 ; Possibly enter low power mode
    .ENDIF

    .IF TX_ENABLE_WAIT==1
        WAIT                                         ; Wait for interrupt
    .ENDIF

    .IF TX_LOW_POWER==1
        CLRPSW I                                     ; Disable interrupts (because WAIT enables interrupts)
        BSR      _tx_low_power_exit                  ; Possibly exit low power mode
        MOV.L    #__tx_thread_preempt_disable, R1    ; Load prempt disable flag.
        MOV.L    [R1], R2
        SUB         #1, R2                 ; Enable preemption
        MOV.L    R2, [R1]
        MOV.L    #__tx_thread_execute_ptr, R1        ; Address of thread to executer ptr
    .ENDIF

        BRA      __tx_thread_schedule_loop           ; Idle system, keep checking

    __tx_thread_thread_ready:
    ;
    ;    }
    ;    while(_tx_thread_execute_ptr == TX_NULL);
    ;    
    ;    /* Yes! We have a thread to execute. Note that interrupts are locked out at this point.  */
    ;
    ;    /* Setup the current thread pointer.  */
    ;    _tx_thread_current_ptr =  _tx_thread_execute_ptr;
    ;
        MOV.L    #__tx_thread_current_ptr, R3
        MOV.L    R2,[R3]                            ; Setup current thread pointer
    ;
    ;    /* Increment the run count for this thread.  */
    ;    _tx_thread_current_ptr -> tx_thread_run_count++;
    ;
        MOV.L    4[R2],R3                           ; Pickup run count  
        ADD      #1,R3                              ; Increment run counter
        MOV.L    R3,4[R2]                           ; Store it back in control block
    ;
    ;    /* Setup time-slice, if present.  */
    ;    _tx_timer_time_slice =  _tx_thread_current_ptr -> tx_thread_time_slice;
    ;
        MOV.L    24[R2],R3                          ; Pickup thread time-slice
        MOV.L    #__tx_timer_time_slice,R4          ; Pickup pointer to time-slice
        MOV.L    R3, [R4]                           ; Setup time-slice                        
    ;
    ;    /* Switch to the thread's stack.  */
    ;    SP =  _tx_thread_execute_ptr -> tx_thread_stack_ptr;
        SETPSW U                                    ; User stack mode
        MOV.L   8[R2],R0                            ; Pickup stack pointer
    ;
    .IF __DPFPU == 1
        MOV.L   144[R2], R1                         ; Get tx_thread_fpu_enable.
        CMP     #0, R1
        BEQ     __tx_thread_schedule_fpu_skip

        DPOPM.L DPSW-DECNT                          ; Restore FPU register bank if tx_thread_fpu_enable is not 0.
        DPOPM.D DR0-DR15

    __tx_thread_schedule_fpu_skip:
    .ENDIF

        POPM    R1-R3                               ; Restore accumulators.
        MVTACLO R3, A0
        MVTACHI R2, A0
        MVTACGU R1, A0
        POPM    R1-R3
        MVTACLO R3, A1
        MVTACHI R2, A1
        MVTACGU R1, A1

        POPM   R6-R13                               ; Recover interrupt stack frame
        POPC   FPSW
        POPM   R14-R15
        POPM   R3-R5
        POPM   R1-R2    
        RTE                                         ; Return to point of interrupt, this restores PC and PSW
     
    ;
    ;}

     

  • なお、Context Switching割り込みですが、以下の部分で割り込み許可の窓を開けているようです。RXコアをWAIT状態に入れる前処理の`おまじない`としてでしょうか。ちがうかな、よくよく見ると、割り込み処理内でループしているようですので、WAITがどうのこうの関係無しに、ユーザ割り込み全般を待ち受けるような構造なのかな。

    続く?

    libs/threadx/ports/rxv3/ccrx/src/tx_thread_schedule.src (1つ前の投稿の最後のソースの前半です)

    ;VOID   _tx_thread_schedule(VOID)
    ;{
        .GLB __tx_thread_schedule
    __tx_thread_schedule:
    ;
    ;
    ;    /* Wait for a thread to execute.  */
    ;    do
    ;    {
        MOV.L    #__tx_thread_execute_ptr, R1        ; Address of thread to executer ptr
    __tx_thread_schedule_loop:
        SETPSW I                                     ; Enable interrupts
        CLRPSW I                                     ; Disable interrupts
        MOV.L    [R1],R2                             ; Pickup next thread to execute
        CMP      #0,R2                               ; Is it NULL?
        BNE      __tx_thread_thread_ready            ; Not NULL, schedule the thread
                                                     ; Idle system - no thread is ready    
    .IF TX_LOW_POWER==1
        MOV.L    #__tx_thread_preempt_disable, R1    ; Load prempt disable flag.
        MOV.L    [R1], R2
        ADD         #1, R2                              ; Disable preemption while enter/exit
        MOV.L    R2, [R1]
        BSR      _tx_low_power_enter                 ; Possibly enter low power mode
    .ENDIF

    .IF TX_ENABLE_WAIT==1
        WAIT                                         ; Wait for interrupt
    .ENDIF

    .IF TX_LOW_POWER==1
        CLRPSW I                                     ; Disable interrupts (because WAIT enables interrupts)
        BSR      _tx_low_power_exit                  ; Possibly exit low power mode
        MOV.L    #__tx_thread_preempt_disable, R1    ; Load prempt disable flag.
        MOV.L    [R1], R2
        SUB         #1, R2                 ; Enable preemption
        MOV.L    R2, [R1]
        MOV.L    #__tx_thread_execute_ptr, R1        ; Address of thread to executer ptr
    .ENDIF

        BRA      __tx_thread_schedule_loop           ; Idle system, keep checking

    __tx_thread_thread_ready:
    ;
    ;    }
    ;    while(_tx_thread_execute_ptr == TX_NULL);
    ;    
    ;    /* Yes! We have a thread to execute. Note that interrupts are locked out at this point.  */
    ;
    …以後省略…

     

  • こんにちは。NoMaYです。

    以前に別スレッドにURLを書いた個人事業主?さんが、こういう記事を執筆されていました。

    Azure RTOS習得(1):習得方針
    2022年5月27日 WithHappy
    happytech.jp/wordpress/2022/05/27/azure-rtos-acquisition-1-acquisition-policy/

    なお、これに続く記事はSTM32特化の記事です。ちなみに、Azure RTOSについてではありませんが、RAマイコンの記事も執筆されています。

  • こんにちは。NoMaYです。

    RXコア向けのAzure RTOSカーネルではPSWのIビットでカーネル内の割り込みの禁止/許可を制御していますが、Cortex-Mコア向けのAzure RTOSカーネルではRXコアのPSWのIPLフィールドと同様の意味合いのもので制御することが出来るようになっていますね。(ですので、FreeRTOSカーネルと同様なことが出来る。) ルネサスさんは認識済みだろうか、、、

    Cortex-M port: TX_PORT_USE_BASEPRI and TX_PORT_BASEPRI has no effect on assembly code
    github.com/azure-rtos/threadx/issues/168