CCS+C6678LE开发记录11:多核协作(IPC)入门
Posted 六月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCS+C6678LE开发记录11:多核协作(IPC)入门相关的知识,希望对你有一定的参考价值。
为更好地发挥C6678的多核性能,需要用到多核协作。幸运的是,我们可以使用官方提供的IPC模块。
IPC=Inter-Processor Communication, 核间通信,粗略来说就是多核之间进行信息、数据交换。
作为入门篇,本文不打算深入讨论IPC,仅仅列出自带的两个简单示例:Notify和MessageQ.
"通知"(Notify)模型
"消息队列"(MessageQ)模型
以下介绍Notify示例的创建过程以及测试结果。
首先新建一个项目,取名demo_ipcNotify,项目类型从模板中选择
选择"IPC and I/O Examples"分支下的"C6678 Examples"
然后【Next】,在XDCtools version选择3.23.4.60(不带"core"后缀的那一个)
创建并编译链接无错误之后执行Debug
建议勾选下方的"Create a debug group for selected cores"
如果没有选,可以在稍后执行如下操作
分组的好处是,当有多个核心加载时,不必一一启动,只需要在组别上点击启动(分组下所有核心全部启动)
这样做虽然不是必要的,但建议这样做。
如果勾选了分组,将会是如下这个样子,测试的时候只需在"Group 1"上点击一次【Step On(继续将执行)】
以下是测试示例的输出(中间有部分省略)
[plain] view plain copy
-
[C66xx_6] main: MultiProc id = 6
-
main: MultiProc name = CORE6
-
[C66xx_7] main: MultiProc id = 7
-
main: MultiProc name = CORE7
-
[C66xx_0] main: MultiProc id = 0
-
[C66xx_1] main: MultiProc id = 1
-
[C66xx_2] main: MultiProc id = 2
-
[C66xx_3] main: MultiProc id = 3
-
[C66xx_4] main: MultiProc id = 4
-
[C66xx_5] main: MultiProc id = 5
-
[C66xx_0] main: MultiProc name = CORE0
-
[C66xx_1] main: MultiProc name = CORE1
-
[C66xx_2] main: MultiProc name = CORE2
-
[C66xx_3] main: MultiProc name = CORE3
-
[C66xx_4] main: MultiProc name = CORE4
-
[C66xx_5] main: MultiProc name = CORE5
-
[C66xx_0] tsk1_func: Sent request #0 to CORE1
-
[C66xx_1] tsk1_func: Received request #1 from CORE0
-
tsk1_func: Sent request #1 to CORE2
-
[C66xx_2] tsk1_func: Received request #1 from CORE1
-
tsk1_func: Sent request #1 to CORE3
-
[C66xx_3] tsk1_func: Received request #1 from CORE2
-
tsk1_func: Sent request #1 to CORE4
-
///省略///
-
[C66xx_3] tsk1_func: Received request #10 from CORE2
-
tsk1_func: Sent request #10 to CORE4
-
Test completed
-
[C66xx_4] tsk1_func: Received request #10 from CORE3
-
tsk1_func: Sent request #10 to CORE5
-
Test completed
-
[C66xx_5] tsk1_func: Received request #10 from CORE4
-
tsk1_func: Sent request #10 to CORE6
-
Test completed
-
[C66xx_6] tsk1_func: Received request #10 from CORE5
-
tsk1_func: Sent request #10 to CORE7
-
Test completed
-
[C66xx_7] tsk1_func: Received request #10 from CORE6
-
tsk1_func: Sent request #10 to CORE0
-
Test completed
-
[C66xx_0] tsk1_func: Received request #10 from CORE7
-
Test completed
类似的可以新建一个MessageQ示例项目
后续步骤同上,测试的输出如下(中间有部分省略)
[plain] view plain copy
-
[C66xx_1] Start the main loop
-
[C66xx_5] Start the main loop
-
[C66xx_7] Start the main loop
-
[C66xx_6] Start the main loop
-
[C66xx_0] Start the main loop
-
[C66xx_2] Start the main loop
-
[C66xx_3] Start the main loop
-
[C66xx_4] Start the main loop
-
[C66xx_0] Sending a message #1 to CORE1
-
[C66xx_1] Sending a message #1 to CORE2
-
[C66xx_2] Sending a message #1 to CORE3
-
[C66xx_3] Sending a message #1 to CORE4
-
[C66xx_4] Sending a message #1 to CORE5
-
[C66xx_5] Sending a message #1 to CORE6
-
[C66xx_6] Sending a message #1 to CORE7
-
[C66xx_7] Sending a message #1 to CORE0
-
///省略///
-
[C66xx_5] Sending a message #9 to CORE6
-
[C66xx_6] Sending a message #9 to CORE7
-
[C66xx_7] Sending a message #9 to CORE0
-
[C66xx_0] Sending a message #10 to CORE1
-
[C66xx_1] Sending a message #10 to CORE2
-
The test is complete
-
[C66xx_2] Sending a message #10 to CORE3
-
The test is complete
-
[C66xx_3] Sending a message #10 to CORE4
-
The test is complete
-
[C66xx_4] Sending a message #10 to CORE5
-
The test is complete
-
[C66xx_5] Sending a message #10 to CORE6
-
The test is complete
-
[C66xx_6] Sending a message #10 to CORE7
-
The test is complete
-
[C66xx_7] Sending a message #10 to CORE0
-
The test is complete
-
[C66xx_0] The test is complete
最后附上示例代码(模板生成的,仅删除部分注释,其他未做改动)
示例Notify的主要代码
[cpp] view plain copy
-
#include <xdc/std.h>
-
/* XDC.RUNTIME module Headers */
-
#include <xdc/runtime/System.h>
-
/* IPC module Headers */
-
#include <ti/ipc/MultiProc.h>
-
#include <ti/ipc/Notify.h>
-
#include <ti/ipc/Ipc.h>
-
/* Bios6 module Headers */
-
#include <ti/sysbios/knl/Semaphore.h>
-
#include <ti/sysbios/knl/Task.h>
-
#include <ti/sysbios/BIOS.h>
-
/* To get globals from .cfg Header */
-
#include <xdc/cfg/global.h>
-
#define INTERRUPT_LINE 0
-
/* Notify event number that the app uses */
-
#define EVENTID 10
-
/* Number of times to run the loop */
-
#define NUMLOOPS 10
-
-
UInt32 seq = 0;
-
UInt16 recvProcId;
-
UInt16 srcProc, dstProc;
-
-
/*
-
* ======== cbFxn ========
-
* This function was registered with Notify. It is called when any event is
-
* sent to this processor.
-
*/
-
Void cbFxn(UInt16 procId, UInt16 lineId, UInt32 eventId, UArg arg,
-
UInt32 payload)
-
{
-
/* The payload is a sequence number. */
-
recvProcId = procId;
-
seq = payload;
-
Semaphore_post(semHandle);
-
}
-
-
/*
-
* ======== tsk0_func ========
-
* Sends an event to the next processor then pends on a semaphore.
-
* The semaphore is posted by the callback function.
-
*/
-
Void tsk0_func(UArg arg0, UArg arg1)
-
{
-
Int i = 1;
-
Int status;
-
-
if (MultiProc_self() == 0)
-
{
-
while (i <= NUMLOOPS)
-
{
-
/* Send an event to the next processor */
-
status = Notify_sendEvent(dstProc, INTERRUPT_LINE, EVENTID, i,
-
TRUE);
-
-
/* Continue until remote side is up */
-
if (status < 0)
-
{
-
continue;
-
}
-
-
System_printf("tsk1_func: Sent request #%d to %s\\n", seq,
-
MultiProc_getName(dstProc));
-
-
/* Wait to be released by the cbFxn posting the semaphore */
-
Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
-
-
System_printf("tsk1_func: Received request #%d from %s\\n", seq,
-
MultiProc_getName(recvProcId));
-
-
/* increment for next iteration */
-
i++;
-
}
-
}
-
else
-
{
-
while (seq < NUMLOOPS)
-
{
-
/* wait forever on a semaphore, semaphore is posted in callback */
-
Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
-
-
System_printf("tsk1_func: Received request #%d from %s\\n", seq,
-
MultiProc_getName(recvProcId));
-
-
/* Send an event to the next processor */
-
status = Notify_sendEvent(dstProc, INTERRUPT_LINE, EVENTID, seq,
-
TRUE);
-
if (status < 0)
-
{
-
System_abort("sendEvent failed\\n");
-
}
-
-
System_printf("tsk1_func: Sent request #%d to %s\\n", seq,
-
MultiProc_getName(dstProc));
-
}
-
}
-
-
System_printf("Test completed\\n");
-
BIOS_exit(0);
-
}
-
-
/*
-
* ======== main ========
-
* Synchronizes all processors (in Ipc_start), calls BIOS_start, and registers
-
* for an incoming event
-
*/
-
Int main(Int argc, Char* argv[])
-
{
-
Int status;
-
UInt numProcs = MultiProc_getNumProcessors();
-
-
/*
-
* Determine which processors Notify will communicate with based on the
-
* local MultiProc id. Also, create a processor-specific Task.
-
*/
-
srcProc = ((MultiProc_self() - 1 + numProcs) % numProcs);
-
dstProc = ((MultiProc_self() + 1) % numProcs);
-
-
System_printf("main: MultiProc id = %d\\n", MultiProc_self());
-
System_printf("main: MultiProc name = %s\\n",
-
MultiProc_getName(MultiProc_self()));
-
-
/*
-
* Ipc_start() calls Ipc_attach() to synchronize all remote processors
-
* because \'Ipc.procSync\' is set to \'Ipc.ProcSync_ALL\' in *.cfg
-
*/
-
status = Ipc_start();
-
if (status < 0)
-
{
-
System_abort("Ipc_start failed\\n");
-
}
-
-
/*
-
* Register call back with Notify. It will be called when the processor
-
* with id = srcProc sends event number EVENTID to this processor.
-
*/
-
status = Notify_registerEvent(srcProc, INTERRUPT_LINE, EVENTID,
-
(Notify_FnNotifyCbck) cbFxn, NULL);
-
if (status < 0)
-
{
-
System_abort("Notify_registerEvent failed\\n");
-
}
-
-
BIOS_start();
-
-
return (0);
-
}
示例MessageQ的主要代码
[cpp] view plain copy
-
#include <xdc/std.h>
-
#include <string.h>
-
/* XDC.RUNTIME module Headers */
-
#include <xdc/runtime/System.h>
-
#include <xdc/runtime/IHeap.h>
-
/* IPC module Headers  
以上是关于CCS+C6678LE开发记录11:多核协作(IPC)入门的主要内容,如果未能解决你的问题,请参考以下文章