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/
 

Parents
  • 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
     
    ;
    ;}

     

Reply
  • 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
     
    ;
    ;}

     

Children
No Data