Part Number: TMS320C6678
Other Parts Discussed in Thread: SYSBIOS
Tool/software: TI-RTOS
The documentation says:
"For BIOS, this function should be called within a 'while' loop within a Task. A Task_sleep() or Task_yield() should be called within the loop to allow other threads in the system to execute. This function needs to be called in a loop because the remote processor may not be in a ready state."
while (Ipc_attach(remoteProcId) < 0) {
Task_sleep(1);
}
I have a simple example:
#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
#define masterProc 6
#define sloverNum 6
UInt16 received_num = 0;
/*
* ======== 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)
{
if(procId !=masterProc)
{
received_num ++;
if(received_num == sloverNum)
{
received_num = 0;
Semaphore_post(semHandle);
}
}
else{
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 = 0;
Int status;
if(MultiProc_self() == masterProc){
while(i <sloverNum){
status = Notify_sendEvent(i,INTERRUPT_LINE,EVENTID,i,TRUE);
if(status <0){
continue;
}
System_printf("materCore has sent event to slaveCore %d\n",i);
i++;
}
System_printf("all event has been sent\n");
Semaphore_pend(semHandle,BIOS_WAIT_FOREVER);
System_printf("all slave core has received event from master\n");
}
else{
Semaphore_pend(semHandle,BIOS_WAIT_FOREVER);
status = Notify_sendEvent(masterProc,INTERRUPT_LINE, EVENTID, 2,TRUE);
if(status < 0){
System_abort("sendEvent to MasterCore failed\n");
}
System_printf("slaveCore %d has sent event to master core",MultiProc_self());
}
}
/*
* ======== main ========
* Synchronizes all processors (in Ipc_start), calls BIOS_start, and registers
* for an incoming event
*/
Int main(Int argc, Char* argv[])
{
Int status;
Int procId = 0;
status = Ipc_start();
if (status < 0) {
System_abort("Ipc_start failed\n");
}
if(MultiProc_self() == masterProc){
while(procId < sloverNum)
{
while(Ipc_attach(procId)){
Task_sleep(1);
}
status = Notify_registerEvent(procId,INTERRUPT_LINE, EVENTID,(Notify_FnNotifyCbck)cbFxn, NULL);
if (status < 0)
{
System_abort("Notify_registerEvent for sloverCore1 failed\n");
}
procId++;
}
}
else{
while(Ipc_attach(masterProc)){
Task_sleep(1);
}
status = Notify_registerEvent(masterProc,INTERRUPT_LINE, EVENTID,(Notify_FnNotifyCbck)cbFxn, NULL);
if(status <0){
System_abort("Notify_registerEvent for sloverCore1 failed\n");
}
}
BIOS_start();
return (0);
}
My cfg-file is
/*
* Copyright (c) 2012, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* */
var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
/*
* Get the list of names that the build device supports.
* I.e. ["CORE0", "CORE1", "CORE2" ... ]
*/
var nameList = MultiProc.getDeviceProcNames();
/*
* Since this is a single-image example, we don't (at build-time) which
* processor we're building for. We therefore supply 'null'
* as the local procName and use MultiProc_setLocalId to set the procId
* at runtime.
*/
MultiProc.setConfig(null, nameList);
var System = xdc.useModule('xdc.runtime.System');
var SysStd = xdc.useModule('xdc.runtime.SysStd');
System.SupportProxy = SysStd;
/* Modules explicitly used in the application */
var Notify = xdc.useModule('ti.sdo.ipc.Notify');
var Ipc = xdc.useModule('ti.sdo.ipc.Ipc');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
BIOS.heapSize = 0x8000;
var Task = xdc.useModule('ti.sysbios.knl.Task');
var tsk0 = Task.create('&tsk0_func');
tsk0.instance.name = "tsk0";
/* To avoid wasting shared memory for MessageQ transports */
for (var i = 0; i < MultiProc.numProcessors; i++) {
Ipc.setEntryMeta({
remoteProcId: i,
setupMessageQ: false,
});
}
/* Synchronize all processors (this will be done in Ipc_start) */
Ipc.procSync = Ipc.ProcSync_PAIR;
/* Shared Memory base address and length */
var SHAREDMEM = 0x0C000000;
var SHAREDMEMSIZE = 0x00200000;
/*
* Need to define the shared region. The IPC modules use this
* to make portable pointers. All processors need to add this
* call with their base address of the shared memory region.
* If the processor cannot access the memory, do not add it.
*/
var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
SharedRegion.setEntryMeta(0,
{ base: SHAREDMEM,
len: SHAREDMEMSIZE,
ownerProcId: 0,
isValid: true,
name: "DDR2_RAM",
});
/* Create a semaphore with count 0 */
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
Program.global.semHandle = Semaphore.create(0);
I don't use Ipc.ProcSync_ALL specially.
When debugging, I get the following error:
ti.sysbios.knl.Task: line 565: assertion failure: A_sleepTaskDisabled: Cannot call Task_sleep() while the Task scheduler is disabled.
How to use Ipc_attach function with Task_sleep in IPC Notify?

