尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

LPC55(S)1x USB固件更新实战:基于ROM Bootloader与CRC校验

LPC55(S)1x USB固件更新实战:基于ROM Bootloader与CRC校验
📅 发布时间:2026/6/21 21:29:32

1. 项目概述

在嵌入式产品开发与维护的生命周期中,固件更新能力是衡量产品成熟度与可维护性的关键指标。想象一下,一个部署在工厂车间或偏远地区的物联网设备,如果发现了一个软件缺陷或需要增加新功能,工程师不可能每次都亲临现场拆机、连接调试器。此时,一套稳定、可靠的远程或本地固件更新机制,就如同给设备赋予了“空中升级”的能力,其价值不言而喻。今天,我们就来深入探讨NXP LPC55(S)1x系列微控制器(MCU)如何利用其内置的ROM Bootloader,通过最常见的USB接口,实现一套高效、实用的固件更新方案。这套方案的核心,在于巧妙地利用了芯片出厂即固化的“底层引导程序”,结合NXP官方提供的开源工具链,构建了一条从PC端到MCU闪存的可靠代码传输通道。对于从事LPC55系列开发,尤其是需要在产品中集成USB固件更新功能的工程师来说,理解并掌握这套流程,能显著提升开发效率和产品可靠性。

2. LPC55(S)1x ROM Bootloader深度解析

2.1 芯片内置引导程序的能力边界

LPC55S1x/LPC551x系列基于Arm Cortex-M33内核,其一大亮点是集成了一个功能丰富的片上ROM Bootloader。这个Bootloader在芯片出厂时就被固化在ROM中,用户无法修改,这保证了其基础功能的绝对可靠。它的能力远不止简单的跳转到应用程序,而是一个支持多种接口和协议的微型“系统”。

首先,它支持从片上闪存启动应用程序镜像,这是最基本的功能。其次,它内置了CRC32完整性校验功能,可以在启动时验证应用程序的完整性,这是实现安全、可靠启动的基石。最核心的是其在系统编程(ISP)能力,它允许通过多种通信接口对内部闪存进行编程,包括:USB1接口(使用HID设备类)、UART接口(支持自动波特率)、SPI从机接口以及I2C从机接口。这意味着开发者可以通过USB线、串口线等常见方式与Bootloader通信,无需依赖昂贵的专用调试器。

此外,ROM还提供了一系列API函数,如闪存编程API、电源控制API等,甚至支持符合NXP安全启动文件格式(SB2)的安全固件更新。对于非安全启动场景,我们主要利用其USB HID和CRC校验功能。Bootloader还能从经过PRINCE模块加密的闪存区域启动,并支持NXP调试认证协议,但这些属于安全启动范畴,本文聚焦于非安全模式。

注意:ROM Bootloader的功能是芯片硬件决定的,不同系列的NXP MCU其ROM Bootloader支持的接口和命令可能不同。在为新项目选型或移植方案时,务必查阅对应芯片的最新版用户手册,确认ROM Bootloader的具体规格。

2.2 非安全启动流程与CRC校验的妙用

理解启动流程是成功实施固件更新的前提。在非安全启动(即未启用TrustZone和安全启动)模式下,LPC55(S)1x的上电复位流程有着清晰的逻辑路径,其核心决策点在于对应用程序镜像的检查。

芯片复位后,ROM代码首先会读取闪存起始地址(通常是0x0)处的镜像头信息。这个头信息包含了栈指针(Initial SP)、程序计数器(Initial PC)、镜像长度(imageLength)、镜像类型(imageType)等关键数据。其中,imageType字段至关重要。如果该字段值为0x0000,表示这是一个普通的、无校验的镜像,ROM代码会直接跳转到Initial PC指向的地址开始执行应用程序。

如果imageType字段值为0x0002(普通CRC镜像)或0x0005(普通CRC XIP镜像),则启动流程进入“增强模式”。此时,ROM代码会使用头信息中的imageLength字段作为长度,对闪存中的应用程序代码区计算CRC32校验值。这里有一个关键细节:计算CRC时,会跳过存储CRC结果本身的字段(即offsetToSpecificHeader指向的位置),防止自指导致校验永真。计算出的CRC值会与头信息中存储的预期CRC值进行比较。

  • 校验通过:CRC匹配,说明应用程序完整无误,ROM代码正常引导进入应用程序。
  • 校验失败:CRC不匹配,说明应用程序可能损坏(如闪存位翻转、意外擦写)或被篡改。此时,ROM代码不会尝试执行可能已损坏的程序,而是自动落入ISP固件更新模式。这正是实现“固件损坏自恢复”或“强制进入升级模式”的硬件基础。

这种设计带来了极大的灵活性。开发者可以预先烧录一个带CRC校验的固件。在需要强制升级时,可以通过应用程序代码主动修改闪存中的某个关键字节(例如,在特定用户操作后),破坏CRC校验。随后重启设备,ROM便会自动进入ISP模式,等待通过USB等接口接收新固件。这比单纯依赖一个物理按键进入升级模式更加智能和可靠。

3. 硬件准备与软件工具链搭建

3.1 硬件平台:LPC55S16-EVK评估板

为了进行实践,我们以官方评估板LPC55S16-EVK为例。这块板载成了LPC55S16芯片的所有主要外设,并提供了方便的调试和用户接口。对于固件更新实验,我们需要关注以下几个关键部分:

  1. 微控制器:板载的LPC55S16JBD100芯片,拥有256KB闪存和96KB SRAM,以及我们需要用到的高速USB控制器。
  2. USB接口:板上的J4接口标记为USB1/HS_USB,这是一个Micro-USB接口,连接至芯片的高速USB PHY。这是我们与PC端blhost工具通信的唯一接口,用于固件传输。切勿连接到用于调试和串口通信的J10(Link2 USB)接口。
  3. 功能按键:
    • SW2 (RESET):系统复位按键。
    • SW4 (ISP):ISP模式触发按键。其信号连接至MCU的PIO0_5引脚,该引脚在ROM Bootloader中被定义为ISP入口引脚。
  4. 电源:可以通过J4的USB口供电,也可以使用外部电源。确保在操作过程中供电稳定。

3.2 核心软件工具:blhost与elftosb

工欲善其事,必先利其器。NXP为MCU Bootloader提供了开源的工具链,其中两个工具是我们的核心:

1. blhost:主机端命令行工具blhost是一个运行在PC(支持Windows、Linux、macOS)上的命令行工具,它实现了与MCU ROM Bootloader通信的协议。我们可以通过它发送命令,来擦除闪存、写入数据、读取内存、复位设备等。它的工作模式是发现并连接处于ISP模式的MCU,然后执行用户输入的命令。我们将主要使用它的flash-erase-all和write-memory命令。

2. elftosb:安全启动镜像生成工具虽然名为“安全”工具,但它的elftosb-gui图形界面版本非常方便用于为普通镜像添加CRC校验头。它接收编译器生成的原始.bin或.elf文件,根据用户的配置(如选择CRC校验类型、执行地址等),生成一个新的、带有完整启动头信息(包括CRC值)的.bin文件。这个新生成的.bin文件才是可以被ROM正确识别并校验的“可启动镜像”。

获取与准备: 这些工具包含在NXP的MCU-Boot项目中。建议从NXP官方GitHub仓库或官网下载最新版本。下载后,在Windows系统下,主要可执行文件通常位于tools\blhost\win(blhost.exe)和tools\elftosb\win(elftosb-gui.exe)目录下。为了操作方便,可以将这些工具的路径添加到系统的环境变量PATH中,或者将待操作的.bin文件拷贝到工具所在目录进行操作。

4. 基于USB HID的固件更新实操全流程

4.1 进入ISP模式的三种方法

要让MCU运行ROM Bootloader并等待更新,首先必须使其进入ISP模式。对于LPC55(S)1x,有三种主要方式:

  1. 硬件引脚触发(最常用):这是通过物理按键操作实现的方法,适用于产品上没有运行用户程序或程序无法配合的情况。

    • 操作顺序:给板子供电 ->按住SW4 (ISP)按键不松开-> 短按一下SW2 (RESET)按键 -> 等待约1秒后,松开SW4按键。
    • 原理:复位时,ROM代码会检测PIO0_5引脚的电平。如果检测到低电平,则跳过闪存中的应用程序,直接进入ISP模式。
  2. 软件API调用:如果应用程序正在正常运行,可以通过调用ROM中提供的runBootloader()函数来软重启并跳转到Bootloader。这种方式需要你在应用程序代码中知道该API的入口地址并正确调用,通常用于在应用程序内发起“系统升级”请求。

  3. CRC校验失败触发(自动恢复):如前所述,如果烧录了带CRC校验的固件,且该固件被破坏(例如,应用程序自己故意擦除一小段闪存),那么下次复位时,ROM校验失败会自动进入ISP模式。这是实现“无感”或“强制”升级的高级手段。

对于初次实验和大多数产品场景,方法1(硬件引脚触发)是最直接可靠的。成功进入ISP模式后,通过USB线连接J4到PC,PC设备管理器会识别到一个新的HID-compliant device(VID: 0x1FC9, PID: 0x0022),这就是ROM Bootloader在USB HID设备类下的表现形式。

4.2 使用blhost进行固件烧录

确认MCU进入ISP模式并被PC识别后,就可以打开命令行工具(如Windows的CMD或PowerShell)进行操作了。假设我们已将blhost.exe和待烧录的固件文件my_firmware.bin放在同一目录D:\lpc_update下。

步骤一:连接与擦除首先,我们需要指定要操作的USB HID设备。LPC55(S)1x Bootloader的USB VID/PID是固定的。

cd /d D:\lpc_update blhost.exe -u 0x1FC9,0x0022 -- flash-erase-all
  • -u 0x1FC9,0x0022:指定目标设备的VID和PID。
  • -- flash-erase-all:命令Bootloader擦除整个用户可用的闪存区域。这是一个危险命令,会清除所有现有程序和数据,务必在确认进入ISP模式后使用。

执行成功后,命令行会返回类似Response status = 0 (0x0) Success的信息。

步骤二:烧写新固件擦除完成后,将新的二进制文件写入闪存起始地址(通常是0x0)。

blhost.exe -u 0x1FC9,0x0022 -- write-memory 0x0 my_firmware.bin
  • -- write-memory 0x0:指定写入的起始内存地址为0x0,即闪存起始。
  • my_firmware.bin:要烧录的二进制文件名。

命令执行时,会显示传输进度。写入完成后,同样会返回成功状态。整个过程中,blhost工具会自动处理HID通信的数据分包、校验和重试。

步骤三:复位并运行烧写完成后,可以让Bootloader复位MCU,运行新程序。

blhost.exe -u 0x1FC9,0x0022 -- reset

执行此命令后,MCU会立即复位。由于闪存0x0地址已经有了新的有效程序(无论是否带CRC),ROM会正常启动它。

实操心得:在实际操作中,可能会遇到blhost找不到设备的情况。首先检查USB线是否可靠连接至J4口,设备管理器是否出现HID-compliant device。其次,进入ISP模式的时机很关键。有时需要多尝试几次“按住ISP键再复位”的操作。如果使用CRC触发方式,确保在操作前已经成功烧录过一个带CRC的有效固件。

5. 生成带CRC校验的增强固件

5.1 为何需要CRC校验?

直接使用编译器生成的原始.bin文件进行烧录,其imageType为0,ROM不会进行任何校验。这意味着如果闪存发生轻微位错误,MCU可能会执行错误代码,导致程序跑飞或死机,无法自动恢复。为固件添加CRC校验,相当于给程序包上了一层“完整性封印”。ROM在每次启动时都会检查这个封印是否完好,一旦破损(数据错误),便启动备用方案(进入ISP模式),从而极大地提高了系统的鲁棒性。

5.2 使用elftosb-gui工具添加CRC校验

我们以最常见的Keil MDK编译环境为例,假设已经通过Keil生成了一个原始的project.bin文件。

  1. 打开elftosb-gui:运行elftosb-gui.exe。
  2. 选择目标芯片:在软件界面的Select target device下拉框中,选择LPC55xx系列。
  3. 创建新镜像配置:在Image Configuration区域,点击New按钮,创建一个新的配置。
  4. 配置输入文件:
    • *Image file:点击浏览按钮,选择Keil生成的原始project.bin文件。
    • *Load address 0x:保持默认的0。这表示镜像将被加载到地址0x0处执行,对于从闪存启动的应用程序这是正确的。
  5. 定义输出格式(关键步骤):
    • Image execution target:选择Internal flash (XIP)。这表示镜像在闪存中直接执行。
    • Image authentication type:选择CRC。这就是我们需要的校验类型。
    • TrustZone image type:由于我们是非安全启动,选择TZ-M Disabled。
  6. 指定输出文件:在Output区域的Master Boot output file中,指定输出文件的路径和名称,例如project_with_crc.bin。
  7. 生成:点击Process按钮。如果配置正确,下方日志窗口会显示处理成功的信息,并在指定路径生成project_with_crc.bin文件。

现在,这个新生成的.bin文件就包含了完整的镜像头,其中imageType被设置为0x0002(CRC镜像),并且在头部的offsetToSpecificHeader字段存储了计算好的CRC32值。使用blhost将这个文件烧录进芯片后,ROM就能对其进行校验了。

5.3 验证CRC保护机制

为了验证CRC保护是否生效,我们可以设计一个小实验:

  1. 首先,将一个带CRC校验的、功能正常的固件(比如一个闪烁LED的程序)烧录进MCU。
  2. 复位运行,观察程序正常运行(LED闪烁)。
  3. 然后,我们不按ISP键,直接进行复位。由于CRC校验通过,程序会再次正常运行。
  4. 接着,通过某种方式破坏固件。一个简单的方法是在用户程序中,通过一个特殊的触发条件(如长按某个按键),执行一段擦除自身一小部分闪存的代码(例如,擦除以0x30000地址开始的512字节)。注意:此操作具有破坏性,仅用于测试,务必在理解代码位置的前提下进行。
  5. 破坏完成后,再次复位MCU。此时ROM计算CRC会发现与存储值不匹配,从而自动进入ISP模式。此时连接USB到PC,blhost就能发现设备并等待更新命令,而不会再运行已损坏的旧程序。

这个机制完美实现了“固件损坏自恢复”,对于需要高可靠性的应用场景至关重要。

6. 不同开发环境生成.bin文件的方法

blhost和elftosb工具通常处理.bin格式的二进制文件。不同集成开发环境(IDE)生成.bin文件的方法略有不同。

6.1 Keil MDK生成.bin文件

在Keil中,可以通过配置用户命令,在编译链接后自动调用fromelf工具生成.bin文件。

  1. 打开项目,点击魔术棒图标进入Options for Target。
  2. 选择User选项卡。
  3. 在After Build/Rebuild区域,勾选Run #1。
  4. 在其后的编辑框中,输入以下命令(请根据你的Keil安装路径调整xxxx部分):
    xxxx\ARM\ARMCLANG\bin\fromelf.exe --bin -o ./output/@L.bin ./output/@L.axf
    • xxxx\ARM\ARMCLANG\bin\fromelf.exe:fromelf工具的完整路径。
    • --bin:指定输出格式为二进制。
    • -o ./output/@L.bin:指定输出文件路径和名称。@L是Keil的内置变量,代表目标名称(Target Name)。这里输出到项目目录下的output文件夹。
    • ./output/@L.axf:输入的ELF格式文件(由链接器生成)。
  5. 点击OK保存。此后每次编译成功,都会在output文件夹下生成对应的.bin文件。

6.2 IAR Embedded Workbench生成.bin文件

在IAR中,配置更为直观。

  1. 在项目工作区右键点击项目名,选择Options。
  2. 在配置对话框中,导航到Output Converter。
  3. 勾选Generate additional output。
  4. 在Output format下拉框中选择Raw binary。
  5. 你还可以在Output file中指定生成文件的路径和名称(通常基于当前配置自动命名)。
  6. 点击OK保存。编译项目后,除了默认的调试文件,还会在指定目录生成.bin文件。

6.3 MCUXpresso IDE生成.bin文件

MCUXpresso IDE基于Eclipse,生成.bin文件也很方便。

  1. 编译项目后,在Project Explorer视图中,展开项目的Debug或Release文件夹。
  2. 找到生成的.axf文件(例如my_project.axf)。
  3. 右键点击该.axf文件,在上下文菜单中选择Binary Utilities->Create Binary。
  4. IDE会自动在同一目录下生成同名的.bin文件。

无论使用哪种IDE,最终得到.bin文件后,都可以按照第5章的方法,使用elftosb-gui为其添加CRC校验头,生成最终的、可被ROM校验的固件文件。

7. 常见问题与深度排查指南

在实际操作中,你可能会遇到各种问题。以下是一些典型问题及其排查思路,这些经验往往在官方文档中不会详细提及。

问题一:blhost执行命令时报错“Error: No device with specified VID/PID was found”

  • 可能原因1:设备未进入ISP模式。这是最常见的原因。请严格按照“按住ISP键 -> 复位 -> 松开ISP键”的顺序操作,并观察板卡上是否有指示灯状态变化(有些板卡设计会在ISP模式点亮特定LED)。可以尝试多操作几次。
  • 可能原因2:USB连接错误。确保USB线连接的是评估板的J4(HS_USB)口,而不是调试器的USB口。尝试更换USB线或电脑USB端口。
  • 可能原因3:驱动问题。Windows系统应能自动识别HID设备。如果设备管理器中出现带有感叹号的未知设备,可以尝试手动指定驱动为“通用HID设备”。在Linux或macOS下,通常无需额外驱动,但需要当前用户有访问USB设备的权限(可能需要将用户加入plugdev组或配置udev规则)。

问题二:blhost可以找到设备,但flash-erase-all或write-memory命令失败

  • 可能原因1:供电不足。高速USB操作对电源有一定要求。如果仅通过USB线供电,且线材质量较差或过长,可能导致通信不稳定。尝试使用外部电源为板卡供电,或者换用更短、质量更好的USB线。
  • 可能原因2:固件文件地址或格式错误。write-memory命令的地址必须是闪存的有效起始地址(通常是0x0)。确保你烧写的是纯二进制.bin文件,而不是.hex或.elf文件。如果使用elftosb处理过的文件,确保处理过程没有报错。
  • 可能原因3:Bootloader版本或命令兼容性。极少数情况下,芯片的ROM版本可能与blhost工具版本存在细微兼容性问题。尝试从NXP官网或GitHub获取最新版本的MCU-Boot工具包。

问题三:烧录带CRC的固件后,复位无法正常运行,也无法进入ISP模式

  • 可能原因1:CRC计算范围错误。这通常是由于elftosb工具配置不当引起的。确保在elftosb-gui中,Load address设置正确,且Image execution target选择了Internal flash (XIP)。错误的地址会导致CRC计算的范围不对,使得ROM校验永远失败或通过一个错误的程序。
  • 可能原因2:应用程序向量表错误。原始.bin文件的起始位置必须是正确的栈顶指针(MSP)和复位向量(Reset_Handler)。如果编译器生成的镜像向量表不正确,即使CRC通过,程序也会在跳转后立刻硬件错误。检查链接脚本,确保向量表位于镜像最开头。
  • 排查方法:先烧录一个不带CRC的原始.bin文件,测试程序是否能正常运行。如果正常,再用elftosb为其添加CRC并烧录测试。这样可以隔离是程序本身问题还是CRC处理过程的问题。

问题四:如何在自己的应用程序中调用ROM API进入Bootloader?

这在产品中用于实现“软件升级”入口非常有用。你需要从芯片的用户手册中找到ROM API表,获取runBootloader函数的入口地址。通常,你需要先设置好必要的参数(例如选择哪个接口进入ISP),然后以函数指针的方式调用这个地址。示例代码如下(地址需查阅具体芯片手册确认):

// 假设 runBootloader API 的入口地址是 0x03000010 (示例地址,非真实) #define ROM_RUN_BOOTLOADER_ADDR (0x03000010UL) typedef void (*run_bootloader_t)(uint32_t param); void jump_to_bootloader(void) { // 可选:设置进入ISP模式的参数,例如选择USB接口 // 根据ROM手册,参数可能是一个结构体指针或特定值 uint32_t isp_param = 0; // 通常0表示使用默认引脚或上次使用的接口 // 禁用所有中断 __disable_irq(); // 设置函数指针并调用 run_bootloader_t run_bl = (run_bootloader_t)ROM_RUN_BOOTLOADER_ADDR; run_bl(isp_param); // 调用后不会返回 while(1); }

重要警告:在调用此API前,必须确保所有外设已处于静止状态,中断已禁用,并且没有正在进行的DMA或关键操作。不恰当的跳转可能导致硬件状态混乱。

问题五:使用CRC自恢复功能,如何防止意外进入升级模式?

CRC校验是一把双刃剑。它能在固件损坏时救命,但也可能因为闪存的偶然位翻转(虽然概率极低)而导致设备“误判”为损坏,意外进入ISP模式,影响正常使用。为了增强鲁棒性,可以考虑以下策略:

  1. 多次重启验证:在应用程序启动初期,如果检测到自己是经过复位才运行的,可以记录一个“启动尝试计数器”在备份寄存器或闪存的特定位置。如果连续多次启动失败(例如CRC失败导致进入ISP,但用户没有更新固件又重启了),可以尝试一个“安全模式”或恢复一个出厂备份固件,而不是无限等待ISP。
  2. 结合看门狗:确保应用程序正确喂狗。如果因为程序跑飞导致看门狗复位,这属于“非正常复位”。可以在应用程序初始化时检查复位源。如果是看门狗复位,且结合CRC失败,则可以更确信地进入恢复模式。
  3. 用户确认:对于有显示或按键的设备,可以在检测到CRC失败后,先尝试运行一个极简的“恢复引导程序”,提示用户选择是否进入升级模式,而不是直接、静默地进入,提升用户体验。

固件更新是连接产品开发与后期维护的桥梁。基于LPC55(S)1x ROM Bootloader的方案,凭借其硬件集成度高、无需额外组件、支持CRC校验等优点,为中小型嵌入式设备提供了一个非常经济且可靠的实现路径。从简单的通过按键触发升级,到利用CRC校验实现智能恢复,这套机制的可拓展性很强。在实际项目中,我通常会建议在量产前,充分测试各种异常场景下的升级流程,例如升级过程中断电、传输数据错误等,并考虑在应用程序中预留一个可靠的、独立的升级触发通道(如特定的串口命令),作为硬件按键之外的备份方案。

相关新闻

  • 本地商家GEO服务选型全解析:合规与效果双维度考量 - 速递信息
  • 2026年 高大空间节能空调系统推荐排行榜:工业厂房/体育馆/候车厅绿色降温与节能优选方案 - 品牌发掘
  • 如何免费提升百度网盘下载速度:macOS用户的完整解决方案

最新新闻

  • SCMP报名需要工作证明吗?需要什么材料? - 众智商学院课程中心
  • 2026年国内铜屑压块机厂家:性能、服务及降本效果对比 - 起跑123
  • 【共创季稿事节】鸿蒙原生 ArkTS 布局实战:使用 Stack 实现商品 Tag 标签叠加
  • 武汉市汉阳区管道疏通|维小达|马桶、蹲便器、地漏、洗菜盆、洗手盆、浴缸一站式疏通养护服务 - 维小达科技
  • 2026扬州抖音公会营业性演出许可证整套全包代办 - 速递信息
  • d2dx:让经典暗黑2在现代PC上焕发新生的终极解决方案

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号