RXv3コアのレジスタ一括退避機能を使ってマルチスーパーループ実行ライブラリ(MultiSuperLoopExecLibrary)を作ってみるスレッド

こんにちは。NoMaYです。

今、以下のスレッドに投稿しているのですけれども、派生ネタが思い浮かびましたので、またひとつ立ててみました。

RXv3コアのレジスタ一括退避機能の使い方(Register Bank Save Function Usage)を調べてみるスレッド
community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/9572/rxv3-register-bank-save-function-usage

派生ネタ

・ スーパーループを複数同時実行する(複数のスーパーループを切り替えながら実行する)、という、ありがちなものです
・ RXv3コアのレジスタ一括退避機能の高速性を鑑みて10μsec程度で切り替えてみたいです
・ お遊びです

Parents
  • こんにちは。NoMaYです。

    2つのループを交互に切り替えるものをCC-RX/GNURX/ICCRXで作ってみました。一応ルネサスRXシミュレータで試してみていますけれども、まだ実機では試していません。プロジェクトのファイル一式を以下のzipファイルに固めました。

    issue_RXv3_MultiSuperLoop_20230121.zip

    以下、今時点での主要部分のソース(main.c×1+Config_CMT3_user.c×3)です。

    RXv3_MultiSuperLoop_{CCRX, GCC, IAR}/src/main.c

    main.c.20230121.txt
    #include "r_smc_entry.h"
    #include "MultiSuperLoop.h"
    
    void main(void);
    void main2(void);
    
    uint32_t ustack2[256 / sizeof(uint32_t)]; /* The stack should be 4 bytes alignment. */
    
    volatile int32_t debug;  /* The `volatile` keyword is for debug purpose. */
    volatile int32_t debug2; /* The `volatile` keyword is for debug purpose. */
    
    void main(void)
    {
        MultiSuperLoop_Add_Loop1( main2, (uint8_t *)ustack2 + sizeof(ustack2) );
    
        volatile int32_t autovar_debug;  /* The `volatile` keyword is for debug purpose. */
    
        autovar_debug = 1;
        for (;;)
        {
            debug = autovar_debug++;
            if (2000000000 <= autovar_debug)
            {
                autovar_debug = 1;
            }
            //MultiSuperLoop_Yield();
            if (0 >= autovar_debug || 2000000000 <= autovar_debug)
            {
                for (;;) { nop(); }
            }
        }
    }
    
    void main2(void)
    {
        volatile int32_t autovar_debug2; /* The `volatile` keyword is for debug purpose. */
    
        autovar_debug2 = -1;
        for (;;)
        {
            debug2 = autovar_debug2--;
            if (-2000000000 >= autovar_debug2)
            {
                autovar_debug2 = -1;
            }
            //MultiSuperLoop_Yield();
            if (0 <= autovar_debug2 || -2000000000 >= autovar_debug2)
            {
                for (;;) { nop(); }
            }
        }
    }
    

     
    RXv3_MultiSuperLoop_CCRX/src/smc_gen/Config_CMT3/Config_CMT3_user.c
    Config_CMT3_user.c.CCRX.20230121.txt
    /***********************************************************************************************************************
    * DISCLAIMER
    * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
    * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
    * applicable laws, including copyright laws. 
    * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
    * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
    * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
    * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
    * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability 
    * of this software. By using this software, you agree to the additional terms and conditions found by accessing the 
    * following link:
    * http://www.renesas.com/disclaimer
    *
    * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    * File Name        : Config_CMT3_user.c
    * Component Version: 2.3.0
    * Device(s)        : R5F566NNHxFP
    * Description      : This file implements device driver for Config_CMT3.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    Pragma directive
    ***********************************************************************************************************************/
    /* Start user code for pragma. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    Includes
    ***********************************************************************************************************************/
    #include "r_cg_macrodriver.h"
    #include "Config_CMT3.h"
    /* Start user code for include. Do not edit comment generated here */
    
    #include "MultiSuperLoop.h"
    #include "r_rx_nested_interrupt/r_rx_nested_interrupt.h"
    
    /* End user code. Do not edit comment generated here */
    #include "r_cg_userdefine.h"
    
    /***********************************************************************************************************************
    Global variables and functions
    ***********************************************************************************************************************/
    /* Start user code for global. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE_ASM(MultiSuperLoop_Dispatch)
    void MultiSuperLoop_Dispatch(void)
    {
    R_BSP_ASM_BEGIN
    
        /* Re-enable interrupt. */
        R_BSP_ASM( setpsw i                                         )
    
        /* Save the current super loop context. Be aware that the USP is used from now. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( setpsw u                                         )
        R_BSP_ASM( sub U_BSP_ASM_IMM(8), r0                         )
        R_BSP_ASM( push.l r1                                        )
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r1  )
        R_BSP_ASM( mov.b 16[r1], r1                                 )
        R_BSP_ASM( save r1                                          )
    
        /* Move PSW, PC from the interrupt stack to the current super loop's user stack. */
        R_BSP_ASM( mvfc isp, r2                                     )
        R_BSP_ASM( mov.l 4[r2], 8[r0]                               )
        R_BSP_ASM( mov.l 0[r2], 4[r0]                               )
        R_BSP_ASM( add U_BSP_ASM_IMM(8), r2                         )
        R_BSP_ASM( mvtc r2, isp                                     )
    
        /* Select the next super loop. */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r2  )
        R_BSP_ASM( add r2, r1                                       )
        R_BSP_ASM( mov.b [r1], r1                                   )
        R_BSP_ASM( mov.b r1, 16[r2]                                 )
    
        /* Restore the next super loop context. Be aware that the USP is used here. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( rstr r1                                          )
        R_BSP_ASM( pop r1                                           )
        R_BSP_ASM( rte                                              )
    
    R_BSP_ASM_END
    }
    
    #define r_Config_CMT3_cmi3_interrupt(...) R_CG_ATTRIB_INTERRUPT_BANK(r_Config_CMT3_cmi3_interrupt, MY_BSP_CFG_REG_BANK_SCRATCH, __VA_ARGS__)
    
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    * Function Name: R_Config_CMT3_Create_UserInit
    * Description  : This function adds user code after initializing the CMT3 channel
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void R_Config_CMT3_Create_UserInit(void)
    {
        /* Start user code for user init. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }
    
    /***********************************************************************************************************************
    * Function Name: r_Config_CMT3_cmi3_interrupt
    * Description  : This function is CMI3 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    #if FAST_INTERRUPT_VECTOR == VECT_PERIB_INTB129
    #pragma interrupt r_Config_CMT3_cmi3_interrupt(vect=VECT(PERIB,INTB129),fint)
    #else
    #pragma interrupt r_Config_CMT3_cmi3_interrupt(vect=VECT(PERIB,INTB129))
    #endif
    static void r_Config_CMT3_cmi3_interrupt(void)
    {
        /* Start user code for r_Config_CMT3_cmi3_interrupt. Do not edit comment generated here */
    
        MultiSuperLoop_Dispatch();
    
        /* End user code. Do not edit comment generated here */
    }
    
    /* Start user code for adding. Do not edit comment generated here */
    
    /* Unfortunately CC-RX complains about unused parameters though inline_asm function. */
    /* Using intermediate function is a workaround for such CC-RX's information message. */
    R_BSP_PRAGMA_STATIC_INLINE_ASM(_Initialize_RegisterSaveBank)
    void _Initialize_RegisterSaveBank(void)
    {
        R_BSP_ASM_INTERNAL_USED(pc)   /* r1 */
        R_BSP_ASM_INTERNAL_USED(usp)  /* r2 */
        R_BSP_ASM_INTERNAL_USED(bank) /* r3 */
    
    R_BSP_ASM_BEGIN
    
        /* Save PSW, USP to scratch registers and disable interrupt.  */
        R_BSP_ASM( mvfc psw, r4                     )
        R_BSP_ASM( clrpsw i                         )
        R_BSP_ASM( mvfc usp, r5                     )
    
        /* Initialize the specified register save bank. */
        R_BSP_ASM( sub U_BSP_ASM_IMM(12), r2        ) /* Reserve the space for PSW, PC and R1. */
        R_BSP_ASM( mvtc r2, usp                     ) /* usp */
        R_BSP_ASM( mov.l r4, 8[r2]                  ) /* psw */
        R_BSP_ASM( mov.l r1, 4[r2]                  ) /* pc */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(0), 0[r2]    ) /* r1 but the value isn't important. */
        R_BSP_ASM( save r3                          ) /* Only the value of USP and FPSW are important. */
    
        /* Restore PSW, USP from scratch registers. */
        R_BSP_ASM( mvtc r5, usp                     )
        R_BSP_ASM( mvtc r4, psw                     )
    
    R_BSP_ASM_END
    }
    
    /* Unfortunately CC-RX complains about unused parameters though inline_asm function. */
    /* Using intermediate function is a workaround for such CC-RX's information message. */
    R_BSP_PRAGMA(noinline Initialize_RegisterSaveBank)
    static void Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        (void) pc;   /* r1 */
        (void) usp;  /* r2 */
        (void) bank; /* r3 */
        _Initialize_RegisterSaveBank();
    }
    
    void MultiSuperLoop_Add_Loop1(void (*pc)(void), uint8_t *usp)
    {
        /* Prevent the debugger from messing up unwinding of the stack. */
        usp = (uint8_t *)usp - sizeof(uint32_t);
        *(uint32_t *)usp = 0;
    
        Initialize_RegisterSaveBank((uint32_t)pc, (uint32_t)usp, 1);
    
        SuperLoopContextTable[16] = 0;
    
        SuperLoopContextTable[ 0] = 1;
        SuperLoopContextTable[ 1] = 0;
        SuperLoopContextTable[ 2] = 255;
        SuperLoopContextTable[ 3] = 255;
        SuperLoopContextTable[ 4] = 255;
        SuperLoopContextTable[ 5] = 255;
        SuperLoopContextTable[ 6] = 255;
        SuperLoopContextTable[ 7] = 255;
        SuperLoopContextTable[ 8] = 255;
        SuperLoopContextTable[ 9] = 255;
        SuperLoopContextTable[10] = 255;
        SuperLoopContextTable[11] = 255;
        SuperLoopContextTable[12] = 255;
        SuperLoopContextTable[13] = 255;
        SuperLoopContextTable[14] = 255;
        SuperLoopContextTable[15] = 255;
    
        R_Config_CMT3_Start();
    }
    
    void MultiSuperLoop_Yield(void)
    {
        uint8_t ipl = get_ipl();
    
        if (ipl == 0)
        {
            set_ipl(1);
        }
    
        /* Switch to the next super loop. Be aware that the value of IPL is */
        /* also switched to the value which is used in the next super loop. */
        int_exception(VECT(PERIB,INTB129));
    
        if (ipl == 0)
        {
            set_ipl(0);
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     
    RXv3_MultiSuperLoop_GCC/src/smc_gen/Config_CMT3/Config_CMT3_user.c
    Config_CMT3_user.c.GNURX.20230121.txt
    /***********************************************************************************************************************
    * DISCLAIMER
    * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
    * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
    * applicable laws, including copyright laws. 
    * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
    * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
    * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
    * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
    * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability 
    * of this software. By using this software, you agree to the additional terms and conditions found by accessing the 
    * following link:
    * http://www.renesas.com/disclaimer
    *
    * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    * File Name        : Config_CMT3_user.c
    * Component Version: 2.3.0
    * Device(s)        : R5F566NNHxFP
    * Description      : This file implements device driver for Config_CMT3.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    Pragma directive
    ***********************************************************************************************************************/
    /* Start user code for pragma. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    Includes
    ***********************************************************************************************************************/
    #include "r_cg_macrodriver.h"
    #include "Config_CMT3.h"
    /* Start user code for include. Do not edit comment generated here */
    
    #include "MultiSuperLoop.h"
    
    /* End user code. Do not edit comment generated here */
    #include "r_cg_userdefine.h"
    
    /***********************************************************************************************************************
    Global variables and functions
    ***********************************************************************************************************************/
    /* Start user code for global. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE(MultiSuperLoop_Dispatch)
    void MultiSuperLoop_Dispatch(void)
    {
    R_BSP_ASM_BEGIN
    
        /* Re-enable interrupt. */
        R_BSP_ASM( setpsw i                                         )
    
        /* Save the current super loop context. Be aware that the USP is used from now. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( setpsw u                                         )
        R_BSP_ASM( sub U_BSP_ASM_IMM(8), r0                         )
        R_BSP_ASM( push.l r1                                        )
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r1  )
        R_BSP_ASM( mov.b 16[r1], r1                                 )
        R_BSP_ASM( save r1                                          )
    
        /* Move PSW, PC from the interrupt stack to the current super loop's user stack. */
        R_BSP_ASM( mvfc isp, r2                                     )
        R_BSP_ASM( mov.l 4[r2], 8[r0]                               )
        R_BSP_ASM( mov.l 0[r2], 4[r0]                               )
        R_BSP_ASM( add U_BSP_ASM_IMM(8), r2                         )
        R_BSP_ASM( mvtc r2, isp                                     )
    
        /* Select the next super loop. */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r2  )
        R_BSP_ASM( add r2, r1                                       )
        R_BSP_ASM( mov.b [r1], r1                                   )
        R_BSP_ASM( mov.b r1, 16[r2]                                 )
    
        /* Restore the next super loop context. Be aware that the USP is used here. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( rstr r1                                          )
        R_BSP_ASM( pop r1                                           )
        R_BSP_ASM( rte                                              )
    
    R_BSP_ASM_END
    }
    
    void r_Config_CMT3_cmi3_interrupt(void) __attribute__((naked));
    
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    * Function Name: R_Config_CMT3_Create_UserInit
    * Description  : This function adds user code after initializing the CMT3 channel
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void R_Config_CMT3_Create_UserInit(void)
    {
        /* Start user code for user init. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }
    
    /***********************************************************************************************************************
    * Function Name: r_Config_CMT3_cmi3_interrupt
    * Description  : This function is CMI3 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void r_Config_CMT3_cmi3_interrupt(void)
    {
        /* Start user code for r_Config_CMT3_cmi3_interrupt. Do not edit comment generated here */
    
        MultiSuperLoop_Dispatch();
    
        /* End user code. Do not edit comment generated here */
    }
    
    /* Start user code for adding. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE_ASM(_Initialize_RegisterSaveBank)
    void _Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        R_BSP_ASM_INTERNAL_USED(pc)   /* r1 */
        R_BSP_ASM_INTERNAL_USED(usp)  /* r2 */
        R_BSP_ASM_INTERNAL_USED(bank) /* r3 */
    
    R_BSP_ASM_BEGIN
    
        /* Save PSW, USP to scratch registers and disable interrupt.  */
        R_BSP_ASM( mvfc psw, r4                     )
        R_BSP_ASM( clrpsw i                         )
        R_BSP_ASM( mvfc usp, r5                     )
    
        /* Initialize the specified register save bank. */
        R_BSP_ASM( sub U_BSP_ASM_IMM(12), r2        ) /* Reserve the space for PSW, PC and R1. */
        R_BSP_ASM( mvtc r2, usp                     ) /* usp */
        R_BSP_ASM( mov.l r4, 8[r2]                  ) /* psw */
        R_BSP_ASM( mov.l r1, 4[r2]                  ) /* pc */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(0), 0[r2]    ) /* r1 but the value isn't important. */
        R_BSP_ASM( save r3                          ) /* Only the value of USP and FPSW are important. */
    
        /* Restore PSW, USP from scratch registers. */
        R_BSP_ASM( mvtc r5, usp                     )
        R_BSP_ASM( mvtc r4, psw                     )
    
    R_BSP_ASM_END
    }
    
    static void Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        (void) pc;   /* r1 */
        (void) usp;  /* r2 */
        (void) bank; /* r3 */
        _Initialize_RegisterSaveBank(pc, usp, bank);
    }
    
    void MultiSuperLoop_Add_Loop1(void (*pc)(void), uint8_t *usp)
    {
        /* Prevent the debugger from messing up unwinding of the stack. */
        usp = (uint8_t *)usp - sizeof(uint32_t);
        *(uint32_t *)usp = 0;
    
        Initialize_RegisterSaveBank((uint32_t)pc, (uint32_t)usp, 1);
    
        SuperLoopContextTable[16] = 0;
    
        SuperLoopContextTable[ 0] = 1;
        SuperLoopContextTable[ 1] = 0;
        SuperLoopContextTable[ 2] = 255;
        SuperLoopContextTable[ 3] = 255;
        SuperLoopContextTable[ 4] = 255;
        SuperLoopContextTable[ 5] = 255;
        SuperLoopContextTable[ 6] = 255;
        SuperLoopContextTable[ 7] = 255;
        SuperLoopContextTable[ 8] = 255;
        SuperLoopContextTable[ 9] = 255;
        SuperLoopContextTable[10] = 255;
        SuperLoopContextTable[11] = 255;
        SuperLoopContextTable[12] = 255;
        SuperLoopContextTable[13] = 255;
        SuperLoopContextTable[14] = 255;
        SuperLoopContextTable[15] = 255;
    
        R_Config_CMT3_Start();
    }
    
    void MultiSuperLoop_Yield(void)
    {
        uint8_t ipl = get_ipl();
    
        if (ipl == 0)
        {
            set_ipl(1);
        }
    
        /* Switch to the next super loop. Be aware that the value of IPL is */
        /* also switched to the value which is used in the next super loop. */
        int_exception(VECT(PERIB,INTB129));
    
        if (ipl == 0)
        {
            set_ipl(0);
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     
    RXv3_MultiSuperLoop_IAR/src/smc_gen/Config_CMT3/Config_CMT3_user.c
    Config_CMT3_user.c.ICCRX.20230121.txt
    /***********************************************************************************************************************
    * DISCLAIMER
    * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
    * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
    * applicable laws, including copyright laws. 
    * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
    * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
    * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
    * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
    * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability 
    * of this software. By using this software, you agree to the additional terms and conditions found by accessing the 
    * following link:
    * http://www.renesas.com/disclaimer
    *
    * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    * File Name        : Config_CMT3_user.c
    * Component Version: 2.3.0
    * Device(s)        : R5F566NNHxFP
    * Description      : This file implements device driver for Config_CMT3.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    Pragma directive
    ***********************************************************************************************************************/
    /* Start user code for pragma. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    Includes
    ***********************************************************************************************************************/
    #include "r_cg_macrodriver.h"
    #include "Config_CMT3.h"
    /* Start user code for include. Do not edit comment generated here */
    
    #include "MultiSuperLoop.h"
    
    /* End user code. Do not edit comment generated here */
    #include "r_cg_userdefine.h"
    
    /***********************************************************************************************************************
    Global variables and functions
    ***********************************************************************************************************************/
    /* Start user code for global. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE(MultiSuperLoop_Dispatch)
    void MultiSuperLoop_Dispatch(void)
    {
    R_BSP_ASM_BEGIN
    
        /* Re-enable interrupt. */
        R_BSP_ASM( setpsw i                                         )
    
        /* Save the current super loop context. Be aware that the USP is used from now. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( setpsw u                                         )
        R_BSP_ASM( sub U_BSP_ASM_IMM(8), r0                         )
        R_BSP_ASM( push.l r1                                        )
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r1  )
        R_BSP_ASM( mov.b 16[r1], r1                                 )
        R_BSP_ASM( save r1                                          )
    
        /* Move PSW, PC from the interrupt stack to the current super loop's user stack. */
        R_BSP_ASM( mvfc isp, r2                                     )
        R_BSP_ASM( mov.l 4[r2], 8[r0]                               )
        R_BSP_ASM( mov.l 0[r2], 4[r0]                               )
        R_BSP_ASM( add U_BSP_ASM_IMM(8), r2                         )
        R_BSP_ASM( mvtc r2, isp                                     )
    
        /* Select the next super loop. */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r2  )
        R_BSP_ASM( add r2, r1                                       )
        R_BSP_ASM( mov.b [r1], r1                                   )
        R_BSP_ASM( mov.b r1, 16[r2]                                 )
    
        /* Restore the next super loop context. Be aware that the USP is used here. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( rstr r1                                          )
        R_BSP_ASM( pop r1                                           )
        R_BSP_ASM( rte                                              )
    
    R_BSP_ASM_END
    }
    
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    * Function Name: R_Config_CMT3_Create_UserInit
    * Description  : This function adds user code after initializing the CMT3 channel
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void R_Config_CMT3_Create_UserInit(void)
    {
        /* Start user code for user init. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }
    
    /***********************************************************************************************************************
    * Function Name: r_Config_CMT3_cmi3_interrupt
    * Description  : This function is CMI3 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    #pragma vector = VECT_PERIB_INTB129
    #if FAST_INTERRUPT_VECTOR == VECT_PERIB_INTB129
    __fast_interrupt static void r_Config_CMT3_cmi3_interrupt(void)
    #else
    __interrupt static void r_Config_CMT3_cmi3_interrupt(void)
    #endif
    {
        /* Start user code for r_Config_CMT3_cmi3_interrupt. Do not edit comment generated here */
    
        MultiSuperLoop_Dispatch();
    
        /* End user code. Do not edit comment generated here */
    }
    
    /* Start user code for adding. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE_ASM(_Initialize_RegisterSaveBank)
    void _Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        R_BSP_ASM_INTERNAL_USED(pc)   /* r1 */
        R_BSP_ASM_INTERNAL_USED(usp)  /* r2 */
        R_BSP_ASM_INTERNAL_USED(bank) /* r3 */
    
    R_BSP_ASM_BEGIN
    
        /* Save PSW, USP to scratch registers and disable interrupt.  */
        R_BSP_ASM( mvfc psw, r4                     )
        R_BSP_ASM( clrpsw i                         )
        R_BSP_ASM( mvfc usp, r5                     )
    
        /* Initialize the specified register save bank. */
        R_BSP_ASM( sub U_BSP_ASM_IMM(12), r2        ) /* Reserve the space for PSW, PC and R1. */
        R_BSP_ASM( mvtc r2, usp                     ) /* usp */
        R_BSP_ASM( mov.l r4, 8[r2]                  ) /* psw */
        R_BSP_ASM( mov.l r1, 4[r2]                  ) /* pc */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(0), 0[r2]    ) /* r1 but the value isn't important. */
        R_BSP_ASM( save r3                          ) /* Only the value of USP and FPSW are important. */
    
        /* Restore PSW, USP from scratch registers. */
        R_BSP_ASM( mvtc r5, usp                     )
        R_BSP_ASM( mvtc r4, psw                     )
    
    R_BSP_ASM_END
    }
    
    static void Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        (void) pc;   /* r1 */
        (void) usp;  /* r2 */
        (void) bank; /* r3 */
        _Initialize_RegisterSaveBank(pc, usp, bank);
    }
    
    void MultiSuperLoop_Add_Loop1(void (*pc)(void), uint8_t *usp)
    {
        /* Prevent the debugger from messing up unwinding of the stack. */
        usp = (uint8_t *)usp - sizeof(uint32_t);
        *(uint32_t *)usp = 0;
    
        Initialize_RegisterSaveBank((uint32_t)pc, (uint32_t)usp, 1);
    
        SuperLoopContextTable[16] = 0;
    
        SuperLoopContextTable[ 0] = 1;
        SuperLoopContextTable[ 1] = 0;
        SuperLoopContextTable[ 2] = 255;
        SuperLoopContextTable[ 3] = 255;
        SuperLoopContextTable[ 4] = 255;
        SuperLoopContextTable[ 5] = 255;
        SuperLoopContextTable[ 6] = 255;
        SuperLoopContextTable[ 7] = 255;
        SuperLoopContextTable[ 8] = 255;
        SuperLoopContextTable[ 9] = 255;
        SuperLoopContextTable[10] = 255;
        SuperLoopContextTable[11] = 255;
        SuperLoopContextTable[12] = 255;
        SuperLoopContextTable[13] = 255;
        SuperLoopContextTable[14] = 255;
        SuperLoopContextTable[15] = 255;
    
        R_Config_CMT3_Start();
    }
    
    void MultiSuperLoop_Yield(void)
    {
        uint8_t ipl = get_ipl();
    
        if (ipl == 0)
        {
            set_ipl(1);
        }
    
        /* Switch to the next super loop. Be aware that the value of IPL is */
        /* also switched to the value which is used in the next super loop. */
        int_exception(VECT(PERIB,INTB129));
    
        if (ipl == 0)
        {
            set_ipl(0);
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     

Reply
  • こんにちは。NoMaYです。

    2つのループを交互に切り替えるものをCC-RX/GNURX/ICCRXで作ってみました。一応ルネサスRXシミュレータで試してみていますけれども、まだ実機では試していません。プロジェクトのファイル一式を以下のzipファイルに固めました。

    issue_RXv3_MultiSuperLoop_20230121.zip

    以下、今時点での主要部分のソース(main.c×1+Config_CMT3_user.c×3)です。

    RXv3_MultiSuperLoop_{CCRX, GCC, IAR}/src/main.c

    main.c.20230121.txt
    #include "r_smc_entry.h"
    #include "MultiSuperLoop.h"
    
    void main(void);
    void main2(void);
    
    uint32_t ustack2[256 / sizeof(uint32_t)]; /* The stack should be 4 bytes alignment. */
    
    volatile int32_t debug;  /* The `volatile` keyword is for debug purpose. */
    volatile int32_t debug2; /* The `volatile` keyword is for debug purpose. */
    
    void main(void)
    {
        MultiSuperLoop_Add_Loop1( main2, (uint8_t *)ustack2 + sizeof(ustack2) );
    
        volatile int32_t autovar_debug;  /* The `volatile` keyword is for debug purpose. */
    
        autovar_debug = 1;
        for (;;)
        {
            debug = autovar_debug++;
            if (2000000000 <= autovar_debug)
            {
                autovar_debug = 1;
            }
            //MultiSuperLoop_Yield();
            if (0 >= autovar_debug || 2000000000 <= autovar_debug)
            {
                for (;;) { nop(); }
            }
        }
    }
    
    void main2(void)
    {
        volatile int32_t autovar_debug2; /* The `volatile` keyword is for debug purpose. */
    
        autovar_debug2 = -1;
        for (;;)
        {
            debug2 = autovar_debug2--;
            if (-2000000000 >= autovar_debug2)
            {
                autovar_debug2 = -1;
            }
            //MultiSuperLoop_Yield();
            if (0 <= autovar_debug2 || -2000000000 >= autovar_debug2)
            {
                for (;;) { nop(); }
            }
        }
    }
    

     
    RXv3_MultiSuperLoop_CCRX/src/smc_gen/Config_CMT3/Config_CMT3_user.c
    Config_CMT3_user.c.CCRX.20230121.txt
    /***********************************************************************************************************************
    * DISCLAIMER
    * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
    * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
    * applicable laws, including copyright laws. 
    * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
    * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
    * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
    * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
    * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability 
    * of this software. By using this software, you agree to the additional terms and conditions found by accessing the 
    * following link:
    * http://www.renesas.com/disclaimer
    *
    * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    * File Name        : Config_CMT3_user.c
    * Component Version: 2.3.0
    * Device(s)        : R5F566NNHxFP
    * Description      : This file implements device driver for Config_CMT3.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    Pragma directive
    ***********************************************************************************************************************/
    /* Start user code for pragma. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    Includes
    ***********************************************************************************************************************/
    #include "r_cg_macrodriver.h"
    #include "Config_CMT3.h"
    /* Start user code for include. Do not edit comment generated here */
    
    #include "MultiSuperLoop.h"
    #include "r_rx_nested_interrupt/r_rx_nested_interrupt.h"
    
    /* End user code. Do not edit comment generated here */
    #include "r_cg_userdefine.h"
    
    /***********************************************************************************************************************
    Global variables and functions
    ***********************************************************************************************************************/
    /* Start user code for global. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE_ASM(MultiSuperLoop_Dispatch)
    void MultiSuperLoop_Dispatch(void)
    {
    R_BSP_ASM_BEGIN
    
        /* Re-enable interrupt. */
        R_BSP_ASM( setpsw i                                         )
    
        /* Save the current super loop context. Be aware that the USP is used from now. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( setpsw u                                         )
        R_BSP_ASM( sub U_BSP_ASM_IMM(8), r0                         )
        R_BSP_ASM( push.l r1                                        )
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r1  )
        R_BSP_ASM( mov.b 16[r1], r1                                 )
        R_BSP_ASM( save r1                                          )
    
        /* Move PSW, PC from the interrupt stack to the current super loop's user stack. */
        R_BSP_ASM( mvfc isp, r2                                     )
        R_BSP_ASM( mov.l 4[r2], 8[r0]                               )
        R_BSP_ASM( mov.l 0[r2], 4[r0]                               )
        R_BSP_ASM( add U_BSP_ASM_IMM(8), r2                         )
        R_BSP_ASM( mvtc r2, isp                                     )
    
        /* Select the next super loop. */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r2  )
        R_BSP_ASM( add r2, r1                                       )
        R_BSP_ASM( mov.b [r1], r1                                   )
        R_BSP_ASM( mov.b r1, 16[r2]                                 )
    
        /* Restore the next super loop context. Be aware that the USP is used here. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( rstr r1                                          )
        R_BSP_ASM( pop r1                                           )
        R_BSP_ASM( rte                                              )
    
    R_BSP_ASM_END
    }
    
    #define r_Config_CMT3_cmi3_interrupt(...) R_CG_ATTRIB_INTERRUPT_BANK(r_Config_CMT3_cmi3_interrupt, MY_BSP_CFG_REG_BANK_SCRATCH, __VA_ARGS__)
    
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    * Function Name: R_Config_CMT3_Create_UserInit
    * Description  : This function adds user code after initializing the CMT3 channel
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void R_Config_CMT3_Create_UserInit(void)
    {
        /* Start user code for user init. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }
    
    /***********************************************************************************************************************
    * Function Name: r_Config_CMT3_cmi3_interrupt
    * Description  : This function is CMI3 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    #if FAST_INTERRUPT_VECTOR == VECT_PERIB_INTB129
    #pragma interrupt r_Config_CMT3_cmi3_interrupt(vect=VECT(PERIB,INTB129),fint)
    #else
    #pragma interrupt r_Config_CMT3_cmi3_interrupt(vect=VECT(PERIB,INTB129))
    #endif
    static void r_Config_CMT3_cmi3_interrupt(void)
    {
        /* Start user code for r_Config_CMT3_cmi3_interrupt. Do not edit comment generated here */
    
        MultiSuperLoop_Dispatch();
    
        /* End user code. Do not edit comment generated here */
    }
    
    /* Start user code for adding. Do not edit comment generated here */
    
    /* Unfortunately CC-RX complains about unused parameters though inline_asm function. */
    /* Using intermediate function is a workaround for such CC-RX's information message. */
    R_BSP_PRAGMA_STATIC_INLINE_ASM(_Initialize_RegisterSaveBank)
    void _Initialize_RegisterSaveBank(void)
    {
        R_BSP_ASM_INTERNAL_USED(pc)   /* r1 */
        R_BSP_ASM_INTERNAL_USED(usp)  /* r2 */
        R_BSP_ASM_INTERNAL_USED(bank) /* r3 */
    
    R_BSP_ASM_BEGIN
    
        /* Save PSW, USP to scratch registers and disable interrupt.  */
        R_BSP_ASM( mvfc psw, r4                     )
        R_BSP_ASM( clrpsw i                         )
        R_BSP_ASM( mvfc usp, r5                     )
    
        /* Initialize the specified register save bank. */
        R_BSP_ASM( sub U_BSP_ASM_IMM(12), r2        ) /* Reserve the space for PSW, PC and R1. */
        R_BSP_ASM( mvtc r2, usp                     ) /* usp */
        R_BSP_ASM( mov.l r4, 8[r2]                  ) /* psw */
        R_BSP_ASM( mov.l r1, 4[r2]                  ) /* pc */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(0), 0[r2]    ) /* r1 but the value isn't important. */
        R_BSP_ASM( save r3                          ) /* Only the value of USP and FPSW are important. */
    
        /* Restore PSW, USP from scratch registers. */
        R_BSP_ASM( mvtc r5, usp                     )
        R_BSP_ASM( mvtc r4, psw                     )
    
    R_BSP_ASM_END
    }
    
    /* Unfortunately CC-RX complains about unused parameters though inline_asm function. */
    /* Using intermediate function is a workaround for such CC-RX's information message. */
    R_BSP_PRAGMA(noinline Initialize_RegisterSaveBank)
    static void Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        (void) pc;   /* r1 */
        (void) usp;  /* r2 */
        (void) bank; /* r3 */
        _Initialize_RegisterSaveBank();
    }
    
    void MultiSuperLoop_Add_Loop1(void (*pc)(void), uint8_t *usp)
    {
        /* Prevent the debugger from messing up unwinding of the stack. */
        usp = (uint8_t *)usp - sizeof(uint32_t);
        *(uint32_t *)usp = 0;
    
        Initialize_RegisterSaveBank((uint32_t)pc, (uint32_t)usp, 1);
    
        SuperLoopContextTable[16] = 0;
    
        SuperLoopContextTable[ 0] = 1;
        SuperLoopContextTable[ 1] = 0;
        SuperLoopContextTable[ 2] = 255;
        SuperLoopContextTable[ 3] = 255;
        SuperLoopContextTable[ 4] = 255;
        SuperLoopContextTable[ 5] = 255;
        SuperLoopContextTable[ 6] = 255;
        SuperLoopContextTable[ 7] = 255;
        SuperLoopContextTable[ 8] = 255;
        SuperLoopContextTable[ 9] = 255;
        SuperLoopContextTable[10] = 255;
        SuperLoopContextTable[11] = 255;
        SuperLoopContextTable[12] = 255;
        SuperLoopContextTable[13] = 255;
        SuperLoopContextTable[14] = 255;
        SuperLoopContextTable[15] = 255;
    
        R_Config_CMT3_Start();
    }
    
    void MultiSuperLoop_Yield(void)
    {
        uint8_t ipl = get_ipl();
    
        if (ipl == 0)
        {
            set_ipl(1);
        }
    
        /* Switch to the next super loop. Be aware that the value of IPL is */
        /* also switched to the value which is used in the next super loop. */
        int_exception(VECT(PERIB,INTB129));
    
        if (ipl == 0)
        {
            set_ipl(0);
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     
    RXv3_MultiSuperLoop_GCC/src/smc_gen/Config_CMT3/Config_CMT3_user.c
    Config_CMT3_user.c.GNURX.20230121.txt
    /***********************************************************************************************************************
    * DISCLAIMER
    * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
    * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
    * applicable laws, including copyright laws. 
    * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
    * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
    * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
    * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
    * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability 
    * of this software. By using this software, you agree to the additional terms and conditions found by accessing the 
    * following link:
    * http://www.renesas.com/disclaimer
    *
    * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    * File Name        : Config_CMT3_user.c
    * Component Version: 2.3.0
    * Device(s)        : R5F566NNHxFP
    * Description      : This file implements device driver for Config_CMT3.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    Pragma directive
    ***********************************************************************************************************************/
    /* Start user code for pragma. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    Includes
    ***********************************************************************************************************************/
    #include "r_cg_macrodriver.h"
    #include "Config_CMT3.h"
    /* Start user code for include. Do not edit comment generated here */
    
    #include "MultiSuperLoop.h"
    
    /* End user code. Do not edit comment generated here */
    #include "r_cg_userdefine.h"
    
    /***********************************************************************************************************************
    Global variables and functions
    ***********************************************************************************************************************/
    /* Start user code for global. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE(MultiSuperLoop_Dispatch)
    void MultiSuperLoop_Dispatch(void)
    {
    R_BSP_ASM_BEGIN
    
        /* Re-enable interrupt. */
        R_BSP_ASM( setpsw i                                         )
    
        /* Save the current super loop context. Be aware that the USP is used from now. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( setpsw u                                         )
        R_BSP_ASM( sub U_BSP_ASM_IMM(8), r0                         )
        R_BSP_ASM( push.l r1                                        )
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r1  )
        R_BSP_ASM( mov.b 16[r1], r1                                 )
        R_BSP_ASM( save r1                                          )
    
        /* Move PSW, PC from the interrupt stack to the current super loop's user stack. */
        R_BSP_ASM( mvfc isp, r2                                     )
        R_BSP_ASM( mov.l 4[r2], 8[r0]                               )
        R_BSP_ASM( mov.l 0[r2], 4[r0]                               )
        R_BSP_ASM( add U_BSP_ASM_IMM(8), r2                         )
        R_BSP_ASM( mvtc r2, isp                                     )
    
        /* Select the next super loop. */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r2  )
        R_BSP_ASM( add r2, r1                                       )
        R_BSP_ASM( mov.b [r1], r1                                   )
        R_BSP_ASM( mov.b r1, 16[r2]                                 )
    
        /* Restore the next super loop context. Be aware that the USP is used here. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( rstr r1                                          )
        R_BSP_ASM( pop r1                                           )
        R_BSP_ASM( rte                                              )
    
    R_BSP_ASM_END
    }
    
    void r_Config_CMT3_cmi3_interrupt(void) __attribute__((naked));
    
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    * Function Name: R_Config_CMT3_Create_UserInit
    * Description  : This function adds user code after initializing the CMT3 channel
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void R_Config_CMT3_Create_UserInit(void)
    {
        /* Start user code for user init. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }
    
    /***********************************************************************************************************************
    * Function Name: r_Config_CMT3_cmi3_interrupt
    * Description  : This function is CMI3 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void r_Config_CMT3_cmi3_interrupt(void)
    {
        /* Start user code for r_Config_CMT3_cmi3_interrupt. Do not edit comment generated here */
    
        MultiSuperLoop_Dispatch();
    
        /* End user code. Do not edit comment generated here */
    }
    
    /* Start user code for adding. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE_ASM(_Initialize_RegisterSaveBank)
    void _Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        R_BSP_ASM_INTERNAL_USED(pc)   /* r1 */
        R_BSP_ASM_INTERNAL_USED(usp)  /* r2 */
        R_BSP_ASM_INTERNAL_USED(bank) /* r3 */
    
    R_BSP_ASM_BEGIN
    
        /* Save PSW, USP to scratch registers and disable interrupt.  */
        R_BSP_ASM( mvfc psw, r4                     )
        R_BSP_ASM( clrpsw i                         )
        R_BSP_ASM( mvfc usp, r5                     )
    
        /* Initialize the specified register save bank. */
        R_BSP_ASM( sub U_BSP_ASM_IMM(12), r2        ) /* Reserve the space for PSW, PC and R1. */
        R_BSP_ASM( mvtc r2, usp                     ) /* usp */
        R_BSP_ASM( mov.l r4, 8[r2]                  ) /* psw */
        R_BSP_ASM( mov.l r1, 4[r2]                  ) /* pc */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(0), 0[r2]    ) /* r1 but the value isn't important. */
        R_BSP_ASM( save r3                          ) /* Only the value of USP and FPSW are important. */
    
        /* Restore PSW, USP from scratch registers. */
        R_BSP_ASM( mvtc r5, usp                     )
        R_BSP_ASM( mvtc r4, psw                     )
    
    R_BSP_ASM_END
    }
    
    static void Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        (void) pc;   /* r1 */
        (void) usp;  /* r2 */
        (void) bank; /* r3 */
        _Initialize_RegisterSaveBank(pc, usp, bank);
    }
    
    void MultiSuperLoop_Add_Loop1(void (*pc)(void), uint8_t *usp)
    {
        /* Prevent the debugger from messing up unwinding of the stack. */
        usp = (uint8_t *)usp - sizeof(uint32_t);
        *(uint32_t *)usp = 0;
    
        Initialize_RegisterSaveBank((uint32_t)pc, (uint32_t)usp, 1);
    
        SuperLoopContextTable[16] = 0;
    
        SuperLoopContextTable[ 0] = 1;
        SuperLoopContextTable[ 1] = 0;
        SuperLoopContextTable[ 2] = 255;
        SuperLoopContextTable[ 3] = 255;
        SuperLoopContextTable[ 4] = 255;
        SuperLoopContextTable[ 5] = 255;
        SuperLoopContextTable[ 6] = 255;
        SuperLoopContextTable[ 7] = 255;
        SuperLoopContextTable[ 8] = 255;
        SuperLoopContextTable[ 9] = 255;
        SuperLoopContextTable[10] = 255;
        SuperLoopContextTable[11] = 255;
        SuperLoopContextTable[12] = 255;
        SuperLoopContextTable[13] = 255;
        SuperLoopContextTable[14] = 255;
        SuperLoopContextTable[15] = 255;
    
        R_Config_CMT3_Start();
    }
    
    void MultiSuperLoop_Yield(void)
    {
        uint8_t ipl = get_ipl();
    
        if (ipl == 0)
        {
            set_ipl(1);
        }
    
        /* Switch to the next super loop. Be aware that the value of IPL is */
        /* also switched to the value which is used in the next super loop. */
        int_exception(VECT(PERIB,INTB129));
    
        if (ipl == 0)
        {
            set_ipl(0);
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     
    RXv3_MultiSuperLoop_IAR/src/smc_gen/Config_CMT3/Config_CMT3_user.c
    Config_CMT3_user.c.ICCRX.20230121.txt
    /***********************************************************************************************************************
    * DISCLAIMER
    * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products.
    * No other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
    * applicable laws, including copyright laws. 
    * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE, WHETHER EXPRESS, IMPLIED
    * OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NON-INFRINGEMENT.  ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY
    * LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT,
    * INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR
    * ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability 
    * of this software. By using this software, you agree to the additional terms and conditions found by accessing the 
    * following link:
    * http://www.renesas.com/disclaimer
    *
    * Copyright (C) 2022 Renesas Electronics Corporation. All rights reserved.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    * File Name        : Config_CMT3_user.c
    * Component Version: 2.3.0
    * Device(s)        : R5F566NNHxFP
    * Description      : This file implements device driver for Config_CMT3.
    ***********************************************************************************************************************/
    
    /***********************************************************************************************************************
    Pragma directive
    ***********************************************************************************************************************/
    /* Start user code for pragma. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    Includes
    ***********************************************************************************************************************/
    #include "r_cg_macrodriver.h"
    #include "Config_CMT3.h"
    /* Start user code for include. Do not edit comment generated here */
    
    #include "MultiSuperLoop.h"
    
    /* End user code. Do not edit comment generated here */
    #include "r_cg_userdefine.h"
    
    /***********************************************************************************************************************
    Global variables and functions
    ***********************************************************************************************************************/
    /* Start user code for global. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE(MultiSuperLoop_Dispatch)
    void MultiSuperLoop_Dispatch(void)
    {
    R_BSP_ASM_BEGIN
    
        /* Re-enable interrupt. */
        R_BSP_ASM( setpsw i                                         )
    
        /* Save the current super loop context. Be aware that the USP is used from now. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( setpsw u                                         )
        R_BSP_ASM( sub U_BSP_ASM_IMM(8), r0                         )
        R_BSP_ASM( push.l r1                                        )
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r1  )
        R_BSP_ASM( mov.b 16[r1], r1                                 )
        R_BSP_ASM( save r1                                          )
    
        /* Move PSW, PC from the interrupt stack to the current super loop's user stack. */
        R_BSP_ASM( mvfc isp, r2                                     )
        R_BSP_ASM( mov.l 4[r2], 8[r0]                               )
        R_BSP_ASM( mov.l 0[r2], 4[r0]                               )
        R_BSP_ASM( add U_BSP_ASM_IMM(8), r2                         )
        R_BSP_ASM( mvtc r2, isp                                     )
    
        /* Select the next super loop. */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(_SuperLoopContextTable), r2  )
        R_BSP_ASM( add r2, r1                                       )
        R_BSP_ASM( mov.b [r1], r1                                   )
        R_BSP_ASM( mov.b r1, 16[r2]                                 )
    
        /* Restore the next super loop context. Be aware that the USP is used here. */
        /* (As of today, the DPFPU registers are neither saved nor restored.) */
        R_BSP_ASM( rstr r1                                          )
        R_BSP_ASM( pop r1                                           )
        R_BSP_ASM( rte                                              )
    
    R_BSP_ASM_END
    }
    
    /* End user code. Do not edit comment generated here */
    
    /***********************************************************************************************************************
    * Function Name: R_Config_CMT3_Create_UserInit
    * Description  : This function adds user code after initializing the CMT3 channel
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    void R_Config_CMT3_Create_UserInit(void)
    {
        /* Start user code for user init. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }
    
    /***********************************************************************************************************************
    * Function Name: r_Config_CMT3_cmi3_interrupt
    * Description  : This function is CMI3 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    
    #pragma vector = VECT_PERIB_INTB129
    #if FAST_INTERRUPT_VECTOR == VECT_PERIB_INTB129
    __fast_interrupt static void r_Config_CMT3_cmi3_interrupt(void)
    #else
    __interrupt static void r_Config_CMT3_cmi3_interrupt(void)
    #endif
    {
        /* Start user code for r_Config_CMT3_cmi3_interrupt. Do not edit comment generated here */
    
        MultiSuperLoop_Dispatch();
    
        /* End user code. Do not edit comment generated here */
    }
    
    /* Start user code for adding. Do not edit comment generated here */
    
    R_BSP_PRAGMA_STATIC_INLINE_ASM(_Initialize_RegisterSaveBank)
    void _Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        R_BSP_ASM_INTERNAL_USED(pc)   /* r1 */
        R_BSP_ASM_INTERNAL_USED(usp)  /* r2 */
        R_BSP_ASM_INTERNAL_USED(bank) /* r3 */
    
    R_BSP_ASM_BEGIN
    
        /* Save PSW, USP to scratch registers and disable interrupt.  */
        R_BSP_ASM( mvfc psw, r4                     )
        R_BSP_ASM( clrpsw i                         )
        R_BSP_ASM( mvfc usp, r5                     )
    
        /* Initialize the specified register save bank. */
        R_BSP_ASM( sub U_BSP_ASM_IMM(12), r2        ) /* Reserve the space for PSW, PC and R1. */
        R_BSP_ASM( mvtc r2, usp                     ) /* usp */
        R_BSP_ASM( mov.l r4, 8[r2]                  ) /* psw */
        R_BSP_ASM( mov.l r1, 4[r2]                  ) /* pc */
        R_BSP_ASM( mov.l U_BSP_ASM_IMM(0), 0[r2]    ) /* r1 but the value isn't important. */
        R_BSP_ASM( save r3                          ) /* Only the value of USP and FPSW are important. */
    
        /* Restore PSW, USP from scratch registers. */
        R_BSP_ASM( mvtc r5, usp                     )
        R_BSP_ASM( mvtc r4, psw                     )
    
    R_BSP_ASM_END
    }
    
    static void Initialize_RegisterSaveBank(uint32_t pc, uint32_t usp, uint32_t bank)
    {
        (void) pc;   /* r1 */
        (void) usp;  /* r2 */
        (void) bank; /* r3 */
        _Initialize_RegisterSaveBank(pc, usp, bank);
    }
    
    void MultiSuperLoop_Add_Loop1(void (*pc)(void), uint8_t *usp)
    {
        /* Prevent the debugger from messing up unwinding of the stack. */
        usp = (uint8_t *)usp - sizeof(uint32_t);
        *(uint32_t *)usp = 0;
    
        Initialize_RegisterSaveBank((uint32_t)pc, (uint32_t)usp, 1);
    
        SuperLoopContextTable[16] = 0;
    
        SuperLoopContextTable[ 0] = 1;
        SuperLoopContextTable[ 1] = 0;
        SuperLoopContextTable[ 2] = 255;
        SuperLoopContextTable[ 3] = 255;
        SuperLoopContextTable[ 4] = 255;
        SuperLoopContextTable[ 5] = 255;
        SuperLoopContextTable[ 6] = 255;
        SuperLoopContextTable[ 7] = 255;
        SuperLoopContextTable[ 8] = 255;
        SuperLoopContextTable[ 9] = 255;
        SuperLoopContextTable[10] = 255;
        SuperLoopContextTable[11] = 255;
        SuperLoopContextTable[12] = 255;
        SuperLoopContextTable[13] = 255;
        SuperLoopContextTable[14] = 255;
        SuperLoopContextTable[15] = 255;
    
        R_Config_CMT3_Start();
    }
    
    void MultiSuperLoop_Yield(void)
    {
        uint8_t ipl = get_ipl();
    
        if (ipl == 0)
        {
            set_ipl(1);
        }
    
        /* Switch to the next super loop. Be aware that the value of IPL is */
        /* also switched to the value which is used in the next super loop. */
        int_exception(VECT(PERIB,INTB129));
    
        if (ipl == 0)
        {
            set_ipl(0);
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     

Children
No Data