PART.01
引言
本文详细介绍了RX MCU从复位到进入main函数的过程,有助于读者对RX MCU体系结构的理解,RAM和ROM的初始化,以及bootloader程序的开发。
PART.02
启动代码流程分析
RX MCU启动代码主要在resetprg.c文件中,RX的启动代码以C语言实现,因此可读性和可维护性更高。启动代码统一放在PowerON_Reset_PC函数内,复位向量表保存的正是该函数入口的物理地址。因此当芯片发生复位后,CPU会从复位向量取出该地址,并自动跳转到PowerON_Reset_PC函数执行,完成启动流程并最终进入应用程序。
具体的启动流程如下

2.1 从复位向量到启动函数
MCU复位后,CPU会从复位向量地址0xFFFFFFFC读取一个32位入口地址(Reset Vector)。该入口地址会被装载到PC(程序计数器)中,随后CPU跳转到该入口地址开始执行启动代码,0xFFFFFFFC存放的是复位入口函数(PowerON_Reset_PC)的地址。RX的内存分区情况以及跳转过程如下图所示:

2.2 设置栈指针
在调用入口函数(PowerOn_Reset_PC)之前,需要初始化栈指针,这一步设计在CC-RX编译器中。CC‑RX编译器在该函数开头自动插入栈指针初始化:
1RX有两种栈可以设置:中断栈指针Interrupt Stack Pointer(ISP)、用户栈指针User Stack Pointer(USP),其中中断栈是必须的。
2MVTC是Renesas RX指令集中的一条汇编指令,全称Move To Control Register,是“把数据写入控制寄存器”。
3TOPOF SU+SIZEOF SU等于SU段起始地址+段大小=段末端(栈顶);SI同理。
4初始化把USP/ISP设到各自栈区的栈顶,以便随后栈向低地址增长。
2.3初始化中断、异常向量表寄存器:INTB、EXTB
配置中断和异常的控制寄存器,初始化系统中断和异常的响应。
代码如下:

2.4 初始化浮点状态寄存器:FPSW
FPSW是CPU控制浮点单元的状态寄存器,在启动时需要初始化为预设值,以确保浮点计算正确。
代码如下:

2.5 切换到高速运行时钟
MCU RX上电复位后,首先使用的是LOCO(Low-speed on-chip oscillator),到这一步后,时钟源从LOCO切换到用户选择的高速运行时钟,如HOCO(High-speed on-chip oscillator)。
代码如下:

1
切换MCU到高速运行模式,调用operating_frequency_set()来设置系统时钟频率。
2
条件编译:如果不是Bootloader工程(BSP_CFG_BOOTLOADER_PROJECT == 0),则执行lpt_clock_source_select(),用于选择低功耗定时器(LPT)的时钟源。
2.6 初始化C运行环境
代码如下:

在该阶段,调用标准库函数_INITSCT完成RAM数据区初始化:
1对初始化表BTBL[]指定的B段(.bss段)执行清零;对DTBL[]指定的D/R段(.data段),将ROM中D段初始值拷贝到RAM中对应的R段。
2DTBL[]与BTBL[]分别存放在C$DSEC 与C$BSEC段,并通过__sectop() / __secend()等段操作符提供各段的边界地址,供_INITSCT函数遍历处理。
2.7 初始化RAM
代码如下:

“硬件资源锁(hardware lock)”机制:用一个全局锁数g_bsp_Locks来防止多个模块/线程/中断同时访问同一个外设资源导致冲突。g_bsp_Locks是RAM变量,必须初始化。BSP_NUM_LOCKS是“枚举总数”。
2.8 初始化I/O库
初始化C标准库的I/O流(stdin/stdout/stderr),代码如下:

打开或创建标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)的文件,可以用printf输出打印信息。
2.9 初始化MCU的中断回调
代码如下:

注
初始化BSP的“中断回调函数表”,把所有中断源的回调函数先设为“空函数占位”。避免野指针。
2.10 初始化寄存器保护功能
代码如下:

注
为MCU的寄存器写保护(Register Write Protection)功能做初始化,并定义受保护寄存器的分类。
2.11 配置MCU和板级硬件
代码如下:

1output_ports_configure():用户可以根据应用需求进行输出端口的配置。
2interrupts_configure():用户可以根据应用需求进行中断的配置。
3peripheral_modules_enable():启用和配置MCU的外设。
4bsp_non_existent_port_init():初始化“芯片封装上不存在的引脚”。
2.12 使能中断和选择栈
(I Stack or U Stack)
代码如下:

开中断和选择使用哪一个栈:
I stack or U stack(即中断栈或用户栈)。
使用RTOS情况下:进入Supervisor(特权)模式,并且在启动阶段保持中断关闭。
非RTOS情况:如果用户只选择1个栈,则不会设置“U”位(即用户栈),CPU将始终使用中断栈。
2.13 选择是否使用RTOS并进入main函数
无RTOS或Azure RTOS直接调用R_BSP_MAIN_FUNCTION()(就是main()),不应该返回。

至此,是RXMCU 从上电复位到进入main()的全过程。
需要技术支持?
如您在使用瑞萨MCU/MPU产品中有任何问题,可识别下方二维码或复制网址到浏览器中打开,进入瑞萨技术论坛寻找答案或获取在线技术支持。