CHAPTER 16 SYSTEM INITIALIZATION


This chapter describes the system initialization routine performed by the RI600V4.

16.1 Outline

The following shows a processing flow from when a reset interrupt occurs until the control is passed to the task.

Figure 16-1 Processing Flow (System Initialization)



16.2 Boot Processing File (User-Own Coding Module)

The following should be described in the boot processing file.

1 ) Boot processing function (PowerON_Reset_PC( ))

2 ) System down routine (_RI_sys_dwn__)
For details, refer to "13.2.1 System down routine (_RI_sys_dwn__)".

3 ) Include kernel_ram.h and kernel_rom.h

Note The boot processing file which is provided by the RI600V4 as a sample file is resetprg.c. This file includes System down routine (_RI_sys_dwn__).

16.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.)

- Initialize base clock timer
Call "void _RI_init_cmt(void)" which is defined in the "ri_cmt.h" generated by the cfg600.
Refer to "8.9 Initialize Base Clock Timer".



- Start the RI600V4 (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 "19.19 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.


16.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 cfg600, in this order.

16.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.

16.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 RI600V4
 #include    "kernel_id.h"               // Generated by cfg600
 
 #if (((_RI_CLOCK_TIMER) >=0) && ((_RI_CLOCK_TIMER) <= 3))
 #include    "ri_cmt.h"   // Generated by cfg600
                       // Do comment-out when clock.timer is either NOTIMER or OTHER.
 #endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 void PowerON_Reset_PC(void);
 void main(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
    
 //#ifdef __cplusplus   // Remove the comment when you use global class object
 //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
 
 #pragma section ResetPRG        // output PowerON_Reset to PResetPRG section
 
 /////////////////////////////////////////////////////////////////////////////
 // Boot processing
 /////////////////////////////////////////////////////////////////////////////
 #pragma entry PowerON_Reset_PC
 
 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();
 
 //  _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
 
 #if (((_RI_CLOCK_TIMER) >=0) && ((_RI_CLOCK_TIMER) <= 3))
     _RI_init_cmt();  // Initialize CMT for RI600V4
             // Do comment-out when clock.timer is either NOTIMER or OTHER.
 #endif
 
 //  _CALL_INIT();           // Remove the comment when you use global class object
 
     vsta_knl();                     // Start RI600V4
                                     // Never return from vsta_knl
 //  _CLOSEALL();                    // Use SIM I/O
     
 //  _CALL_END();            // Remove the comment when you use global class object
 
     brk();
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // System down routine for RI600V4
 /////////////////////////////////////////////////////////////////////////////
 #pragma section P PRI_KERNEL
 #pragma section B BRI_RAM
 struct SYSDWN_INF{
     W   type;
     VW  inf1;
     VW  inf2;
     VW  inf3;
 };
 
 volatile struct SYSDWN_INF _RI_sysdwn_inf;
 
 void _RI_sys_dwn__( W type, VW inf1, VW inf2, VW inf3 )
 {
    // Now PSW.I=0 (all interrupts are masked.)
     _RI_sysdwn_inf.type = type;
     _RI_sysdwn_inf.inf1 = inf1;
     _RI_sysdwn_inf.inf2 = inf2;
     _RI_sysdwn_inf.inf3 = inf3;
 
    while(1)
    ;
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // RI600V4 system data
 /////////////////////////////////////////////////////////////////////////////
 #include "kernel_ram.h"     // generated by cfg600
 #include "kernel_rom.h"     // generated by cfg600


16.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 cfg600.

3 ) Initialize the system time to 0.

4 ) Create various object which are defined in the system configuration file.

5 ) Pass control to scheduler

16.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().

16.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 RI600V4 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") },
     /* RI600V4 section */
     { __sectop("DRI_ROM"), __secend("DRI_ROM"), __sectop("RRI_RAM") }
 };
 #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") }
 };
 
 #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")
 };
 
 #pragma packoption


16.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 "19.19 Fixed Vector/Exception Vector Information (interrupt_fvector[])".