瑞萨RH850 CODE flash 库详细解说,代码闪存库(Type T01)使用教程
瑞萨RH850 CODE flash 库详细解说,代码闪存库(Type T01)使用教程
RH850 系列微控制器的代码闪存库(Code Flash Library,简称 FCL)Type T01 用户手册(版本 V2.xx,xx≥10)编写,RH850 器件代码闪存的自编程功能
该 FCL 库为 RH850 系列微控制器提供代码闪存的擦除、写入、保护等自编程操作支持,适用于 Green Hills、IAR 和瑞萨 CubeSuite + 开发环境,需注意 IAR 环境仅在欧美地区支持。库以源代码形式交付,同时提供设备相关的示例应用程序、构建脚本和 GNU Make 工具,便于开发人员快速集成和使用。
二、基础知识
2.1 关键术语与缩写
在使用FCL库前,需理解以下关键术语和缩写,后续内容将基于这些术语展开:
| 缩写 | 全称 | 说明 |
|---|---|---|
| API | Application Programming Interface | 应用程序编程接口,用于用户程序与FCL库交互 |
| Code Flash | 代码闪存 | 存储应用代码或常量数据的嵌入式闪存 |
| Data Flash | 数据闪存 | 主要存储EEPROM仿真数据的嵌入式闪存 |
| Dual operation | 双重操作 | 在重新编程一个闪存区域时访问另一个闪存区域的能力,不同代码闪存宏之间的支持情况取决于器件实现 |
| ECC | Error Correction Code | 纠错码,用于检测和纠正闪存数据错误 |
| Flash | 闪存 | 电可擦除可编程非易失性存储器,可多次重新编程,区别于ROM |
| Flash area | 闪存区域 | 由多个连贯闪存块组成的闪存区域 |
| Flash block | 闪存块 | 闪存的最小可擦除单元 |
| FCL | Code Flash Library | 代码闪存库(代码闪存访问层) |
| FDL | Data Flash Library | 数据闪存库(数据闪存访问层) |
| OPB | Option bytes | 用于定义器件启动时行为的选项字节 |
| OTP | One Time Programmable | 一次性可编程,只能编程一次的存储区域 |
| RAM | Random Access Memory | 随机存取存储器,易失性存储器,可随机访问 |
| ROM | Read Only Memory | 只读存储器,非易失性存储器,正常操作时内容无法更改 |
| Self-programming | 自编程 | 无需外部编程工具,仅通过微控制器上运行的控制代码重新编程嵌入式闪存的能力 |
| Serial programming | 串行编程 | 使用外部编程工具对器件进行编程的板载编程模式 |
| User area(User memory) | 用户区域(用户存储器) | 可用于常规用户程序的代码闪存区域,大部分用户代码存储于此 |
| User boot area(Extended user memory) | 用户引导区域(扩展用户存储器) | 用于存储引导加载程序(bootloader)应用的代码闪存区域 |
2.2 闪存架构
RH850微控制器系列的多数器件除代码闪存(Code Flash)外,还配备独立的数据闪存(Data Flash)区域,数据闪存专门用于存储数据,不能用于指令执行(代码获取)。
2.2.1 双重操作(Dual Operation)
所有闪存实现的共性是:在执行闪存修改操作(擦除/写入)期间,一定量的闪存无法进行读取和/或程序执行,这不仅涉及被修改的闪存范围,还包括整个闪存系统的特定部分,无法访问的闪存量取决于器件架构。
标准架构方案是将闪存分为代码闪存和数据闪存,通过这种分离,在修改数据闪存时可以从代码闪存读取(执行程序代码或读取数据),反之亦然。若需确认器件是否支持双重操作,可参考该器件的用户手册。
注意:不能同时修改代码闪存和数据闪存。
2.2.2 闪存粒度(Flash Granularity)
RH850器件的代码闪存分为8KB或32KB大小的块,FCL擦除操作只能对这两种可用大小中的完整块执行,部分器件可能没有8KB块大小,有些器件可能有两个代码闪存库,具体器件的代码闪存块数量和库信息可参考对应器件的用户手册。
数据写入的粒度为256字节,且需与块边界对齐。此外,不要从已擦除的代码闪存中读取数据,否则会产生ECC错误。
RH850器件的代码闪存分为两个用户区域:
- 用户区域(User area/User memory):存储用户程序的代码闪存区域。
- 用户引导区域(User boot area/Extended user memory):用于存储特殊应用部分(如引导加载程序)的代码闪存区域,部分器件可能禁止通过自编程对其进行编程或擦除,具体需参考对应器件的用户手册。
三、FCL库架构
自编程系统由多个分层功能块构成,本教程重点介绍FCL的功能和使用方法,但了解所有相关功能块及其关系对理解FCL的概念和使用至关重要。
自编程系统的软件架构包含以下几个块,各块之间的关系如图1所示:
- 用户应用程序(User Application):代表用户提供的应用程序(包括可能的启动程序)。
- FCL库:提供所有必要的功能和操作,以用户友好的C语言接口实现应用程序的重新编程。
- 微控制器(Microcontroller):作为中间层,连接用户应用程序、FCL库与闪存硬件。
- 闪存硬件(Flash Hardware):代表由FCL控制的闪存编程硬件(闪存定序器)。

FCL库以源代码形式发布,作为安装程序包交付,包含示例应用程序、构建脚本和GNU Make工具,可直接在专用器件上编译和运行,有关交付包的详细文件结构信息,可参考后续“库的设置与使用”章节中的“文件结构”部分。
四、FCL功能规范
4.1 RAM中的代码执行
自编程应用程序和FCL最初位于代码闪存中,但在库操作期间,由于硬件资源忙于闪存编程,代码闪存通常无法访问,因此必须将用户应用程序和库的部分代码复制到RAM存储器中执行,可使用内部RAM,若不考虑安全性,也可使用外部RAM。
无需将所有代码复制到RAM,只需复制编程期间会访问的代码部分,复制的代码量不大,但需仔细选择。若访问未复制的代码,或因中断、异常、看门狗复位等导致访问代码闪存,可能会引发诸多错误。
将必要部分复制到可用RAM有三种方法:
- C启动(C-startup):代码链接到目标地址,系统启动时,调用编译器特定的例程,将代码从ROM映像(通常在代码闪存中)复制到RAM。
- R_FCL_CopySections函数:FCL库提供API函数
R_FCL_CopySections,可将所有需要的段复制到用户定义的地址。 - 用户特定方法(User specific):若为特定实现,用户需负责段的正确定位。
根据配置的模式(内部模式或用户模式,详见4.2节“操作模式”),需复制到RAM的链接段如下表所示:
| 预编译配置 | 复制到RAM的段 |
|---|---|
| R_FCL_CODE_RAM_USRINT | R_FCL_CODE_RAM_USR、R_FCL_CODE_RAM、R_FCL_CODE_ROMRAM、R_FCL_HANDLER_CALL_USER |
| R_FCL_CODE_RAM_USRINT | R_FCL_CODE_RAM_USR、R_FCL_CODE_RAM、R_FCL_HANDLER_CALL_INTERNAL |
有关链接段的更多信息,可参考后续“库的设置与使用”章节中的“链接段”部分。
4.2 操作模式
自编程可考虑以下两种主要场景,对应FCL库的两种操作模式:
4.2.1 用户模式(User mode)
自编程库的大部分代码在内部RAM中执行,包括重新编程控制功能和自编程期间需执行的其他用户代码,此模式适用于RAM充足的器件。
在用户模式下,自编程期间始终可以执行用户代码,因为FCL函数调用仅启动闪存操作,FCL将控制权返回给用户应用程序后,闪存操作在后台执行,用户需通过状态检查函数(详见后续“用户接口(API)”章节中的“R_FCL_Handler函数”)轮询操作状态。若所有相关函数以及中断向量表都位于RAM中,则中断例程和用户代码执行均可行。
要启用此模式,需将库配置为使用用户模式(详见后续“用户接口(API)”章节中的“库编译时配置”)。
用户模式下的异步执行示例如图2所示(此处应插入图2,因文本限制无法直接插入,可参考原文档图2),用户应用程序需通过调用R_FCL_Handler函数轮询库,以处理库和硬件中发生的所有小型操作。
4.2.2 内部模式(Internal mode)
库中只有小部分代码在RAM中执行,其余代码在代码闪存中执行。自编程期间无法执行正常的用户代码,因为FCL函数同步执行——操作未完成前函数不会返回,因此自编程期间只能处理中断。
要启用此模式,需将库配置为使用内部模式(详见后续“用户接口(API)”章节中的“库编译时配置”)。
4.3 面向请求的操作
FCL采用请求-响应架构启动命令,即任何“请求者”(用户应用程序中的任何任务)都需准备一个请求结构,并通过R_FCL_Execute函数将其以引用方式传递给库。FCL解析请求结构的内容,检查结构成员的合理性并启动执行,反馈通过同一请求结构的status_enu成员返回给请求者。
根据库的操作模式,status_enu结构成员的更新方式不同:
- 内部模式:
R_FCL_Execute函数返回时,会用最终结果更新状态。 - 用户模式:若给定参数正确,
R_FCL_Execute会立即返回R_FCL_BUSY状态,需定期调用R_FCL_Handler函数,直到请求状态不再是R_FCL_BUSY,命令才算完成。在其余时间,只要不使用闪存资源,用户应用程序可自由执行其他操作。
请求结构是FCL操作的核心,其使用方式如图3所示(此处应插入图3,因文本限制无法直接插入,可参考原文档图3),用户应用程序可对请求结构进行读写操作,请求结构包含command_enu(命令)、bufferAdd_u32(缓冲区地址)、idx_u32(索引)、cnt_u16(计数)和status_enu(状态)等成员。
4.4 暂停/恢复机制(Suspend/Resume mechanism)
部分操作可能持续较长时间,用户可能无法等待其完成,FCL提供暂停这些操作并在后续恢复执行的功能。
FCL支持暂停R_FCL_CMD_WRITE(写入)和R_FCL_CMD_ERASE(擦除)操作,命令暂停后,代码闪存会重新开启,以便从其中执行代码。此外,在R_FCL_CMD_ERASE操作暂停期间,还可执行R_FCL_CMD_WRITE操作,但只能在不受暂停擦除操作影响的闪存块上执行。
注意:暂停-恢复功能仅在用户模式下可用。
暂停擦除命令、执行写入操作然后恢复擦除命令的示例流程如图4所示(此处应插入图4,因文本限制无法直接插入,可参考原文档图4)。
同时,需注意以下序列无法实现:
- 擦除→暂停→擦除
- 写入→暂停→擦除
- 写入→暂停→写入
- 嵌套暂停(如:擦除→暂停→写入→暂停)
另外,擦除操作暂停后恢复,不会被视为对指定闪存擦除耐久性的额外擦除。
4.5 取消机制(Cancel mechanism)
闪存擦除和写入是耗时操作,在某些情况下,用户应用程序可能无法等待长时间的闪存操作完成,因此这类操作应可取消。
注意:取消功能仅在用户模式下可用。
取消擦除命令的示例流程如图5所示(此处应插入图5,因文本限制无法直接插入,可参考原文档图5),正在进行或已暂停的擦除/写入操作,在取消请求后都会以取消状态结束;若一个操作已暂停且另一个操作正在进行,请求取消时两个操作都会被取消。
4.6 循环监控(Loop supervision)
部分FCL命令有内部轮询循环以检查硬件状态,这些循环由FCL软件进行时间监控,避免CPU陷入无限循环。若发生硬件错误,FCL会在超时后中止操作,并在当前命令上报告R_FCL_ERR_INTERNAL(内部错误)。
超时时间取决于轮询循环的延迟,但只要器件CPU在FCL正常操作允许的频率范围内运行,超时时间会小于800微秒。
4.7 内部错误(Internal error)
当FCL检测到异常行为时,会报告命令状态R_FCL_ERR_INTERNAL(内部错误),遇到此错误后可采取以下步骤恢复:
- 重新运行命令。
- 重新初始化库(执行
R_FCL_Init函数,然后运行R_FCL_CMD_PREPARE_ENV命令)。 - 若步骤2再次失败,复位器件并继续重新初始化。
- 若步骤3仍失败,更换器件。
注意:根据硬件错误情况,代码闪存或数据闪存可能仍处于编程模式,这种情况下只能采用步骤3和步骤4的补救措施。
五、用户接口(API)
5.1 库编译时配置
FCL的预编译配置位于fcl_cfg.h文件中,用户需通过修改该头文件中的相关常量定义,配置所有参数和属性,该文件还可能包含器件或应用程序特定的定义。
配置文件包含多个选项元素,用于配置和自定义FCL,各选项的描述如下表所示:
| 选项 | 描述 |
|---|---|
| R_FCL_COMMAND_EXECUTION_MODE | 定义状态检查是由库内部执行还是由用户执行,以允许在状态检查之间执行用户代码。可能的值: - R_FCL_HANDLER_CALL_INTERNAL(内部模式) - R_FCL_HANDLER_CALL_USER(用户模式) 详见后续各模式优缺点说明 |
| R_FCL_SUPPORT_LOCKBIT | 启用或禁用以下命令: - R_FCL_CMD_GET_LOCKBIT(获取锁定位) - R_FCL_CMD_SET_LOCKBIT(设置锁定位) - R_FCL_CMD_ENABLE_LOCKBITS(启用锁定位机制) - R_FCL_CMD_DISABLE_LOCKBITS(禁用锁定位机制) |
| R_FCL_SUPPORT_OTP | 启用或禁用以下命令: - R_FCL_CMD_GET_OTP(获取OTP位) - R_FCL_CMD_SET_OTP(设置OTP位) |
| R_FCL_SUPPORT_DEVICENAME | 启用或禁用R_FCL_CMD_GET_DEVICE_NAME(获取器件名称)命令 |
| R_FCL_SUPPORT_BLOCKCNT | 启用或禁用R_FCL_CMD_GET_BLOCK_CNT(获取块数量)命令 |
| R_FCL_SUPPORT_BLOCKENDADDR | 启用或禁用R_FCL_CMD_GET_BLOCK_END_ADDR(获取块结束地址)命令 |
| R_FCL_SUPPORT_OPB | 启用或禁用以下命令: - R_FCL_CMD_GET_OPB(获取选项字节) - R_FCL_CMD_SET_OPB(设置选项字节) |
| R_FCL_SUPPORT_ID | 启用或禁用以下命令: - R_FCL_CMD_GET_ID(获取ID) - R_FCL_CMD_SET_ID(设置ID) |
| R_FCL_SUPPORT_RESETVECTOR | 启用或禁用以下命令: - R_FCL_CMD_GET_RESET_VECTOR(获取复位向量) - R_FCL_CMD_SET_RESET_VECTOR(设置复位向量) |
| R_FCL_SUPPORT_SECURITYFLAGS | 启用或禁用以下命令: - R_FCL_CMD_SET_READ_PROTECT_FLAG(设置读保护标志) - R_FCL_CMD_SET_WRITE_PROTECT_FLAG(设置写保护标志) - R_FCL_CMD_SET_ERASE_PROTECT_FLAG(设置擦除保护标志) - R_FCL_CMD_SET_SERIAL_PROG_DISABLED(禁用串行编程) - R_FCL_CMD_SET_SERIAL_ID_ENABLED(启用串行ID检查) |
| R_FCL_NO_BFA_SWITCH(V2.11及更高版本支持) | 执行R_FCL_CMD_PREPARE_ENV命令期间,代码闪存需多次关闭,以从固件区域读取数据并准备FCL环境。部分器件执行此准备工作所需的关闭次数较少,若FCL在这类器件上运行,必须定义R_FCL_NO_BFA_SWITCH。当FCL以此选项定义构建时,不要定义R_FCL_MIRROR_FCU_COPY或R_FCL_NO_FCU_COPY,此选项适用于F1K、F1KM、F1KH器件组,不适用于其他器件 |
| R_FCL_MIRROR_FCU_COPY(V2.12及更高版本支持,面向未来产品) | 定义此选项后,FCL不会在用户区域和FCU固件区域之间切换。当FCL以此选项定义构建时,不要定义R_FCL_NO_BFA_SWITCH或R_FCL_NO_FCU_COPY |
| R_FCL_NO_FCU_COPY(V2.12及更高版本支持) | 定义此选项后,不会执行FCU固件传输功能。此选项为RH850/D1M1A、D1M1-V2和D1S1器件设置和构建,当FCL以此选项定义构建时,不要定义R_FCL_NO_BFA_SWITCH或R_FCL_MIRROR_FCU_COPY |
| R_FCL_CFL2_START_ADDR_2048K(V2.12及更高版本支持,面向未来产品) | 此选项将代码闪存库B的起始地址设置为0x00200000,有关代码闪存库B的信息,参考器件硬件手册,目标器件需有代码闪存库B且其起始地址为0x00200000 |
| R_FCL_CFL2_START_ADDR_4096K(V2.12及更高版本支持,面向未来产品) | 此选项将代码闪存库B的起始地址设置为0x00400000,有关代码闪存库B的信息,参考器件硬件手册,目标器件需有代码闪存库B且其起始地址为0x00400000 |
预编译选项R_FCL_COMMAND_EXECUTION_MODE的两个取值对应不同模式,各模式的优缺点如下:
5.1.1 内部模式(R_FCL_HANDLER_CALL_INTERNAL)
- 优点:无需轮询;RAM消耗较少。
- 缺点:自编程期间无法返回应用程序;自编程期间只能通过中断执行用户代码;无法擦除启动命令所在的代码闪存区域。
5.1.2 用户模式(R_FCL_HANDLER_CALL_USER)
- 优点:CPU负载较低;自编程期间可同时执行用户代码。
- 缺点:RAM消耗较多;需进行状态轮询。
两种模式的一个重要区别是能否重新编程整个代码闪存(或用户程序所在的代码闪存区域),两种模式都可执行完整的代码闪存擦除,但实际上只有用户模式有意义。这意味着要重新编程整个代码闪存,以内部模式编译的包含FCL的代码必须重新定位,否则会挂起。
有关操作模式的详细信息,可参考前面“FCL功能规范”章节中的“操作模式”部分。
注意:RH850 FCL Type01的V2.12及更高版本支持的预编译定义R_FCL_NO_FCU_COPY、R_FCL_MIRROR_FCU_COPY和R_FCL_NO_BFA_SWITCH仅适用于特定器件组,各定义与器件组的对应关系如下表所示:
| 预编译定义 | F1L/F1M/F1H | D1L/D1M1/D1M1H/D1M2/D1M2H | D1M1A/D1M1-V2/D1S1 | F1K/F1KM/F1KH | 未来产品 |
|---|---|---|---|---|---|
| R_FCL_NO_BFA_SWITCH | - | - | - | √ | - |
| R_FCL_MIRROR_FCU_COPY | - | - | - | - | √ |
| R_FCL_NO_FCU_COPY | - | - | √ | - | - |
注意:关于所使用FCL版本支持的器件组,可参考FCL附带的support.txt文件。
5.2 数据类型
本节描述FCL使用和提供的所有数据定义,为减少用户应用程序中类型不匹配的可能性,请严格使用提供的类型,避免使用标准数据类型替代。
这些定义与标准C99的stdint.h头文件中的定义类似,但如果在项目中使用其他定义,请仔细检查是否存在大小或字节序不匹配问题。
5.2.1 编译版本差异
- V2.13及更高版本:编译RH850 FCL Type 01的V2.13及更高版本时,假设所有数据定义都将根据ISO定义的C99或更高标准进行编译。若为所使用的GHS编译器、瑞萨编译器或IAR编译器选择C99或更高标准,编译器会提供包含数据定义的
stdint.h头文件;若选择低于C99的标准或不选择标准,则会使用r_typedefs.h(等同于stdint.h)中的数据定义。 - V2.12及更低版本:编译RH850 FCL Type 01的V2.12及更低版本时,需将以下两个文件中的
#include "r_typedefs.h"指令修改为#include "stdint.h":
-r_fcl_hw_access.c
-r_fcl_user_if.c
类似地,使用附带的示例文件时,也需将#include "r_typedefs.h"修改为#include "stdint.h",RH850 FCL Type 01的示例文件包括main.c、fcl_descriptor.c和fcl_user.c。
5.2.2 简单类型定义
- 选择C99或更高标准时:参考编译器提供的
stdint.h文件。 - 选择低于C99的标准或不选择标准时:从
r_typedefs.h中提取的类型定义如下:
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef unsigned char rBool;
这些简单类型在整个库API中使用,所有库特定的简单类型定义都可在库安装包中的r_typedefs.h文件中找到。
5.2.3 r_fcl_command_t(命令类型)
类型定义:
typedef enum R_FCL_COMMAND_T {
R_FCL_CMD_PREPARE_ENV, // 准备环境
R_FCL_CMD_ERASE, // 擦除
R_FCL_CMD_WRITE, // 写入
R_FCL_CMD_SET_LOCKBIT, // 设置锁定位
R_FCL_CMD_GET_LOCKBIT, // 获取锁定位
R_FCL_CMD_ENABLE_LOCKBITS, // 启用锁定位机制
R_FCL_CMD_DISABLE_LOCKBITS, // 禁用锁定位机制
R_FCL_CMD_SET_OTP, // 设置OTP位
R_FCL_CMD_GET_OTP, // 获取OTP位
R_FCL_CMD_SET_OPB, // 设置选项字节
R_FCL_CMD_GET_OPB, // 获取选项字节
R_FCL_CMD_SET_ID, // 设置ID
R_FCL_CMD_GET_ID, // 获取ID
R_FCL_CMD_SET_READ_PROTECT_FLAG,// 设置读保护标志
R_FCL_CMD_GET_READ_PROTECT_FLAG,// 获取读保护标志
R_FCL_CMD_SET_WRITE_PROTECT_FLAG,// 设置写保护标志
R_FCL_CMD_GET_WRITE_PROTECT_FLAG,// 获取写保护标志
R_FCL_CMD_SET_ERASE_PROTECT_FLAG,// 设置擦除保护标志
R_FCL_CMD_GET_ERASE_PROTECT_FLAG,// 获取擦除保护标志
R_FCL_CMD_SET_SERIAL_PROG_DISABLED,// 禁用串行编程
R_FCL_CMD_GET_SERIAL_PROG_DISABLED,// 检查串行编程是否禁用
R_FCL_CMD_SET_SERIAL_ID_ENABLED,// 启用OCID检查
R_FCL_CMD_GET_SERIAL_ID_ENABLED,// 检查OCID检查是否启用
R_FCL_CMD_SET_RESET_VECTOR, // 设置复位向量
R_FCL_CMD_GET_RESET_VECTOR, // 获取复位向量
R_FCL_CMD_GET_BLOCK_CNT, // 获取闪存块数量
R_FCL_CMD_GET_BLOCK_END_ADDR, // 获取块结束地址
R_FCL_CMD_GET_DEVICE_NAME // 获取器件名称
} r_fcl_command_t;
描述:库提供一组闪存操作,这些操作由库启动和控制,所有操作通过调用R_FCL_Execute函数启动,之后由R_FCL_Handler函数控制,管理这些操作是库的主要目的。
各可用命令的详细信息,可参考后续“库命令”部分,各命令的描述如下表所示:
| 成员/值 | 描述 |
|---|---|
| R_FCL_CMD_PREPARE_ENV | 将库的内部函数复制到RAM,并初始化内部状态和变量。但使用RH850/F1K、F1KM、F1KH、D1M1A、D1M1-V2或D1S1时,不会将库的内部函数复制到RAM |
| R_FCL_CMD_ERASE | 擦除一个或多个闪存块 |
| R_FCL_CMD_WRITE | 向闪存写入多个256字节的数据 |
| R_FCL_CMD_SET_LOCKBIT | 锁定一个闪存块,防止其被进一步修改 |
| R_FCL_CMD_GET_LOCKBIT | 读取当前锁定位设置 |
| R_FCL_CMD_ENABLE_LOCKBITS | 启用使用锁定位保护块的机制 |
| R_FCL_CMD_DISABLE_LOCKBITS | 禁用使用锁定位保护块的机制 |
| R_FCL_CMD_SET_OTP | 为一个块设置一次性可编程(OTP)标志 |
| R_FCL_CMD_GET_OTP | 读取一次性可编程(OTP)标志 |
| R_FCL_CMD_SET_OPB | 写入新的选项字节设置 |
| R_FCL_CMD_GET_OPB | 读取当前选项字节设置 |
| R_FCL_CMD_SET_ID | 写入新的OCID(用于保护调试和串行接口并启用自编程) |
| R_FCL_CMD_GET_ID | 读取当前OCID设置 |
| R_FCL_CMD_SET_READ_PROTECT_FLAG | 启用读保护 |
| R_FCL_CMD_GET_READ_PROTECT_FLAG | 读取当前读保护设置 |
| R_FCL_CMD_SET_WRITE_PROTECT_FLAG | 启用写保护 |
| R_FCL_CMD_GET_WRITE_PROTECT_FLAG | 读取当前写保护设置 |
| R_FCL_CMD_SET_ERASE_PROTECT_FLAG | 启用擦除保护 |
| R_FCL_CMD_GET_ERASE_PROTECT_FLAG | 读取当前擦除保护设置 |
| R_FCL_CMD_SET_SERIAL_PROG_DISABLED | 禁用串行编程 |
| R_FCL_CMD_GET_SERIAL_PROG_DISABLED | 检查串行编程是否已禁用 |
| R_FCL_CMD_SET_SERIAL_ID_ENABLED | 启用OCID检查 |
| R_FCL_CMD_GET_SERIAL_ID_ENABLED | 检查OCID检查是否已禁用 |
| R_FCL_CMD_SET_RESET_VECTOR | 向器件写入新的复位向量 |
| R_FCL_CMD_GET_RESET_VECTOR | 读取当前复位向量设置 |
| R_FCL_CMD_GET_BLOCK_CNT | 读取闪存块数量 |
| R_FCL_CMD_GET_BLOCK_END_ADDR | 读取块的结束地址 |
| R_FCL_CMD_GET_DEVICE_NAME | 读取器件的ASCII编码名称 |
5.2.4 r_fcl_status_t(状态类型)
类型定义:
typedef enum R_FCL_STATUS_T {
R_FCL_OK, // 操作成功完成
R_FCL_BUSY, // 操作已成功启动且正在进行中
R_FCL_SUSPENDED, // 当前操作已暂停
R_FCL_ERR_FLMD0, // 由于启用了FLMD0硬件保护,未执行请求的命令
R_FCL_ERR_PARAMETER, // 由于请求结构中传递的输入数据错误,未执行请求的命令
R_FCL_ERR_PROTECTION, // 由于启用了安全功能(如启用擦除保护、设置锁定位等),请求的命令未完全执行
R_FCL_ERR_REJECTED, // 由于另一个操作正在进行,未执行请求的命令
R_FCL_ERR_FLOW, // 由于初始化序列不正确或暂停-恢复序列不正确,未执行当前请求
R_FCL_ERR_WRITE, // 由于写入未擦除区域、硬件错误或FLMD0引脚不稳定,请求的写入命令遇到错误
R_FCL_ERR_ERASE, // 由于硬件擦除错误或FLMD0引脚不稳定,请求的擦除命令遇到错误
R_FCL_ERR_COMMAND, // 请求的命令不存在或已通过预编译选项禁用
R_FCL_CANCELLED, // 当前操作已取消
R_FCL_ERR_INTERNAL // 库或硬件内部错误
} r_fcl_status_t;
描述:枚举类型r_fcl_status_t定义了FCL的状态返回值,上述状态/错误代码由库返回,用于指示FCL命令的当前状态,初始化、暂停-恢复和取消等其他API函数也返回这些状态代码。
所有状态和错误代码的根本原因和解释取决于所执行的操作或调用的函数,各代码在操作中的含义解释如下表所示:
| 成员/值 | 描述 |
|---|---|
| R_FCL_OK | 请求的操作成功完成 |
| R_FCL_BUSY | 请求的操作已成功启动且正在进行中 |
| R_FCL_SUSPENDED | 当前操作已暂停 |
| R_FCL_ERR_FLMD0 | 由于启用了FLMD0硬件保护,未执行请求的命令 |
| R_FCL_ERR_PARAMETER | 由于请求结构中传递的输入数据错误,未执行请求的命令 |
| R_FCL_ERR_PROTECTION | 由于启用了安全功能(如启用擦除保护、设置锁定位等),请求的命令未完全执行 |
| R_FCL_ERR_REJECTED | 由于另一个操作正在进行,未执行请求的命令 |
| R_FCL_ERR_FLOW | 由于初始化序列不正确或暂停-恢复序列不正确,未执行当前请求 |
| R_FCL_ERR_WRITE | 由于写入未擦除区域、硬件错误或FLMD0引脚不稳定,请求的写入命令遇到错误 |
| R_FCL_ERR_ERASE | 由于硬件擦除错误或FLMD0引脚不稳定,请求的擦除命令遇到错误 |
| R_FCL_ERR_COMMAND | 请求的命令不存在或已通过预编译选项禁用 |
| R_FCL_CANCELLED | 当前操作已取消 |
| R_FCL_ERR_INTERNAL | 库或硬件内部错误 |
5.2.5 r_fcl_request_t(请求类型)
类型定义:
typedef volatile struct R_FCL_REQUEST_T {
r_fcl_command_t command_enu; // 要执行的用户命令
uint32_t bufferAdd_u32; // 缓冲区地址(根据命令类型有不同含义)
uint32_t idx_u32; // 索引(根据命令类型有不同含义)
uint16_t cnt_u16; // 计数(根据命令类型有不同含义)
r_fcl_status_t status_enu; // 库返回代码(状态和错误代码取决于所调用的命令)
} r_fcl_request_t;
描述:所有用户操作都通过名为R_FCL_Execute的中央启动函数启动,执行所需的所有信息通过请求结构传递给FCL,错误信息也通过同一结构返回。有关此结构的详细信息,可参考前面“FCL功能规范”章节中的“面向请求的操作”部分,各命令如何填充此结构以及如何检查结果的详细信息,可参考后续“库命令”部分。
各成员的描述如下表所示:
| 成员/值 | 描述 |
|---|---|
| command_enu | 要执行的用户命令 |
| bufferAdd_u32 | - R_FCL_CMD_WRITE(写入命令):应用程序的写入缓冲区地址 - 所有GET命令:存储结果的缓冲区地址 - SET命令:包含要设置的数据的缓冲区地址(如有必要) - 所有其他命令:此参数未使用 |
| idx_u32 | - R_FCL_CMD_WRITE(写入命令):要写入的代码闪存地址(必须256字节对齐) - R_FCL_CMD_ERASE(擦除命令):擦除操作要擦除的第一个块 - R_FCL_SET_LOCKBIT(设置锁定位)、R_FCL_GET_LOCKBIT(获取锁定位)、R_FCL_SET_OTP(设置OTP位)、R_FCL_GET_OTP(获取OTP位):受影响的块编号 - 所有其他命令:此参数未使用 |
| cnt_u16 | - R_FCL_CMD_WRITE(写入命令):要写入的写入单元数量(一个写入单元为256字节) - R_FCL_CMD_ERASE(擦除命令):要擦除的块数量 - 所有其他命令:此参数未使用 |
| status_enu | 库返回代码(状态和错误代码取决于所调用的命令) |
5.2.6 r_fcl_descriptor_t(描述符类型)
类型定义:
typedef struct R_FCL_DESCRIPTOR_T {
uint32_t id_au32[4]; // 用于启用自编程的ID,ID设置不正确会导致保护错误
uint32_t addrRam_u32; // 为FCL执行保留的RAM起始地址
uint16_t frequencyCpuMHz_u16; // CPU频率(MHz),值应向上取整到最接近的整数(如24.3MHz设置为25),参考器件用户手册了解限制值,超时监控时序以及闪存硬件频率由CPU频率内部推导得出
} r_fcl_descriptor_t;
描述:运行时配置(详见后续“库的设置与使用”章节中的“文件结构”)定义在单独的数据类型中,初始化阶段会读取此数据类型的变量,并根据配置设置内部变量。
各成员的描述如下表所示:
| 成员/值 | 描述 |
|---|---|
| id_au32 | 用于启用自编程的ID,ID设置不正确会导致保护错误 |
| addrRam_u32 | 为FCL执行保留的RAM起始地址 |
| frequencyCpuMHz_u16 | CPU频率(MHz),值应向上取整到最接近的整数(如24.3MHz设置为25),参考器件用户手册了解限制值,超时监控时序以及闪存硬件频率由CPU频率内部推导得出 |
5.3 函数
FCL提供的API函数汇总如下:
R_FCL_Init:初始化库R_FCL_CopySections:将使用的链接段从ROM复制到RAM中的新地址R_FCL_CalcFctAddr:计算复制过程后的新地址R_FCL_GetVersionString:返回库版本字符串R_FCL_Execute:启动新的用户命令R_FCL_Handler:处理FCL命令和操作处理(仅用户模式可用)R_FCL_SuspendRequest:请求暂停正在进行的闪存擦除或写入操作(仅用户模式可用)R_FCL_ResumeRequest:请求恢复之前暂停的命令(仅用户模式可用)R_FCL_CancelRequest:请求取消正在进行或已暂停的擦除或写入闪存操作(仅用户模式可用)
5.3.1 初始化函数
5.3.1.1 R_FCL_Init(库初始化)
- 概述:初始化FCL库。
- 接口:C接口
r_fcl_status_t R_FCL_Init (const r_fcl_descriptor_t * descriptor_pstr) - 参数:
| 参数 | 类型 | 访问方式 | 描述 |
|---|---|---|---|
| descriptor_pstr | r_fcl_descriptor_t | 只读(r) | FCL配置描述符 |
- 返回值:
| 类型 | 描述 | 原因 | 补救措施 |
|---|---|---|---|
| r_fcl_status_t | R_FCL_OK | 操作成功完成,执行过程中无问题 | 无需操作 |
| R_FCL_ERR_PARAMETER | 操作因参数值无效而停止 | 描述符变量仍未初始化或未定义,设置/修正描述符变量并重复命令 |
- 前置条件:无。
- 后置条件:无。
- 描述:此函数初始化FCL,在执行任何FCL函数之前必须调用该函数,它会初始化所有内部变量并执行一些参数检查,该函数应从ROM执行。
- 示例:
r_fcl_status_t status_enu; /* 初始化自编程库 */ status_enu = R_FCL_Init (&RTConfig_enu); /* 错误处理... */
5.3.1.2 R_FCL_CopySections(复制段)
- 概述:将使用的链接段从ROM复制到RAM中的新地址。
- 接口:C接口
r_fcl_status_t R_FCL_CopySections (void) - 参数:无。
- 返回值:
| 类型 | 描述 | 原因 | 补救措施 |
|---|---|---|---|
| r_fcl_status_t | R_FCL_OK | 操作成功完成,执行过程中无问题 | 无需操作 |
| R_FCL_ERR_FLOW | 当前无法执行函数 | 库处理流程错误(如库未初始化、库操作正在进行中),修正流程 | |
| R_FCL_ERR_INTERNAL | 当前无法执行函数 | 初始化配置描述符中给出的RAM地址错误,使用正确的配置描述符重新初始化库 |
- 前置条件:必须初始化库(调用
R_FCL_Init函数)。 - 后置条件:无。
- 描述:此函数用于将FCL的一些代码段复制到RAM中指定的目标地址,从该位置可以在代码闪存不可用时执行代码。有关复制的代码段的详细信息,可参考后续“库的设置与使用”章节中的“链接段”部分,该函数应从ROM执行。
- 示例:
r_fcl_status_t status_enu; /* 将FCL复制到内部RAM */ status_enu = R_FCL_CopySections (); /* 错误处理 */
5.3.1.3 R_FCL_CalcFctAddr(计算函数地址)
- 概述:计算复制过程后的函数新地址。
- 接口:C接口
uint32_t R_FCL_CalcFctAddr (uint32_t addFct_u32) - 参数:
| 参数 | 类型 | 访问方式 | 描述 |
|---|---|---|---|
| addFct_u32 | uint32_t | 只读(r) | 已复制函数的ROM地址 |
- 返回值:
| 类型 | 描述 |
|---|---|
| uint32_t | 函数的新RAM地址 |
- 前置条件:库必须处于初始化状态(调用
R_FCL_Init函数)。 - 后置条件:无。
- 描述:此函数计算从ROM复制到RAM后的函数新地址,要计算函数的新地址,已复制的函数必须位于后续“库的设置与使用”章节中的“链接段”部分所述的FCL链接段之一,该函数应从ROM执行。
- 示例:
/* 计算位于FCL段R_FCL_CODE_RAM_USR中的用户控制函数fctUserCtrl的新地址 */ uint32_t (*fpFct)(void); fpFct = (uint32_t(*)())R_FCL_CalcFctAddr ((void *)fctUserCtrl);
5.3.2 操作函数
5.3.2.1 R_FCL_GetVersionString(获取版本字符串)
- 概述:返回库版本字符串。
- 接口:C接口
const uint8_t *R_FCL_GetVersionString (void) - 参数:无。
- 返回值:
| 类型 | 描述 |
|---|---|
| const uint8_t * | 库版本为字符串值,格式为“SH850T01xxxxxYZabcD”,各部分含义详见下文描述 |
- 前置条件:该函数位于
FCL_CODE_ROM段,由于R_FCL_Copy_Sections函数不会将其复制到RAM,因此必须在其链接位置调用该函数。 - 后置条件:无。
- 描述:此函数返回指向库版本字符串的指针,版本字符串是一个以零结尾的字符串,用于标识库(与以前库中使用的约定版本字符串定义相同),版本字符串存储在库代码段中。
版本字符串的结构如下:S H850 T01 xxxxx Y Z abc D
-
S:表示代码闪存库(Code Flash Library),D表示数据闪存库(Data Flash Library)
-
H850:表示MCU系列名称(RH850)
-
T01:表示库类型(Type01)
-
xxxxx:表示支持的编译器的编码信息,若未编码信息,则表示该库是适用于不同编译器的源代码库
-
Y:表示版本类型,“E”表示工程版本(engineering version),“V”表示正常版本(normal version)
-
Z:表示使用的内存/寄存器模型的编码信息,若未编码信息,则表示该库是适用于所有内存/寄存器模型的通用库
-
abc:表示库版本号(a.bc)
-
D:表示不同工程版本的可选字符
-
示例:
/* 读取库版本 */ const uint8_t *version_pu08; version_pu08 = R_FCL_GetVersionString ();
5.3.2.2 R_FCL_Execute(执行命令)
- 概述:启动新的用户命令。
- 接口:C接口
void R_FCL_Execute (r_fcl_request_t * request_pstr) - 参数:
| 参数 | 类型 | 访问方式 | 描述 |
|---|---|---|---|
| request_pstr | r_fcl_request_t | 读写(rw) | 请求结构(详见前面“数据类型”章节中的“r_fcl_request_t”部分),函数返回后,status_enu成员包含命令启动的返回值(详见前面“数据类型”章节中的“r_fcl_status_t”部分) |
- 返回值:无。
- 前置条件:
- 必须执行初始化序列:
- 执行闪存操作的命令需要禁用硬件保护(FLMD0引脚/寄存器)
- 必须初始化库(调用
R_FCL_Init函数) - 必须复制FCL链接段(调用
R_FCL_CopySections函数)
- 对于
R_FCL_CMD_PREPARE_ENV以外的命令,库必须处于准备状态(调用R_FCL_Execute函数并传递R_FCL_CMD_PREPARE_ENV命令)。
- 必须执行初始化序列:
- 后置条件:无。
- 描述:
Execute函数启动所有闪存修改操作,操作类型和操作参数通过请求结构传递给FCL,操作的状态和结果也通过该结构的成员返回给用户应用程序。
请求结构成员的不同值组合是可能的,各命令如何填充请求结构的详细信息,可参考后续“库命令”部分。根据库的配置方式,此函数有两种操作方式:
- 内部模式:请求的命令同步执行。
- 用户模式:请求的命令异步执行,除非发生错误,否则命令执行仅由
R_FCL_Execute函数启动,必须反复调用R_FCL_Handler函数,直到请求结构中的状态不再是R_FCL_BUSY,命令才算完成。
请注意,两种模式在从ROM执行与从RAM执行以及可重新编程的区域方面存在重要差异,各模式适用的限制可参考后续“注意事项”章节。
根据所使用的库模式,此函数可从ROM或RAM执行,因此它位于链接段R_FCL_CODE_ROMRAM中。
- 示例:
r_fcl_request_t myRequest; /* 擦除块10、11、12和13 */ myRequest.command_enu = R_FCL_CMD_ERASE; myRequest.idx_u32 = 10; myRequest.cnt_u16 = 4; R_FCL_Execute (&myRequest); #if R_FCL_COMMAND_EXECUTION_MODE == R_FCL_HANDLER_CALL_USER while (myRequest.status_enu == R_FCL_BUSY) { R_FCL_Handler (); } #endif if (R_FCL_OK != myRequest.status_enu) { /* 错误处理... */ }
5.3.2.3 R_FCL_Handler(处理命令)
- 注意:此函数仅在用户模式下可用。
- 概述:处理FCL命令和操作处理。
- 接口:C接口
void R_FCL_Handler (void) - 参数:无。
- 返回值:无。
- 前置条件:
- 必须执行初始化序列:
- 执行闪存操作的命令需要禁用硬件保护(FLMD0引脚/寄存器)
- 必须初始化库(调用
R_FCL_Init函数) - 必须复制FCL链接段(调用
R_FCL_CopySections函数)
- 对于
R_FCL_CMD_PREPARE_ENV以外的命令,库必须处于准备状态(调用R_FCL_Execute函数并传递R_FCL_CMD_PREPARE_ENV命令)。
- 必须执行初始化序列:
- 后置条件:无。
- 描述:此函数处理FCL闪存操作的命令处理,在通过
R_FCL_Execute函数启动操作后,需要频繁调用此函数,它会检查操作状态,并在操作完成时更新请求结构的status_enu变量,从而可以轮询操作的结束。此函数应从RAM执行,因此它位于链接段R_FCL_CODE_RAM中。 - 示例:参考
R_FCL_Execute函数(用户模式)的示例。
5.3.2.4 R_FCL_SuspendRequest(暂停请求)
- 注意:此函数仅在用户模式下可用。
- 概述:请求暂停正在进行的闪存擦除或写入操作(例如,为了能够读取闪存)。
- 接口:C接口
r_fcl_status_t R_FCL_SuspendRequest (void) - 参数:无。
- 返回值:
| 类型 | 描述 | 原因 | 补救措施 |
|---|---|---|---|
| r_fcl_status_t | R_FCL_OK | 操作成功完成,执行过程中无问题 | 无需操作 |
| R_FCL_ERR_FLOW | 当前无法暂停 | 库处理流程错误(如库未初始化、无操作正在进行中),修正流程 | |
| R_FCL_ERR_REJECTED | 当前无法暂停 | 正在进行的命令不可暂停(不是擦除或写入命令),仅对擦除和写入命令调用暂停 |
- 前置条件:
- 必须已启动或正在执行闪存擦除或写入命令。
- 不得已暂停另一个命令。
- 后置条件:
- 不能暂停
R_FCL_CMD_ERASE命令以执行另一个R_FCL_CMD_ERASE操作。 - 如果暂停的命令是
R_FCL_CMD_WRITE,则不能执行R_FCL_CMD_ERASE或R_FCL_CMD_WRITE操作。
- 不能暂停
- 描述:此函数暂停正在进行的闪存擦除或写入操作,此函数仅请求暂停,暂停处理由
R_FCL_Handler函数完成,因此必须执行R_FCL_Handler函数,直到闪存操作暂停,这通过请求结构返回的状态值R_FCL_SUSPENDED报告。此函数应从RAM或其他安全位置执行,因此它位于链接段R_FCL_CODE_RAM中。 - 示例:
r_fcl_request_t myRequest; r_fcl_status_t srRes_enu; uint32_t i; /* 擦除块0、1、2和3 */ myRequest.command_enu = R_FCL_CMD_ERASE; myRequest.idx_u32 = 0; myRequest.cnt_u16 = 4; R_FCL_Execute (&myRequest); i = 0; /* 调用处理程序一段时间 */ while ((myRequest.status_enu == R_FCL_BUSY) && (i < 10)) { R_FCL_Handler (); i++; } /* 暂停请求并等待直到暂停 */ srRes_enu = R_FCL_SuspendRequest (); if (srRes_enu != R_FCL_OK) { /* 错误处理... */ } while (myRequest.status_enu != R_FCL_SUSPENDED) { R_FCL_Handler (); } /* 现在FCL已暂停,我们可以读取闪存... */ /* 恢复擦除 */ srRes_enu = R_FCL_ResumeRequest (); if (srRes_enu != R_FCL_OK) { /* 错误处理... */ } /* 完成擦除 */ while (myRequest.status_enu == R_FCL_SUSPENDED) { R_FCL_Handler (); } while (myRequest.status_enu == R_FCL_BUSY) { R_FCL_Handler (); } if (myRequest.status_enu != R_FCL_OK) { /* 错误处理... */ }
5.3.2.5 R_FCL_ResumeRequest(恢复请求)
- 注意:此函数仅在用户模式下可用。
- 概述:请求恢复之前暂停的命令。
- 接口:C接口
r_fcl_status_t R_FCL_ResumeRequest (void) - 参数:无。
- 返回值:
| 类型 | 描述 | 原因 | 补救措施 |
|---|---|---|---|
| r_fcl_status_t | R_FCL_OK | 操作成功完成,执行过程中无问题 | 无需操作 |
| R_FCL_ERR_FLOW | 当前无法恢复 | 库处理流程错误(如库未初始化、无操作已暂停、数据闪存操作正在进行中),修正流程 |
- 前置条件:
- 闪存操作命令必须已成功暂停(状态应为
R_FCL_SUSPENDED)。 - 如果在待机期间更改了请求结构的内容,则必须恢复该内容。
- 闪存操作命令必须已成功暂停(状态应为
- 后置条件:无。
- 描述:此函数请求恢复之前暂停的FCL操作,此函数仅请求恢复,恢复处理由
R_FCL_Handler函数完成,因此必须执行R_FCL_Handler函数,直到闪存操作恢复,这通过请求结构返回的状态值报告。此函数应从RAM或其他安全位置执行,因此它位于链接段R_FCL_CODE_RAM中。 - 示例:参考
R_FCL_SuspendRequest函数的示例。
5.3.2.6 R_FCL_CancelRequest(取消请求)
- 注意:此函数仅在用户模式下可用。
- 概述:请求取消正在进行或已暂停的擦除或写入闪存操作。
- 接口:C接口
r_fcl_status_t R_FCL_CancelRequest (void) - 参数:无。
- 返回值:
| 类型 | 描述 | 原因 | 补救措施 |
|---|---|---|---|
| r_fcl_status_t | R_FCL_OK | 操作成功完成,执行过程中无问题 | 无需操作 |
| R_FCL_ERR_FLOW | 当前无法取消 | 库处理流程错误(如库未初始化、无操作正在进行或已暂停、数据闪存操作正在进行中),修正流程 | |
| R_FCL_ERR_REJECTED | 当前无法取消 | 正在进行的命令不可取消(不是擦除或写入命令),仅对正在进行或已暂停的擦除和写入命令调用取消 |
- 前置条件:
- 必须已启动、正在执行或已暂停闪存擦除或写入命令。
- 不接受其他取消请求。
- 后置条件:无。
- 描述:此函数取消正在进行或已暂停的闪存擦除/写入操作,此函数仅请求取消,取消处理由
R_FCL_Handler函数完成,因此必须执行R_FCL_Handler函数,直到闪存操作取消,这通过请求结构返回的状态值R_FCL_CANCELLED报告。此函数应从RAM或其他安全位置执行,因此它位于链接段R_FCL_CODE_RAM中。 - 示例:
r_fcl_request_t myRequest; r_fcl_status_t srRes_enu; uint32_t i; /* 擦除块0、1、2和3 */ myRequest.command_enu = R_FCL_CMD_ERASE; myRequest.idx_u32 = 0; myRequest.cnt_u16 = 4; R_FCL_Execute (&myRequest); /* 调用处理程序一段时间 */ i = 0; while ((myRequest.status_enu == R_FCL_BUSY) && (i < 10)) { R_FCL_Handler (); i++; } /* 取消请求并等待直到取消 */ srRes_enu = R_FCL_CancelRequest (); if (R_FCL_OK != srRes_enu) { /* 错误处理... */ } while (R_FCL_CANCELLED != myRequest.status_enu) { R_FCL_Handler (); }
5.4 库命令
下表简要概述了FCL可用的命令以及每个命令使用的请求结构(为简洁起见,命令均省略了R_FCL_CMD_前缀),请注意所有情况下都适用CPU对齐要求。
| 命令 | bufferAdd_u32(缓冲区地址) | idx_u32(索引) | cnt_u16(计数) |
|---|---|---|---|
| PREPARE_ENV | 未使用(X) | 未使用(X) | 未使用(X) |
| ERASE | 未使用(X) | 起始块编号 | 要擦除的块数量 |
| WRITE | 源数据地址(大小应为256字节的倍数) | 目标闪存地址(256字节对齐) | 要写入的256字节组数量 |
| SET_LOCKBIT | 未使用(X) | 块编号 | 未使用(X) |
| GET_LOCKBIT | 目标数据地址(1个字) | 块编号 | 未使用(X) |
| ENABLE_LOCKBITS | 未使用(X) | 未使用(X) | 未使用(X) |
| DISABLE_LOCKBITS | 未使用(X) | 未使用(X) | 未使用(X) |
| SET_OTP | 未使用(X) | 块编号 | 未使用(X) |
| GET_OTP | 目标数据地址(1个字) | 块编号 | 未使用(X) |
| SET_OPB | 源数据地址(32字节) | 未使用(X) | 未使用(X) |
| GET_OPB | 目标数据地址(32字节) | 未使用(X) | 未使用(X) |
| SET_ID | 源数据地址(16字节) | 未使用(X) | 未使用(X) |
| GET_ID | 目标数据地址(16字节) | 未使用(X) | 未使用(X) |
| SET_READ_PROTECT_FLAG | 未使用(X) | 未使用(X) | 未使用(X) |
| GET_READ_PROTECT_FLAG | 目标数据地址(1个字) | 未使用(X) | 未使用(X) |
| SET_WRITE_PROTECT_FLAG | 未使用(X) | 未使用(X) | 未使用(X) |
| GET_WRITE_PROTECT_FLAG | 目标数据地址(1个字) | 未使用(X) | 未使用(X) |
| SET_ERASE_PROTECT_FLAG | 未使用(X) | 未使用(X) | 未使用(X) |
| GET_ERASE_PROTECT_FLAG | 目标数据地址(1个字) | 未使用(X) | 未使用(X) |
| SET_SERIAL_PROG_DISABLED | 未使用(X) | 未使用(X) | 未使用(X) |
| GET_SERIAL_PROG_DISABLED | 目标数据地址(1个字) | 未使用(X) | 未使用(X) |
| SET_SERIAL_ID_ENABLED | 未使用(X) | 未使用(X) | 未使用(X) |
| GET_SERIAL_ID_ENABLED | 目标数据地址(1个字) | 未使用(X) | 未使用(X) |
| SET_RESET_VECTOR | 源数据地址(16字节) | 未使用(X) | 未使用(X) |
| GET_RESET_VECTOR | 目标数据地址(16字节) | 未使用(X) | 未使用(X) |
| GET_BLOCK_CNT | 目标数据地址(1个字) | 未使用(X) | 未使用(X) |
| GET_BLOCK_END_ADDR | 目标数据地址(1个字) | 块编号 | 未使用(X) |
| GET_DEVICE_NAME | 目标数据地址(16字节) | 未使用(X) | 未使用(X) |
5.4.1 R_FCL_CMD_PREPARE_ENV(准备环境命令)
准备环境命令用于初始化闪存编程硬件,此代码用于自编程,需要在内部代码闪存之外执行,执行命令期间代码闪存可能无法访问。
请求结构配置
| 请求结构成员 | 值 | 描述 |
|---|---|---|
| command_enu | R_FCL_CMD_PREPARE_ENV | 请求的命令 |
| bufferAdd_u32 | 未使用 | - |
| idx_u32 | 未使用 | - |
| cnt_u16 | 未使用 | - |
| status_enu | 见下表 | 由R_FCL_Execute和R_FCL_Handler自动更新 |
操作返回状态
命令完成后,结果将更新到请求结构的status_enu成员中;若库配置为用户模式,操作期间status_enu成员将设置为R_FCL_BUSY。
| 状态 | 背景与处理 |
|---|---|
| R_FCL_OK | 含义:操作成功完成,库已准备好供进一步使用 原因:执行过程中无问题 补救措施:无需操作 |
| R_FCL_BUSY * | 含义:操作尚未完成 原因:执行过程中无问题 补救措施:继续调用 R_FCL_Handler |
| R_FCL_ERR_FLOW | 含义:当前命令被拒绝 原因:库未初始化或处于错误状态,无法执行函数 补救措施:调查根本原因并修正库处理流程 |
| R_FCL_ERR_REJECTED | 含义:当前命令被拒绝 原因:库正忙于执行另一个操作 补救措施:在前一个命令完成后重复此命令 |
| R_FCL_ERR_PARAMETER | 含义:当前命令被拒绝或停止 原因:检测到描述符中的错误设置(如CPU频率) 补救措施:修正描述符中的设置 |
| R_FCL_ERR_INTERNAL | 含义:发生库内部错误,正常应用程序执行中不会发生 原因:库无法确定的错误,如FCL代码或数据段损坏、程序流程错误、硬件缺陷 补救措施:参考前面“FCL功能规范”章节中的“内部错误”部分 |
| R_FCL_ERR_PROTECTION | 含义:当前命令被拒绝 原因:描述符中的身份验证ID值与器件中的不匹配;命令操作期间FLMD0寄存器/引脚变为低电平;硬件缺陷 补救措施:修正描述符中的身份验证ID设置;检查FLMD0设置并修正;更换器件 |
| R_FCL_ERR_FLMD0 | 含义:当前命令被拒绝 原因:FLMD0寄存器/引脚设置不正确 补救措施:调查根本原因并修正寄存器值或引脚输入 |
*仅在用户模式下可用
5.4.2 R_FCL_CMD_ERASE(擦除命令)
擦除命令用于擦除由起始块和块数量定义的多个闪存块,若器件有第二个代码闪存库,此命令也可在该库上执行,执行命令期间代码闪存可能无法访问。
请求结构配置
| 请求结构成员 | 值 | 描述 |
|---|---|---|
| command_enu | R_FCL_CMD_ERASE | 请求的命令 |
| bufferAdd_u32 | 未使用 | - |
| idx_u32 | 0 … 器件块数量 - 1:用户区域中的操作起始块 0x80000000 … 0x80000000u + 用户引导区域块数量 - 1:用户引导区域中的操作起始块 |
操作起始块编号 |
| cnt_u16 | 1 … 器件块数量 - idx_u32 | 要擦除的块数量 |
| status_enu | 见下表 | 由R_FCL_Execute和R_FCL_Handler自动更新 |
操作返回状态
命令完成后,结果将更新到请求结构的status_enu成员中;若库配置为用户模式,操作期间status_enu成员将设置为R_FCL_BUSY。
| 状态 | 背景与处理 |
|---|---|
| R_FCL_OK | 含义:操作成功完成,指定的块现在为空 原因:执行过程中无问题 补救措施:无需操作 |
| R_FCL_BUSY * | 含义:操作成功启动 原因:执行过程中无问题 补救措施:继续调用 R_FCL_Handler |
| R_FCL_SUSPENDED * | 含义:正在进行的擦除操作已成功暂停 原因:暂停处理成功完成 补救措施:无需操作 |
| R_FCL_CANCELLED * | 含义:正在进行或已暂停的擦除操作已成功取消 原因:取消处理成功完成 补救措施:无需操作 |
| R_FCL_ERR_FLOW | 含义:当前命令被拒绝 原因:库未初始化或处于错误状态,无法执行函数 补救措施:调查根本原因并修正库处理流程 |
| R_FCL_ERR_FLMD0 | 含义:当前命令被拒绝 原因:FLMD0寄存器/引脚设置不正确 补救措施:调查根本原因并修正寄存器值或引脚输入 |
| R_FCL_ERR_REJECTED | 含义:当前命令被拒绝 原因:库正忙于执行另一个操作 补救措施:在前一个命令完成后重复此命令 |
| R_FCL_ERR_PARAMETER | 含义:当前命令被拒绝或停止 原因:指定的块或计数错误 补救措施:调查根本原因并修正参数 |
| R_FCL_ERR_ERASE | 含义:无法完全擦除受影响的闪存区域 原因:FCL使用错误的CPU频率初始化;硬件缺陷;命令执行期间FLMD0不稳定 补救措施:使用正确的频率重新初始化FCL;认为相应的闪存块(或整个代码闪存)有缺陷;修正FLMD0处理并重复命令 |
| R_FCL_ERR_PROTECTION | 含义:当前命令被拒绝 原因:当前安全设置(安全标志)阻止闪存块擦除 补救措施:禁用安全设置并重复命令 |
| R_FCL_ERR_INTERNAL | 含义:发生库内部错误,正常应用程序执行中不会发生 原因:库无法确定的错误,如FCL代码或数据段损坏、程序流程错误、硬件缺陷 补救措施:参考前面“FCL功能规范”章节中的“内部错误”部分 |
*仅在用户模式下可用
5.4.3 R_FCL_CMD_WRITE(写入命令)
写入命令用于将RAM中位于指定地址的多个数据字(256字节对齐)写入到代码闪存的指定目标地址,若器件有第二个代码闪存库,此命令也可在该库上执行,执行命令期间代码闪存可能无法访问。
请求结构配置
| 请求结构成员 | 值 | 描述 |
|---|---|---|
| command_enu | R_FCL_CMD_WRITE | 请求的命令 |
| bufferAdd_u32 | 数据源地址 | 要写入的数据的来源地址 |
| idx_u32 | 0 … 最后一个闪存地址 - 256:用户区域中的写入目标地址 0x01000000 … 最后一个用户引导地址 - 256:用户引导区域中的写入目标地址 |
写入目标地址(256字节对齐) |
| cnt_u16 | 1 … 闪存大小 / 256 | 要写入的256字节块数量 |
| status_enu | 见下表 | 由R_FCL_Execute和R_FCL_Handler自动更新 |
操作返回状态
命令完成后,结果将更新到请求结构的status_enu成员中;若库配置为用户模式,操作期间status_enu成员将设置为R_FCL_BUSY。
| 状态 | 背景与处理 |
|---|---|
| R_FCL_OK | 含义:操作成功完成,指定的块现在已写入数据 原因:执行过程中无问题 补救措施:无需操作 |
| R_FCL_BUSY * | 含义:操作成功启动 原因:执行过程中无问题 补救措施:继续调用 R_FCL_Handler |
| R_FCL_SUSPENDED * | 含义:正在进行的写入操作已成功暂停 原因:暂停处理成功完成 补救措施:无需操作 |
| R_FCL_CANCELLED * | 含义:正在进行或已暂停的写入操作已成功取消 原因:取消处理成功完成 补救措施:无需操作 |
| R_FCL_ERR_FLOW | 含义:当前命令被拒绝 原因:库未初始化或处于错误状态,无法执行函数 补救措施:调查根本原因并修正库处理流程 |
| R_FCL_ERR_FLMD0 | 含义:当前命令被拒绝 原因:FLMD0寄存器/引脚设置不正确 补救措施:调查根本原因并修正寄存器值或引脚输入 |
| R_FCL_ERR_REJECTED | 含义:当前命令被拒绝 原因:库正忙于执行另一个操作 补救措施:在前一个命令完成后重复此命令 |
| R_FCL_ERR_PARAMETER | 含义:当前命令被拒绝或停止 原因:指定的目标地址或计数错误 补救措施:调查根本原因并修正参数 |
| R_FCL_ERR_WRITE | 含义:无法正确写入受影响的闪存区域 原因:要写入的受影响闪存区域未完全成功擦除;FCL使用错误的CPU频率初始化;硬件缺陷;命令执行期间FLMD0不稳定 补救措施:修正应用程序流程(写入操作前擦除闪存区域);使用正确的频率重新初始化FCL;认为相应的闪存块(或整个代码闪存)有缺陷;修正FLMD0处理并重复命令 |
| R_FCL_ERR_PROTECTION | 含义:当前命令被拒绝 原因:当前安全设置(安全标志)阻止代码闪存修改 补救措施:禁用安全设置并重复命令 |
| R_FCL_ERR_INTERNAL | 含义:发生库内部错误,正常应用程序执行中不会发生 原因:库无法确定的错误,如FCL代码或数据段损坏、程序流程错误、 |
更多推荐




所有评论(0)