工具/软件:Linux
您好!
首先、让我警告您、我是 PRU 和 BeagleBone 合作的完全新手、因此如果我在这里遗漏了一些显而易见的东西、我深表歉意。
对于一个学校项目、从 TI PRU 培训动手实验5的解决方案开始、我尝试尽快将消息从 PRU 发送到 BeagleBoard 上的 Linux 主机。 想法是使用连接到 PRU 的麦克风输入对 PRU 执行一些音频处理、然后将结果数据发送到主机。
这是我在 PRU 上运行的代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include "resource_table_1.h"
易失性寄存器 uint32_t __r30;
易失性寄存器 uint32_t __r31;
//主机1中断设置寄存器 R31中的位31 */
#define host_INT(((uint32_t) 1 << 31)
////用于 RPMsg 的 PRU-ICSS 系统事件在 Linux 系统树
中使用* PRU-ICSS 系统事件0 (Uint32 _t) 和17 (来自 ARM)
* PRU1使用系统事件18 (到 ARM)和19 (来自 ARM)
//
#define TO_ARM_HOST18
#define From_ARM_HOST19
//
*使用名称'rpmsg-PRU'将探测在
linux-x.y.x.y.z/drivers/rpmsg/rpmsg_pru.c
*上找到的 rpmsg_PRU 驱动程序。//
#define CHAN_PRU #channel_pru*
在 linux-x.31
端口上
找到*用于定义 Rmsg/ rmsg_r31的通信驱动程序 linux-x.y.z/include/uapi/linux/virtio_config.h
*/
#define virtio_config_S_driver_OK4
#define hex_mask 0xFF
#define clock_T_LEN sizeof (clock_t)
uint8_t PAYLOAD[RPMSG_BUF_SIZE];
size_t print_n_buffer (size_t)(size_t);uint8_t
= 0
(如果返回、则为
1 + t);如果为1、则为1、则为1、则为1、< 1、< 1、< 1、t 1、< 1、t (如果为1、则为1、则为1)
buffer[n-1]='\n';
return n;
}
void toggleLED()
{
__R30 ^=(1);
}
//
* main.c
*/
void main (void)
{
struct pru_rpmsg_transport;
uint16_t src、dst、len;
volatile uint8_t * status;
/*允许 PRU 访问 OCP 主端口、以便 PRU 可以读取外部存储器*/
CT_CFG.SYSCFG_BIT.STANDBY_INIT = 0;
//清除 ARM 将用于"启动"我们的 PRU-ICSS 系统事件的状态*/
CT_INTC.SICR_BIT.STS_CLR_IDX = From_ARM_HOST_HOST;
/*确保 Linux 驱动程序已准备好进行 RPMsg 通信*/
status =&resourceTable.rpmsg_vdev.status;
while (!(* status & virtio_config_S_driver_OK);
//初始化与 vring0相对应的 PRU_virtqueue (PRU 到 ARM 主机方向)*/ PRU_tquequequequeu_config_driver_OK (
从 ring_ring_vring_transport 到 vring_ringu.host_ringu.ringu.ringu.rit_ringu.rg_ring_rg_rit_
/*初始化与 vring1相对应的 PRU_virtqueue (ARM 主机到 PRU 方向)*/
PRU_virtqueue_init (&translation.virtqueue1、&resourceTable.rpmsg_vring1、TO_ARM_HOST、from_ARM_host);
//使用传输结构在 PRU 和 ARM 用户空间之间创建 RPMsg 通道。 //
while (PRU_rpmsg_channel (RPMSG_NS_create、&transport、CHAN_NAME、CHAN_DESC、CHAN_PORT)!= PRU_RPMSG_SUCCESS);
while (1){
/*检查寄存器 R31的第30位以查看 ARM 是否已启动*/
if (_R31和 host_INT){
//清除事件状态*/
CT_INTC.SICR_bit.STS_CLR_IDX = from_ARM_host;
/*接收所有可用消息,每次启动可以发送多个消息*/
while (PRU_rpmsg_receive (&transport,&src,&dst,PAYLOAD,&len)=PRU_RPMSG_SUCCESS ){//
多次调用 ctime 以检查发送消息所需的周期数。 //
#define text“以尽可能快的速度发送100条消息:\n"char
msg1[]= text;
PRU_rpmsg_send (&transport、dst、src、msg1、 sizeof (text);
#undef text
clock_t i;
len = print_n_characters(400、有效载荷);
for (i = 0;i < 100;+i){
//等待缓冲区可用
while (PRU_rpmsg_send (&transport、dst、有效载荷、len)!= PRU_RPMSG_SUCCESS);
//__delay_cycles (30000);
}
#define text "Transmission ended successfully.(传输成功结束。)"
char msg2[]= text;
PRU_rpmsg_send (&transport、dst、src、msg2、 sizeof (text);
#undef text
}
}
}
我没有编写任何在主机端运行的代码。 我只需 回显 S >/dev/rpmsg_pru31 && cat /dev/rpmsg_pru31.即可
如果我没有在每次调用 PRU_rpmsg_send()之间设置任何显著延迟(大约为500 000个周期),我会在主机端的 dmesg 中得到大量以下错误消息:
[+0.005616] rpmsg_PRU rpmsg36:消息长度表已满
PRU 上的程序挂起。 但是、如果延迟足够高、则所有消息都将成功无误地发送。
我的代码中是否会出现错误? 我对 BeagleBone、PRU 和嵌入式编程非常陌生、我通常是为学校项目执行此操作。
我注意到有人有一个非常类似的问题,他得到了回答,说这是 pru_rpmsg_virtqueue.h 文件中的一个错误,自此以后,PRU-software-support-package 中已经修复了该错误(请参阅此帖子:
) ,但问题仍然存在。
如有需要、请随时索取更多信息。
此致、
Loïc μ A