ZYNQ PS 读取 TF 卡 BIN 文件中的浮点数

news2024/9/22 17:26:47
  • 动机
    在进行 AI 算法加速器设计时,需要读取模型导出的权重和数据集数据作为加速器的输入,而目前我个人比较常用的做法是将权重和数据集(如果数据集过大,可以选择一两张图片)放到 SD/TF 卡中,然后 PS CPU核去进行数据读取,最后传输给 PL 端的加速器。
  • 目标
    本示例工程实现了读取 SD/TF 卡中 BIN文件 所包含的浮点数 到 PS 的DDR中, 每个 BIN的浮点数均保存在一维数组空间中

如果要读取 int , 如果读取后将浮点数转为定点数,都是可以在此工程基础上进行修改,去做测试的。

1 购买示例工程的途径

  • 示例工程价格: 5 元 (教学视频无字幕)
  • 购买渠道
  1. (QQ) 736340716 雪天鱼 — 加我好友进行咨询即可,备注 SD读取工程购买 或者类似的都行
  2. 雪天鱼的 B 站工房 — 用哔哩哔哩 app 扫码下面的二维码,即可跳转至我的工房 — ZYNQ_PS读取TF卡中bin文件的浮点数据示例工程 商品
    商品链接:ZYNQ_PS读取TF卡中bin文件的浮点数据示例工程
    二维码:
    image.png|350

也可以从我的B站主页进入我的工房,然后选择 ZYNQ_PS读取TF卡中bin文件的浮点数据示例工程 商品即可

image.png|375

2 工程资料包概览

image.png|725

4个教学视频,总共 30 min 左右,其中 3-上板结果演示 已上传 B站,链接为:ZYNQ PS 读取 TF 卡 BIN 文件中的浮点数 (3)上板结果演示_哔哩哔哩_bilibili

3 Vitis 工程实际操作

参考资料:领航者ZYNQ之嵌入式SDK开发指南_V2.0.pdf — 第十三章 SD 卡读写 TXT 文本实验

  • Vivado 工程:
  1. 使能 UART 和 SD 外设(使能CD),绑定到板卡指定的管脚,并在 MIO 的配置界面将 Bank1 的电压改为 LVCMOS 1.8V
  • Vitis 应用工程:
  1. 将测试数据的文件夹复制到 TF 卡(文件系统为:FAT32)中,并插入到板卡的 TF 卡槽中
  2. 选好纯英文文件夹,创建Vitis工程
    1. 创建好平台工程后,不要编译,否则创建的应用工程无法选择开发语言为c++先创建应用工程,再进行平台的编译
  3. 导入应用源代码
  4. 修改硬件平台设置,使能 xilffs 库,并进行平台编译
  5. 进行应用编译,并下载到开发板进行测试。(需要打开串口助手)
  • DDR Size 计算
    0x3FF00000(hex) = 1,072,693,248(dec)
    1,072,693,248 Bytes / 1024 = 1,047,552 KB
    1,047,552 / 1024 = 1023 MB

  • 最终结果
    PS CPU 实际读到的浮点数与参考值基本一致,有些许不同是因为参考值是保留了10位小数位,精度高一些。而 PS CPU 保留 6位小数位。
    image.png|750

image.png|500

4 FAT FileSystem

4.1 简介

  • 官网:FatFs - Generic FAT Filesystem Module (elm-chan.org)

FAT、HPFS 和 NTFS 文件系统的概述 - Windows Client | Microsoft Learn

4.2 FatFs 库文件组织:

ffconf.h     FatFs 模块配置文件
ff.h         FatFs 和应用模块公用的包含文件
ff.c         FatFs 模块
diskio.h     FatFs and disk I/O 模块公用的包含文件
integer.h    数据类型定义
option       可选的外部功能
diskio.c     FatFs 与disk I/O 模块接口层文件(不属于 FatFs 需要由用户提供)

4.3 常用结构体和函数

  • File object structure (FIL) 文件对象结构, 我理解为文件句柄
  • File function return code (FRESULT) 文件函数返回码, 指定该次函数执行情况, 返回为 FR_OK=0 时,执行成功,其余返回码都表示执行有问题,但可以通过打印返回码的方式快速了解错误原因。

FatFs - f_mount (elm-chan.org)

f_open 打开或者创建一个文件:

FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);				/* Open or create a file */
参数:
fp 文件对象
path 文件所在路径
mode 文件访问模式,具体见下图

image.png|725

  • f_lseek FatFs - f_lseek (elm-chan.org)
    移动一个打开的文件对象的文件读/写指针:
// Seek File Read/Write Pointer
FRESULT f_lseek (FIL* fp, FSIZE_t ofs);	 /* Move file pointer of the file object */
fp  指向打开的文件对象的指针
ofs 设置读/写指针距文件顶部的字节偏移量。数据类型 FSIZE_t 是 DWORD(32 位)或 QWORD(64 位)的别名,具体取决于配置选项 FF_FS_EXFAT。
  • 读操作: f_read FatFs - f_read (elm-chan.org)
    该函数从文件对象的读/写指针指向的文件偏移处开始从文件中读取数据。读/写指针随着读取的字节数而前进。函数成功后,应检查 *br 以检测文件结尾。如果 *br < btr,则表示读操作期间读/写指针到达文件末尾。
FRESULT f_read (
  FIL* fp,     /* [IN] File object */  指向打开的文件对象的指针
  void* buff,  /* [OUT] Buffer to store read data */ 指向用于存储数据的buffer
  UINT btr,    /* [IN] Number of bytes to read */ 要读取的字节数
  UINT* br     /* [OUT] Number of bytes read */ 已读取的字节数
);

5 实际遇到的问题

5.1 为什么不直接读取txt文件

txt 数据如下:

0.0219814759   
-0.0472012386
-0.6958550811
0.1151463836
0.3210625350

根据python打印长度和类型得:
13 <class 'str'>
14 <class 'str'>
14 <class 'str'>
13 <class 'str'>
13 <class 'str'>

即每个符号或者数字都按1字节算,然后加上字符结尾"\0", 得到每个浮点数的总字节数,并不是 4 个字节
所以不能 4 个字节, 4个字节的读。

5.2 terminate called after throwing an instance of ‘std::bad_alloc’

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

堆分配的空间过小

5.3 ERROR : f_open returned 13

查看 ff.h 文件,我们发现返回码 13 对应:

FR_NO_FILESYSTEM,		/* (13) There is no valid FAT volume */

即 SD 卡的格式不对,

  • FPGA板卡读取不了的格式:exFAT
  • 支持的格式:FAT32

格式化教程:参考视频

  1. 下载 DiskGenius 免费版本 DiskGenius – 正式版下载|免费下载,解压即可使用
  2. 清除SD卡的所有分区(注意:千万不要删成自己电脑的其他硬盘了),看到所有空间空闲即为成功
  3. 新建新分区,文件系统类型选择 FAT32,其余保持默认就行
    image.png|475

image.png|375
4. 点击左上角的 保存更改,并确认。

5.4 ERROR : f_read returned 7

返回码 7 在 ff.h 中的 FRESULT 枚举 中表示:FR_DENIED, /* (7) Access denied due to prohibited access or directory full */

reading vit_weights_bin/pos_embed.bin
ERROR : f_read returned 7

经检查,是此文件为空文件,估计是复制时出错了。

6 未实现的思路

读取浮点数直接到 2D/3D/4D 数组
伪代码:
(1) 打开文件
(2) 复位文件指针
(3) 通过嵌套循环,读取文件数据至指定数组单元 arr[i][j]...
(4) 关闭文件

思路:读取一个 float 字节的数据,然后单个字节循环读取,直到读取到换行符"\n"
用 python 打开 txt 文件结尾字符
只软复位 CPU 来重启程序,不对PL进行编程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1488662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring:FactoryBean预加载逻辑以及自定义实现Mybatis的接口扫描

Spring&#xff1a;FactoryBean预加载逻辑以及自定义实现Mybatis的接口扫描 1 前言 参考Mybatis框架的Mapper注解扫描Mapper接口的业务逻辑&#xff0c;其中集成Spring的逻辑里使用到了Spring框架的FactoryBean拓展点&#xff0c;本文针对Spring FactoryBean的加载流程进行分…

嵌入式中C语言结构体的实现

C语言中的数组只能允许程序员定义存储相同类型数据。但是结构是C语言编程中允许您存储不同数据类型的数据。 结构体的定义 要想定义结构&#xff0c;必须用到struct关键字&#xff0c;struct的语句格式&#xff1a; 在struct 中声明了一个含有若干新成员的数据类型。 tag 是结构…

Vision Pro开发者学习路线

官方给到的Vision Pro开发者学习路线&#xff1a; 1. 学习基础知识&#xff1a; - 学习 Xcode、Swift 和 SwiftUI 的基础知识&#xff0c;包括语法、UI 设计等。 - 掌握 ARKit 和 SwiftUI 的使用&#xff0c;了解如何创建沉浸式增强现实体验。 2. 学习 3D 建模&#xf…

CleanMyMac X2024测评深度分析与功能全面介绍

一、软件概述 CleanMyMac X 是一款强大的Mac清理和优化工具&#xff0c;它可以帮助用户轻松管理和释放Mac上的空间&#xff0c;优化系统性能&#xff0c;提高运行速度。这款软件以其直观的用户界面和丰富的功能受到了广大Mac用户的欢迎。 CleanMyMac X4.14.6全新版下载如下: …

Xcode :Could not build module ‘WebKit‘ 已验证解决

问题&#xff1a;Could not build module WebKit 具体报错如下&#xff1a; error: type argument nw_proxy_config_t (aka struct nw_proxy_config *) is neither an Objective-C object nor a block type property (nullable, nonatomic, copy) NSArray<nw_proxy_config_…

Python爬虫副业真的可行吗?

首先回答你&#xff0c;是可行的&#xff0c;python爬虫能当副业&#xff0c;副业的方式比较多&#xff0c;等下我会讲几种。 那学到哪个层次可以接单呢&#xff1f;主要看你是接什么样的单&#xff0c;爬一些资料&#xff0c;视频这种简单的学一两个月就没什么问题&#xff0…

三级分销数据库设计

一&#xff0c;数据结构 二&#xff0c;查询方法 1.mysql递归查询 获取id9的所有上级 r : 9 设置自己所要搜索子节点的id SELECTT2.* FROM(SELECTr AS _id,( SELECT r : pid FROM sj_user WHERE id _id ) AS 2v2,l : l 1 AS lvl FROM( SELECT r : 9 ) vars, -- 查询id为…

力扣61:旋转链表

题目 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2输出&#xff1a;[4,5,1,2,3] 示例 2&#xff1a; 输入&#xff1a;head [0,1,2], k 4输出&#xff1a;…

Revit-二开之立面视图创建FilledRegion-(3)

在上一篇博客中介绍了FilledRegion的创建方法,这种方法通常只在平面视图中适用,在三维视图中也是无法创建的(目前研究的是这样的,如果有其他方法,请赐教)。 本片文章介绍一个下在立面视图中创建FilledRegion的方法,主要操作是在立面视图中拾取一个点,然后以该点为原点,…

【单调栈】Leetcode 739.每日温度

【单调栈】Leetcode 739.每日温度 解法&#xff1a;维护单调栈栈中存的是数组的索引 解法&#xff1a;维护单调栈栈中存的是数组的索引 栈中存的是数组的索引 当新的值比当前栈顶的大&#xff0c;那么就执行出栈-更新result数组-判断当新的值比当前栈顶的大&#xff1f;的循环…

【Java设计模式】四、原型设计模式

文章目录 1、原型设计模式2、深克隆和浅克隆 1、原型设计模式 说明&#xff1a; 用一个原型对象&#xff0c;创建和原型对象相同的对象&#xff0c;以能够保证创建对象的性能是创建大量相同对象的最佳方式 使用场景&#xff1a; 对象的创建非常复杂&#xff0c;可以使用原型…

前端学习第六天-css浮动和定位

达标要求 了解浮动的意义 掌握浮动的样式属性 熟练应用清除浮动 熟练掌握定位的三种方式 能够说出网页布局的不同方式的意义 1. 浮动(float) 1.1 CSS 布局的三种机制 网页布局的核心——就是用 CSS 来摆放盒子。CSS 提供了 3 种机制来设置盒子的摆放位置&#xff0c;分…

复现 CVE-2020-9548:Jackson-databind

1、编译Exploit.java Java版本使用的是&#xff1a; Exploit.java代码如下&#xff1a; import java.lang.Runtime;public class Exploit {static {try {Runtime.getRuntime().exec("calc");} catch (Exception e) {e.printStackTrace();}} }对Exploit.java进行编译…

代码随想录训练营第36天 | LeetCode 435. 无重叠区间、​​​​​​LeetCode 763.划分字母区间、LeetCode 56. 合并区间

目录 LeetCode 435. 无重叠区间 文章讲解&#xff1a;代码随想录(programmercarl.com) 视频讲解&#xff1a;贪心算法&#xff0c;依然是判断重叠区间 | LeetCode&#xff1a;435.无重叠区间_哔哩哔哩_bilibili 思路 ​​​​​​LeetCode 763.划分字母区间 文章讲解&…

[GYCTF2020]EasyThinking --不会编程的崽

看标题就知道&#xff0c;这大概率是关于thinkphp的题目。先尝试错误目录使其报错查看版本号 thinkphp v6.0.0&#xff0c;在网上搜索一下&#xff0c;这个版本有一个任意文件上传漏洞。参考以下文章。 https://blog.csdn.net/god_zzZ/article/details/104275241 先注册一个账…

Java SE:反射

反射作用 获取字节码文件里面的所有信息&#xff0c;包括构造方法、成员、成员方法&#xff0c;以及修饰他们的修饰符、类型和方法的返回值等等&#xff0c;只要是类里面的内容都能获取&#xff0c;获取之后可以动态的调用方法&#xff0c;动态的创建对象 获取类字节码文件对象…

回溯难题(算法村第十八关黄金挑战)

复原 IP 地址 93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 &q…

MATLAB读取txt文本数据及可视化指南

MATLAB读取txt文本数据的说明指南 目录 MATLAB读取txt文本数据的说明指南摘要1. 数据准备2. 读取数据3. 绘制图形4. 小结 摘要 在MATLAB中&#xff0c;读取txt文本格式文件数据是一项基本的操作&#xff0c;特别是在数据分析和可视化方面。本文将介绍如何使用MATLAB读取txt文本…

Socket网络编程(二)——UDP快速入门

目录 UDP相关概念UDP是什么为什么不可靠UDP能做什么UDP包最大长度 UDP单播、广播、多播概念1. 单播、广播、多播模型图2. ip地址分类3. 子网掩码的作用&#xff1a;4. 广播地址5. 网段划分6. 变长子网掩码 UDP核心APIAPI-DatagramSocketDatagramSocket构造方法DatagramSocket常…

Redis 淘汰策略、持久化、高可用

淘汰策略 只有 redis 内存空间已满并且往里面写新数据&#xff0c;才会触发淘汰策略。通过 expire / / /pexpire 让 key-value 过期&#xff0c;从而让 redis 清除这个 key-value。value 的数据结构typedef struct redisObject {unsigned tpye:4;unsigned encoding:4;// 判断哪…