Flash双冗余程序切换功能实现文档
1. 项目概述
本项目基于Xilinx Zynq-7000 SoC平台,在Vivado 2018.3+Xilinx SDK 2018.3环境下开发,实现了Flash双冗余程序功能。该功能使系统能够在单一Flash芯片上存储两套不同的程序,并根据定时器自动在两个程序之间进行切换。
2. 硬件参数
- 处理器平台:Xilinx Zynq-7000系列SoC (双核ARM Cortex-A9)
- 处理器频率:333MHz
- 存储设备:QSPI Flash (用于程序存储),eMMC (用于配置数据存储)
- 定时器:SCU定时器 (Timer0用于系统定时,Timer1用于程序切换)
- 内存:OCM (On-Chip Memory) 用于程序加载和执行
- 网络接口:以太网接口 (PS7_ETHERNET_0)
- 串口:PS7_UART_1 (用于程序切换信息输出)
3. 修改文件说明
本次修改涉及以下文件:
3.1 新建文件
-
CTRL_SYS/src/include/program_switch.h
- 目的:定义程序切换功能的接口
- 内容:声明
InitProgramSwitch
函数,提供程序切换功能的初始化入口
-
CTRL_SYS/src/source/program_switch.c
- 目的:实现Flash双冗余程序切换功能
- 内容:
- QSPI Flash初始化和容量检测
- 程序加载和执行功能
- 定时器中断处理程序切换
- 用户界面信息输出
3.2 修改文件
-
CTRL_SYS/src/source/main.c
- 目的:集成程序切换功能到现有系统
- 修改:
- 添加program_switch.h头文件
- 在main函数中初始化程序切换功能
-
CTRL_SYS/src/include/timer_intr.h
- 目的:支持多个定时器操作
- 修改:
- 添加定时器相关常量定义
- 增加函数文档注释
- 定义第二个定时器的中断ID (TIMER_SWITCH_INTR)
4. 项目流程与模块功能
4.1 整体流程
-
系统启动:
- FSBL启动后加载主程序
- 主程序初始化系统组件(控制系统、中断系统等)
-
程序切换初始化:
- 初始化QSPI Flash并检测容量
- 计算程序A和程序B的偏移地址
- 设置定时器中断(5秒触发一次)
- 初次加载并执行程序A
-
运行时切换:
- 定时器每5秒触发一次中断
- 中断处理程序切换当前运行的程序
- 从Flash读取新程序到OCM
- 执行新加载的程序
- 通过串口输出切换信息
4.2 模块功能
-
QSPI Flash控制模块:
- 初始化QSPI设备
- 自动检测Flash容量
- 从Flash读取程序到内存
-
程序加载与执行模块:
- 将程序从Flash加载到OCM
- 执行加载的程序
- 管理程序切换标志
-
定时器中断模块:
- 配置5秒定时器
- 处理定时器中断
- 触发程序切换
-
状态输出模块:
- 通过串口输出切换信息
- 提供系统状态和错误信息
5. 需要调整的参数
根据实际项目需求,可能需要调整以下参数:
-
程序A偏移地址:
- 文件:
CTRL_SYS/src/source/program_switch.c
- 参数:
program_a_offset
- 当前值:0x00040000 (FSBL后的位置)
- 说明:根据实际FSBL大小可能需要调整
- 文件:
-
程序大小:
- 文件:
CTRL_SYS/src/source/program_switch.c
- 功能:
SwitchProgram()
函数中的program_size
- 当前值:1024 * 1024 (1MB)
- 说明:根据实际程序大小调整
- 文件:
-
切换时间间隔:
- 文件:
CTRL_SYS/src/source/program_switch.c
- 功能:
SetupProgramSwitchTimer()
函数 - 当前值:333000000 * 5 (5秒)
- 说明:根据需要调整切换频率
- 文件:
-
加载地址:
- 文件:
CTRL_SYS/src/source/program_switch.c
- 参数:
PROGRAM_LOAD_ADDR
- 当前值:0xFFFF0000 (OCM区域)
- 说明:根据实际内存布局可能需要调整
- 文件:
6. 前期准备工作
-
环境准备:
- 安装Xilinx Vivado 2018.3和SDK 2018.3
- 配置Zynq开发板和JTAG调试器
-
程序准备:
- 准备两个独立的程序二进制文件 (位于bin文件夹)
- 确保程序符合自立运行要求
-
Flash准备:
- 确保QSPI Flash正常工作并有足够容量
- 清除可能的现有程序干扰
7. 实际应用步骤
7.1 环境准备与项目打开
-
启动Xilinx Vivado 2018.3:
- 在Windows开始菜单中找到"Xilinx Design Tools" > "Vivado 2018.3" > "Vivado 2018.3"
- 等待Vivado完全启动(显示开始页面)
-
导入硬件描述文件:
- 点击"Open Project"按钮
- 导航到项目所在文件夹,选择
.xpr
项目文件,点击"OK" - 等待项目完全加载
-
导出硬件设计:
- 在Vivado主界面左侧"Flow Navigator"中,点击"Program and Debug" > "Generate Bitstream"
- 如果出现提示,点击"Yes"运行所需的任何先前步骤
- 等待比特流生成完成(可能需要几分钟)
- 点击菜单"File" > "Export" > "Export Hardware..."
- 选中"Include bitstream"复选框
- 点击"OK"完成硬件平台导出
-
启动Xilinx SDK 2018.3:
- 在Vivado中,点击"File" > "Launch SDK"
- 或者单独启动SDK:在Windows开始菜单中找到"Xilinx Design Tools" > "SDx 2018.3" > "Xilinx SDK 2018.3"
- 如果单独启动,需要选择工作空间位置指向项目文件夹,点击"Launch"
7.2 添加程序切换功能实现
-
打开项目:
- 在SDK中,如果没有自动加载项目,点击"File" > "Open Projects from File System..."
- 选择项目路径,点击"Finish"
-
创建新文件:
-
右击项目中的"src/include"文件夹,选择"New" > "File"
-
命名为
program_switch.h
,点击"Finish" -
复制上面提供的program_switch.h内容到该文件
-
保存文件(Ctrl+S)
-
同样方式,右击"src/source"文件夹,创建
program_switch.c
文件 -
复制上面提供的program_switch.c内容到该文件
-
保存文件(Ctrl+S)
-
-
修改现有文件:
-
在项目浏览器中双击打开
src/include/timer_intr.h
-
按照前面描述的修改更新文件内容
-
保存文件(Ctrl+S)
-
双击打开
src/source/main.c
-
添加program_switch.h头文件包含语句
-
在main函数中添加程序切换初始化代码
-
保存文件(Ctrl+S)
-
-
编译项目:
- 点击顶部工具栏上的锤子图标(Build All)或按Ctrl+B
- 等待编译完成,检查"Console"窗口中是否有错误信息
- 如有错误,根据提示修复后重新编译
7.3 生成二进制文件
-
创建FSBL(第一阶段引导加载程序):
- 点击"File" > "New" > "Application Project"
- 输入项目名称(例如"fsbl")
- 确保选择了正确的处理器和硬件平台
- 点击"Next"
- 选择"Zynq FSBL"模板
- 点击"Finish"
- 等待FSBL项目生成和编译完成
-
创建BOOT.bin文件:
- 点击"Xilinx" > "Create Boot Image"
- 在"Output BIF file path"中选择保存路径
- 确保"Output format"设置为"BIN"
- 在"Boot image partitions"部分:
- 添加FSBL.elf作为第一个文件(类型为bootloader)
- 添加您的应用程序.elf文件作为第二个文件(类型为datafile)
- 点击"Create Image"
-
导出二进制文件:
- 右击应用程序项目
- 选择"Build Project"确保最新构建
- 打开项目的Debug或Release文件夹
- 找到生成的
.elf
文件 - 右击项目,选择"Create Boot Image"
- 配置启动镜像包括FSBL和您的应用程序
- 点击"Create Image"生成BOOT.bin文件
-
准备独立二进制文件:
- 在SDK中,点击"Xilinx Tools" > "Create Zynq Boot Image"
- 点击"Add"按钮,添加ELF文件
- 对于"Partition type"选择"data"
- 点击"OK",然后点击"Create Image"
- 这将在指定位置生成
.bin
文件 - 为两个程序分别执行此步骤,生成两个独立的bin文件
- 将生成的bin文件复制到开发板上的bin文件夹
7.4 将程序烧录到QSPI Flash
-
连接硬件:
- 将Zynq开发板通过JTAG/USB线缆连接到计算机
- 确保开发板电源已接通
- 确保跳线配置为JTAG引导模式
-
启动Xilinx硬件服务器:
- 在SDK中,点击"Xilinx" > "Xilinx Hardware Server Settings"
- 确认连接设置正确,点击"OK"
- 如果未自动连接,点击"Refresh"按钮查找设备
-
打开SDK终端:
- 在SDK中,点击"Window" > "Show View" > "Terminal"
- 在Terminal视图中,点击"+"按钮打开新终端
- 选择"Serial Terminal"
- 选择正确的COM端口(可在设备管理器中查看)
- 设置波特率为115200,数据位8,停止位1,无校验
- 点击"OK"
-
启动XSDB终端:
- 在SDK中,点击"Xilinx" > "XSDB Console"
- 在XSDB控制台中输入以下命令连接到处理器:
connect
- 查看可用目标设备:
targets
- 选择Cortex-A9处理器(通常为目标2):
targets 2
-
擦除QSPI Flash:
- 在XSDB中输入以下命令停止处理器:
stop
- 擦除整个QSPI Flash(这可能需要几分钟):
fpga -f [path_to_bit_file]/design_1_wrapper.bit exec load_image {[path_to_fsbl]/fsbl.elf}; after 5000 rst exec {ps7_init} after 1000 dow [path_to_fsbl]/fsbl.elf con after 5000 stop
- 现在Flash已准备好编程
- 在XSDB中输入以下命令停止处理器:
-
烧录程序A:
- 在XSDB控制台中输入以下命令:
dow -data [完整路径]/bin/programA.bin 0x00040000
- 等待操作完成,确认没有错误信息
- 在XSDB控制台中输入以下命令:
-
确定Flash容量并烧录程序B:
- 查看QSPI Flash信息确定总容量(通常是16MB或32MB)
- 计算中点地址(例如16MB Flash的中点是0x00800000)
- 烧录程序B到中点位置:
dow -data [完整路径]/bin/programB.bin 0x00800000
- 等待操作完成
-
验证烧录结果:
- 在XSDB中使用以下命令读取Flash内容并验证:
rrd -bin [偏移地址] [长度] [输出文件路径]
- 例如,验证程序A:
rrd -bin 0x00040000 0x100000 verify_a.bin
- 使用文件比较工具比较原始文件和读取文件
- 在XSDB中使用以下命令读取Flash内容并验证:
-
配置启动模式并重启系统:
- 配置开发板跳线为QSPI引导模式
- 在XSDB中重启处理器:
rst con
- 或者,断开电源并重新连接
7.5 监控与测试
-
连接串口终端:
- 确保SDK Terminal已配置好(或使用Tera Term、PuTTY等终端软件)
- 设置波特率:115200
- 数据位:8
- 停止位:1
- 奇偶校验:无
- 流控制:无
-
上电启动系统:
- 确保开发板设置为QSPI引导模式
- 接通电源或按下复位按钮
-
观察串口输出:
- 系统启动后应看到以下信息:
Initializing program switching functionality... Flash size: xx MB Program A offset: 0x00040000 Program B offset: 0x00800000 Program switch initialized successfully Initial program: Program A Initial program loaded successfully, executing...
- 系统启动后应看到以下信息:
-
验证程序切换:
- 等待约5秒钟,观察串口输出
- 应看到以下消息表示切换到程序B:
Timer triggered. Switching program... Switching to Program B Program loaded successfully, executing...
- 再等待5秒,应看到切换回程序A
-
长时间测试:
- 让系统持续运行至少30分钟
- 确认程序每5秒稳定切换
- 观察是否有任何错误消息或异常行为
-
故障排查:
- 如果没有看到预期输出,检查串口连接和设置
- 如果输出中断,检查电源稳定性
- 如果程序未切换,确认QSPI Flash烧录成功
- 如果出现错误消息,记录下来并检查相应代码逻辑
8. 注意事项
- 程序A和程序B需要设计为可重入,保证切换后系统状态一致
- 使用英文进行串口输出,确保信息正确显示
- 程序切换过程中可能暂时中断其他功能,需在设计中考虑
- 处理器缓存控制关键,确保程序加载后正确执行
- 实际Flash容量可能与检测结果不同,可能需要手动调整
- 项目路径不应包含中文字符,避免编译和烧录问题
- 确保使用的Vivado和SDK版本完全匹配(都是2018.3)
- 为避免意外断电导致数据丢失,建议使用稳定电源
文档版本:1.1
最后更新:2023年