amd-zynq-freeRTOS-开发笔记

2024/07/07

Tags: C AMD Zynq FreeRTOS

Table of Contents

0.序

Zynq®-7000 系列基于 Xilinx SoC 架构。这些产品在单个器件中集成了功能丰富的基于 ARM® Cortex™-A9 的双核或单核处理系统 (PS) 和 28 nm Xilinx 可编程逻辑 (PL)。 ARM Cortex-A9 CPU 是 PS 的核心,还包括片上存储器、外部存储器接口和丰富的外设连接接口。


本文档记录的是 zynq 7020开发过程中的一些经验

7020上PS端有两个ARM 核 ,还有一个FPGA用的PL

我们的FPGA工程师使用Vivado完成PL端的工程配置,编码后,导出.xsa 文件,

我和我组内的小伙伴使用Vitis ,将.xsa生成为 PS端的工程

使用xilinx BSP中集成的SDK和FreeRTOS,进行裸机开发

由我同事完成网络相机核心代码

我作为摸鱼罪犯,被发配到这个项目做一些比较有手就行的任务

裸机意味着很多工具都不能用了,比如ssh, shell,文件系统, 还有c++的libc

所以我在这个项目中主要用c进行下面这几项开发

1.FreeRTOS串口CLI 移植

zynq 7020有两个串口,默认会把启动信息写到第0个, 第1个串口则预留着,

我们的硬件工程师只把串口0 暴露到设备外壳上,所以我们要做的是 zynq 默认串口通道上 加上CLI命令行交互功能以及传输文件功能,

1.1 zynq相关源码获取

签出FreeRTOS源码,切换到vitis 内置的FreeRTOS对应的版本,对于我来说是10.4.x ,我们需要下列这些

  1. CLI插件整个目录

  2. 串口CLI实现

  3. 几个示例命令实现

  4. Zynq串口头文件Zynq的串口实现 (官方提供了一个基于队列的串口,性能比较差,但够用,如果想更快,需要自己用DMA实现

1.2 修改源码

1.2.1 解决编译错误

把 1.1中2,3,4, 文件放放 1 目录中, 把目录放到你的Vitis工程中,设置为Include path

image-20240705162343051

添加一个源码中用到的的宏

1
 #define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096  

用于定义cli 输出buff的大小,如果不定义会编译报错

官网示例是加在FreeRTOSConfig.h里, 不过vitis的freeRTOS代码会在你修改bsp配置时从安装目录复制覆盖项目中的,所以建议把这个宏加到自己工程里

1.2.2 串口号修改

然后确认一下自己想要用于命令行交互的串口端口是0或1,如果是1的话,不需要修改serial.c (在步骤1.1.4中获取)

如果是0的话,需要修改源码中的宏,

修改内容参照下面的diff 图片, 左边是串口0端口,右边是串口1端口, 有2个宏需要修改

image-20240705165307797

1.2.3 自定义cli 命令

在 Sample-CLI-Commands.c中有vRegisterSampleCLICommands方法,用于注册命令

image-20240705172340325

在UARTCommandConsole.c中 收到用户按钮下换行后,会自动分割命令,校验参数个数,调用注册的命令结构体中的函数指针,传递参数

1.2.4 在main()中启动命令行cli并注册命令

70  int main( void )
  1 {
  2     /* Start the tasks that implements the command console on the UART, as
  3     described above. */
  4     vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY );
  5
  6     /* Register the standard CLI commands. */
  7     vRegisterSampleCLICommands();
  8

vUARTCommandConsoleStart 用于启动一个较高优先级的freeRTOS的task,

vRegisterSampleCLICommands用于注册 1.2.3中写的那些命令回调,详细逻辑查看UARTCommandConsole.c中的实现

1.2.5 关于上传文件

在CLI/UARTCommandConsole.c,可以看到, 注册的命令回调会被调用1次或多次,直到返回 1

image-20240705173046457

利用好这个特点,可以写一个循环接收串口数据的命令

2.烧录固化

2.1 制作固件

之前我们在PS跑linux时,Zynq 的启动顺序为

现在我们在PS跑裸机程序,不再需要uboot

所以在vitis中创建boot.bin时这样选择

image-20240705175229943

boot.bin的三个分区,

第一个是fsbl.elf, partition type为bootloader

第二个是PL的 .bit , partition type为datafile

第三个是PS的.elf , partition type为datafile

2.2 开启硬件服务

用 jtag电缆连接 zynq 和 pc

打开vivado, 在主界面下面的命令行输入

1
hw_server

这时会在3121端口打开一个硬件server, 其他电脑或本机可以通过这个服务在线下载或烧录程序

2.3 烧录

创建一个批处理脚本 flash.bat

1
2
3
4
set cmdpath=D:\Xilinx\SDK\2018.3\bin\
set program_flash=%cmdpath%program_flash

%program_flash% -f .\BOOT.BIN -offset 0 -flash_type qspi_single -fsbl .\fsbl.elf -cable type xilinx_tcf url TCP:127.0.0.1:3121

把BOOT.bin和 fsbl.elf 和这个脚本放在一起,

执行

1
./flash.bat 

此时应该看到程序正在烧录, 如果有错误或烧录完成,都会在命令窗口体现

2.4 注意

2021的vitis, vivado不支持 zynq 7020的烧录(没有qsip-single选项),可能是因为硬件太旧软件太新

image-20240705180424169

所以 步骤2.3中,我才使用调用 vivado 2018版本的sdk进行烧录

3. 附录:问题记录

  1. vitis 2021固化 zynq 7020失败

    新的 ide 的qsip flash模式不支持 经典款 zynq 7020芯片相应的qsip flash模式 (qsip-single),

    用2021项目生成的 fsbl+ bit+ elf 生成 boot.bin

    再用vitis 2018 + vtis 2018 hello wold的 .fsbl 文件 烧录 boot.bin可以成功烧录+ 启动

  2. 程序下载完成,但没有启动,弹窗提示 mmu section translation fault

固化的程序的MMU中的地址和在线 jtag 写入的系统MMU sections信息不匹配,重新固化即可

  1. xilffs文件系统创新文件时提示打开失败

    确保已经格式化了文件系统后

    文件名称限制在8个字符内就没问题

  2. xilffs文件系统打开文件后,第二次次调用f_seek写入文件失败

    可能是因为xilffs是一个很简陋的文件系统,所以创建文件后只支持写一次,关闭

    这个不太确定,暂时开一个大buffer用来接收串口字节流,一次性写入文件

  3. 程序编译时不会自动生成boot.bin

    在 project_system项目右键 , create boot image,

    依次填入.fsbl .bit .elf后, 生成一次boot.bin,之后每次编译都会生成

  4. 生成的boot.bin不能烧录固化成功,但用可以在线写入jtag, 在线调试

    检查.bit文件是不是和用来生成fsbl项目的 FPGA导出的 .xsa是对应的,如果不是,可能会出现固化失败,但jtag可以在线写入的情况

>> Home

Comments