×

Rpi SenseHAT与AMD-Xilinx Kria KR260和Petalinux的接口

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-07-13

分享资料个

描述

本教程是关于“Rpi SenseHAT 与 AMD-Xilinx Kria KR260 和 Petalinux 的接口”。

本教程中使用的工具有:

  • 维瓦多 2022.2
  • 花瓣 2022.2
Rpi-SenseHAT 的 VIVADO/Petalinux 项目源码、BSP、Kria 固件可在 Github 获取:https://github.com/LogicTronix/KR260-SenseHAT-Petalinux [ Git Branch: SenseHAT-Sensors ]

树莓派感知帽子

Raspberry Pi Sense HAT是一个附加板,可提供一系列传感功能。机载传感器使我们能够监控压力、湿度、温度、颜色、方向和运动。8x8 RGB LED 矩阵让我们能够可视化来自传感器的数据,五键操纵杆可以充当输入设备。

板上的所有传感器都连接到单个 I2C 总线。所有的传感器都充当从机,并使用 I2C 协议与主机进行通信。

Sense Hat 上使用的 IC:

poYBAGSBKZ-AAM4oAACL7SJEYyY066.png
 
poYBAGSBKaSAYG-BAAHaHl52-VQ834.png
图片:Raspberry Pi- Sense HAT
 

Vivado 设计流程

设计中使用的 IP

以下是 Vivado 设计中使用的 IP 内核,用于创建在 Kria KR260 上运行的“Sense HAT-I2C 接口”。

Zynq® Ultrascale+™ MPSoC

pYYBAGSBKaeAM2EzAAA8FxsEuaQ808.png
 

Zynq® Ultrascale+™ MPSoC 充当 PS 和 PL 之间的逻辑连接,同时协助使用 Vivado® IP 集成器将定制和嵌入式 IP 与处理系统集成。

AXI 中断控制器

poYBAGSBKaqAdWCMAAAdOC157sg073.png
 

AXI 中断控制器 (AXI INTC) 内核将来自外围设备的多个中断输入集中到系统处理器的单个中断输出。

时钟向导

pYYBAGSBKa2AX7o3AAAYHPqw_cM056.png
 

Clocking Wizard IP 简化了为根据用户时钟要求定制的时钟威廉希尔官方网站 创建 HDL 源代码包装器的过程。该向导指导用户为您的时钟原语设置适当的属性,并允许覆盖任何向导计算的参数。

AXI IIC 总线接口

pYYBAGSBKa-AWG4sAAAd1Y-Cgb4413.png
 

AXI IIC 总线接口连接到 AMBA® AXI 规范,并为大量流行设备提供低速、双线、串行总线接口。本产品规范定义了 AXI IIC 总线接口模块的架构、硬件(信号)接口、软件(寄存器)接口和参数化选项。

处理系统重置

poYBAGSBKbKAQP4aAABFAh-WCg0500.png
 

处理系统复位是一个软 IP,它提供了一种机制来处理给定系统的复位条件。内核在输入端处理多种复位条件,并在输出端生成适当的复位。该内核根据外部或内部复位条件生成复位。

AXI互连

poYBAGSBKbWAXcSQAAArjUgvIeg523.png
 

AXI 互连 IP 将一个或多个 AXI 内存映射主设备连接到一个或多个内存映射从设备。AXI 互连内核允许 AXI 主设备和从设备的任意组合连接到它,这些设备在数据宽度、时钟域和 AXI 子协议(AXI4、AXI3 或 AXI4-Lite)方面可能各不相同。

块设计-完整的块设计

pYYBAGSBKbmABB0HAAE3TRJX6RY497.png
图片:完整的 VIVADO 模块设计
 

Sense HAT - KR260 接头对齐

poYBAGSBKb2AIKrzAADmUxxOFDQ660.png
图片:Sense HAT - KR260 接头对齐
 

如上图所示,Sense HAT 位于 KR260 上的 RPi 接头上方。此对齐显示了 40 个引脚的描述。传感器通过使用引脚 3 和 5 的 I2C 进行通信。

约束

KR260 上只有 2 个引脚(AE14 和 AE15)需要约束 I2C 才能工作。AE15 用于 SDA,AE14 用于 SCL。

set_property PACKAGE_PIN AE15 [get_ports {iic_sda_io}]
set_property IOSTANDARD LVCMOS33 [get_ports {iic_sda_io}]
set_property PULLUP true [get_ports {iic_sda_io}]

set_property PACKAGE_PIN AE14 [get_ports {iic_scl_io}]
set_property IOSTANDARD LVCMOS33 [get_ports {iic_scl_io}]
set_property PULLUP true [get_ports {iic_scl_io}]

但是,下图可用作映射和约束所有其他引脚的参考。

pYYBAGSBKcGANmjEAADm4bseuDQ959.png
图片:使用 Raspberry Pi 40 针 GPIO 接头(HAT 接头)的详细约束映射
 

生成 XSA

  • 从“文件”菜单中,选择“导出”>“导出平台”。
  • 在平台类型窗口中选择硬件选项。
poYBAGSBKcSAf5MlAABnQXp_shg780.png
 
  • 选择 Pre-Synthesis 状态,并在 Platform State 窗口中选择 Include bitstream 选项。
poYBAGSBKcaAbn1AAAB2r2IHntE719.png
 
  • 更改所需的平台属性。
pYYBAGSBKcmAIqrwAABjfMidd5Q698.png
 
  • 输入 XSA 的名称并选择要将 XSA 导出到的文件夹,然后选择完成。
poYBAGSBKcuAaL2QAABQdx5g2r4857.png
 

Petalinux 流程:

Sense HAT 传感器的驱动程序可用性

为了集成 SenseHAT 传感器,我们必须拥有这些传感器的 Petalinux 驱动程序或 linux 驱动程序。对于 SenseHAT,大多数传感器的 C/C++ 驱动程序都可以从供应商那里获得。一些驱动程序也是由独立开发人员编写的。

湿度/温度

加速度计/陀螺仪和磁力计

压力/温度

LED驱动器

Petalinux 开发:

先决条件

创建 petalinux 项目需要支持的 BSP,可从以下链接下载。也可以在没有 BSP 的情况下创建项目,但不太方便。

创建、配置和构建 Petalinux 项目

下面列出了创建 petalinux 项目的步骤。

● 创建一个文件夹并复制从Vivado 导出的平台(XSA)。

● 同时复制 Vivado 生成的 BIN 文件,位于 /.runs/impl_1/.bin

● 在目录中打开终端并获取petalinux 脚本。

● 运行以下命令创建名为 的petalinux 项目。

petalinux-create --type project -s to-bsp> --name name>

● 运行以下命令配置项目。

petalinux-config --get-hw-description 

● 在项目配置窗口中,

○ 在 FPGA 管理器下启用 FPGA 管理器。

pYYBAGSBKc6AL8WzAACx-6j5vNY532.png
 
  • 在图像打包配置下,
  • 将根文件系统类型更改为 INITRD
  • 将 INITRAMFS/INITRD 映像名称更改为 petalinux-initramfs-image
  • 禁用 Copy final images to tftpbootUnder Image Packaging Configuration,
pYYBAGSBKdGAbzosAADqbK9E6Fo495.png
 
  • 保存并退出配置窗口。
  • 运行以下命令来配置内核。
petalinux-config -c kernel
  • 在 Device Drivers > I2C support > I2C Hardware Bus support 下,启用
  • Cadence I2C 控制器
  • 赛灵思 I2C 控制器
poYBAGSBKdaAMH4xAAGmmZpE0BE206.png
 
  • 保存并退出配置。
  • 运行以下命令来配置根文件系统。
petalinux-config -c rootfs
  • 在 Filesystem Packages > base > i2c-tools 下,启用
  • i2c-工具
  • i2c-工具-dev
pYYBAGSBKdqAdwXSAAC2C4IL7eM435.png
 
  • 在 Filesystem Packages > misc > python3 下,启用
  • 蟒蛇3
  • 您需要的所有其他 python 模块
poYBAGSBKd2AWC95AAD6Mq48Nmo976.png
 
  • 保存并退出配置。
  • 运行petalinux-build来构建项目。
poYBAGSBKeGAYMKQAAG_o02aluU805.png
 

生成/创建可引导映像

  • 运行以下命令以创建可引导的 WIC 映像。
petalinux-package --wic --images-dir images/linux/ --bootfiles "ramdisk.cpio.gz.u-boot, boot.scr, Image, system.dtb, system-zynqmp-sck-kr-g-revB.dtb" --disk-name "sda"
  • 确保 dtb 文件存在于 /images/linux/ 目录中。
pYYBAGSBKeSAbN2CAAIjgUAE8Do479.png
 
  • 下载、安装并运行 BalenEtcher。
  • 在 images/linux 目录中找到 WIC 映像。
pYYBAGSBKemAbleoAAAqo6sUjdg699.png
 
  • 选择目标设备并选择 Flash。
poYBAGSBKeuAfx7RAAArN6UYvuU330.png
 

准备覆盖:

生成设备树覆盖

  • 在复制 XSA 的目录中打开终端。在这里再次获取 Petalinux 并运行xsct命令。
  • 如果系统找不到 xsct 命令,请确保获取 Vitis 或 PetaLinux shell 脚本。
  • 如果在运行 Petalinux shell 脚本后 xsct 命令仍然缺失,请运行以下命令。
PATH="${XSCT_TOOLCHAIN}/bin:${PATH}"
  • 运行以下“HSI”命令将在当前目录中提取 XSA 的内容。
hsi::open_hw_design ./.xsa
pYYBAGSBKe2AYJggAABjLXPWbgs534.png
 
createdts -hw ./name>.xsa -zocl -platform-name platform-name> -git-branch  -overlay -compile -out ./name-is-better>
  • 运行上面的命令将:
  • 从 Xilinx 设备树生成器 repo 克隆分支
  • 在.////psu_cortexa53_0/device_tree_domain/bsp/ 目录
poYBAGSBKfCAY4-zAACBXMIwwZU688.png
 
  • 退出xsct外壳。
注意:以下命令可以在没有 Petalinux 脚本源的常规终端中运行。
  • 运行以下命令编译设备树。
dtc -@ -O dtb -o ./kr260.dtbo ./kr260_dt/kr260_dt/kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi
  • 确保编辑 pl.dtsi 的路径。
  • 此命令将在当前目录中生成 kr260.dtbo。
  • 如果 dtc 抛出“ dtc: invalid option -- '@'”错误,则需要自己编译 dtc。

编译故障码

  • 运行以下命令。
git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git
cd dtc
make
  • 如果遇到“cc1: all warnings being treated as errors”,编辑 dtc 目录中的 Makefile 并从 CFLAGS 中删除 -Werror 标志。
make install
  • 运行上面的命令将在 $HOME/bin.. 中安装 dtc

重试编译设备树

  • 运行 cd../ 移出 dtc 目录
  • dtc -@ -O dtb -o./kr260.dtbo./kr260_dt/kr260_dt/kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi

将文件传输到设备

  • 运行以下命令创建 shell.json。
echo '{ "shell_type" : "XRT_FLAT", "num_slots": "1" }' > shell.json
  • 将 Vivado 实现目录中的 bin 文件重命名为您命名 dtbo 的相同名称。
  • 我已将它们重命名为 kr260.bit.bin 和 kr260.dtbo。
  • 将 Sense HAT 连接到 KR260 接头。
  • 现在启动设备并登录。
  • 用户名密码默认petalinux
  • 在设备主目录中创建一个目录。
mkdir ~/<any-directory-name>
  • 将您的设备连接到路由器并通过运行 ifconfig 命令查找 IP 地址。如果您在路由器设置中为设备分配静态 IP 会更好。
  • 在主机上运行 scp 命令以将文件传输到设备。
scp ./kr260.bit.bin ./kr260.dtbo ./shell.json petalinux@:~/
poYBAGSBKfSAdGM6AAVftdJpBI8265.jpg
图片:带有 KR260 连接的 SenseHAT
 

在 I2C 总线上加载覆盖和检测设备

  • 将包含 kr260.bit.bin、kr260.dtbo 和 shell.json 的目录移动到 /lib/firmware/xilinx/。
sudo mv ./ /lib/firmware/xilinx/
  • 列出设备上存在的应用程序。
sudo xmutil listapps
pYYBAGSBKfeAPJqAAACEcoDh8nI563.png
 
  • 卸载当前应用程序。
sudo xmutil unloadapp
  • 加载您的应用程序(在本例中为 kr260)。
sudo xmutil loadapp kr260
  • 检查 XIIC 是否在系统中被列为 I2C 总线。
i2cdetect -l
  • 这将列出系统中的所有 I2C 总线(在本例中为 i2c-7)。
poYBAGSBKfqAU4QyAABjxLYhB4s289.png
 
  • 检查 XIIC 总线上的设备。
I2cdetect -y -r <i2c-bus-number>
  • 这将显示连接到 I2C 总线的传感器的地址。
  • 如果 Sense Hat 正在工作,它应该显示以下地址。
  • 以下 I2C 总线 7 的地址映射显示了来自 Sense HAT 的所有传感器地址。这些地址也在表 1 中列出。
pYYBAGSBKf2AZumlAABKK_eYVzg177.png
 

使用 Python 与传感器通信

要使用 python 与连接到总线的传感器进行通信,需要安装 python 包。

安装 pip,Python 的包安装程序

要安装所需的包,需要 pip。由于 petalinux 没有启用 pip 的选项,因此应手动安装。

值得庆幸的是,安装 pip 非常容易。按照以下步骤操作。

  • 在终端中运行以下任何命令以下载 get-pip.py python 脚本。
wget https://bootstrap.pypa.io/get-pip.py
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
  • 运行 python get-pip.py 并等待它完成。
  • 如果上述命令不起作用,请运行 python3 get-pip.py。

安装 SMBus

要安装 SMBus,请运行pip install smbusSMBus 通过 i2c-dev 为 Linux SMBus 访问提供 python 绑定。

编写一个粗糙的 python 应用程序

为了与传感器通信,我们需要一个 SMBus 类的对象,它为我们提供了使通信更容易的各种功能。我们通过传递传感器所连接的 I2C 总线编号来创建 SMBus 类的新实例。

bus = smbus.SMBus(<i2c-bus-number>)

使用总线对象,我们可以访问以下功能,帮助我们从/向传感器寄存器读取/写入数据。

poYBAGSBKgCAHK0ZAABU6bJmb1M197.png
 

为了从传感器获取数据,我们将特定字节数据写入控制寄存器,以启用/禁用设备中的某些功能。最重要的一步是将传感器置于活动模式,这将开始感应并将结果存储在其内部寄存器中。然后我们可以读取这些寄存器并使用也存储在其他寄存器中的校准数据进行计算。

校准数据存储在内部非易失性存储器中,并在开机时写入校准寄存器。

有关寄存器及其描述的详细信息,请查看传感器的数据表。

与传感器通信的通用方式

设备上的所有传感器都遵循类似的配置和校准方法。

  • 设置输出数据速率和平均
  • 输出数据速率指定更新输出数据的频率
  • 平均给出所选样本数量的平均值
  • 激活传感器
  • 读取并存储校准数据
  • 读取输出值并应用校准

代码片段

# HTS221 Sensor Initialization

def HTS221_Init():
temp = bus.read_byte_data(HTS221_ADDRESS, HTS221_CTRL1)
temp |= HTS221_CTRL1_MASK
bus.write_byte_data(HTS221_ADDRESS, HTS221_CTRL1, temp)

# Reading Temperature from Sensor

def HTS221_T_ReadTemp():
buffer = bus.read_i2c_block_data(HTS221_ADDRESS, HTS221_T0_C_8 | 0x80, 2)
tmp = bus.read_byte_data(HTS221_ADDRESS, HTS221_T1_T0)
T0_degC_x8_u16 = ((tmp & 0x03) << 8) | buffer[0]
T1_degC_x8_u16 = ((tmp & 0x0C) << 6) | buffer[1]
T0_degC = twos_complement(bin_str((T0_degC_x8_u16 >> 3), 16), 16)
T1_degC = twos_complement(bin_str((T1_degC_x8_u16 >> 3), 16), 16)
buffer = bus.read_i2c_block_data(HTS221_ADDRESS, HTS221_T0_OUT | 0x80, 4)
T0_out = twos_complement(bin_str(((buffer[1] << 8) | buffer[0]), 16), 16)
T1_out = twos_complement(bin_str(((buffer[3] << 8) | buffer[2]), 16), 16)
buffer = bus.read_i2c_block_data(
HTS221_ADDRESS, HTS221_TEMP_OUT_L | 0x80, 2)
T_out = twos_complement(bin_str(((buffer[1] << 8) | buffer[0]), 16), 16)
temperature = (T_out - T0_out) * (T1_degC - T0_degC) / \
(T1_out - T0_out) + T0_degC
return temperature

传感器的输出

HTS221 传感器的温度和湿度读数

pYYBAGSBKgKAbDKYAACa7VB4cmk031.png
 

LPS25H 传感器的温度和压力读数

poYBAGSBKgWAJwNlAACD6PKyhbE756.png
 

LSM9DS1 传感器的加速度、磁力计和陀螺仪读数

pYYBAGSBKgiAOipFAADWESRf_I0485.png
 

本教程的VIVADO、Petalinux工程源码和Python源码查看:Github【Git分支:SenseHAT-Sensors】

您可以在您的 PC 上通过以下命令克隆 Git Branch:

git clone -b SenseHAT-Sensors https://github.com/logictronix/kr260-sensehat-petalinux

感谢 Frank Shrestha [frank_shrestha@logictronix.com] 创建了这个“深入”教程!


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'Rpi SenseHAT与AMD-Xilinx Kria KR260和Petalinux的接口',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);