XVF3610 系统启动以及初始化配置
引导XVF3610的标准机制是从一个连接的QSPI闪存设备上启动。这提供了独立的操作 ,以及配置数据的持久性存储。XVF3510支持通过USB(-UA产品型号)和I2C(-INT产品型号)的设备固件升级(DFU)。
我们为执行DFU操作提供了预编译的主机实用程序和参考源代码。
此外,当使用闪存启动XVF3610处理器时,闪存中的一个数据分区可用于存储命令,这些命令在启动后立即执行,以配置和定义设备的功能。
XVF3610还可以使用另一种启动模式,即使用由主机处理器通过SPI接口提供的可执行映像。
下面几节描述了启动过程和数据分区,包括为特定应用进行的定制。
引导程序
标准的启动机制是来自一个连接的QSPI闪存设备。这提供了独立的操作,以及配置数据的持久性存储。VocalFusion XVF3610支持通过USB(-UA产品变量)和I2C(-INT产品变量)进行设备固件升级(DFU)。为执行DFU操作提供了预编译的主机实用程序和参考源代码。
下面的章节讨论了闪存中的数据结构和DFU的操作。
虽然DFU的功能与USB DFU规范相似,但它已经分化,以适应USB和I2C操作,因此与兼容的USB DFU工具不兼容。
Flash存储结构
VocalFusion XVF3610内的数据结构被安排为包含一个出厂映像、一个单一的升级映像、设备序列号以及出厂和升级映像的数据分区。如下所示:

-
出厂启动映像(factory boot image)是VocalFusion的可执行代码,在发布包的bin目录下提供。文件格式是xe,指的是XMOS可执行文件。这是通过XTAG调试器或通过批量闪存编程操作写入设备的。
-
如果存在升级启动映像(upgrade boot image),则是通过DFU操作写入闪存的可执行代码。下文将介绍升级启动映像的生成。
-
硬件构建信息(HW build info)在出厂映像的.json数据分区文件中指定,并与出厂映像和数据分区同时写入。它是一个唯一的标识符,不受后续DFU升级操作的影响。
-
序列号(Serial Number)是一个自定义字段,可以通过USB和I2S控制接口进行编程,不受后续DFU操作的影响。
-
出厂和升级数据分区(Factory and Upgrade Data Partitions)是出厂和升级映像的相关数据分区(如果存在升级)。它们在与启动映像相同的操作中被写入闪存。关于数据分区的生成和使用的更多信息,见配置和数据分区部分。
只支持存储单个升级引导映像和数据分区对。因此,任何应用的升级映像将覆盖现有的任何升级映像。
基于闪存的系统的出厂编程和现场更新过程的摘要在参考章节给出
对出厂启动映像和数据分区进行编程
XVF3610语音处理器有两个预编译的版本(-UA和-INT),因此只需要使用XTC工具的编程工具,特别是xFLASH。它作为一个命令行程序运行,以创建启动映像,如果使用闪存,则将启动映像编程到连接的设备上。
一个XTAG调试器必须连接到XVF3610上进行闪存编程操作。关于使用XTAG连接到XVF3610开发套件的信息,请参考开发套件用户指南。
用于创建闪存映像和用数据分区编程的xFLASH命令的基本形式如下:
xflash --boot-partition-size 0x100000 --factory [Application executable (.xe)] --data [Data partition description (.bin)]
其中
-
应用程序可执行文件 (.xe) .xe 文件是与支持的配置(-UA 或 -INT 产品变体)之一的 VocalFusion 发行包一起提供的启动映像。
-
数据分区描述 (.bin) .bin 文件是数据分区描述,可以在发布包(-UA 或 -INT)中提供,也可以按照本节后面的描述进行定制。
对于通过SPI从主机处理器启动的情景,使用一个特定的映像,该映像在发布包中提供。发布包中没有包括数据分区,因为配置命令被认为是由主机的控制器提供的。
升级映像和数据分区
为了能够在设备上应用升级映像,必须用出厂映像和数据分区进行编程。
DFU过程需要使用两个工具,dfu_usb或dfu_i2c(取决于固件变体),以及dfu_suffix_generator。
这些工具的预编译版本作为发布包的一部分提供给\host中适当的平台目录(如\host\Win32\bin),DFU工具的源代码提供在\host\src\dfu目录中。
关于构建主机应用程序的更多信息,请参考发布包中的 \host\how_to_build_host_apps.rst 的构建说明。
除了DFU工具外,还需要升级映像和数据分区。这些都在发布包的 \bin 和 \data-partition\images 目录中提供。
自定义数据分区的生成在配置和数据分区部分有详细说明。
准备和执行DFU需要经过一些阶段,以确保安全和成功的更新。这些将在下一节中详细介绍。
二进制升级映像的生成
首先,升级映像(.xe)需要被转换为二进制格式。使用xflash和以下命令将.xe映像转换为二进制形式:
xflash --noinq --factory-version 15.0 --upgrade [UPGRADE_VERSION] [UPGRADE_EXECUTABLE] -o [OUTPUT_BINARY_NAME]
此命令为所有15.x.x版本的XTC工具指定--factory-version值为15.0。(15.0的值指的是XTC工具链的boot loader API)
如果在未来的固件发布中使用不同版本的XTC工具,则应注意版本号,以便可以创建兼容格式的更新映像。
升级的版本号是用--upgrade <version>指定的。它的格式应该如下。
16位数字0xJJMP其中
- J代表major
- M代表minor
- P代表point
例如,要从v5.3.0发行包中为-UA系统创建一个升级二进制映像,请使用以下命令:
xflash --noinq --factory-version 15.0 --upgrade 0x0520 app_xvf3610_ua_v5.3.0.xe -o app_xvf3610_ua_v5.3.0.bin
在二进制文件中增加DFU后缀
为了防止意外升级不兼容的镜像,二进制升级镜像和数据分区二进制都必须使用所提供的dfu_suffix_generator进行签名,它可以在发布包的主机平台目录下找到预编译,例如:/host/MAC/bin。
这个机制在二进制文件中嵌入了一个结构,可以被DFU工具读取,以检查二进制数据是否适合连接的设备,然后再执行。
dfu_suffix_generator的一般使用形式如下:
dfu_suffix_generator VENDOR_ID PRODUCT_ID [BCD_DEVICE] BINARY_INPUT_FILE BINARY_OUTPUT_FILE
VENDOR_ID、PRODUCT_ID和BCD_DEVICE是非零的16位值的十进制或十六进制格式,0xFFFF绕过了这个字段的验证。
当为XVF3610-UA设备建立升级映像时,USB供应商标识符(VID)和USB产品标识符(PID)被添加到头文件中,然后由DFU工具检查连接的设备是否匹配。如果与所连接的设备不匹配,该工具会报告错误。
对于XVF3610-INT设备,供应商和产品ID字段都应该被设置为0xFFFF,以便生成。这会让DFU绕过检查,因为对于I2C系统来说,没有相当于USB标识符的东西。然而,即使XVF3610-INT的检查被绕过,后缀也必须被添加到升级和数据分区文件中,因为DFU工具会根据这些信息检查二进制文件的完整性。
下面的例子显示了如何为XVF3610-INT和XVF3610-UA产品的升级二进制文件添加DFU后缀。
对于XVF3610-UA(默认的XMOS Vendor和XVF3610-UA产品标识符是用来说明的):
dfu_suffix_generator.exe 0x20B1 0x0016 app_xvf3610_ua_v5.2.0.bin boot.dfu
dfu_suffix_generator.exe 0x20B1 0x0016 data_partition_upgrade_ua_v5_5_0.bin data.dfu
对于XVF3610-INT:
dfu_suffix_generator.exe 0xFFFF 0xFFFF app_xvf3610_int_v5.2.0.bin boot.dfu
dfu_suffix_generator.exe 0xFFFF 0xFFFF data_partition_upgrade_int_v5_2_0.bin data.dfu
如果通过数据分区修改默认的供应商和产品ID,必须特别小心。如果从数据分区配置失败,USB VID和PID将保持其默认值(VID=0x20B1,PID=0x0016),并且不允许对修改后的签名文件进行DFU请求。
执行DFU
预编译的DFU工具在主机架构目录下的发布包中提供,例如:/host/Linux/bin。对于MAC、Linux和Windows,提供了DFU_USB,对于Raspberry Pi提供了DFU_I2C。源代码可以用来在所需的平台上重建任一版本。
dfu_usb工具的一般形式如下:
dfu_usb [OPTIONS] write_upgrade BOOT_IMAGE_BINARY DATA_PARTITION_BIN
选项: --quiet
--vendor-id 0x20B1 (default)
--product-id 0x0014 (default)
--bcd-device 0xFFFF (default)
--block-size 128 (default)
然后dfu_i2c工具的一般形式如下所示:
dfu_i2c [OPTIONS] write_upgrade BOOT_IMAGE_BINARY DATA_PARTITION_BIN
选项: --quiet
--i2c-address 0x2c (default)
--block-size 128 (default)
传递给工具的两个二进制文件,即启动镜像和数据分区,必须有DFU的后缀,否则DFU工具会产生错误。下面是XVF3610-UA和XVF3610-INT的DFU工具使用实例。
对于XVF3610-UA:
dfu_usb --vendor-id 0x20B1 --product-id 0x0014 write_upgrade boot.dfu data.dfu
对于XVF3610-INT:
dfu_i2c write_upgrade boot.dfu data.dfu
一旦完成,将返回以下信息,设备将重新启动。在XVF3610-UA的情况下,设备将重新枚举。
write upgrade successful
为了验证DFU是否按计划成功,可以使用vfctrl工具来查询更新前后的固件版本。例如,要查询XVF3610-UA的版本,可以使用以下命令。
vfctrl_usb GET_VERSION
vfctrl工具检查所连接设备的版本号以确保正确操作。为了抑制由于vfctrl和升级的固件版本不一致而引起的错误,可以在该工具中使用--no-check-version选项。
恢复出厂设置
要将设备恢复到出厂配置,有效地放弃任何升级,需要遵循上述同样的过程,但使用空白的启动镜像和数据分区。
这是唯一可以启动恢复的方法,因为设备没有自我恢复的能力。
同样的空白文件可以用于启动镜像和数据分区,可以在MAC和Linux上使用dd,在windows下使用fsutil生成,如下图所示。
空白映像可以用一个闪存扇区大小的0文件来创建。在UNIX兼容平台上4KB扇区的正常情况下,可以按如下方式创建:
dd bs=4096 count=1 < /dev/zero 2>/dev/null blank.dfu
对于Windows系统:
fsutil file createNew blank.dfu 4096
现在可以使用空白.dfu文件对Boot Image和Data Partition进行升级镜像和数据分区的生成和应用这一节所概述的过程。
启动镜像和数据分区的兼容性检查
数据分区和引导映像的格式可能在不同的版本增量之间发生变化。因此,为了防止不兼容的 Boot 和 Data Partition 运行并导致未定义的行为,在 Data Partition 中嵌入了一个称为兼容性版本的字段。运行中的Boot Image在读取分区数据之前,会对照数据分区中的兼容版本检查自己的版本。
如前所述,在生成升级镜像时,固件的版本也应在xflash的--upgrade参数中指定。
如果兼容性检查失败,启动的映像(可能是工厂映像或升级映像)将不会读取数据分区,并将以其默认设置运行(在上面的默认操作部分描述)。启动状态在RUN_STATUS 寄存器中报告,可以通过vfctrl工具访问,例如:
vfctrl_usb.exe GET_RUN_STATUS
成功的启动状态由FACTORY_DATA_SUCCESS或UPGRADE_DATA_SUCCESS报告,这取决于所执行的启动镜像。
如果不成功,设备将恢复到故障安全的操作模式。RUN_STATUS寄存器可以被查询到进一步的调试信息。RUN_STATUS代码的完整列表在参考部分有描述。
故障安全模式使用默认的供应商ID为0x20B1(XMOS),产品ID为0x16。在这种情况下,主机需要具备定位不同ID的USB设备的能力。
自定义闪存设备
大多数QSPI闪存设备都符合定义闪存设备访问和使用的同一套参数。然而,为了支持闪存接口参数不同的情况,下面的章节解释了如何定义一个自定义的闪存接口。
用于存储Boot Image和数据分区数据的闪存设备的细节必须在工厂Boot Image和任何数据分区文件中指定,以确保成功的工厂编程和执行DFU升级固件的能力。
用于出厂编程的自定义闪存定义
在工厂编程过程中,使用XMOS XTAG调试器,闪存设备的规格(specification)被用来创建加载器,负责从闪存和设备中下载启动镜像。
闪存规格被提供给xflash,如固件更新部分所述,使用一个.spispec文件。发布包中会提供一个有代表性的.spispec文件,它支持大多数的QSPI闪存设备和开发工具包。
\data-partition\16mbit_12.5mhz_sector_4kb.spispec
这是一个文本文件,并且在使用前必须根据flash型号用不同的参数进行修改。一个.spispec文件的例子显示在参考部分。
用于生成数据分区的自定义闪存定义
.spispec文件也必须包括在数据分区中,同时还有扇区大小,以便DFU操作可以正确执行。
由于DFU功能的性质,在生产制造之前,在目标系统中测试DFU过程的执行是非常重要的。
SPI Slave模式启动
XVF3610的-UA和-INT配置除了从闪存模式启动外,还有一个SPI Slave启动模式。SPI Slave启动以二进制形式下载发布包中提供的启动映像。这里用Raspberry Pi和Python脚本来说明,以管理下面讨论的传输。
XVF3610-INT SPI模式启动
使用Raspberry Pi上可用的XVF3610-INT发布包,可以通过以下步骤执行SPI启动。
-
使用Raspberry Pi上的终端控制台,导航到XVF3610-INT发布包的位置。
-
使用下面的命令来执行SPI启动过程,启动发布包中的XVF3610-INT固件(用适当的版本号替换vX_X_X)。
python3 host/Pi/scripts/send_image_from_rpi.py bin/app_xvf3610_int_spi_boot_vX_X_X.bin --delay设备应在3秒内准备就绪。
-
使用控制程序
vfctrl_i2c将主时钟更新为PDM特定时钟:./host/Pi/bin/vfctrl_i2c SET_MCLK_IN_TO_PDM_CLK_DIVIDER 1 -
使用控制工具
vfctrl_i2c配置任何系统特定的设置。 -
通过VocalFusion控制工具发出以下命令,启动XVF3610的处理和接口。
./host/Pi/bin/vfctrl_i2c SET_MIC_START_STATUS 1
./host/Pi/bin/vfctrl_i2c SET_I2S_START_STATUS 1备注在SPI启动之后,XVF3610将不会读取闪存中可能存在的任何数据分区。这就是为什么第3步是必要的,
SET_MCLK_IN_TO_PDM_CLK_DIVIDER命令被包含在XVF3610-INT的数据分区中。
XVF3610-UA SPI模式启动
使用Raspberry Pi上的XVF3610-UA发行包,可以通过以下步骤执行SPI启动。
-
使用Raspberry Pi上的终端控制台,导航到XVF3610-UA发布包的位置。
-
使用下面的命令来执行SPI启动过程,启动发布包中的XVF3610-UA固件(用适当的版本号替换vX_X_X)。
python3 host/pi/scripts/send_image_from_rpi.py bin/app_xvf3610_ua_spi_boot_vX_X_X.bin
设备应该在3秒内启动。
延迟启动模式不适用于XVF3610-UA。
配置和数据分区
当使用闪存启动XVF3610处理器时,数据分区可用于存储启动后立即执行的命令,以配置和定义该设备的功能。以下各节描述了数据分区的定义、如何生成以及针对具体应用的定制。
分区文件结构
数据分区的内容是在一个.json文件中定义的,该文件被传递给一个生成脚本,该脚本形成了在闪烁设备时使用的二进制文件。在描述了.json文件的定义后,下面将描述生成过程。
为了解释的目的,请考虑下面的例子,一个自定义的XVF3610-UA数据分区:
{
"comment": "Example data partition definition",
"spispec_path": "16mbit_12.5mhz_sector_4kb.spispec",
"regular_sector_size": "4096",
"hardware_build": "0xFFFFFFFF",
"item_files": [
{ "path": "input/usb_to_device_rate_48k.txt", "comment": "" },
{ "path": "input/device_to_usb_rate_48k.txt", "comment": "" },
{ "path": "input/usb_mclk_divider.txt", "comment": "" },
{ "path": "input/xmos_usb_params.txt", "comment": "" },
{ "path": "input/i2s_rate_16k.txt", "comment": "" },
{ "path": "input/led_after_boot.txt", "comment":"" }
]
}
Comment键值对用于配置.json文件,但也为个别项目文件提供
{ "comment": "Example Comment" }
运行中的VocalFusion设备需要知道其外部QSPI闪存的大小和几何形状,以便向其写入固件升级。这将以闪存规范或SPI规范的形式添加到数据分区中。
{ "spispec_path": "16mbit_12.5mhz_sector_4kb.spispec" }
数据分区的生成过程将各个部分排列在闪存扇区上,并需要知道扇区的大小(这可以在闪存设备的数据手册中找到):
{ "regular_sector_size": "4096" }
Hardware build是一个自定义的、32位的标识符,它与应用固件一起写入闪存中。它可以用来为硬件修订版或其他信息定义一个独特的标识符,不能被后续更新所覆盖:
{ "hardware_build": "0xFFFFFFFF" }
包含要执行的命令的项目文件(项目文件的格式见下文)。提供一个可选的注释字段:
{ "path": "input/usb_to_device_rate_48k.txt", "comment": "" }
注意:由于生成器是一个Python脚本,所以无论在什么平台上,路径都使用正斜杠。
项目文件
项目文件包含用于配置系统的命令。这些命令被简单地添加到文件中,其格式与命令行控制工具相同。为了清楚起见,可以在.json定义中包含多个项目文件,每个项目文件都指定了与某个特定功能或方面有关的命令子集。在发布包的data-partition/input目录中提供了常见配置的项目文件示例。例如,agc_bypass.txt项目文件为两个输出通道绕过AGC,包含以下命令。
SET_ADAPT_CH0_AGC 0
SET_ADAPT_CH1_AGC 0
SET_GAIN_CH0_AGC 1
SET_GAIN_CH1_AGC 1
为自定义应用程序生成一个数据分区
建议在创建自定义数据分区时,使用一套现有的.json和项目文件作为模板,并根据需要进行修改。发布包包含了用于此目的的.json和项目文件的例子。
所需的额外控制命令应存储在data-partition/input子目录内一个适当命名的文本文件中。例如,可以添加一个名为aec_bypass.txt的文件,其中包含收集的命令:
SET_BYPASS_AEC 1
注意:只有那些需要设置非默认值的命令才需要包含在项目文件列表中。
然后这些文本文件被包括在自定义JSON描述中。
在上面的例子中,aec_bypass.txt被添加到JSON描述中,bypass_AEC.json,如下所示。
...
"item_files": [
...
{
"path": "input/aec_bypass.txt",
"comment": ""
}
...
]
...
命令和输入文件的执行顺序会影响设备的行为。配置USB和I2S的命令应该加在数据镜像的开头。
最后,为了生成自定义数据分区,应该从数据分区目录中运行下面的命令:
python3 xvf3510_data_partition_generator.py <build_type>.json
生成器脚本产生两个数据图像文件;一个用于工厂编程,一个用于设备升级,放在一个名为output的目录下。
在上述例子中,这些文件将被称为:
data_partition_factory_<build_type>.bin
以及
data_partition_upgrade_<build_type>.bin
这两个二进制文件可用于工厂编程或升级,分别在更新固件和生成及应用升级映像和数据分区部分进行描述。
还会产生一个.JSON文件用于调试。
数据分区文件结构
数据分区的内容是在一个json文件中定义的,该文件被传递给一个生成脚本,该脚本在闪烁设备时形成二进制文件。在描述了.json文件的定义之后,下面将描述生成过程。
为了解释的目的,请考虑下面的例子,一个自定义的XVF3610-UA数据分区:
{
"comment": "",
"spispec_path": "16mbit_12.5mhz_sector_4kb.spispec",
"regular_sector_size": "4096",
"hardware_build": "0xFFFFFFFF",
"item_files": [
{ "path": "input/usb_to_device_rate_48k.txt", "comment": "" },
{ "path": "input/device_to_usb_rate_48k.txt", "comment": "" },
{ "path": "input/usb_mclk_divider.txt", "comment": "" },
{ "path": "input/xmos_usb_params.txt", "comment": "" },
{ "path": "input/i2s_rate_16k.txt", "comment": "" },
{ "path": "input/led_after_boot.txt", "comment":"" }
]
}
为.json配置提供注释对,也为个别项目文件提供注释对。
{ "comment": "" }
运行中的VocalFusion设备需要知道其外部QSPI闪存的大小和几何形状,以便向其写入固件升级。这将以闪存规格或SPI规格的形式添加到数据分区中(关于定制闪存支持,见附录C)。
{ "spispec_path": "16mbit_12.5mhz_sector_4kb.spispec" }
数据分区的生成过程将各个部分排列在闪存扇区上,并需要知道扇区的大小(这可以在闪存设备的datasheet中找到):
{ "regular_sector_size": "4096" }
硬件构建是一个自定义的、32位的标识符,与应用固件一起写入闪存中。它可以用来为硬件修订版或其他信息定义一个独特的标识符,不能被后续更新所覆盖。
{ "hardware_build": "0xFFFFFFFF" }
Item files which contain the commands to execute (format of item files described below). An optional comment field is provided:
{ "path": "input/usb_to_device_rate_48k.txt", "comment": "" }
因为生成器是一个Python脚本,所以无论在什么平台上,路径都使用正斜杠。
项目文件
项目文件包含用于配置系统的命令。这些命令被简单地添加到文件中,其格式与命令行控制工具相同。为了清楚起见,可以在.json定义中包含多个项目文件,每个项目文件都指定了与某个特定功能或方面有关的命令子集。在发布包的data-partition/input目录中提供了常见配置的项目文件示例。例如,agc_bypass.txt项目文件为两个输出通道绕过AGC,包含以下命令。
SET_ADAPT_CH0_AGC 0
SET_ADAPT_CH1_AGC 0
SET_GAIN_CH0_AGC 1
SET_GAIN_CH1_AGC 1