/* * ======== 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(); System_printf("main: MultiProc id = %d\n", MultiProc_self()); System_printf("main: MultiProc name = %s\n", MultiProc_getName(MultiProc_self())); /* 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); }
/* * ======== tsk0_func ======== * Sends an event to the remote 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 remote 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 remote 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 remote 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) and calls BIOS_start */ Int main(Int argc, Char* argv[]) { /* Generate queue names based on own proc ID and total number of procs */ System_sprintf(localQueueName, "%s_queue", MultiProc_getName(MultiProc_self())); System_sprintf(remoteQueueName, "%s_queue", MultiProc_getName(1 - MultiProc_self())); BIOS_start(); return (0); }
/* * ======== main ======== * Create a task. * Synchronize all processors. * Register an event with Notify. */ Int main(Int argc, Char* argv[]) { selfId = MultiProc_self(); System_printf("main: MultiProc id = %d\n", selfId); System_printf("main: MultiProc name = %s\n", MultiProc_getName(selfId)); if (numCores == 0) { numCores = MultiProc_getNumProcessors(); } /* * Determine which processors Notify will communicate with based on the * local MultiProc id. */ srcProc = ((selfId - 1 + numCores) % numCores); dstProc = ((selfId + 1) % numCores); attachAll(numCores); BIOS_start(); return (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())); /* * 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); }
/* * ======== main ======== */ Int main(Int argc, Char* argv[]) { selfId = MultiProc_self(); System_printf("Core (\"%s\") starting\n", MultiProc_getName(selfId)); if (numCores == 0) { numCores = MultiProc_getNumProcessors(); } attachAll(numCores); System_sprintf(localQueueName, "CORE%d", selfId); System_sprintf(nextQueueName, "CORE%d", ((selfId + 1) % numCores)); System_sprintf(prevQueueName, "CORE%d", (selfId - 1 + numCores) % numCores); /* Create a message queue. */ messageQ = MessageQ_create(localQueueName, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n" ); } BIOS_start(); return (0); }
/* * ======== Processor_getCoreName ======== */ String Processor_getCoreName(UInt32 id) { #if MESSAGEQ_ENABLED UInt16 mpId = (UInt16)id; return (MultiProc_getName(mpId)); #else return (NULL); #endif }
/*! * ======== NotifySetup_attach ======== * Initialize interrupt */ Int NotifySetup_attach(UInt16 remoteProcId, Ptr sharedAddr) { NotifyDriverShm_Params notifyShmParams; NotifyDriverShm_Handle shmDrvHandle; ti_sdo_ipc_Notify_Handle notifyHandle; UInt16 myId = MultiProc_self(); Int status = Notify_S_SUCCESS; Error_Block eb; /* Initialize the error block */ Error_init(&eb); NotifyDriverShm_Params_init(¬ifyShmParams); notifyShmParams.sharedAddr = sharedAddr; notifyShmParams.remoteProcId = remoteProcId; if (myId == NotifySetup_core1ProcId && remoteProcId != NotifySetup_core0ProcId || myId != NotifySetup_core0ProcId && remoteProcId == NotifySetup_core1ProcId) { Error_raise(&eb, NotifySetup_E_noInterruptLine, MultiProc_getName(remoteProcId), NULL); System_exit(1); } /* Disable cache for inter-ducati NotifyDriverShm instances */ if ((myId == NotifySetup_core1ProcId && remoteProcId == NotifySetup_core0ProcId) || (myId == NotifySetup_core0ProcId && remoteProcId == NotifySetup_core1ProcId)) { notifyShmParams.cacheLineSize = 0; notifyShmParams.cacheEnabled = FALSE; } /* Only used by the DSP */ notifyShmParams.intVectorId = NotifySetup_dspIntVectId; shmDrvHandle = NotifyDriverShm_create(¬ifyShmParams, &eb); if (shmDrvHandle == NULL) { return (Notify_E_FAIL); } notifyHandle = ti_sdo_ipc_Notify_create(NotifyDriverShm_Handle_upCast(shmDrvHandle), remoteProcId, 0, NULL, &eb); if (notifyHandle == NULL) { NotifyDriverShm_delete(&shmDrvHandle); status = Notify_E_FAIL; } return (status); }
/* * ======== isMapLine ======== */ int isMapLine(char *line, UInt16 procId) { int retval = FALSE; char procName[32]; if (line[0] != '#') { strncpy(procName, MultiProc_getName(procId), 32); if (strncmp(procName, line, strlen(procName)) == 0) { retval = TRUE; } } return (retval); }
Void FirmwareLoad_printStatus (Void) { Int status = 0; ProcMgr_Handle handle = NULL; UInt16 numProcs; UInt16 i; ProcMgr_State state; Char strState [32u]; printf ("Current status of slave cores:\n"); numProcs = MultiProc_getNumProcessors (); for (i = 0 ; (i < numProcs) && (i != MultiProc_self ()) ; i++) { { status = ProcMgr_open (&handle, i); if (status >= 0) { state = ProcMgr_getState (handle); switch (state) { case ProcMgr_State_Unknown: strncpy (strState, "Unknown", 32u); break; case ProcMgr_State_Powered: strncpy (strState, "Powered", 32u); break; case ProcMgr_State_Reset: strncpy (strState, "Reset", 32u); break; case ProcMgr_State_Loaded: strncpy (strState, "Loaded", 32u); break; case ProcMgr_State_Running: strncpy (strState, "Running", 32u); break; case ProcMgr_State_Unavailable: strncpy (strState, "Unavailable", 32u); break; case ProcMgr_State_EndValue: /* Not a valid value. */ break; } printf ("Slave core %d: %8s [%s]\n", i, MultiProc_getName (i), strState); status = ProcMgr_close (&handle); } } } }
static Void workerFxn(IArg arg) { Char inFile[MAXFILENAME]; Char outFile[MAXFILENAME]; String procId; String engineName; sprintf(inFile, "./in%d.dat", arg); sprintf(outFile, "./out%d.dat", arg); procId = MultiProc_getName(arg); engineName = (arg == 0) ? "local_engine" : "audio1_copy"; smain("audio1_copy", procId, engineName, inFile, outFile); }
Int main(Int argc, char* argv[]) { Task_Params params; System_printf("%s starting..\n", MultiProc_getName(MultiProc_self())); /* Create a Task to respond to the ping from the Host side */ Task_Params_init(¶ms); params.instance->name = "ping"; params.arg0 = 51; Task_create(pingTaskFxn, ¶ms, NULL); BIOS_start(); return (0); }
Int32 System_ipcNotifyInit() { UInt32 procId, i; Int32 status; memset(gSystem_ipcObj.notifyCb, 0, sizeof(gSystem_ipcObj.notifyCb)); i = 0; while (gSystem_ipcEnableProcId[i] != SYSTEM_PROC_MAX) { procId = gSystem_ipcEnableProcId[i]; if ((procId != System_getSelfProcId()) && (procId != SYSTEM_PROC_INVALID)) { Vps_printf (" %d: SYSTEM: Notify register to [%s] line %d, event %d ... \n", Utils_getCurTimeInMsec(), MultiProc_getName(procId), SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID); if (Notify_intLineRegistered(procId, SYSTEM_IPC_NOTIFY_LINE_ID) == FALSE) { UTILS_assert(0); } if (Notify_eventAvailable (procId, SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID) == FALSE) { UTILS_assert(0); } status = Notify_registerEvent(procId, SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID, System_ipcNotifyHandler, NULL); UTILS_assert(status == Notify_S_SUCCESS); } i++; } return status; }
Int32 System_ipcSendNotify(UInt32 linkId) { Int32 status; UInt32 procId = SYSTEM_GET_PROC_ID(linkId); UTILS_assert(procId < SYSTEM_PROC_MAX); status = Notify_sendEvent(procId, SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID, linkId, TRUE); if (status != Notify_S_SUCCESS) { Vps_printf (" %d: NOTIFY: Send Event to [%s][%d] failed !!! (status = %d)\n", Utils_getCurTimeInMsec(), MultiProc_getName(SYSTEM_GET_PROC_ID(linkId)), SYSTEM_GET_LINK_ID(linkId), status); UTILS_assert(status == Notify_S_SUCCESS); } return FVID2_SOK; }
int main(int argc, char * *argv) { extern void start_load_task(void); UInt16 hostId; /* Set up interprocessor notifications */ System_printf("%s starting..\n", MultiProc_getName(MultiProc_self())); hostId = MultiProc_getId("HOST"); RPMessage_init(hostId); /* Some background ping testing tasks, used by rpmsg samples: */ start_ping_tasks(); /* CPU load reporting in the trace. */ // start_load_task(); /* Dump Tools version */ tools_ShowVersion(); BIOS_start(); return (0); }
/****************************************************************************** * MAIN FUNCTION *****************************************************************************/ Int main(Int argc, Char* argv[]){ srand(time(NULL)); selfId = CSL_chipReadReg(CSL_CHIP_DNUM); if (numCores == 0){ numCores = MultiProc_getNumProcessors(); } /* Attach All Cores */ attachAll(numCores); /* Create a MessageQ */ System_sprintf(localQueueName, "%s", MultiProc_getName(MultiProc_self())); messageQ = MessageQ_create(localQueueName, NULL); if (messageQ == NULL){ System_abort("MessageQ_create failed\n"); } BIOS_start(); return (0); }
Int main(Int argc, char* argv[]) { RcmServer_Params rcmServerParams; System_printf("%s starting..\n", MultiProc_getName(MultiProc_self())); /* * Enable use of runtime Diags_setMask per module: * * Codes: E = ENTRY, X = EXIT, L = LIFECYCLE, F = INFO, S = STATUS */ Diags_setMask("ti.ipc.rpmsg.MessageQCopy=EXLFS"); /* Setup the table of services, so clients can create and connect to * new service instances: */ ServiceMgr_init(); /* initialize RcmServer create params */ RcmServer_Params_init(&rcmServerParams); /* The first function, at index 0, is a special create function, which * gets passed a Service_Handle argument. * We set this at run time as our C compiler is not allowing named union * field initialization: */ OMXServer_fxnTab.elem[0].addr.createFxn = RPC_SKEL_GetHandle; rcmServerParams.priority = Thread_Priority_ABOVE_NORMAL; rcmServerParams.fxns.length = OMXServer_fxnTab.length; rcmServerParams.fxns.elem = OMXServer_fxnTab.elem; int i = 0; for (i = 0; i < 255; i ++) bit_num[i] = ((i&1) != 0) + ((i&2) != 0) + ((i&4) != 0) + ((i&8) != 0) + ((i&16) != 0) + ((i&32) != 0) + ((i&64) != 0) + ((i&128) != 0); /* Register an OMX service to create and call new OMX components: */ ServiceMgr_register("OMX", &rcmServerParams); #if 0 /* Some background ping testing tasks, used by rpmsg samples: */ start_ping_tasks(); #endif #if 0 /* DSP or CORE0 or IPU */ /* Run a background task to test rpmsg_resmgr service */ start_resmgr_task(); #endif #if 0 /* DSP or CORE0 or IPU */ /* Run a background task to test hwspinlock */ start_hwSpinlock_task(); #endif /* Start the ServiceMgr services */ ServiceMgr_start(0); BIOS_start(); return (0); }
/* * ======== Processor_getCoreName ======== */ String Processor_getCoreName(UInt32 id) { UInt16 mpId = (UInt16)id; return(MultiProc_getName(mpId)); }
/****************************************************************************** * TASK FUNCTION *****************************************************************************/ void task_fxn(UArg arg0, UArg arg1){ Int status; Int coreCount; Int nextCore; MessageQ_Msg msg; MessageQ_QueueId msgQueueIds[MAX_NUM_CORES]; /* Register this heap with the Message Q */ MessageQ_registerHeap((IHeap_Handle)SharedRegion_getHeap(0), HEAP_ID); /* * In order to send messages to other cores, we must know that core's Queue * ID. So, we'll create an array on each core that associates the Queue ID * with the core number, and then we'll open each queue. Again, we spin * here until the queue is open, sleeping for one tick after every attempt. */ for (coreCount = 0; coreCount < MAX_NUM_CORES; coreCount++){ System_sprintf(remoteQueueName, "%s", MultiProc_getName(coreCount)); do { status = MessageQ_open(remoteQueueName, &msgQueueIds[coreCount]); if (status < 0){ Task_sleep(1); } }while (status < 0); } /* * At this point, our application is ready to begin sending messages using * Message Queue. The core with the number TOKEN_START_CORE has the * responsibility of sending the first message. So, we'll handle that in * this block. */ if (selfId == TOKEN_START_CORE){ /* * Allocate the initial message. If the message is not properly * allocated, we must abort */ /* * TODO: IPC #1 - Allocate Memory for Token Message * Add core below that ALLOCATES the memory for the token message. * We've already declared the variable msg to hold the pointer to * this message. The code to check if the pointer is NULL is * already included. */ msg = MessageQ_alloc(HEAP_ID, sizeof(myMsg)); if (msg == NULL){ System_abort("MessageQ_alloc failed\n"); } /* * Now randomly select the next processor to send the. This function * simply selects a random core number and ensures it's not the same as * the current core number. */ nextCore = findNextCore(selfId); /* * Set the Initial Token Count in the message, and specify that the * message type is MSG_TOKEN */ ((myMsg*)msg)->tokenCount = 1; ((myMsg*)msg)->messageType = MSG_TOKEN; /* * We can also set a reply queue so that the core can acknowledge this * message without having to know which core it came from. */ MessageQ_setReplyQueue(messageQ, msg); /* * Now we actually send the message to the next core that we've chosen. */ /* TODO: IPC #2 - Pass the token to the destination core * Add the code to send the message to the destination core. This is * done by putting the message in the destination core's queue. Don't * forget that the ID of the destination core's queue is stored at * element "nextCore" in the array msgQueueIds, and is NOT the same * as the core number. */ status = MessageQ_put(msgQueueIds[nextCore], msg); } while (TRUE){ msgType messageType; MessageQ_Msg ack; MessageQ_QueueId ackQueueId; Int currentTokenCount; /* TODO: IPC #3 - Get a Message from the local queue. * Take the message from the local queue and store it in the variable * message. The function call return value should be stored in the * variable status. Hint: The parameters passed to this function * specify a time out size. We want to configure this call to * never time out, and block eternally until a message is received. */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0){ System_abort("This should not occur since the timeout is forever\n"); } /* * Read the Message Type from the received message, along with the current * token count. */ messageType = ((myMsg*)msg)->messageType; currentTokenCount = ((myMsg*)msg)->tokenCount; /* * Now, check what type of message it is and take action. Here are the * actions to be taken. * * MSG_TOKEN * - Acknowledge that token is received to sending core. * - If token count is less than MAX_MESSAGES * - Increment the token count. * - Forward the token on to the next random core * - If token count is equal to MAX Messages * - Free the Token message. * - Send a Done Message to all other cores. * - Break out of the infinite loop. * * MSG_ACK * - Free the Ack message * MSG_DONE * - Free the Done Message * - Break Out of infinite loop */ switch (messageType){ case MSG_TOKEN: System_printf("Token Received - Count = %d\n", currentTokenCount); /* * TODO: IPC #4 - Get the Reply Queue for the token * Store the ID of the reply queue in the variable ackQueueId. * This function allows us to not have to figure out which core * sent this message. This is the analogous function to the * MessageQ_setReplyQueue() function that was set before the * message was sent. This data is stored in the MessageQ_MsgHeader * element that's included with the message */ ackQueueId = MessageQ_getReplyQueue(msg); /* * TODO: IPC #5 - Allocate the acknowledge message * Allocate the acknowledge message and store the pointer to it * in the variable ack. */ ack = MessageQ_alloc(HEAP_ID, sizeof(myMsg)); // Set the Message Type of the new Message to MSG_ACK if (ack==NULL){ System_abort("MessageQ Alloc Failed\n"); } // Set the Message Type of the new Message to MSG_ACK ((myMsg*)ack)->messageType = MSG_ACK; /* * TODO: IPC #6 - Send the Acknowledge message * Don't forget that we've already stored the reply queue ID in * ackQueueId above. */ status = MessageQ_put(ackQueueId, ack); /* * Now handle the actions required by the status of the message. First * we must check to see if we're at the Token Passing limit. So we'll * compare the current Token count with MAX_MESSAGES. */ /* * If the current token count is the max, then we must free the current * message and then allocate new DONE messages to be sent to the other * cores. */ if (currentTokenCount == NUM_MESSAGES){ /* * TODO: IPC #7 - Free the memory used by the token message * Don't forget that the pointer to this memory is in the * variable msg. */ MessageQ_free(msg); /* * Now allocate and send ALL cores a DONE message. We don't need to * worry about special handling of the current core. It will just * send itself a DONE message and handle it just as the other cores * do */ /* * TODO: IPC #8 - Note that this core will send itself a message. * There's nothing to be added here. just note that this * routine is blindly sending done messages to all of the cores * and not taking into account it's own core number. So, this * core will send one of these messages to itself. */ for (coreCount =0; coreCount < MAX_NUM_CORES; coreCount++){ msg = MessageQ_alloc(HEAP_ID, sizeof(myMsg)); if (msg == NULL){ System_abort("MessageQ Alloc Failed\n"); } // Set the Message Type to MSG_DONE ((myMsg*)msg)->messageType = MSG_DONE; // Now send it to the selected core status = MessageQ_put(msgQueueIds[coreCount], msg); } break; } /* * If we're not at the last message, then we must increment the * tokenCount and pass the message on to a random core. Don't * forget to set the reply queue so we can get an acknowledge. */ nextCore = findNextCore(selfId); ((myMsg*)msg)->tokenCount = currentTokenCount + 1; /* * TODO: IPC #9- Set the reply queue for the token message. * We need to be sure to set the reply queue each time. * Otherwise, the wrong core will receive the acknowledge. */ MessageQ_setReplyQueue(messageQ, msg); // Put the message on the proper queue status = MessageQ_put(msgQueueIds[nextCore], msg); break; case MSG_ACK: System_printf("Ack Received\n"); /* * All we need to do in this case is free the Ack message */ MessageQ_free(msg); break; case MSG_DONE: System_printf("Done Received\n"); /* * If we receive the Done message we just need to free the message, and * then exit SYS/BIOS because the application is complete. */ MessageQ_free(msg); BIOS_exit(0); break; default: System_printf("Invalid Message Type Received\n"); return; } } }
Int main(Int argc, char* argv[]) { RcmServer_Params rcmServerParams; System_printf("%s starting..\n", MultiProc_getName(MultiProc_self())); /* * Enable use of runtime Diags_setMask per module: * * Codes: E = ENTRY, X = EXIT, L = LIFECYCLE, F = INFO, S = STATUS */ Diags_setMask("ti.ipc.rpmsg.MessageQCopy=EXLFS"); /* Setup the table of services, so clients can create and connect to * new service instances: */ ServiceMgr_init(); /* initialize RcmServer create params */ RcmServer_Params_init(&rcmServerParams); /* The first function, at index 0, is a special create function, which * gets passed a Service_Handle argument. * We set this at run time as our C compiler is not allowing named union * field initialization: */ OMXServer_fxnTab.elem[0].addr.createFxn = RPC_SKEL_GetHandle; rcmServerParams.priority = Thread_Priority_ABOVE_NORMAL; rcmServerParams.fxns.length = OMXServer_fxnTab.length; rcmServerParams.fxns.elem = OMXServer_fxnTab.elem; /* Register an OMX service to create and call new OMX components: */ ServiceMgr_register("OMX", &rcmServerParams); /* Some background ping testing tasks, used by rpmsg samples: */ //start_ping_tasks(); #if 0 /* DSP or CORE0 or IPU */ /* Run a background task to test rpmsg_resmgr service */ start_resmgr_task(); #endif #if 0 /* DSP or CORE0 or IPU */ /* Run a background task to test hwspinlock */ start_hwSpinlock_task(); #endif /* Create 1 task with priority 15 */ Error_init(&eb0); Task_Params_init(&taskParams0); //taskParams0.stackSize = 512; taskParams0.priority = 15; taskParams0.affinity = 1; taskParams0.arg0 = (xdc_UArg)(&(t1)) ; taskParams0.arg1 = 0 ; /* Create 1 task with priority 15 */ Error_init(&eb1); Task_Params_init(&taskParams1); //taskParams1.stackSize = 512; taskParams1.priority = 15; taskParams1.affinity = 0; taskParams1.arg0 = (xdc_UArg)(&(t2)) ; taskParams1.arg1 = 1 ; /* create an Event object. All events are binary */ Error_Block eb; Error_init(&eb); edgeDetectEvent = Event_create(NULL, &eb); if (edgeDetectEvent == NULL) { System_abort("Event create failed"); } local_barrier_sense = local_barrier_counter = 2 ; sem0 = Semaphore_create(1, NULL, NULL) ; /* Start the ServiceMgr services */ ServiceMgr_start(0); BIOS_start(); return (0); }
Void *System_ipcMsgQTaskMain(Void *arg) { UInt32 prmSize; SystemIpcMsgQ_Msg *pMsgCommon; Void *pPrm; Int32 status; while(1) { status = MessageQ_get(gSystem_ipcObj.selfMsgQ, (MessageQ_Msg*)&pMsgCommon, OSA_TIMEOUT_FOREVER); if(status==MessageQ_E_UNBLOCKED) break; if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ get failed !!!\n", OSA_getCurTimeInMsec() ); continue; } #if 0 printf(" %u: MSGQ: Received command [0x%04x] (prmSize = %d) for [%s][%02d] (waitAck=%d)\n", OSA_getCurTimeInMsec(), pMsgCommon->cmd, pMsgCommon->prmSize, MultiProc_getName(SYSTEM_GET_PROC_ID(pMsgCommon->linkId)), SYSTEM_GET_LINK_ID(pMsgCommon->linkId), pMsgCommon->waitAck ); #endif prmSize = pMsgCommon->prmSize; pPrm = SYSTEM_IPC_MSGQ_MSG_PAYLOAD_PTR(pMsgCommon); if(pMsgCommon->cmd==SYSTEM_CMD_GET_INFO) { UTILS_assert(prmSize == sizeof(System_LinkInfo)); pMsgCommon->status = System_linkGetInfo_local(pMsgCommon->linkId, pPrm); } else { pMsgCommon->status = System_linkControl_local( pMsgCommon->linkId, pMsgCommon->cmd, pPrm, prmSize, pMsgCommon->waitAck ); } if(pMsgCommon->waitAck) { MessageQ_QueueId replyMsgQ; replyMsgQ = MessageQ_getReplyQueue(pMsgCommon); status = MessageQ_put(replyMsgQ, (MessageQ_Msg)pMsgCommon); if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ Ack put failed !!!\n", OSA_getCurTimeInMsec() ); MessageQ_free((MessageQ_Msg)pMsgCommon); } } else { MessageQ_free((MessageQ_Msg)pMsgCommon); } } return NULL; }
Int32 System_ipcMsgQSendMsg(UInt32 linkId, UInt32 cmd, Void *pPrm, UInt32 prmSize, Bool waitAck, UInt32 timeout) { Int32 status=OSA_SOK; SystemIpcMsgQ_Msg *pMsgCommon; UInt32 procId; Void *pMsgPrm; UTILS_assert(prmSize<=SYSTEM_IPC_MSGQ_MSG_SIZE_MAX); procId = SYSTEM_GET_PROC_ID(linkId); #ifdef TI_8107_BUILD if(procId==SYSTEM_PROC_DSP) { printf(" %u: MSGQ: WARNING: Trying to send command [0x%04x] to link [%d] on processor [%s], BUT [%s] is NOT present on this platform !!!\n", OSA_getCurTimeInMsec(), cmd, SYSTEM_GET_LINK_ID(linkId), MultiProc_getName(procId), MultiProc_getName(procId) ); /* return SUCCESS so that calling API can continue */ return status; } #endif UTILS_assert( procId < SYSTEM_PROC_MAX); /*wuzc modify for malloc fail*/ OSA_mutexLock(&gSystem_ipcObj.msgQLock); pMsgCommon = (SystemIpcMsgQ_Msg *)MessageQ_alloc( SYSTEM_IPC_MSGQ_HEAP, sizeof(*pMsgCommon)+prmSize ); UTILS_assert(pMsgCommon!=NULL); if(prmSize && pPrm) { pMsgPrm = SYSTEM_IPC_MSGQ_MSG_PAYLOAD_PTR(pMsgCommon); memcpy(pMsgPrm, pPrm, prmSize); } pMsgCommon->linkId = linkId; pMsgCommon->cmd = cmd; pMsgCommon->prmSize = prmSize; pMsgCommon->waitAck = waitAck; pMsgCommon->status = OSA_SOK; MessageQ_setReplyQueue(gSystem_ipcObj.selfAckMsgQ, (MessageQ_Msg)pMsgCommon); MessageQ_setMsgId(pMsgCommon, linkId); //OSA_mutexLock(&gSystem_ipcObj.msgQLock); status = MessageQ_put(gSystem_ipcObj.remoteProcMsgQ[procId], (MessageQ_Msg)pMsgCommon); if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ put for [%s] failed !!!\n", OSA_getCurTimeInMsec(), MultiProc_getName(procId) ); MessageQ_free((MessageQ_Msg)pMsgCommon); OSA_mutexUnlock(&gSystem_ipcObj.msgQLock); return status; } if(waitAck) { SystemIpcMsgQ_Msg *pAckMsg; status = MessageQ_get(gSystem_ipcObj.selfAckMsgQ, (MessageQ_Msg*)&pAckMsg, timeout); if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ Ack get from [%s] failed !!!\n", OSA_getCurTimeInMsec(), MultiProc_getName(procId) ); MessageQ_free((MessageQ_Msg)pMsgCommon); OSA_mutexUnlock(&gSystem_ipcObj.msgQLock); return status; } if(prmSize && pPrm) { pMsgPrm = SYSTEM_IPC_MSGQ_MSG_PAYLOAD_PTR(pAckMsg); memcpy(pPrm, pMsgPrm, prmSize); } status = pAckMsg->status; MessageQ_free((MessageQ_Msg)pAckMsg); } OSA_mutexUnlock(&gSystem_ipcObj.msgQLock); return status; }
Int MessageQApp_execute(UInt32 numLoops, UInt32 payloadSize, UInt16 procId) { Int32 status = 0; MessageQ_Msg msg = NULL; MessageQ_Params msgParams; UInt32 i; MessageQ_QueueId queueId = MessageQ_INVALIDMESSAGEQ; MessageQ_Handle msgqHandle; char remoteQueueName[64]; struct timespec start, end; long elapsed; UInt32 msgId; printf("Entered MessageQApp_execute\n"); /* Create the local Message Queue for receiving. */ MessageQ_Params_init(&msgParams); msgqHandle = MessageQ_create(MPU_MESSAGEQNAME, &msgParams); if (msgqHandle == NULL) { printf("Error in MessageQ_create\n"); goto exit; } else { printf("Local MessageQId: 0x%x\n", MessageQ_getQueueId(msgqHandle)); } sprintf(remoteQueueName, "%s_%s", SLAVE_MESSAGEQNAME, MultiProc_getName(procId)); /* Poll until remote side has its messageQ created before we send: */ do { status = MessageQ_open(remoteQueueName, &queueId); sleep (1); } while (status == MessageQ_E_NOTFOUND); if (status < 0) { printf("Error in MessageQ_open [%d]\n", status); goto cleanup; } else { printf("Remote queueId [0x%x]\n", queueId); } msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg) + payloadSize); if (msg == NULL) { printf("Error in MessageQ_alloc\n"); MessageQ_close(&queueId); goto cleanup; } /* handshake with remote to set the number of loops */ MessageQ_setReplyQueue(msgqHandle, msg); ((SyncMsg *)msg)->numLoops = numLoops; ((SyncMsg *)msg)->print = FALSE; MessageQ_put(queueId, msg); MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); printf("Exchanging %d messages with remote processor %s...\n", numLoops, MultiProc_getName(procId)); clock_gettime(CLOCK_REALTIME, &start); for (i = 1 ; i <= numLoops; i++) { ((SyncMsg *)msg)->numLoops = i; /* Have the remote proc reply to this message queue */ MessageQ_setReplyQueue(msgqHandle, msg); status = MessageQ_put(queueId, msg); if (status < 0) { printf("Error in MessageQ_put [%d]\n", status); break; } status = MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); if (status < 0) { printf("Error in MessageQ_get [%d]\n", status); break; } else { /* Validate the returned message */ msgId = ((SyncMsg *)msg)->numLoops; if ((msg != NULL) && (msgId != i)) { printf("Data integrity failure!\n" " Expected %d\n" " Received %d\n", i, msgId); break; } } } clock_gettime(CLOCK_REALTIME, &end); elapsed = diff(start, end); if (numLoops > 0) { printf("%s: Avg round trip time: %ld usecs\n", MultiProc_getName(procId), elapsed / numLoops); } MessageQ_free(msg); MessageQ_close(&queueId); cleanup: status = MessageQ_delete(&msgqHandle); if (status < 0) { printf ("Error in MessageQ_delete [%d]\n", status); } exit: printf("Leaving MessageQApp_execute\n\n"); return (status); }
Int MessageQApp_execute(UInt32 numLoops, UInt16 procId) { Int32 status = 0; MessageQ_Msg msg = NULL; MessageQ_Params msgParams; UInt32 i; MessageQ_QueueId queueId = MessageQ_INVALIDMESSAGEQ; MessageQ_Handle msgqHandle; char remoteQueueName[64]; UInt32 msgId; printf("Entered MessageQApp_execute\n"); /* Create the local Message Queue for receiving. */ MessageQ_Params_init(&msgParams); msgqHandle = MessageQ_create(MPU_MESSAGEQNAME, &msgParams); if (msgqHandle == NULL) { printf("Error in MessageQ_create\n"); goto exit; } else { printf("Local MessageQId: 0x%x\n", MessageQ_getQueueId(msgqHandle)); } sprintf(remoteQueueName, "%s_%s", SLAVE_MESSAGEQNAME, MultiProc_getName(procId)); /* Poll until remote side has it's messageQ created before we send: */ do { status = MessageQ_open(remoteQueueName, &queueId); sleep (1); } while (status == MessageQ_E_NOTFOUND); if (status < 0) { printf("Error in MessageQ_open [%d]\n", status); goto cleanup; } else { printf("Remote queueId [0x%x]\n", queueId); } msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg)); if (msg == NULL) { printf("Error in MessageQ_alloc\n"); MessageQ_close(&queueId); goto cleanup; } /* handshake with remote to set the number of loops */ MessageQ_setReplyQueue(msgqHandle, msg); ((SyncMsg *)msg)->numLoops = numLoops; ((SyncMsg *)msg)->print = FALSE; MessageQ_put(queueId, msg); MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); printf("Exchanging %d messages with remote processor %s...\n", numLoops, MultiProc_getName(procId)); for (i = 1 ; i <= numLoops; i++) { ((SyncMsg *)msg)->numLoops = i; /* Have the remote proc reply to this message queue */ MessageQ_setReplyQueue(msgqHandle, msg); status = MessageQ_put(queueId, msg); if (status < 0) { printf("Error in MessageQ_put [%d]\n", status); MessageQ_free(msg); break; } status = MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); if (status < 0) { printf("Error in MessageQ_get [%d]\n", status); break; } else { /* validate the returned message */ msgId = ((SyncMsg *)msg)->numLoops; if ((msg != NULL) && (msgId != i)) { printf("Data integrity failure!\n" " Expected %d\n" " Received %d\n", i, msgId); break; } } if (numLoops <= 200) { printf("MessageQ_get #%d Msg = 0x%x\n", i, (UInt)msg); } else if ((i % 1000) == 0) { printf("MessageQ_get #%d Msg = 0x%x\n", i, (UInt)msg); } } printf("Exchanged %d messages with remote processor %s\n", (i-1), MultiProc_getName(procId)); if (status >= 0) { printf("Sample application successfully completed!\n"); MessageQ_free(msg); } MessageQ_close(&queueId); cleanup: /* Clean-up */ status = MessageQ_delete(&msgqHandle); if (status < 0) { printf("Error in MessageQ_delete [%d]\n", status); } exit: printf("Leaving MessageQApp_execute\n\n"); return (status); }
/*! * @brief This function implements the interrupt service routine for the * interrupt received from the remote cores. * * @param refData object to be handled in ISR * * @sa VirtQueue_cb */ static Bool VirtQueue_ISR (UInt32 msg, Void * arg) { UInt32 procId = (UInt32)arg; ProcMgr_Handle handle = NULL; Int status = 0; GT_2trace (curTrace, GT_ENTER, "_VirtQueue_ISR", msg, arg); /* Interrupt clear is done by ArchIpcInt. */ switch(msg) { case (UInt)RP_MBOX_ECHO_REPLY: Osal_printf ("Echo reply from %s", MultiProc_getName(procId)); break; case (UInt)RP_MBOX_CRASH: Osal_printf ("Crash notification for %s", MultiProc_getName(procId)); status = ProcMgr_open(&handle, procId); if (status >= 0) { ProcMgr_setState(handle, ProcMgr_State_Error); ProcMgr_close(&handle); } else { Osal_printf("Failed to open ProcMgr handle"); } break; case (UInt)RP_MBOX_BOOTINIT_DONE: Osal_printf ("Got BootInit done from %s", MultiProc_getName(procId)); // TODO: What to do with this message? break; case (UInt)RP_MBOX_HIBERNATION_ACK: Osal_printf ("Got Hibernation ACK from %s", MultiProc_getName(procId)); break; case (UInt)RP_MBOX_HIBERNATION_CANCEL: Osal_printf ("Got Hibernation CANCEL from %s", MultiProc_getName(procId)); break; default: /* * If the message isn't one of the above, it's a virtqueue * message */ if (msg%2 < NUM_QUEUES) { /* This message is for us! */ VirtQueue_cb((void *)msg, queueRegistry[procId][msg%2]); } break; } return TRUE; }