Everything

CHAPTER 17 SYSTEM INITIALIZATION


This chapter describes the system initialization routine performed by the RI600PX.
17.1 Outline
The following shows a processing flow from when a reset interrupt occurs until the control is passed to the task.
Figure 17-1 Processing Flow (System Initialization)
17.2 Boot Processing File (User-Own Coding Module)
The following should be described in the boot processing file.
Note The boot processing file which is provided by the RI600PX as a sample file is "resetprg.c".
17.2.1 Boot processing function (PowerON_Reset_PC( ))
The boot processing function is the program registered in the reset vector, and is executed in supervisor mode. Generally, following processing are required in the boot processing function.
- Initialize the processor and hardwares
If using Fast Interrupt of the RX-MCU, initialize the FINTV register to the start address of the fast interrupt handler.
- Initialize C/C++ runtime environment (Initialize sections, etc.)
- Start the RI600PX (call vsta_knl or ivsta_knl)
- Basic form of boot processing function
The boot processing function should be implemented as "void PowerON_Reset_PC(void)". When the name of the boot processing function is other, it is necessary to define the function name to "interrupt_fvector[31]" in the system configuration file.
Note For the details of the details of the static API "interrupt_fvector[]", refer to "20.22 Fixed Vector/Exception Vector Information (interrupt_fvector[])".
- The points of concern about the boot processing function
- Stack
Describe #pragma entry directive to be shown below. Thereby, the object code which sets the stack pointer (ISP) as the system stack at the head of the boot processing function is generated.
 #pragma entry PowerON_Reset_PC

- PSW register
Keep the status that all interrupts are prohibited and in the supervisor mode until calling the Kernel Initialization Module (vsta_knl, ivsta_knl). This status is satisfied just behind CPU reset (PSW.I=0, PSW.PM=0). Generally, the boot processing function should not change the PSW.
- EXTB register (RXv2 architecture)
Initialize EXTB register to the start address of FIX_INTERRUPT_VECTOR section if needed. Please refer to FIX_INTERRUPT_VECTOR section in section 2.6.4.
- Service call
Since the boot processing function is executed before executing of Kernel Initialization Module (vsta_knl, ivsta_knl), service calls except vsta_knl and ivsta_knl must not be called from the boot processing function.
17.2.2 Include kernel_ram.h and kernel_rom.h
The boot processing file must include "kernel_ram.h" and "kernel_rom.h", which are generated by the cfg600px, in this order.
17.2.3 Compiler option for boot processing file
The following compiler options are required for the boot processing file.
- "-lang=c" or "-lang=c99"
- "-nostuff"
- Suitable -isa or -cpu
Note Compiler option "-isa" is supported by the compiler CC-RX V2.01 or later.
17.2.4 Example of the boot processing file
 #include    <machine.h>
 #include    <_h_c_lib.h>
 //#include  <stddef.h>                  // Remove the comment when you use errno
 //#include  <stdlib.h>                  // Remove the comment when you use rand()
 #include    "typedefine.h"              // Define Types
 #include    "kernel.h"                  // Provided by RI600PX
 #include    "kernel_id.h"               // Generated by cfg600px
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 void PowerON_Reset_PC(void);
 #ifdef __cplusplus
 }
 #endif
 
 // #ifdef __cplusplus                // Use SIM I/O
 // extern "C" {
 // #endif
 // extern void _INIT_IOLIB(void);
 // extern void _CLOSEALL(void);
 // #ifdef __cplusplus
 // }
 // #endif
 
 #define FPSW_init 0x00000000  // FPSW bit base pattern
 
 // extern void srand(_UINT);     // Remove the comment when you use rand()
 // extern _SBYTE *_s1ptr;        // Remove the comment when you use strtok()
 
 // #ifdef __cplusplus                // Use Hardware Setup
 // extern "C" {
 // #endif
 // extern void HardwareSetup(void);
 // #ifdef __cplusplus
 
 // #endif
 
 // extern "C" {                  // Sections C$INIT and C$END will be generated
 // #endif
 // extern void _CALL_INIT(void);
 // extern void _CALL_END(void);
 // #ifdef __cplusplus
 // }
 // #endif
 ////////////////////////////////////////////////////////////
 // Section definition
 ////////////////////////////////////////////////////////////
 #pragma section P PS
 #pragma section B BS
 #pragma section C CS
 #pragma section D DS
 
 #pragma entry PowerON_Reset_PC
 
 ////////////////////////////////////////////////////////////
 // Boot processing
 ////////////////////////////////////////////////////////////
 void PowerON_Reset_PC(void)
 {
 #ifdef __ROZ                        // Initialize FPSW
 #define _ROUND 0x00000001           // Let FPSW RMbits=01 (round to zero)
 #else
 #define _ROUND 0x00000000           // Let FPSW RMbits=00 (round to nearest)
 #endif
 #ifdef __DOFF
 #define _DENOM 0x00000100           // Let FPSW DNbit=1 (denormal as zero)
 #else
 #define _DENOM 0x00000000           // Let FPSW DNbit=0 (denormal as is)
 #endif
 
 //    set_extb(__sectop("FIX_INTERRUPT_VECTOR"));// Initialize EXTB register
                                                  //  (only for RXv2 arch.)
     set_fpsw(FPSW_init | _ROUND | _DENOM);
 
     _INITSCT();                     // Initialize Sections
 
 //  _INIT_IOLIB();                  // Use SIM I/O
 
 //  errno=0;                        // Remove the comment when you use errno
 //  srand((_UINT)1);                // Remove the comment when you use rand()
 //  _s1ptr=NULL;                    // Remove the comment when you use strtok()
 
 //  HardwareSetup();                // Use Hardware Setup
     nop();
 
 //  set_fintv(<handler address>);   // Initialize FINTV register
 
 //  _CALL_INIT();           // Remove the comment when you use global class object
 
     vsta_knl();                     // Start RI600PX
                                     // Never return from vsta_knl
 
 //  _CLOSEALL();                    // Use SIM I/O
 
 //  _CALL_END();            // Remove the comment when you use global class object
 
     brk();
 
 }
 /////////////////////////////////////////////////////////////////////////////
 // RI600PX system data
 /////////////////////////////////////////////////////////////////////////////
 #include "kernel_ram.h"     // generated by cfg600px
 #include "kernel_rom.h"     // generated by cfg600px

17.3 Kernel Initialization Module (vsta_knl, ivsta_knl)
The kernel initialization module is executed by calling vsta_knl, ivsta_knl. Generally, vsta_knl, ivsta_knl is called from the Boot processing function (PowerON_Reset_PC( )).
The following processing is executed in the kernel initialization module.
1 ) Initialize ISP register to the end address of SI section + 1
2 ) Initialize INTB register to the start address of the relocatable vector table (INTERRUPT_VECTOR section). The relocatable vector table is generated by the cfg600px.
3 ) Initialize the system time to 0.
4 ) Create various object which are defined in the system configuration file. If an error is detected in this process, the system will be down.
5 ) Initialize MPU (Memory Protection Unit).
7 ) Pass control to scheduler
17.4 Section Initialization Function (_INITSCT( ))
The section initialization function "_INITSCT()" called from Boot processing function (PowerON_Reset_PC( )) is provided by the compiler. The _INITSCT() clears the uninitialized data section to 0 and initializes the initialized data section in order to the tables described in the Section information file (User-Own Coding Module).
The user needs to write the sections to be initialized to the tables for section initialization (DTBL and BTBL) in the section information file. The section address operator is used to set the start and end addresses of the sections used by the _INITSCT(). Section names in the section initialization tables are declared, using C$BSEC for uninitialized data areas, and
C$DSEC for initialized data areas.
Initialized sections written in DTBL must be mapped from ROM to RAM by using "-rom" linker option. For details, refer to "2.6.5 Initialized data section".
Note See "CubeSuite+ RX Coding" for details of the _INITSCT().
17.4.1 Section information file (User-Own Coding Module)
The section information file should be implemented as user-own coding module.
The example of the section information file is shown below.
Note The section information file which is provided by the RI600PX as a sample file is "dbsct.c".
 #include "typedefine.h"
 
 #pragma unpack
 
 #pragma section C C$DSEC
 extern const struct {
     _UBYTE *rom_s;       /* Start address of the initialized data section in ROM */
     _UBYTE *rom_e;       /* End address of the initialized data section in ROM   */
     _UBYTE *ram_s;       /* Start address of the initialized data section in RAM */
 }   _DTBL[] = {
     { __sectop("D"), __secend("D"), __sectop("R") },
     { __sectop("D_2"), __secend("D_2"), __sectop("R_2") },
     { __sectop("D_1"), __secend("D_1"), __sectop("R_1") },
     { __sectop("DS"), __secend("DS"), __sectop("RS") },
     { __sectop("DS_2"), __secend("DS_2"), __sectop("RS_2") },
     { __sectop("DS_1"), __secend("DS_1"), __sectop("RS_1") },
     { __sectop("DU_SH"), __secend("DU_SH"), __sectop("RU_SH") },
     { __sectop("DU_SH_2"), __secend("DU_SH_2"), __sectop("RU_SH_2") },
     { __sectop("DU_SH_1"), __secend("DU_SH_1"), __sectop("RU_SH_1") },
     { __sectop("DU_MASTERDOM"), __secend("DU_MASTERDOM"),
                                             __sectop("RU_MASTERDOM") },
     { __sectop("DU_MASTERDOM_2"), __secend("DU_MASTERDOM_2"),
                                             __sectop("RU_MASTERDOM_2") },
     { __sectop("DU_MASTERDOM_1"), __secend("DU_MASTERDOM_1"),
                                             __sectop("RU_MASTERDOM_1") },
     { __sectop("DU_DOM_A"), __secend("DU_DOM_A"), __sectop("RU_DOM_A") },
     { __sectop("DU_DOM_A_2"), __secend("DU_DOM_A_2"), __sectop("RU_DOM_A_2") },
     { __sectop("DU_DOM_A_1"), __secend("DU_DOM_A_1"), __sectop("RU_DOM_A_1") },
     { __sectop("DU_DOM_B"), __secend("DU_DOM_B"), __sectop("RU_DOM_B") },
     { __sectop("DU_DOM_B_2"), __secend("DU_DOM_B_2"), __sectop("RU_DOM_B_2") },
     { __sectop("DU_DOM_B_1"), __secend("DU_DOM_B_1"), __sectop("RU_DOM_B_1") }
 };
 
 #pragma section C C$BSEC
 extern const struct {
     _UBYTE *b_s;         /* Start address of non-initialized data section */
     _UBYTE *b_e;         /* End address of non-initialized data section */
 }   _BTBL[] = {
     { __sectop("B"), __secend("B") },
     { __sectop("B_2"), __secend("B_2") },
     { __sectop("B_1"), __secend("B_1") },
     { __sectop("BS"), __secend("BS") },
     { __sectop("BS_2"), __secend("BS_2") },
     { __sectop("BS_1"), __secend("BS_1") },
     { __sectop("BU_SH"), __secend("BU_SH") },
     { __sectop("BU_SH_2"), __secend("BU_SH_2") },
     { __sectop("BU_SH_1"), __secend("BU_SH_1") },
     { __sectop("DU_MASTERDOM"), __secend("DU_MASTERDOM"),
                                             __sectop("RU_MASTERDOM") },
     { __sectop("DU_MASTERDOM_2"), __secend("DU_MASTERDOM_2"),
                                             __sectop("RU_MASTERDOM_2") },
     { __sectop("DU_MASTERDOM_1"), __secend("DU_MASTERDOM_1"),
                                             __sectop("RU_MASTERDOM_1") },
     { __sectop("DU_DOM_A"), __secend("DU_DOM_A"), __sectop("RU_DOM_A") },
     { __sectop("DU_DOM_A_2"), __secend("DU_DOM_A_2"), __sectop("RU_DOM_A_2") },
     { __sectop("DU_DOM_A_1"), __secend("DU_DOM_A_1"), __sectop("RU_DOM_A_1") },
     { __sectop("DU_DOM_B"), __secend("DU_DOM_B"), __sectop("RU_DOM_B") },
     { __sectop("DU_DOM_B_2"), __secend("DU_DOM_B_2"), __sectop("RU_DOM_B_2") },
     { __sectop("DU_DOM_B_1"), __secend("DU_DOM_B_1"), __sectop("RU_DOM_B_1") }
 };
 
 #pragma section C C$BSEC
 extern const struct {
     _UBYTE *b_s;         /* Start address of non-initialized data section */
     _UBYTE *b_e;         /* End address of non-initialized data section */
 }   _BTBL[] = {
     { __sectop("B"), __secend("B") },
     { __sectop("B_2"), __secend("B_2") },
     { __sectop("B_1"), __secend("B_1") },
     { __sectop("BS"), __secend("BS") },
     { __sectop("BS_2"), __secend("BS_2") },
     { __sectop("BS_1"), __secend("BS_1") },
     { __sectop("BU_SH"), __secend("BU_SH") },
     { __sectop("BU_SH_2"), __secend("BU_SH_2") },
     { __sectop("BU_SH_1"), __secend("BU_SH_1") },
     { __sectop("BU_MASTERDOM"), __secend("BU_MASTERDOM") },
     { __sectop("BU_MASTERDOM_2"), __secend("BU_MASTERDOM_2") },
     { __sectop("BU_MASTERDOM_1"), __secend("BU_MASTERDOM_1") },
     { __sectop("BU_DOM_A"), __secend("BU_DOM_A") },
     { __sectop("BU_DOM_A_2"), __secend("BU_DOM_A_2") },
     { __sectop("BU_DOM_A_1"), __secend("BU_DOM_A_1") },
     { __sectop("BU_DOM_B"), __secend("BU_DOM_B") },
     { __sectop("BU_DOM_B_2"), __secend("BU_DOM_B_2") },
     { __sectop("BU_DOM_B_1"), __secend("BU_DOM_B_1") }
 };
 #pragma section
 
 /*
 ** CTBL prevents excessive output of L1100 messages when linking.
 ** Even if CTBL is deleted, the operation of the program does not change.
 */
 _UBYTE * const _CTBL[] = {
     __sectop("C_1"), __sectop("C_2"), __sectop("C"),
     __sectop("W_1"), __sectop("W_2"), __sectop("W"),
     __sectop("CU_MASTERDOM"),
     __sectop("CU_DOM_A_1"), __sectop("CU_DOM_A_2"), __sectop("CU_DOM_A"),
     __sectop("CU_DOM_B_1"), __sectop("CU_DOM_B_2"), __sectop("CU_DOM_B"),
     __sectop("WU_SH_1"), __sectop("WU_SH_2"), __sectop("WU_SH"),
     __sectop("LU_SH"),
     __sectop("CU_SH_1"), __sectop("CU_SH_2"), __sectop("CU_SH"),
     __sectop("CS_1"), __sectop("CS_2"), __sectop("CS"), __sectop("P")
 };
 
 #pragma packoption

17.5 Registers in Fixed Vector Table / Exception Vector Table
For some MCUs, the endian select register, ID code protection on connection of the on-chip debugger, etc. are assigned in the address from 0xFFFFFF80 to 0xFFFFFFBF in fixed vector table (RXv1 architecture) / exception vector table (RXv2 architecture). To set up such registers, describe "interrupt_fvector[]" in the system configuration file. For details, refer to "20.22 Fixed Vector/Exception Vector Information (interrupt_fvector[])".