AWorksLP 對(duì)外設(shè)進(jìn)行了高度抽象化,為同一類外設(shè)提供了相同的接口,應(yīng)用程序可以輕松跨平臺(tái)。本文以MR6750平臺(tái)為例,介紹AWorksLP 雙核通信的基本用法。
?簡(jiǎn)介
通信信箱MBX 有2 套寄存器訪問接口,接口A 和接口B。A 和B 接口都具有一套TX FIFO 寄存器、RX FIFO
寄存器、控制寄存器和狀態(tài)寄存器。用戶從A 接口的發(fā)送端TX 發(fā)送的數(shù)據(jù),可以在B 接口的接收端RX 接收到。同理,A 接口的接收端RX 可以接收到B 接口發(fā)送端TX 發(fā)送的數(shù)據(jù)。
雙核燒錄的用法請(qǐng)參考《AWorksLP樣例詳解(MR6750)——雙核燒錄》
雙核調(diào)試的用法請(qǐng)參考《AWorksLP樣例詳解(MR6750)——雙核調(diào)試》
?雙核通信
1. MBX信箱
{SDK}\demos\multi-core\openamp路徑下為openamp的例程。雙核通信需要使用信箱在gui上勾選對(duì)應(yīng)的信箱接口,hart0和hart1需勾選同一個(gè)信箱的兩個(gè)不同接口。例如hart0勾選了mbx0a、則hart1需勾選mbx0b。
圖1 mbx設(shè)備
2.OpenAMP
OpenMP是由OpenMP Architecture Review Board牽頭提出的,并已被廣泛接受,用于共享內(nèi)存并行系統(tǒng)的多處理器程序設(shè)計(jì)的一套指導(dǎo)性編譯處理方案。
3.例程
#if CONFIG_AW_OPENAMP_MASTERaw_local int rx_callback (struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv){ aw_kprintf("[Master receive]: %s\n", data); return 0;}#elseaw_local int rx_callback (struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv){ char sendbuf[512];
aw_kprintf("[Slave receive]: %s\n", data); aw_snprintf(sendbuf, sizeof(sendbuf), "%s ACK", data); if (rpmsg_send(&__resmgr_ept, sendbuf, strlen(sendbuf) + 1) < 0) { ? ? ? ?aw_kprintf("[Slave send]: error!\n"); ? ?} ? ?return 0;}#endif
aw_local int __mail_box_notify(void *priv, uint32_t id){ uint32_t tmp;
#if CONFIG_AW_OPENAMP_MASTER /* master to remote */ if (id == VRING1_ID) { /* send msg */ tmp = EPT_SEND_MSG_FLAG; } else { /* remote to master */ /* send ack */ tmp = EPT_SEND_ACK_FLAG; }#else if (id == VRING1_ID) { /* send ack */ tmp = EPT_SEND_ACK_FLAG; } else { /* send msg */ tmp = EPT_SEND_MSG_FLAG; }#endif
aw_write(__g_mbx_fd, &tmp, 4); return 0;}
/* 處理其它設(shè)備發(fā)送過來的MBX */aw_local void __openamp_task(void *p_arg){
struct rpmsg_virtio_device *p_dev = (struct rpmsg_virtio_device *)p_arg;
aw_kprintf("Entry OpenAMP task!\n");
while(1) { uint32_t tmp;
aw_read(__g_mbx_fd, &tmp, 4);
/* * 默認(rèn)Master VRING0是接收, VRING1是發(fā)送, 從機(jī)反之 */#if CONFIG_AW_OPENAMP_MASTER if (tmp == EPT_SEND_MSG_FLAG) {
/* 接收到來自從機(jī)的消息 */ rproc_virtio_notified(p_dev->vdev, VRING0_ID); } else {
/* 接收到來自從機(jī)的ACK */ rproc_virtio_notified(p_dev->vdev, VRING1_ID); }#else
if (tmp == EPT_SEND_MSG_FLAG) { rproc_virtio_notified(p_dev->vdev, VRING1_ID); } else { rproc_virtio_notified(p_dev->vdev, VRING0_ID); }#endif }}
void rpmsg_demo(){ int ret = 0;#if CONFIG_AW_OPENAMP_MASTER int i = 0; int RPMsgRole = 0;#else int RPMsgRole = 1;#endif
__g_mbx_fd = aw_open(CONFIG_MBX_CHOOSE, AW_O_RDWR, 0);
ret = aw_openamp_init(&rpmsg_dev, RPMsgRole, NULL, __mail_box_notify);
#if CONFIG_AW_OPENAMP_MASTER /* 啟動(dòng)固件 */ ret = aw_openamp_remoteproc_init(&__aworks_rproc_ops); if (ret) { aw_kprintf("Start processor fail!\n"); }#endif
if (ret) { aw_kprintf("OpenAMP init error!\n"); while(1); }
aw_openamp_create_ept(&rpmsg_dev, &__resmgr_ept, "rpmsg-client-sample", 0xFFFFFFFF, rx_callback, NULL);
aw_openamp_ep_poll_task_start(&rpmsg_dev); aw_openamp_wait_ept_ready(&__resmgr_ept);
while(1) {
#if CONFIG_AW_OPENAMP_MASTER char sendbuf[512]; aw_snprintf(sendbuf, sizeof(sendbuf), "AWorks %d", i); aw_kprintf("[Master send]: %s\n", sendbuf); if (aw_openamp_send(&__resmgr_ept, sendbuf, strlen(sendbuf) + 1) < 0) { ? ? ? ? ? ?aw_kprintf("[Master send]: error!\n"); ? ? ? ?} ? ? ? ?i++;#else ? ? ? ?aw_kprintf("Salve is alive!\n");#endif ? ? ? ?aw_mdelay(100); ? ?}}
由于篇幅原因本文僅截取部分關(guān)鍵代碼。
- 在rpmsg_demo中使用aw_open打開信箱、使用aw_openamp_init并注冊(cè)__mail_box_notify函數(shù);
- 在__mail_box_notify函數(shù)中發(fā)送相應(yīng)的標(biāo)記、使用aw_openamp_remoteproc_init函數(shù)注冊(cè)__aworks_rproc_ops,參數(shù)中是各運(yùn)行階段的函數(shù)接口;
- 使用aw_openamp_create_ept函數(shù)注冊(cè)rx_callback接收回調(diào)函數(shù),當(dāng)作為主核時(shí)打印從核發(fā)送的數(shù)據(jù),當(dāng)作為從核時(shí)將收到的數(shù)據(jù)發(fā)送回去;
- 使用aw_openamp_ep_poll_task_start函數(shù)創(chuàng)建一個(gè)任務(wù),任務(wù)的函數(shù)入口為__openamp_task,在__openamp_task函數(shù)中根據(jù)讀到的標(biāo)記做相應(yīng)的處理。
使用aw_openamp_wait_ept_ready函數(shù)等待從機(jī)準(zhǔn)備好。
在while循環(huán)中主核使用aw_openamp_send函數(shù)循環(huán)的發(fā)送數(shù)據(jù)、從核在rx_callback回調(diào)函數(shù)中將主核發(fā)送的數(shù)據(jù)發(fā)送回去、串口打印如下圖。
圖2串口打印
-
接口
+關(guān)注
關(guān)注
33文章
8997瀏覽量
153707 -
通信
+關(guān)注
關(guān)注
18文章
6206瀏覽量
137793 -
雙核
+關(guān)注
關(guān)注
0文章
37瀏覽量
15430
發(fā)布評(píng)論請(qǐng)先 登錄
單核CPU網(wǎng)關(guān)和雙核CPU網(wǎng)關(guān)有什么區(qū)別
請(qǐng)問雙核的芯片如何調(diào)試?
Analog Devices Inc. ADSP-SC592 SHARC+?雙核DSP數(shù)據(jù)手冊(cè)

全志科技機(jī)器人專用芯片MR527與MR813特性概述

RZT2H CR52雙核BOOT流程和例程代碼分析

雙核鎖步技術(shù)在汽車芯片軟錯(cuò)誤防護(hù)中的應(yīng)用詳解
STM32H745的FreeRTOS是單核工作還是雙核工作?
RK3036:高效能雙核處理器詳解
關(guān)于cc2541程序代碼樣例
全志T113雙核異構(gòu)處理器的使用基于Tina Linux5.0——異構(gòu)雙核通信驗(yàn)證
在FPGA里面例化了8個(gè)jesd204B的ip核同步接收8塊AFE芯片的信號(hào),怎么連接設(shè)備時(shí)鐘和sysref到AFE和FPGA?
HPM6750 Bootloader設(shè)計(jì)
雙核dsp和單核dsp的區(qū)別
TI基于Concerto雙核MCU的PRIME電力線通信數(shù)據(jù)集中器方案應(yīng)用說明

評(píng)論