This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/处理器 SDK-AM335X:PRU 作为独立微控制器

Guru**** 2587365 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/634776/compiler-processor-sdk-am335x-pru-as-a-standalone-microcontroller

器件型号:PROCESSOR-SDK-AM335X

工具/软件:TI C/C++编译器

您好!

我在 BeagleBone Black 上使用 Linux 的 AM335x Sitara 处理器的 PRU、我对 PRU 本身有一些疑问。

我将在下面继续我的问题:PRU 是否可以用作独立微控制器?

为了更好地解释我的意思、我将展示执行以下任务的以下示例:

  1. 1 -切换 P9_27 GPIO
  2. 1 -读取 P9_28 GPIO
  3. 3 -如果 P9_28处于逻辑状态0、则向 Linux 程序发送中断事件。

PRU 汇编代码如下:

//在 PRU 存储器
中启动程序.origin 0

//程序入口点(对于调试器)
.entrypoint 开始

//每条指令5ns
#define INS_PER_us 200

//每个延迟循环两条指令
#define INS_PER_DELAY_LOOP 2

#define DELAY 1 *(INS_PER_us / INS_PER_DELAY_LOOP)

//允许通知程序完成
#define PRU0_R31_VEC_VALID 32

//发回
的事件编号#define PRU_EVTOUT_0 3

#define GER 0x00020010
#define SECR0 0x00020280
#define SECR1 0x00020284

start:
//打开输出引脚(LED 打开)
设置 r30.T5
//将延迟长度存储在 reg0中
MOV r0、延迟

delayon:

//将 reg0减1
subr0、r0、1
//循环到 delayon,除非 reg0=0
qbne delayon、r0、0

LEDOFF:

//清除出纸槽(LED 关闭)
CLR r30.T5
//将 reg0重置为延迟的长度
MOV r0、延迟

取消:
//将 reg0减1
subr0、r0、1
//循环到 delayoff,除非 reg0=0
qbne delayoff、r0、0

//是否按下了按钮? 如果没有、则循环
qbbc start、r31.T3

exec_int:

//通知已完成的呼叫应用程序
MOV R31.b0、PRU0_R31_VEC_VALID | PRU_EVTOUT_0
JMP 启动

使用 prussdrv 库的 C 程序是:

/**编程加载 PRU 程序,使 LED 闪烁,直到
*按下按钮。 作者:Derek Molloy、阅读《探索 BeagleBone
*》一书、该书基于以下网址的示例代码:
*   processors.wiki.ti.com/.../PRU_Linux_Application_Loader_API_Guide
*/

#include 
#include 
#include 
#include 
#include 
#include 

#define PRU_NUM0 //在这些示例

中使用 PRU0 typedef 枚举
{
false、true
}bool;

int main (void)
{
int n = 0;
int res = 0;

if (getuid()!=0)
{
printf("You must run this program as root. 正在退出。\n");
EXIT (EXIT_FAILURE);
}

//初始化 prussdrv_pruintc_intc 使用的结构
//可在 pruss_intc_mapping.h 中找到 PRUSS_INTC_INITDATA
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

//分配和初始化内存
RES = prussdrv_init ();
printf ("prussdrv_init =%d\n"、res);

RES = prussdrv_open (PRU_EVTOUT_0);
printf ("prussdrv_open =%d\n"、res);
//映射 PRU 的中断

prussdrv_pru_reset (0); 
RES = prussdrv_pruintc_init (&pruss_intc_initdata); printf ("prussdrv_pruintc_init =%d\n"、res);
//在 PRU 上加载并执行 PRU 程序 prussdrv_exec_program (PRU_NUM、"./ledButton.bin"); while (真) { //等待 PRU 的事件完成,返回 PRU_EVTOUT_0编号 N = prussdrv_PRU_WAIT_EVENT (PRU_EVTOUT_0); printf ("ebb PRU 程序已完成、事件编号%d.\n"、n); // prussdrv_exec_program (PRU_NUM、"../ledButton。bin"); } //禁用 PRU 并关闭存储器映射 prussdrv_PRU_disable (PRU_NUM); prussdrv_exit (); 返回 EXIT_SUCCESS ;}

程序本身正常工作、GPIO 切换、中断从 PRU 发送并从 Linux 程序捕获、但:

  1. 2 - PRU 正在对 P9_28 GPIO 执行轮询。
  2. 2 - 在 PRU 向 Linux 发送一个中断事件后、我无法再次发送该中断事件。 如果要重新发送中断事件、我必须将固件重新加载到 PRU。

最后的问题是:

  1. 3-是否可以在向 Linux 发送通知之前从 PRU 生成硬件中断(如 GPIO 状态更改)? 换句话说、让 PRU 进入无限循环、并在生成硬件中断时跳转到中断矢量。
  2. 3-是否可以在无需重新加载 PRU 固件的情况下将中断事件重新发送到 Linux?

您能否确认任务1.32.3是否可行?  

如果可能的话、我当然会在 AM335x Techincal 参考手册中遗漏一些信息。 在这种情况下,您能否给我指正确的部分或给我一些建议?

谢谢你。

此致、

Simon

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    PRU 专家已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Simon、

    1.3 PRU 必须使用其中断/事件作为标志。 当一个中断事件发生时、它不能将程序计数器跳转到一个中断向量。 大多数 PRU 固件的作用类似于代码结构: 在无限循环中运行、同时执行后台任务(在本例中为 LED 切换)、然后在循环的顶部(或底部)检查中断/事件标志、以查看是否需要根据外部事件运行其他代码。 根据所需的响应速率、您还可以拆分后台任务、并在整个程序中多次检查该标志。

    2.3正如我在今天回复的另一篇文章中所说的、TI 不再支持 prussdrv 及其附带的 Linux 驱动程序。 但是、我认为您应该能够使用 API 中的"prussdrv_PRU_clear_event"函数清除并重新启用来自 PRU 的中断。 这样、PRU 就可以再次发送事件、而无需重新加载。

    Jason Reeder

    P.S. 根据我的理解、如果您还想在 BeagleBoard 社区中进行检查、则 prussdrv API 仍在相当广泛的范围内得到使用: http://beagleboard.org/discuss