CCS+C6678LE开发记录11:多核协作(IPC)入门
来源:互联网 发布:思途旅游cms 6.0 下载 编辑:程序博客网 时间:2024/05/19 19:12
为更好地发挥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(继续将执行)】
以下是测试示例的输出(中间有部分省略)
[C66xx_6] main: MultiProc id = 6main: MultiProc name = CORE6[C66xx_7] main: MultiProc id = 7main: 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 CORE0tsk1_func: Sent request #1 to CORE2[C66xx_2] tsk1_func: Received request #1 from CORE1tsk1_func: Sent request #1 to CORE3[C66xx_3] tsk1_func: Received request #1 from CORE2tsk1_func: Sent request #1 to CORE4///省略///[C66xx_3] tsk1_func: Received request #10 from CORE2tsk1_func: Sent request #10 to CORE4Test completed[C66xx_4] tsk1_func: Received request #10 from CORE3tsk1_func: Sent request #10 to CORE5Test completed[C66xx_5] tsk1_func: Received request #10 from CORE4tsk1_func: Sent request #10 to CORE6Test completed[C66xx_6] tsk1_func: Received request #10 from CORE5tsk1_func: Sent request #10 to CORE7Test completed[C66xx_7] tsk1_func: Received request #10 from CORE6tsk1_func: Sent request #10 to CORE0Test completed[C66xx_0] tsk1_func: Received request #10 from CORE7Test completed
类似的可以新建一个MessageQ示例项目
后续步骤同上,测试的输出如下(中间有部分省略)
[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 CORE2The test is complete[C66xx_2] Sending a message #10 to CORE3The test is complete[C66xx_3] Sending a message #10 to CORE4The test is complete[C66xx_4] Sending a message #10 to CORE5The test is complete[C66xx_5] Sending a message #10 to CORE6The test is complete[C66xx_6] Sending a message #10 to CORE7The test is complete[C66xx_7] Sending a message #10 to CORE0The test is complete[C66xx_0] The test is complete
最后附上示例代码(模板生成的,仅删除部分注释,其他未做改动)
示例Notify的主要代码
#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);}
#include <xdc/std.h>#include <string.h>/* XDC.RUNTIME module Headers */#include <xdc/runtime/System.h>#include <xdc/runtime/IHeap.h>/* IPC module Headers */#include <ti/ipc/Ipc.h>#include <ti/ipc/MessageQ.h>#include <ti/ipc/HeapBufMP.h>#include <ti/ipc/MultiProc.h>/* BIOS6 module Headers */#include <ti/sysbios/BIOS.h>#include <ti/sysbios/knl/Task.h>/* To get globals from .cfg Header */#include <xdc/cfg/global.h>#define HEAP_NAME "myHeapBuf"#define HEAPID 0#define NUMLOOPS 10Char localQueueName[10];Char nextQueueName[10];UInt16 nextProcId;/* * ======== tsk0_func ======== * Allocates a message and ping-pongs the message around the processors. * A local message queue is created and a remote message queue is opened. * Messages are sent to the remote message queue and retrieved from the * local MessageQ. */Void tsk0_func(UArg arg0, UArg arg1){MessageQ_Msg msg;MessageQ_Handle messageQ;MessageQ_QueueId remoteQueueId;Int status;UInt16 msgId = 0;HeapBufMP_Handle heapHandle;HeapBufMP_Params heapBufParams;if (MultiProc_self() == 0){/* * Create the heap that will be used to allocate messages. */HeapBufMP_Params_init(&heapBufParams);heapBufParams.regionId = 0;heapBufParams.name = HEAP_NAME;heapBufParams.numBlocks = 1;heapBufParams.blockSize = sizeof(MessageQ_MsgHeader);heapHandle = HeapBufMP_create(&heapBufParams);if (heapHandle == NULL){System_abort("HeapBufMP_create failed\n");}}else{/* Open the heap created by the other processor. Loop until opened. */do{status = HeapBufMP_open(HEAP_NAME, &heapHandle);/* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */if (status < 0){Task_sleep(1);}} while (status < 0);}/* Register this heap with MessageQ */MessageQ_registerHeap((IHeap_Handle) heapHandle, HEAPID);/* Create the local message queue */messageQ = MessageQ_create(localQueueName, NULL);if (messageQ == NULL){System_abort("MessageQ_create failed\n");}/* Open the remote message queue. Spin until it is ready. */do{status = MessageQ_open(nextQueueName, &remoteQueueId);/* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */if (status < 0){Task_sleep(1);}} while (status < 0);if (MultiProc_self() == 0){/* Allocate a message to be ping-ponged around the processors */msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader));if (msg == NULL){System_abort("MessageQ_alloc failed\n");}/* * Send the message to the next processor and wait for a message * from the previous processor. */System_printf("Start the main loop\n");while (msgId < NUMLOOPS){/* Increment...the remote side will check this */msgId++;MessageQ_setMsgId(msg, msgId);System_printf("Sending a message #%d to %s\n", msgId,nextQueueName);/* send the message to the remote processor */status = MessageQ_put(remoteQueueId, msg);if (status < 0){System_abort("MessageQ_put had a failure/error\n");}/* Get a message */status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);if (status < 0){System_abort("This should not happen since timeout is forever\n");}}}else{/* * Wait for a message from the previous processor and * send it to the next processor */System_printf("Start the main loop\n");while (TRUE){/* Get a message */status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);if (status < 0){System_abort("This should not happen since timeout is forever\n");}System_printf("Sending a message #%d to %s\n",MessageQ_getMsgId(msg), nextQueueName);/* Get the message id */msgId = MessageQ_getMsgId(msg);/* send the message to the remote processor */status = MessageQ_put(remoteQueueId, msg);if (status < 0){System_abort("MessageQ_put had a failure/error\n");}/* test done */if (msgId >= NUMLOOPS){break;}}}System_printf("The test is complete\n");BIOS_exit(0);}/* * ======== main ======== * Synchronizes all processors (in Ipc_start) and calls BIOS_start */Int main(Int argc, Char* argv[]){Int status;nextProcId = (MultiProc_self() + 1) % MultiProc_getNumProcessors();/* Generate queue names based on own proc ID and total number of procs */System_sprintf(localQueueName, "%s", MultiProc_getName(MultiProc_self()));System_sprintf(nextQueueName, "%s", MultiProc_getName(nextProcId));/* * 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");}BIOS_start();return (0);}
本文原创,博文地址
http://blog.csdn.net/fengyhack/article/details/44034941
0 0
- CCS+C6678LE开发记录11:多核协作(IPC)入门
- CCS+C6678LE开发记录14:多核协作之OMP与IPC方式的较量
- CCS+C6678LE开发记录15:多核协作(OpenMP)示例探索
- CCS+C6678LE开发记录17:多核协作(OpenMP)示例更新
- CCS+C6678LE开发记录13:多核协作图像处理demo测试
- CCS+C6678LE开发记录16:多核协作(OpenMP)示例代码浅析
- CCS+C6678LE开发记录03:常规入门HeloWorld
- CCS+C6678LE开发记录02:CCS的安装
- CCS+C6678LE开发记录01:开箱图赏
- CCS+C6678LE开发记录04:编写CMD文件+读取Bitmap
- CCS+C6678LE开发记录06:以太网接口测试
- CCS+C6678LE开发记录07:DSP网页测试
- CCS+C6678LE开发记录10:(图像)数据处理与传输框架
- CCS+C6678LE开发记录12:UIA组件的安装
- CCS+C6678LE开发记录05:编译并使用开源JPEG图像(解)压缩库libjpeg
- CCS+C6678LE开发记录08:以太网接口测试示例之代码研究
- CCS+C6678LE开发记录09:以太网接口测试续(大块数据传输)
- CCS+C6678LE开发记录18:解决EVM网口“DHCP配置无法获取IP”的问题
- 谷歌官方两种下拉刷新样式(横线样式、圆圈样式)
- VB学习笔记——Len函数和LenB函数
- SQL导出txt文件字段用逗号 ,隔开
- 详解“系统应用不能访问sdcard”
- CentOS6.6配置防火墙
- CCS+C6678LE开发记录11:多核协作(IPC)入门
- tcp-ip : snmp
- Linux网络编程之多进程
- ubuntu12.04LTS-ARM平台交叉编译器的制作
- CentOS7.0网络设置和域名绑定
- Shell-计算多行数值求和
- Android Volley完全解析(三),定制自己的Request
- Linux网络编程之多线程
- jquery easyui datagrid 数据绑定java版本