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 */
- #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 10
- Char 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
CCS+C6678LE开发记录11:多核协作(IPC)入门的更多相关文章
- CCS+C6678LE开发记录12:UIA组件的安装
在安装了CCS 6.0版本的IDE和最新版的MCSDK后似乎一切都很完美,但事实并非如此. 当我试图编译SDK附带的image_processing (IPC based) demo时出现如下错误: ...
- MS CRM 2011的自定义和开发(11)——插件(plugin)开发(四)
http://www.cnblogs.com/StoneGarden/archive/2012/02/08/2343294.html MS CRM 2011的自定义和开发(11)——插件(plugin ...
- MS CRM 2011的自定义和开发(11)——插件(plugin)开发(二)
http://www.cnblogs.com/StoneGarden/archive/2012/02/06/2339490.html MS CRM 2011的自定义和开发(11)——插件(plugin ...
- Windows Phone 8初学者开发—第11部分:设置SounBoard应用程序
原文 Windows Phone 8初学者开发—第11部分:设置SounBoard应用程序 原文地址: http://channel9.msdn.com/Series/Windows-Phone-8- ...
- Android艺术开发探索——第二章:IPC机制(下)
Android艺术开发探索--第二章:IPC机制(下) 我们继续来讲IPC机制,在本篇中你将会学习到 ContentProvider Socket Binder连接池 一.使用ContentProvi ...
- Python全栈开发记录_第一篇(循环练习及杂碎的知识点)
Python全栈开发记录只为记录全栈开发学习过程中一些难和重要的知识点,还有问题及课后题目,以供自己和他人共同查看.(该篇代码行数大约:300行) 知识点1:优先级:not>and 短路原则:a ...
- JFinal使用笔记3-注册和登录功能开发记录
首页 开源项目 问答 代码 博客 翻译 资讯 移动开发 招聘 城市圈 当前访客身份:游客 [ 登录 | 加入开源中国 ] 当前访客身份: 游客 [ 登录 | 加入开源中国 ] 软件 土龙 关注 ...
- CozyRSS开发记录22-界面退化
CozyRSS开发记录22-界面退化 1.问题1-HtmlTextBlock 找的这个HtmlTextBlock有很严重的bug,有时候显示不完全,有时候直接就崩了.然后看了下代码,完全是学生仔水平写 ...
- CozyRSS开发记录21-默认RSS源列表
CozyRSS开发记录21-默认RSS源列表 1.默认列表 在第一次使用CozyRSS的情况下,我们让它内置五个RSS源吧: 2.响应RSS源的更新 先不处理RSS源列表项的点击,响应下下拉菜单里的更 ...
随机推荐
- 编译安装FFmpeg 要支持xvid、x264、mp3、ogg、amr、faac
编译安装FFmpeg 要支持xvid.x264.mp3.ogg.amr.faac libfaac faac格式的编解码包libmp3lame mp3格式编解码包libopencore-am ...
- linux下服务启动脚本
#!/usr/bin/env python# -*- coding: utf-8 -*-# @File : deployment.py# @Author: Anthony.waa# @Date : 2 ...
- vue中的事件修饰符
vue提倡的是在方法中只有对数据的处理,所以提供了事件修饰符用于DOM的事件处理,常用的事件修饰符有以下几个: (1). stop:阻止冒泡(通俗讲就是阻止事件向上级DOM元素传递) 点击内层div的 ...
- iOS原生数据存储策略
一 @interface NSCache : NSObject Description A mutable collection you use to temporarily store transi ...
- IOS - [UIDevice currentDevice] name/model/localizedMode/systemName/systemVersion...../userInterfaceIdiom
+ (UIDevice *)currentDevice; @property(nonatomic,readonly,retain) NSString *name; // ...
- Linux 进程及作业管理
进程简介: 内核的功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能 进程(Process):什么是进程,进程是程序的执行实例,即运行中的程序,同时也是程序的一个副本:程序是放置于磁 ...
- 紫书 习题7-8 UVa 12107 (IDA*)
参考了这哥们的博客 https://blog.csdn.net/hyqsblog/article/details/46980287 (1)atoi可以char数组转int, 头文件 cstdlib ...
- 紫书 例题7-14 UVa 1602(搜索+STL+打表)
这道题想了很久不知道怎么设置状态,怎么拓展,怎么判重, 最后看了这哥们的博客 终于明白了. https://blog.csdn.net/u014800748/article/details/47400 ...
- struts2解决动态多文件上传的问题(上传文件与数据库字段一一对应)(转)
struts2多文件上传我想只要会用struts2的朋友都不会陌生,但是怎么在action中根据用户上传的文 件把文件路径写到数据库中对应的字段上呢?ps:我的意思是这样,页面上有固定的5个上传文件的 ...
- 【codeforces 767E】Change-free
[题目链接]:http://codeforces.com/problemset/problem/767/E [题意] 你有m个1元硬币和无限张100元纸币; 你在第i天,需要花费ci元; 同时在第i天 ...