ZYNQ7000 openAMP 通信模式与文件读写模式合并总结

以openAMP echo_test demo进行channel扩展,将echo_test和proxy两个模式合并,从而实现可同时进行核间通信和文件读写

OpenAMP软件框架简介:

通常在AMP(非对称多处理)配置中,会采用在不同的处理核上运行不同的软件环境并执行各自的代码程序,各核之间通力合作实现处理器性能的提升。OpenAMP(开源的非对称多处理框架)软件框架为开发AMP系统提供了必要的API函数。

通过共享内存方式,两核可以访问同一块内存,通过中断协调同步。

OpenAMP 提供的demo有3个:
1,echo_test核间数据通信
2,proxy将openAMP提供接口重新封装成对文件操作的接口_open, _read, _write, _close可直接读写linux端的文件
3.矩阵计算,没详细了解

echo_test通信流程:
在这里插入图片描述

1.主机端调用remoteproc_init并启动远端

2.远端通过remoteproc_resource_init创建rpmsg,并通知主机RPMsg name

3.主机创建RPMsgchannel并回传给远端name确认消息

4.远端注册channel回调

以echo_test demo为例扩展为双通道,如何保证两端正确接收的:

linux:查询。两个channel对用两个字符设备。不停的读字符设备是否有数据
freeRtos:中断。中断处理中会调用注册的回调函数rpmsg_read_cb,回调函数是与通道绑定的,在回调函数中根据不同channel将数据写入不同的缓冲区,并记下标记,测试用例是用的全局变量,正式应用可改为信号量。
验证通过。

通信模式流程:
创建channel流程:
app(hproc)–>
hil_poll(proc->proc,0);–>
_poll(virtqueue_notification(vring->vq);–>
rpmsg_rx_callback[rdev->channel_created(rp_chnl);]–>
rpmsg_channel_created

获取消息流程:
app(hproc) -->
hil_poll(proc->proc,0); -->
_poll(virtqueue_notification(vring->vq);)–>
rpmsg_rx_callback 【rp_ept->cb(rp_chnl,
(void *)RPMSG_LOCATE_DATA(rp_hdr), rp_hdr->len, rp_ept->priv, rp_hdr->src);】–>
rpmsg_read_cb

proxy模式简介:

  1. 将openAMP提供接口重新封装成对文件操作的接口_open, _read, _write, _close。
  2. proxy模式remote串口输出定向到host

如何处理通信模式与读写文件模式同时运行问题
使用双通道模式一个channel来处理消息通信和一个chanel读写文件操作,达到可以同时进行核间通信,又可以CORE1读写core0 的nandflash的目的。消息通信以echo_test为模板进行开发,CORE1读写core0 的nandflash以proxy_app为模板进行扩展。

此方案存在的问题:
从上述的代码处理流程可以看出消息的处理都是软中断hil_poll触发,在rpmsg_rx_callback进行消息处理,而proxy模式则将hil_poll重定向到API中。这就出现了,两者都依赖于软中断hil_poll,所以中断信号来了,而不知道做何处理,到底是进行核间通信哪?还是文件读写哪?

解决方案:

方案1:

在改动尽量小的情况下,由于rpmsg_rx_callback 携带channel和endpoint信息,根据channel进行消息分发

验证结果:proxy模式下相应消息的poll会被通信模式劫持而当做通信消息,导致读写文件等操作无返回。

方案2:

中断扩展,将每个通道有自己独立的中断号。查看代码对中断的处理:中断与cpu shutdown boot有绑定关系,hil(hardware Interface layer)硬件接口层及对上层接口都需要修个,且修改量较大

方案3:中断信息根据channel进行1分2,将proxy重定向的接口重新实现,此方案验证通过。

附验证通过的代码:

  static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
    			  void *priv, unsigned long src)
    {
    	(void)priv;
    	(void)src;

	if(!strcmp(rp_chnl->name, RPMSG_CHAN_NAME))
	{
		memcpy(rpc_data->rpc_response, data, len);

		atomic_flag_clear(&rpc_data->sync);
		if (rpc_data->rpc_response->id == TERM_SYSCALL_ID) {
			/* Application terminate signal is received from the proxy app,
			 * so let the application know of terminate message.
			 */
			rpc_data->shutdown_cb(rp_chnl);
		}

		xSemaphoreGive(xCountSemaphoreforfile);
	}
	else if(!strcmp(rp_chnl->name, RPMSG_CHAN_NAME2))
	{
		xIPC_Data.len = len;
		memcpy(&(xIPC_Data.data[0]),data,len);
		portBASE_TYPE val = xQueueSend( xIPC_Data_Queue,	/* The queue being written to. */
				(void *)(&xIPC_Data.len), 					/* The address of the data being sent. */
				10UL );										/* The block time. */

		if (!val) {
			LPERROR("cannot save data\n");
		} else {
			xSemaphoreGive(xCountSemaphoreforIPC);
			//LPRINTF("xCountSemaphoreforIPCGiveNum = %d\n\r",xCountSemaphoreforIPCGiveNum++);
		}
	}
	else
		LPRINTF("channel not match between linux and rtos\n");
}

static inline void rpmsg_retarget_wait(struct _rpc_data *rpc)
{
	//struct hil_proc *proc = rpc->rpmsg_chnl->rdev->proc;
	while (atomic_flag_test_and_set(&rpc->sync)) {
		//hil_poll(proc, 0);
		xSemaphoreTake( xCountSemaphoreforfile, portMAX_DELAY );
	}
}
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值