一、项目介绍
点灯!使用PRU控制一个LED实现呼吸灯,并且使用一个按键按下后切换闪烁的速度。在本次项目中,我将P9_25端口配置为了输入模式,P9_31端口配置为了输出模式,供以按键与LED灯使用。当程序运行后,单击按钮可以切换LED模式。本次项目为LED呼吸灯设计了四个模式:mode 0,LED熄灭;mode 1,LED慢闪;mode 2,LED快闪;mode 3 LED点闪。
二、硬件设计
1、板卡
本次项目的硬件使用了非常经典的Linux开发板,BeagleBone Black。
BeagleBone Black 是一款面向开发人员和业余爱好者的低成本、高扩展、社区支持的开发平台,基于ARM Cortex-A8架构处理器的开发板,具有强大的处理能力和丰富的接口,具有低成本、易用性和开源软件生态系统等优点。BeagleBone® Black面向开源社区用户、开源硬件爱好者和任何对Arm Cortex-A8低成本处理器感兴趣的人而设计,配备精简,旨在为不需要搭建完整开发平台并想体验Arm处理器功能的用户提供入门的捷径。它配备了最低限度的外设,使用户能够体验处理器的强大功能,还提供了许多接口,用户还可以开发自己的电路板或添加自己的电路。
值得注意的便是板上带有的pru功能,这是一个AM335x等芯片上自带的,独立于ARM CPU运行的子系统。其时钟频率为200MHz,可以直接控制特定的IO口,可以达到非常高的实时性要求。一般两种情况需要用到它:一是linux系统的实时性不满足要求的时候;二是芯片的功能模块不够用的时候(比如你想要10个UART,但芯片上只有6个,那你可以用它再创造4个)。
从某种意义上说,有了它,我们就有了一个片上CPLD或FPGA,只不过PRU编程不是用VDHL语言,而是用专门的汇编语言。它的汇编语句都是在一个时钟周期内执行完的,没有流水线之类可能扰乱程序时序的因素,这使得程序的可预测性大大提高。
2、实物连接
LED灯一段接地,另一端连接板卡的端口P9_31,高电平点亮;
按键一端接3.3v,一段连接端口P9_25,当按键按下后,P9_27将会被置高电平。
三、软件流程图
四、环境配置
1、安装驱动
当板卡连接电脑后,电脑会识别其为一个存储设备,点进文件夹,安装电脑对应操作系统的驱动。
此处按步骤执行可能会出现安装失败的情况,我查阅网络资料后找到了解决方法,即是将设备的驱动程序强制签名禁用,具体实现步骤此处不多赘述,可自行查阅。
2、烧录镜像
在getting start引导界面我们可以学习到详细的系统安装步骤,
目前我是通过sd卡启动的bbb,所有我选择的系统版本为am335x-debian-11.7-iot-armhf-2023-09-02-4gb.img(iot版本为不带桌面图形化的简化系统),通过win32_disk_imager将img系统文件烧录进tf卡,制作为启动sd卡,插入bbb中,再将板卡上电,bbb将优先从sd卡运行系统。
3、配置网络
在开始bbb板卡的正式学习之前,我们需要先将板卡连上网络,这样才能下载官网的例程。
最简单的方式呢,就是直接通过板卡自带的网口,使用网线将板卡与路由之间连接,这样板卡就连接上网络了。
第二种方式呢就是将pc连接的无线网络共享给bbb板卡。由于学校的网络需要通过vpn访问,所以此处我是通过共享网络的方式将bbb上网。
具体步骤:
1、首先将已连接的网络分享给bbb网口
2、将bbb网口的IPv4改为自动获取。
确保地址为192.168.7.1即可。
4、配置VScode页面
在bbb官网的cookbook中给出了具体的步骤:
“只需将主机上的浏览器指向 http://192.168.7.2:3000 并开始探索。您可能还希望升级 bb-code-server 以提取最新更新。 另一种做法是应用此命令来启动名为 bb-code-server 的服务。sudo systemctl start bb-code-server.service”
实际上呢,我执行完后并不能打开VScode,最后在群友的解决下才配置完毕。
还需要通过ssh输入以下命令:systemctl enable --now bb-code-server。
自此我们成功打开了VScode。
5、下载例程
在VScode的terminal终端里通过命令来下载例程:
可以通过运行例程中的hello.pru0.c来实验环境是否配置完毕。(代码现象应是板载的user3闪烁十次)
五、代码编写
1、funpack_setup.sh
首先需要编写一个.sh文件来配置pin口。
代码如下:
#!/bin/bash
#
export TARGET=funpack.pru0
echo TARGET=$TARGET
# Configure the PRU pins based on which Beagle is running
machine=$(awk '{print $NF}' /proc/device-tree/model)
echo -n $machine
if [ $machine = "Black" ]; then
echo " Found"
config-pin P9_31 pruout
config-pin -q P9_31
config-pin P9_25 pruin
config-pin -q P9_25
pins="P9_31 P9_29 P9_30 P9_28"
elif [ $machine = "Blue" ]; then
echo " Found"
pins=""
elif [ $machine = "PocketBeagle" ]; then
echo " Found"
config-pin P1_36 pruout
config-pin -q P1_36
config-pin P1_29 pruin
config-pin -q P1_29
pins="P1_36 P1_33 P2_32 P2_30"
else
echo " Not Found"
pins=""
fi
for pin in $pins
do
echo $pin
config-pin $pin pruout
config-pin -q $pin
done
配置了gpio的对应模式:将P9_25端口配置为了输入模式,P9_31端口配置为了输出模式,供以按键与LED灯使用。
2、funpack.pru0.c
接下来才是所需要运行的程序的编写
代码如下:
#include <stdint.h>
#include <pru_cfg.h>
#include "resource_table_empty.h"
#include "prugpio.h"
volatile register uint32_t __R30;
volatile register uint32_t __R31;
uint8_t Key_GetNum(uint32_t sw)
{
uint8_t KeyNum = 0;
if((__R31&sw) == sw)
{
__delay_cycles(4000000);
while((__R31&sw) ==sw);
__delay_cycles(4000000);
KeyNum = 1;
}
return KeyNum;
}
void main(void)
{
uint32_t gpio = P9_31;
uint32_t sw;
uint32_t mode = 0;
uint8_t KeyNum = 0;
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
sw = 0x1<<7; // P9_27
while (1)
{
KeyNum = Key_GetNum(sw);
if(KeyNum == 1)
{
mode++;
mode %=4;
}
switch(mode)
{
case 0:
__R30 &= ~gpio; // Clear the GPIO pin
break;
case 1:
__R30 |= gpio;
__delay_cycles(100000000);
__R30 &= ~gpio; // Clear the GPIO pin
__delay_cycles(100000000);
break;
case 2:
__R30 |= gpio;
__delay_cycles(10000000);
__R30 &= ~gpio; // Clear the GPIO pin
__delay_cycles(10000000);
break;
case 3:
__R30 |= gpio;
__delay_cycles(20000000);
__R30 &= ~gpio; // Clear the GPIO pin
__delay_cycles(180000000);
break;
}
}
}
包括了 按键获取函数Key_GetNum()以及主函数main。
在Key_GetNum()中,通过判断输入引脚来判断按键是否按下,如果按键按下,则返回键值1给主函数。
在主函数里,当判断按键确实按下后,便将mode++。根据mode的值去switchLED呼吸灯的模式。
六、项目总结
整个项目写起来不长,实际上我在过程学习到了非常非常多的知识。
作为从未使用过linux的新人,连接ssh以及使用命令行来编辑带给了我十足新奇的体验。同时自带操作系统的板子,在处理任务这方面确实有得天独厚的优势。
这是我第二次参与funpack活动,我非常喜欢这样的促学活动,果然在压力下才更有学习的动力哈哈哈。