int Init_IPC() { Int status; HeapBufMP_Handle heapHandle; HeapBufMP_Params heapBufParams; /* Create the heap that will be used to allocate messages. */ HeapBufMP_Params_init(&heapBufParams); heapBufParams.regionId = 0; heapBufParams.name = IMAGE_PROCESSING_HEAP_NAME; heapBufParams.numBlocks = number_of_cores; heapBufParams.blockSize = sizeof(process_message_t); heapHandle = HeapBufMP_create(&heapBufParams); if (heapHandle == NULL) { logout("Main: HeapBufMP_create failed\n" ); goto ipc_exit; } /* Register this heap with MessageQ */ status = MessageQ_registerHeap((IHeap_Handle)heapHandle, IMAGE_PROCESSING_HEAPID); if(status != MessageQ_S_SUCCESS) { logout("Main: MessageQ_registerHeap failed\n" ); goto ipc_exit; } if (mc_process_init(number_of_cores)) { logout("mc_process_init returns error\n"); goto ipc_exit; } ipc_exit: return(0); }
/* * ======== main ======== * Synchronizes all processors. * Creates a HeapBufMP and registers it with MessageQ. */ Int main(Int argc, Char* argv[]) { Int status; HeapBufMP_Handle heapHandle; HeapBufMP_Params heapBufParams; /* * 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"); } /* * Create the heap that will be used to allocate messages. */ HeapBufMP_Params_init(&heapBufParams); heapBufParams.regionId = 0; heapBufParams.name = HEAP_NAME; heapBufParams.align = HEAP_ALIGN; heapBufParams.numBlocks = HEAP_NUMMSGS; heapBufParams.blockSize = HEAP_MSGSIZE; heapHandle = HeapBufMP_create(&heapBufParams); if (heapHandle == NULL) { System_abort("HeapBufMP_create failed\n" ); } /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAPID); BIOS_start(); return (0); }
Int SystemCfg_createResources(SystemCfg_Object *obj) { Error_Block eb; Int status = 0; HeapBufMP_Params heapParams; Log_print1(Diags_ENTRY | Diags_INFO, "--> "FXNN": (obj=0x%x)",(IArg)obj); Error_init(&eb); /* create heap for rcm messages */ HeapBufMP_Params_init(&heapParams); heapParams.name = SystemCfg_RcmMsgHeapName_CompDev; heapParams.regionId = 0; heapParams.blockSize = 128; // header = 52 B, payload = 76 B heapParams.numBlocks = 5; // 5 messages, total heap storage = 640 B heapParams.align = 128; // align on cache line boundary obj->rcmHeapH = HeapBufMP_create(&heapParams); if (Error_check(&eb)) { Log_error0(FXNN": HeapBuf_create() failed"); status = -1; goto leave; } /* register this heap with MessageQ */ MessageQ_registerHeap((Ptr)(obj->rcmHeapH), SystemCfg_RcmMsgHeapId_CompDev); leave: Log_print1(Diags_EXIT, "<-- "FXNN": %d", (IArg)status); return(status); }
/* * ======== tsk0 ======== */ Void tsk0(UArg arg0, UArg arg1) { Int status; MessageQ_Msg msg; System_printf("tsk0 starting\n"); /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)SharedRegion_getHeap(0), HEAP_ID); /* Open the 'next' remote message queue. Spin until it is ready. */ do { status = MessageQ_open(nextQueueName, &nextQueueId); } while (status < 0); if (selfId == 0) { msg = MessageQ_alloc(HEAP_ID, MSGSIZE); if (msg == NULL) { System_abort("MessageQ_alloc failed\n"); } /* Kick off the loop */ status = MessageQ_put(nextQueueId, msg); if (status < 0) { System_abort("MessageQ_put failed\n"); } } for (numReceived = 0; numReceived < NUMLOOPS; numReceived++) { /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("MessageQ_get failed\n"); } if (selfId == 0) { rawtimestamps[numReceived] = Timestamp_get32(); if (numReceived == NUMLOOPS - 1) { printStatistics(); break; } } status = MessageQ_put(nextQueueId, msg); if (status < 0) { System_abort("MessageQ_put failed\n"); } } System_exit(0); }
/** * Handler for messageq setup API. * * \param ctp Thread's associated context information. * \param msg The actual devctl() message. * \param ocb OCB associated with client's session. * * \return POSIX errno value. * * \retval EOK Success. * \retval ENOTSUP Unsupported devctl(). */ int syslink_messageq_registerheap(resmgr_context_t *ctp, io_devctl_t *msg, syslink_ocb_t *ocb) { MessageQDrv_CmdArgs * cargs = (MessageQDrv_CmdArgs *) (_DEVCTL_DATA (msg->i)); MessageQDrv_CmdArgs * out = (MessageQDrv_CmdArgs *) (_DEVCTL_DATA (msg->o)); out->apiStatus = MessageQ_registerHeap (cargs->args.registerHeap.heap, cargs->args.registerHeap.heapId); if (out->apiStatus >= 0) { /* At this call to the list to be cleaned-up */ add_ocb_res(ocb, DCMD_MESSAGEQ_UNREGISTERHEAP, (int)cargs->args.registerHeap.heapId, NULL); } return (_RESMGR_PTR (ctp, &msg->o, sizeof (msg->o) + sizeof(MessageQDrv_CmdArgs))); }
Int SystemCfg_createResources(SystemCfg_Object *obj) { Error_Block eb; Int status = 0; HeapBuf_Params heapBufP; IHeap_Handle heapH; Log_print1(Diags_ENTRY | Diags_INFO, "--> "FXNN": (obj=0x%x)",(IArg)obj); Error_init(&eb); /* allocate heap backing store from SR_0 heap */ heapH = (IHeap_Handle)SharedRegion_getHeap(0); obj->rcmHeapBufSize = 5 * 128; obj->rcmHeapBufBase = Memory_alloc(heapH, obj->rcmHeapBufSize, 128, &eb); if (Error_check(&eb)) { Log_error1(FXNN": out of memory: size=%u", obj->rcmHeapBufSize); status = -1; goto leave; } /* create heap for messages */ HeapBuf_Params_init(&heapBufP); heapBufP.blockSize = 128; // header = 52 B, payload = 76 B heapBufP.numBlocks = 5; // 5 messages, total heap storage = 640 B heapBufP.align = 128; // align on cache line boundary heapBufP.buf = obj->rcmHeapBufBase; // heap storage base address heapBufP.bufSize = obj->rcmHeapBufSize; // heap storage size obj->rcmHeapH = HeapBuf_create(&heapBufP, &eb); if (Error_check(&eb)) { Log_error0(FXNN": HeapBuf_create() failed"); status = -1; goto leave; } /* register this heap with MessageQ */ Log_print2(Diags_INFO, FXNN": MessageQ_registerHeap: (rcmHeapH: 0x%x, heapId: %d)", (IArg)(obj->rcmHeapH), (IArg)SystemCfg_RcmMsgHeapId_CompDev); MessageQ_registerHeap((Ptr)(obj->rcmHeapH), SystemCfg_RcmMsgHeapId_CompDev); leave: Log_print1(Diags_EXIT, "<-- "FXNN": %d", (IArg)status); return(status); }
/* * ======== main ======== */ Void main() { Int status; struct HeapBufMP_Params heapBufMPParams; HeapBufMP_Handle heapHandle; System_printf("Enter main()\n"); System_flush(); /* Call Ipc_start() */ status = Ipc_start(); if (status < 0) { System_abort("Ipc_start failed\n"); } #ifdef DSP_ACTIVE /* Attach to DSP */ while (Ipc_attach(1) < 0) { Task_sleep(1000); }; #endif #if 1 /* Create the heap that will be used to allocate messages. */ HeapBufMP_Params_init(&heapBufMPParams); heapBufMPParams.regionId = 0; /* use default region */ heapBufMPParams.name = "shareHeap"; heapBufMPParams.align = 4; heapBufMPParams.numBlocks = 40; heapBufMPParams.blockSize = 256; heapBufMPParams.gate = NULL; /* use system gate */ heapHandle = HeapBufMP_create(&heapBufMPParams); if (heapHandle == NULL) { System_abort("HeapBufMP_create failed\n"); while(1); } /* Register this heap with MessageQ */ if(MessageQ_registerHeap(heapHandle, 0) != MessageQ_S_SUCCESS) while(1); #endif BIOS_start(); /* enable interrupts and start SYS/BIOS */ }
/* * ======== SystemCfg_openResources ======== */ Int SystemCfg_openResources(SystemCfg_Object *obj) { Int status; /* open rcm heap created on host processor */ status = HeapBufMP_open(SystemCfg_RcmMsgHeapName_CompDev, &(obj->rcmHeapH)); if (status < 0) { Log_error1("HeapBufMP_open() error %d", (IArg)status); goto leave; } /* register this heap with MessageQ */ MessageQ_registerHeap((Ptr)(obj->rcmHeapH), SystemCfg_RcmMsgHeapId_CompDev); leave: return(status); }
Int32 System_ipcMsgQHeapCreate() { Int32 status; UInt32 retryCount; { /* open heap */ retryCount = 10; while(retryCount) { /* printf(" %u: SYSTEM: Opening MsgQ Heap [%s] ...\n", OSA_getCurTimeInMsec(), SYSTEM_IPC_MSGQ_HEAP_NAME ); */ status = HeapMemMP_open(SYSTEM_IPC_MSGQ_HEAP_NAME, &gSystem_ipcObj.msgQHeapHndl); if (status == HeapMemMP_E_NOTFOUND) { /* Sleep for a while before trying again. */ OSA_waitMsecs (1000); } else if (status == HeapMemMP_S_SUCCESS) { break; } retryCount--; if(retryCount<=0) UTILS_assert(0); } } /* Register this heap with MessageQ */ MessageQ_registerHeap( (IHeap_Handle)gSystem_ipcObj.msgQHeapHndl, SYSTEM_IPC_MSGQ_HEAP ); return OSA_SOK; }
/****************************************************************************** * 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; } } }
/* * ======== tsk1_func ======== * Send and receive messages */ Void tsk1_func(UArg arg0, UArg arg1) { MessageQ_Msg msg; MessageQ_Handle messageQ; MessageQ_QueueId remoteQueueId; HeapBufMP_Handle heapHandle; Int status; UInt16 msgId; /* * Open the heap that is created on the other processor. Loop until opened. * Not using the name since the interrupts are not enabled yet! */ 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 a local message queue */ messageQ = MessageQ_create(DSP_MESSAGEQNAME, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n" ); } /* Open the core0 message queue. Spin until it is ready. */ do { status = MessageQ_open(CORE0_MESSAGEQNAME, &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); /* Wait for a message and send it to core0 */ 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 CORE0\n", MessageQ_getMsgId(msg)); /* 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) { System_printf("Test complete!\n"); BIOS_exit(0); } } }
static Int dvsdk_grapx_display_rpc_remote_mode_init () { RcmClient_Params rcmClientParams; IArg key; Bool doInit = FALSE; Int status = 0; key = Gate_enterSystem(); if (FALSE == g_RemoteStubContext.bRemoteInitDone) { doInit = TRUE; } Gate_leaveSystem(key); if (TRUE == doInit) { GateThread_Params gtParams; GateThread_Params_init (>Params); g_RemoteStubContext.hGate = GateThread_Handle_upCast(GateThread_create(>Params, NULL)); key = GateH_enter (g_RemoteStubContext.hGate); MessageQ_registerHeap(SharedRegion_getHeap(0),Global_GrpxDssMsgHeapId); RcmClient_Params_init (&rcmClientParams); rcmClientParams.heapId = Global_GrpxDssMsgHeapId; do { status = RcmClient_create(DVSDK_DSS_GRPX_SERVER_NAME, &rcmClientParams, &g_RemoteStubContext.hRcmClient); if (status < 0) { Thread_yield(NULL); } } while (status < 0); if (0 == status) { status = RcmClient_getSymbolIndex (g_RemoteStubContext.hRcmClient, DVSDK_DSS_GRPX_INIT_FXN_NAME, &g_RemoteStubContext.nInitFxnIdx); } if (0 == status) { status = RcmClient_getSymbolIndex (g_RemoteStubContext.hRcmClient, DVSDK_DSS_GRPX_START_FXN_NAME, &g_RemoteStubContext.nStartFxnIdx); } if (0 == status) { status = RcmClient_getSymbolIndex (g_RemoteStubContext.hRcmClient, DVSDK_DSS_GRPX_STOP_FXN_NAME, &g_RemoteStubContext.nStopFxnIdx); } if (0 == status) { status = RcmClient_getSymbolIndex (g_RemoteStubContext.hRcmClient, DVSDK_DSS_GRPX_DEINIT_FXN_NAME, &g_RemoteStubContext.nDeinitFxnIdx); } if (0 == status) { status = RcmClient_getSymbolIndex (g_RemoteStubContext.hRcmClient, DVSDK_DSS_GRPX_DISPLAYTOGGLE_FXN_NAME, &g_RemoteStubContext.nDisplayToggelFxnIdx); } g_RemoteStubContext.bRemoteInitDone = TRUE; GateH_leave(g_RemoteStubContext.hGate, key); } return status; }
Void smain(UArg arg0, UArg arg1) { HeapBufMP_Params heapBufMPP; HeapBufMP_Handle heapH = NULL; UInt16 serverProcId; Int status = 0; /* create heap for rcm messages */ HeapBufMP_Params_init(&heapBufMPP); heapBufMPP.name = Global_RcmClientHeapName; heapBufMPP.regionId = 0; heapBufMPP.blockSize = 0x80; /* 128 B */ heapBufMPP.numBlocks = 4; heapH = HeapBufMP_create(&heapBufMPP); if (heapH == NULL) { Log_error0(FXNN": HeapBuf_create() failed"); goto leave; } /* register this heap with MessageQ */ MessageQ_registerHeap((Ptr)heapH, Global_RcmClientHeapId); /* attach to the server processor */ serverProcId = MultiProc_getId(Global_ServerProcName); do { status = Ipc_attach(serverProcId); if (status < 0) { #ifdef __ARCTIC__ Task_yield(); /* no timers on EVE simulator */ #else Task_sleep(10); /* 10ms (when 1 tick == 1 ms) */ #endif } } while (status < 0); /* delay 500ms to give server a chance to boot */ #ifdef __ARCTIC__ Task_yield(); #else Task_sleep(500); #endif /* invoke the application entry point */ App_exec(NULL); leave: /* detach from server processor */ Ipc_detach(serverProcId); /* unregister the heap and delete it */ if (heapH != NULL) { MessageQ_unregisterHeap(Global_RcmClientHeapId); HeapBufMP_delete(&heapH); } /* report if error */ if (status < 0) { System_printf("FAIL: example encountered errors\n"); } return; }
/* * ======== ipcSetup ======== */ Int ipcSetup (Int testCase) { Int status = 0; Char * procName; UInt16 procId; ProcMgr_AttachParams attachParams; ProcMgr_State state; #if !defined(SYSLINK_USE_DAEMON) UInt32 entryPoint = 0; ProcMgr_StartParams startParams; Char uProcId; HeapBufMP_Params heapbufmpParams; #if defined(SYSLINK_USE_LOADER) Char * imageName; UInt32 fileId; #endif #endif Ipc_Config config; Int i; UInt32 srCount; SharedRegion_Entry srEntry; Osal_printf ("ipcSetup: Setup IPC componnets \n"); switch(testCase) { case 0: Osal_printf ("ipcSetup: Local RCM test\n"); remoteServerName = RCMSERVER_NAME; procName = MPU_PROC_NAME; break; case 1: Osal_printf ("ipcSetup: RCM test with RCM client and server on " "Sys M3\n\n"); remoteServerName = SYSM3_SERVER_NAME; procName = SYSM3_PROC_NAME; break; case 2: Osal_printf ("ipcSetup: RCM test with RCM client and server on " "App M3\n\n"); remoteServerName = APPM3_SERVER_NAME; procName = APPM3_PROC_NAME; break; case 3: Osal_printf ("ipcSetup: RCM test with RCM client and server on " "Tesla\n\n"); remoteServerName = DSP_SERVER_NAME; procName = DSP_PROC_NAME; break; default: Osal_printf ("ipcSetup: Please pass valid arg " "(0-local, 1-Sys M3, 2-App M3, 3-Tesla) \n"); goto exit; break; } Ipc_getConfig (&config); status = Ipc_setup (&config); if (status < 0) { Osal_printf ("ipcSetup: Error in Ipc_setup [0x%x]\n", status); goto exit; } Osal_printf("Ipc_setup status [0x%x]\n", status); procId = ((testCase == 3) ? MultiProc_getId (DSP_PROC_NAME) : \ MultiProc_getId (SYSM3_PROC_NAME)); remoteIdClient = MultiProc_getId (procName); /* Open a handle to the ProcMgr instance. */ status = ProcMgr_open (&procMgrHandleClient, procId); if (status < 0) { Osal_printf ("ipcSetup: Error in ProcMgr_open [0x%x]\n", status); goto exit; } if (status >= 0) { Osal_printf ("ipcSetup: ProcMgr_open Status [0x%x]\n", status); ProcMgr_getAttachParams (NULL, &attachParams); /* Default params will be used if NULL is passed. */ status = ProcMgr_attach (procMgrHandleClient, &attachParams); if (status < 0) { Osal_printf ("ipcSetup: ProcMgr_attach failed [0x%x]\n", status); } else { Osal_printf ("ipcSetup: ProcMgr_attach status: [0x%x]\n", status); state = ProcMgr_getState (procMgrHandleClient); Osal_printf ("ipcSetup: After attach: ProcMgr_getState\n" " state [0x%x]\n", state); } } if ((status >= 0) && (testCase == 2)) { status = ProcMgr_open (&procMgrHandleClient1, remoteIdClient); if (status < 0) { Osal_printf ("ipcSetup: Error in ProcMgr_open [0x%x]\n", status); goto exit; } if (status >= 0) { Osal_printf ("ipcSetup: ProcMgr_open Status [0x%x]\n", status); ProcMgr_getAttachParams (NULL, &attachParams); /* Default params will be used if NULL is passed. */ status = ProcMgr_attach (procMgrHandleClient1, &attachParams); if (status < 0) { Osal_printf ("ipcSetup: ProcMgr_attach failed [0x%x]\n", status); } else { Osal_printf ("ipcSetup: ProcMgr_attach status: [0x%x]\n", status); state = ProcMgr_getState (procMgrHandleClient1); Osal_printf ("ipcSetup: After attach: ProcMgr_getState\n" " state [0x%x]\n", state); } } } #if !defined(SYSLINK_USE_DAEMON) /* Daemon sets this up */ #if defined(SYSLINK_USE_LOADER) if (testCase == 1) imageName = RCM_MPUCLIENT_SYSM3ONLY_IMAGE; else if (testCase == 2) imageName = RCM_MPUCLIENT_SYSM3_IMAGE; else if (testCase == 3) imageName = RCM_MPUCLIENT_DSP_IMAGE; if (testCase != 0) { status = ProcMgr_load (procMgrHandleClient, imageName, 2, &imageName, &entryPoint, &fileId, procId); if (status < 0) { Osal_printf ("ipcSetup: Error in ProcMgr_load %s image [0x%x]\n", procName, status); goto exit; } Osal_printf ("ipcSetup: ProcMgr_load %s image Status [0x%x]\n", procName, status); } #endif /* defined(SYSLINK_USE_LOADER) */ if (testCase != 0) { startParams.proc_id = procId; status = ProcMgr_start (procMgrHandleClient, entryPoint, &startParams); if (status < 0) { Osal_printf ("ipcSetup: Error in ProcMgr_start %s [0x%x]\n", procName, status); goto exit; } Osal_printf ("ipcSetup: ProcMgr_start %s Status [0x%x]\n", procName, status); } if (testCase == 2) { #if defined(SYSLINK_USE_LOADER) imageName = RCM_MPUCLIENT_APPM3_IMAGE; uProcId = MultiProc_getId (APPM3_PROC_NAME); status = ProcMgr_load (procMgrHandleClient1, imageName, 2, &imageName, &entryPoint, &fileId, uProcId); if (status < 0) { Osal_printf ("ipcSetup: Error in ProcMgr_load AppM3 image: " "[0x%x]\n", status); goto exit; } Osal_printf ("ipcSetup: AppM3: ProcMgr_load Status [0x%x]\n", status); #endif /* defined(SYSLINK_USE_LOADER) */ startParams.proc_id = MultiProc_getId (APPM3_PROC_NAME); status = ProcMgr_start (procMgrHandleClient1, entryPoint, &startParams); if (status < 0) { Osal_printf ("ipcSetup: Error in ProcMgr_start AppM3 [0x%x]\n", status); goto exit; } Osal_printf ("ipcSetup: ProcMgr_start AppM3 Status [0x%x]\n", status); } #endif /* defined(SYSLINK_USE_DAEMON) */ srCount = SharedRegion_getNumRegions(); Osal_printf ("SharedRegion_getNumRegions = %d\n", srCount); for (i = 0; i < srCount; i++) { status = SharedRegion_getEntry (i, &srEntry); Osal_printf ("SharedRegion_entry #%d: base = 0x%x len = 0x%x " "ownerProcId = %d isValid = %d cacheEnable = %d " "cacheLineSize = 0x%x createHeap = %d name = %s\n", i, srEntry.base, srEntry.len, srEntry.ownerProcId, (Int)srEntry.isValid, (Int)srEntry.cacheEnable, srEntry.cacheLineSize, (Int)srEntry.createHeap, srEntry.name); } #if !defined(SYSLINK_USE_DAEMON) /* Daemon sets this up */ /* Create Heap and register it with MessageQ */ if (status >= 0) { HeapBufMP_Params_init (&heapbufmpParams); heapbufmpParams.sharedAddr = NULL; heapbufmpParams.align = 128; heapbufmpParams.numBlocks = 4; heapbufmpParams.blockSize = MSGSIZE; heapSize = HeapBufMP_sharedMemReq (&heapbufmpParams); Osal_printf ("ipcSetup: heapSize = 0x%x\n", heapSize); srHeap = SharedRegion_getHeap (RCM_HEAP_SR); if (srHeap == NULL) { status = MEMORYOS_E_FAIL; Osal_printf ("ipcSetup: SharedRegion_getHeap failed for srHeap:" " [0x%x]\n", srHeap); } else { Osal_printf ("ipcSetup: Before Memory_alloc = 0x%x\n", srHeap); heapBufPtr = Memory_alloc (srHeap, heapSize, 0); if (heapBufPtr == NULL) { status = MEMORYOS_E_MEMORY; Osal_printf ("ipcSetup: Memory_alloc failed for ptr: [0x%x]\n", heapBufPtr); } else { heapbufmpParams.name = RCM_MSGQ_HEAPNAME; heapbufmpParams.sharedAddr = heapBufPtr; Osal_printf ("ipcSetup: Before HeapBufMP_Create: [0x%x]\n", heapBufPtr); heapHandle = HeapBufMP_create (&heapbufmpParams); if (heapHandle == NULL) { status = HeapBufMP_E_FAIL; Osal_printf ("ipcSetup: HeapBufMP_create failed for Handle:" "[0x%x]\n", heapHandle); } else { /* Register this heap with MessageQ */ status = MessageQ_registerHeap (heapHandle, RCM_MSGQ_HEAPID); if (status < 0) { Osal_printf ("ipcSetup: MessageQ_registerHeap " "failed!\n"); } } } } } #endif /* defined(SYSLINK_USE_DAEMON) */ exit: Osal_printf ("ipcSetup: Leaving ipcSetup()\n"); return status; }
Int App_create(UInt16 remoteProcId) { Int status =0; int retStatus =0; UInt32 event =0; HeapBufMP_Params heapParams; MessageQ_Params msgqParams; printf("--> App_create:\n"); /* setting default values */ Module.remoteProcId = remoteProcId; Module.lineId = SystemCfg_LineId; Module.eventId = SystemCfg_AppEventId; Module.head = 0; Module.tail = 0; Module.error = 0; Module.msgHeap = NULL; Module.hostQue = NULL; Module.videoQue = MessageQ_INVALIDMESSAGEQ; Module.heapId = App_MsgHeapId; Module.msgSize = sizeof(App_Msg); /* 1. create sync object */ retStatus = sem_init(&Module.semH, 0, 0); if (retStatus == -1) { printf("App_create: Failed to create a semaphore\n"); goto leave; } /* 2. register notify callback */ status = Notify_registerEventSingle(Module.remoteProcId, Module.lineId, Module.eventId, App_notifyCB, (UArg)&Module); if (status < 0) { printf("App_create: Host failed to register an event\n"); goto leave; } /* 3. wait until remote core has also registered notify callback */ do { status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_NOP, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { sleep(1); } } while (status == Notify_E_EVTNOTREGISTERED); if (status < 0) { printf("App_create: Failed to send event\n"); goto leave; } /* 4. create local & shared resources (to be opened by remote processor) */ /* create heap for messages */ HeapBufMP_Params_init(&heapParams); heapParams.name = App_MsgHeapName; heapParams.regionId = App_MsgHeapSrId; heapParams.blockSize = 64; heapParams.numBlocks = 10; Module.msgHeap = HeapBufMP_create(&heapParams); if (Module.msgHeap == NULL) { printf("App_create: Failed to create a HeapBufMP\n"); status = -1; goto leave; } /* register heap with MessageQ */ status = MessageQ_registerHeap((Ptr)(Module.msgHeap), App_MsgHeapId); if (status < 0) { printf("App_create: Failed to register HeapBufMP with MessageQ\n"); goto leave; } /* create local message queue (inbound messages) */ MessageQ_Params_init(&msgqParams); Module.hostQue = MessageQ_create(App_HostMsgQueName, &msgqParams); if (Module.hostQue == NULL) { printf("App_create: Failed creating MessageQ\n"); status = -1; goto leave; } /* 5. send resource ready event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_RESRDY, TRUE); if (status < 0) { printf("App_create: Failed to send event\n"); goto leave; } /* 6. wait for remote resource ready event */ do { event = App_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; printf("App_create: Failed waiting for event\n"); goto leave; } } while (event != App_CMD_RESRDY); /* 7. open remote resources */ /* open the video message queue */ status = MessageQ_open(App_VideoMsgQueName, &Module.videoQue); if (status < 0) { printf("App_create: Failed opening MessageQ\n"); goto leave; } /* 8. send application ready event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_READY, TRUE); if (status < 0) { printf("App_create: Failed to send event\n"); goto leave; } /* 9. wait for remote server ready event */ do { event = App_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; printf("App_create: Failed waiting for event\n"); goto leave; } } while (event != App_CMD_READY); printf("App_create: Host is ready\n"); leave: printf("<-- App_create:\n"); return(status); }
/* * ======== Server_setup ======== * * 1. create semaphore object * 2. register notify callback * 3. wait until remote core has also registered notify callback * 4. create local & shared resources * 5. send resource ready event * 6. wait for remote resource ready event * 7. open remote resources * 8. handshake the ready event */ Int Server_setup(Void) { Int status; UInt32 event; Semaphore_Params semParams; RcmServer_Params rcmServerP; Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_setup:"); /* * 1. create semaphore object */ Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_COUNTING; Semaphore_construct(&Module.semS, 0, &semParams); Module.semH = Semaphore_handle(&Module.semS); /* * 2. register notify callback */ status = Notify_registerEventSingle(Module.hostProcId, Module.lineId, Module.eventId, Server_notifyCB, (UArg)&Module); if (status < 0) { goto leave; } /* * 3. wait until remote core has also registered notify callback */ do { status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_NOP, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Task_sleep(200); /* ticks */ } } while (status == Notify_E_EVTNOTREGISTERED); if (status < 0) { goto leave; } /* * 4. create local & shared resources (to be opened by remote processor) */ /* * 5. send resource ready event */ status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_RESRDY, TRUE); if (status < 0) { goto leave; } /* * 6. wait for remote resource ready event */ do { event = Server_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_RESRDY); /* * 7. open remote resources */ /* open the rcm heap */ status = HeapBufMP_open(Global_RcmClientHeapName, &Module.heapH); if (status < 0) { Log_error1("Server_setup: HeapBufMP_open() returned error %d", (IArg)status); goto leave; } /* register the rcm heap with MessageQ */ status = MessageQ_registerHeap((Ptr)(Module.heapH), Global_RcmClientHeapId); if (status < 0) { Log_error1("Server_setup: MessageQ_restierHeap() returned error %d", (IArg)status); goto leave; } /* initialize RcmServer create params */ RcmServer_Params_init(&rcmServerP); rcmServerP.fxns.length = Server_fxnTab.length; rcmServerP.fxns.elem = Server_fxnTab.elem; /* create the RcmServer instance */ status = RcmServer_create(Global_RcmServerName, &rcmServerP, &Module.rcmServerH); if (status < 0) { Log_error1("Server_setup: RcmServer_create() returned error %d", (IArg)status); goto leave; } /* start the server */ RcmServer_start(Module.rcmServerH); /* * 8. handshake the ready event */ status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_READY, TRUE); if (status < 0) { goto leave; } do { event = Server_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_READY); leave: Log_print1(Diags_EXIT, "<-- Server_setup: %d", (IArg)status); return(status); }
void slave_main(void) { process_message_t * p_msg = 0; MessageQ_Handle h_receive_queue = 0; MessageQ_QueueId reply_queue_id = 0; HeapBufMP_Handle heapHandle; Int status; char receive_queue_name[16]; GET_SLAVE_QUEUE_NAME(receive_queue_name, DNUM); /* Open the heap created by the other processor. Loop until opened. */ do { status = HeapBufMP_open(IMAGE_PROCESSING_HEAP_NAME, &heapHandle); if (status < 0) { Task_sleep(1); } } while (status < 0); /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)heapHandle, IMAGE_PROCESSING_HEAPID); /* Create the local message queue */ h_receive_queue = MessageQ_create(receive_queue_name, NULL); if (h_receive_queue == NULL) { logout("MessageQ_create failed\n" ); goto close_n_exit; } for (;;) { if (MessageQ_get(h_receive_queue, (MessageQ_Msg *)&p_msg, MessageQ_FOREVER) < 0) { logout("%s: This should not happen since timeout is forever\n", receive_queue_name); goto close_n_exit; } reply_queue_id = MessageQ_getReplyQueue(p_msg); if (reply_queue_id == MessageQ_INVALIDMESSAGEQ) { logout("receive_queue_name: Ignoring the message as reply queue is not set.\n", receive_queue_name); continue; } //Execute calculation #ifdef _TRACE_MC_ logout("[core_%u] Execute process (processing_type=%u)\n", p_msg->core_id, p_msg->info.processing_type); //trace #endif switch(p_msg->info.processing_type) { case pt_ssd: //Call calculation code exec_ssd(p_msg); break; case pt_ssdJacHess: //Call calculation code exec_ssdJacHess(p_msg); break; case pt_cacheinval: CacheInvalTotalMemory(p_msg); break; case pt_shrink: //Call image shrink code exec_shrinkImage(p_msg); break; default: logout("Invalid IPC processing type: %u", p_msg->info.processing_type); } /* send the message to the remote processor */ #ifdef _TRACE_MC_ logout("[core_%u] Putting slave response to the MessageQ, then going idle again ...\n", p_msg->core_id); #endif if (MessageQ_put(reply_queue_id, (MessageQ_Msg)p_msg) < 0) { logout("%s: MessageQ_put had a failure error\n", receive_queue_name); } } close_n_exit: if(h_receive_queue) MessageQ_delete(&h_receive_queue); }
/* * ======== procCreate ======== */ static Bool procCreate(Processor_Handle proc) { Int status = 0; Bool retVal; ProcMgr_AttachParams attachParams; ProcMgr_StartParams startParams; ProcMgr_State state; ProcMgr_AddrInfo CMEMAddrInfo; HeapBufMP_Params heapP; CMEM_BlockAttrs cmemBlockAttrs; Int blockNum; Int nCMEMBlocks; Bool createAndRegisterHeap; Int16 heapId; UInt16 regionId; UInt32 numMsgs; UInt32 msgSize; Char heapName[32]; Log_print1(Diags_ENTRY, "[+E] Processor_create_d> Enter(proc=0x%x)", (IArg)proc); /* Create and initialize the PROC object */ Log_print1(Diags_USER2, "[+2] Processor_create_d> " "Retrieving CPU ID for '%s'...", (IArg)(proc->attrs.cpuId)); proc->cpuId = Processor_getCoreId(proc->attrs.cpuId); if (proc->cpuId < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "Processor_getCoreId() failed: %d", proc->cpuId); goto fail; } /* Open DSP ProcMgr */ Log_print2(Diags_USER2, "[+2] Processor_create_d> " "Opening %s ProcMgr for cpuId %d...", (IArg)proc->attrs.cpuId, proc->cpuId); status = ProcMgr_open(&proc->procMgrH, proc->cpuId); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_open() failed: %d", (IArg)status); goto fail; } /* Attach the DSP */ Log_print1(Diags_USER2, "[+2] Processor_create_d> " "Attaching to %s...", (IArg)proc->attrs.cpuId); if (proc->useExtLoader == FALSE) { /* We load the slave */ ProcMgr_getAttachParams(NULL, &attachParams); status = ProcMgr_attach(proc->procMgrH, &attachParams); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_attach() failed: %d", (IArg)status); goto fail; } /* Map slave memory */ if (!mapByFile(proc->procMgrH, proc->memMapName, proc->cpuId, TRUE)) { Log_print0(Diags_USER6, "Processor_create_d> mapByFile() failed!"); } /* Load the executable on the DSP */ Log_print3(Diags_USER2, "[+2] Processor_create_d> " "Loading %s on %s (%d args)...", (IArg)(proc->imageName), (IArg)(proc->attrs.cpuId), (IArg)(proc->attrs.argc)); status = ProcMgr_load(proc->procMgrH, proc->imageName, proc->attrs.argc, proc->attrs.argv, NULL, &proc->fileId); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_load() failed: %d", status); goto fail; } /* temporary: to be done by SysLink in the future */ Log_print0(Diags_USER1, "[+2] Processor_create_d> " "calling Ipc_control(LOADCALLBACK)..."); status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_LOADCALLBACK, NULL); Log_print1(Diags_USER1, "[+2] Processor_create_d> " "Ipc_control(LOADCALLBACK) status: %d", (IArg)status); /* Start execution on DSP */ Log_print1(Diags_USER2, "[+2] Processor_create_d> Starting %s ...", (IArg)proc->attrs.cpuId); ProcMgr_getStartParams(proc->procMgrH, &startParams); status = ProcMgr_start(proc->procMgrH, &startParams); if (status < 0) { Log_print1(Diags_USER7, "Processor_create_d> " "ProcMgr_start() failed: %d", status); goto fail; } } // if (proc->useExtLoader == FALSE) else { /* Check the state of the processor to make sure it's really running */ state = ProcMgr_getState(proc->procMgrH); if (state != ProcMgr_State_Running) { Log_print1(Diags_USER7, "Processor_create_d> Invalid processor " "state [%d].", state); goto fail; } Log_print0(Diags_USER1, "[+2] Processor_create_d> " "calling Ipc_control(LOADCALLBACK)..."); status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_LOADCALLBACK, NULL); proc->loadCallBackStatus = status; Log_print1(Diags_USER1, "[+2] Processor_create_d> " "Ipc_control(LOADCALLBACK) status: %d", (IArg)status); if (status < 0) { Log_print1(Diags_USER7, "Processor_create_d> " "Ipc_control(LOADCALLBACK) failed: %d", status); goto fail; } } status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_STARTCALLBACK, NULL); proc->startCallBackStatus = status; Log_print1(Diags_USER1, "[+2] Processor_create_d> " "Ipc_control(STARTCALLBACK) status: %d", (IArg)status); if (status < 0) { Log_print1(Diags_USER7, "Processor_create_d> " "Ipc_control(STARTCALLBACK) failed: %d", status); goto fail; } /* get user-specified heapId */ heapId = perCoreHeapId(proc->cpuId); createAndRegisterHeap = FALSE; if (heapId == Processor_INVALID) { /* runtime validation of user configuration */ if (perCoreUserCreatedHeapFlag(proc->cpuId) == TRUE || perCoreNumMsgs(proc->cpuId) != Processor_INVALID || perCoreMsgSize(proc->cpuId) != Processor_INVALID || perCoreSharedRegionId(proc->cpuId) != Processor_INVALID) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "Invalid heap configuration for core %d: " "attempting to set other Processor_CommDesc " "elements while Processor_CommDesc.heapId is " "undefined", proc->cpuId); goto fail; } /* will return default heapId since user didn't specify */ heapId = Processor_getHeapId(proc->cpuId); if (defaultHeapRefCount++ == 0) { createAndRegisterHeap = TRUE; /* tell code below to record heapH in defaultHeapH */ defaultHeapH = (HeapBufMP_Handle)-1; } } else { if (perCoreUserCreatedHeapFlag(proc->cpuId) == FALSE) { createAndRegisterHeap = TRUE; } } if (createAndRegisterHeap) { /* create a heap for message queue usage */ /* get either user-config'ed or module default */ numMsgs = Processor_getNumMsgs(proc->cpuId); msgSize = Processor_getMsgSize(proc->cpuId); regionId = Processor_getSharedRegionId(proc->cpuId); HeapBufMP_Params_init(&heapP); heapP.numBlocks = numMsgs; heapP.blockSize = msgSize; heapP.sharedAddr = NULL; heapP.regionId = regionId; if (defaultHeapH == (HeapBufMP_Handle)-1) { sprintf(heapName, "CE-default"); } else { sprintf(heapName, "CE<->Svr%d", proc->cpuId); } heapP.name = heapName; Log_print2(Diags_USER1, "[+2] Processor_create_d> " "calling HeapBufMP_create(): nblocks %d, blocksize 0x%x", heapP.numBlocks, heapP.blockSize); proc->heapH = HeapBufMP_create(&heapP); if (proc->heapH == NULL) { Log_print0(Diags_USER7, "[+7] Processor_create_d> " "HeapBufMP_create failed"); goto fail; } if (defaultHeapH == (HeapBufMP_Handle)-1) { /* we've just created the module default heap singleton */ defaultHeapH = proc->heapH; } /* register this heap with MessageQ */ Log_print2(Diags_USER1, "[+2] Processor_create_d> " "MessageQ_registerHeap(heapH: 0x%x, heapId: %d)", (IArg)(proc->heapH), (IArg)heapId); if (MessageQ_registerHeap((Ptr)(proc->heapH), heapId) != MessageQ_S_SUCCESS) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "MessageQ_registerHeap() failed for heapId %d", heapId); goto fail; } } else { /* * createAndRegisterHeap == FASLE * If using the default heap, need to set proc->heapH for use by * procDelete(). */ if (heapId == Processor_defaultHeapId) { proc->heapH = defaultHeapH; } } proc->heapId = heapId; blockNum = 0; nCMEMBlocks = 0; status = CMEM_getNumBlocks(&nCMEMBlocks); if (status != 0) { Log_print1(Diags_USER2, "[+2] Processor_create_d> " "CMEM_getNumBlocks() failed, not registering: %d", status); } while (blockNum < nCMEMBlocks) { status = CMEM_getBlockAttrs(blockNum, &cmemBlockAttrs); if (status != 0) { Log_print2(Diags_USER7, "[+7] Processor_create_d> " "CMEM_getBlockAttrs(%d) failed: %d", blockNum, status); goto fail; } CMEMAddrInfo.addr[ProcMgr_AddrType_MasterPhys] = cmemBlockAttrs.phys_base; CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt] = cmemBlockAttrs.phys_base; CMEMAddrInfo.size = cmemBlockAttrs.size; CMEMAddrInfo.isCached = FALSE; Log_print3(Diags_USER1, "[+1] Processor_create_d> CMEM block " "#%d found, doing ProcMgr_map(0x%x, 0x%x)...", blockNum, (IArg)cmemBlockAttrs.phys_base, (IArg)cmemBlockAttrs.size); status = ProcMgr_map(proc->procMgrH, ProcMgr_SLAVEVIRT, &CMEMAddrInfo, ProcMgr_AddrType_MasterPhys); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_map() failed: %d", status); goto fail; } if (CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt] != cmemBlockAttrs.phys_base) { Log_print2(Diags_USER1, "[+2] Processor_create_d> " "mapped CMEM slave virtual address 0x%x doesn't " "match expected value 0x%x", CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt], cmemBlockAttrs.phys_base); } blockNum++; } if (Global_getenv("CE_DSPDEBUG") != NULL) { printf("Codec Engine system message (b/c CE_DSPDEBUG=1) : %s image " "loaded and started, press Enter to continue: ", proc->attrs.cpuId); getchar(); } retVal = TRUE; goto procCreate_return; /* TODO:[4] should try those asyncErrorHandlers that link supports? * (MSGQ_SetErrorHandler) */ fail: Log_print3(Diags_USER7, "[+7] Processor_create_d> " "Loading and starting %s server '%s' FAILED, status=[0x%x]", (IArg)proc->attrs.cpuId, (IArg)proc->imageName, status); procDelete(proc); retVal = FALSE; procCreate_return: Log_print1(Diags_USER2, "[+2] Processor_create_d> return (%d)", (IArg)retVal); return (retVal); }
Int SystemCfg_createLocalResources(Void) { Error_Block eb; SemThread_Params semThreadP; HeapBufMP_Params heapBufMPP; Int count; Char heapName[32]; Int status = 0; struct SystemCfg *stateObj = &SystemCfg_State; static Int heapId = 1; Log_print1(Diags_ENTRY, "--> %s: ()", (IArg)FXNN); Error_init(&eb); /* create sync object used to wait on remote core startup */ SemThread_Params_init(&semThreadP); semThreadP.mode = SemThread_Mode_COUNTING; SemThread_construct(&stateObj->semObj, 0, &semThreadP, &eb); if (Error_check(&eb)) { /* Log_error() */ Log_print3(Diags_USER8, "Error: %s, line %d: %s: SemThread_construct() failed", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN); status = -1; goto leave; } stateObj->semH = SemThread_handle(&stateObj->semObj); /* register notify callback for ready event from remote core */ status = Notify_registerEvent(stateObj->hostProcId, Global_NotifyLineId, Global_HostDspEvtNum, SystemCfg_notifyCB__P, (UArg)stateObj); if (status < 0) { /* Log_error() */ Log_print4(Diags_USER8, "Error: %s, line %d: %s: " "Notify_registerEventSingle() returned error %d", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status); goto leave; } /* create a heap for tiler usage */ Log_print0(Diags_USER2, FXNN": HeapBufMP_create for tiler"); HeapBufMP_Params_init(&heapBufMPP); heapBufMPP.regionId = 0; heapBufMPP.blockSize = 0x200; /* 512 B */ heapBufMPP.numBlocks = 8; /* hack: make a unique heap name */ System_sprintf(heapName, "rcmHeap-%d", heapId); heapBufMPP.name = heapName; stateObj->heapH = HeapBufMP_create(&heapBufMPP); if (stateObj->heapH == NULL) { /* Log_error() */ Log_print3(Diags_USER8, "Error: %s, line %d: %s: HeapBuf_create() failed", (IArg)FXNN, (IArg)__FILE__, (IArg)__LINE__); status = -1; goto leave; } /* register this heap with MessageQ */ Log_print2(Diags_USER2, FXNN": MessageQ_registerHeap: (heapH: 0x%x, heapId: %d)", (IArg)(stateObj->heapH), (IArg)Global_TilerHeapId); MessageQ_registerHeap((Ptr)(stateObj->heapH), Global_TilerHeapId); /* Send create done event to remote core. Need to loop in case * the remote core has not yet registered with notify to receive * this event. */ Log_print0(Diags_USER1, FXNN": send EvtCreateDone to remote core"); count = 0; do { status = Notify_sendEvent(stateObj->hostProcId, Global_NotifyLineId, Global_HostDspEvtNum, Global_EvtCreateDone, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Thread_sleep(500, &eb); /* 0.5 ms */ } } while ((++count < 10) && (status == Notify_E_EVTNOTREGISTERED)); if (status < 0) { /* Log_error() */ Log_print5(Diags_USER8, "Error: %s, line %d: %s: Notify_sendEvent() returned error %d," "giving up after %d tries", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status, (IArg)count); goto leave; } /* wait for create done event from remote core */ Log_print0(Diags_USER1, FXNN": waiting for EvtCreateDone event..."); SemThread_pend(stateObj->semH, SemThread_FOREVER, &eb); if (Error_check(&eb)) { /* Log_error() */ Log_print3(Diags_USER8, "Error: %s, line %d: %s: SemThread_pend() returned with error", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN); status = -1; goto leave; } Log_print0(Diags_USER1, FXNN": ...received EvtCreatDone event"); leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
/* * ======== ipcSetup ======== */ static Int ipcSetup (Char * sysM3ImageName, Char * appM3ImageName) { Ipc_Config config; ProcMgr_StopParams stopParams; ProcMgr_StartParams startParams; UInt32 entryPoint = 0; UInt16 procId; Int status = 0; ProcMgr_AttachParams attachParams; ProcMgr_State state; HeapBufMP_Params heapbufmpParams; Int i; UInt32 srCount; SharedRegion_Entry srEntry; if(appM3ImageName != NULL) appM3Client = TRUE; else appM3Client = FALSE; Ipc_getConfig (&config); status = Ipc_setup (&config); if (status < 0) { Osal_printf ("Error in Ipc_setup [0x%x]\n", status); goto exit; } /* Get MultiProc IDs by name. */ remoteIdSysM3 = MultiProc_getId (SYSM3_PROC_NAME); Osal_printf ("MultiProc_getId remoteId: [0x%x]\n", remoteIdSysM3); remoteIdAppM3 = MultiProc_getId (APPM3_PROC_NAME); Osal_printf ("MultiProc_getId remoteId: [0x%x]\n", remoteIdAppM3); procId = remoteIdSysM3; Osal_printf ("MultiProc_getId procId: [0x%x]\n", procId); /* Temporary fix to account for a timing issue during recovery. */ usleep(FAULT_RECOVERY_DELAY); printf("RCM procId= %d\n", procId); /* Open a handle to the ProcMgr instance. */ status = ProcMgr_open (&procMgrHandleSysM3, procId); if (status < 0) { Osal_printf ("Error in ProcMgr_open [0x%x]\n", status); goto exit_ipc_destroy; } else { Osal_printf ("ProcMgr_open Status [0x%x]\n", status); ProcMgr_getAttachParams (NULL, &attachParams); /* Default params will be used if NULL is passed. */ status = ProcMgr_attach (procMgrHandleSysM3, &attachParams); if (status < 0) { Osal_printf ("ProcMgr_attach failed [0x%x]\n", status); } else { Osal_printf ("ProcMgr_attach status: [0x%x]\n", status); state = ProcMgr_getState (procMgrHandleSysM3); Osal_printf ("After attach: ProcMgr_getState\n" " state [0x%x]\n", status); } } if (status >= 0 && appM3Client) { procId = remoteIdAppM3; Osal_printf ("MultiProc_getId procId: [0x%x]\n", procId); /* Open a handle to the ProcMgr instance. */ status = ProcMgr_open (&procMgrHandleAppM3, procId); if (status < 0) { Osal_printf ("Error in ProcMgr_open [0x%x]\n", status); goto exit_ipc_destroy; } else { Osal_printf ("ProcMgr_open Status [0x%x]\n", status); ProcMgr_getAttachParams (NULL, &attachParams); /* Default params will be used if NULL is passed. */ status = ProcMgr_attach (procMgrHandleAppM3, &attachParams); if (status < 0) { Osal_printf ("ProcMgr_attach failed [0x%x]\n", status); } else { Osal_printf ("ProcMgr_attach status: [0x%x]\n", status); state = ProcMgr_getState (procMgrHandleAppM3); Osal_printf ("After attach: ProcMgr_getState\n" " state [0x%x]\n", status); } } } #if defined(SYSLINK_USE_LOADER) Osal_printf ("SysM3 Load: loading the SysM3 image %s\n", sysM3ImageName); status = ProcMgr_load (procMgrHandleSysM3, sysM3ImageName, 2, &sysM3ImageName, &entryPoint, &fileIdSysM3, remoteIdSysM3); if(status < 0) { Osal_printf ("Error in ProcMgr_load, status [0x%x]\n", status); goto exit_procmgr_close_sysm3; } #endif startParams.proc_id = remoteIdSysM3; Osal_printf ("Starting ProcMgr for procID = %d\n", startParams.proc_id); status = ProcMgr_start(procMgrHandleSysM3, entryPoint, &startParams); if(status < 0) { Osal_printf ("Error in ProcMgr_start, status [0x%x]\n", status); goto exit_procmgr_close_sysm3; } if(appM3Client) { #if defined(SYSLINK_USE_LOADER) Osal_printf ("AppM3 Load: loading the AppM3 image %s\n", appM3ImageName); status = ProcMgr_load (procMgrHandleAppM3, appM3ImageName, 2, &appM3ImageName, &entryPoint, &fileIdAppM3, remoteIdAppM3); if(status < 0) { Osal_printf ("Error in ProcMgr_load, status [0x%x]\n", status); goto exit_procmgr_stop_sysm3; } #endif startParams.proc_id = remoteIdAppM3; Osal_printf ("Starting ProcMgr for procID = %d\n", startParams.proc_id); status = ProcMgr_start(procMgrHandleAppM3, entryPoint, &startParams); if(status < 0) { Osal_printf ("Error in ProcMgr_start, status [0x%x]\n", status); goto exit_procmgr_stop_sysm3; } } Osal_printf ("SysM3: Creating Ducati DMM pool of size 0x%x\n", DUCATI_DMM_POOL_0_SIZE); status = ProcMgr_createDMMPool (DUCATI_DMM_POOL_0_ID, DUCATI_DMM_POOL_0_START, DUCATI_DMM_POOL_0_SIZE, remoteIdSysM3); if(status < 0) { Osal_printf ("Error in ProcMgr_createDMMPool, status [0x%x]\n", status); goto exit_procmgr_stop_sysm3; } srCount = SharedRegion_getNumRegions(); Osal_printf ("SharedRegion_getNumRegions = %d\n", srCount); for (i = 0; i < srCount; i++) { status = SharedRegion_getEntry (i, &srEntry); Osal_printf ("SharedRegion_entry #%d: base = 0x%x len = 0x%x " "ownerProcId = %d isValid = %d cacheEnable = %d " "cacheLineSize = 0x%x createHeap = %d name = %s\n", i, srEntry.base, srEntry.len, srEntry.ownerProcId, (Int)srEntry.isValid, (Int)srEntry.cacheEnable, srEntry.cacheLineSize, (Int)srEntry.createHeap, srEntry.name); } /* Create the heap to be used by RCM and register it with MessageQ */ /* TODO: Do this dynamically by reading from the IPC config from the * baseimage using Ipc_readConfig() */ if (status >= 0) { HeapBufMP_Params_init (&heapbufmpParams); heapbufmpParams.sharedAddr = NULL; heapbufmpParams.align = RCM_MSGQ_TILER_HEAP_ALIGN; heapbufmpParams.numBlocks = RCM_MSGQ_TILER_HEAP_BLOCKS; heapbufmpParams.blockSize = RCM_MSGQ_TILER_MSGSIZE; heapSize = HeapBufMP_sharedMemReq (&heapbufmpParams); Osal_printf ("heapSize = 0x%x\n", heapSize); srHeap = SharedRegion_getHeap (RCM_MSGQ_HEAP_SR); if (srHeap == NULL) { status = MEMORYOS_E_FAIL; Osal_printf ("SharedRegion_getHeap failed for srHeap:" " [0x%x]\n", srHeap); goto exit_procmgr_stop_sysm3; } else { Osal_printf ("Before Memory_alloc = 0x%x\n", srHeap); heapBufPtr = Memory_alloc (srHeap, heapSize, 0); if (heapBufPtr == NULL) { status = MEMORYOS_E_MEMORY; Osal_printf ("Memory_alloc failed for ptr: [0x%x]\n", heapBufPtr); goto exit_procmgr_stop_sysm3; } else { heapbufmpParams.name = RCM_MSGQ_TILER_HEAPNAME; heapbufmpParams.sharedAddr = heapBufPtr; Osal_printf ("Before HeapBufMP_Create: [0x%x]\n", heapBufPtr); heapHandle = HeapBufMP_create (&heapbufmpParams); if (heapHandle == NULL) { status = HeapBufMP_E_FAIL; Osal_printf ("HeapBufMP_create failed for Handle:" "[0x%x]\n", heapHandle); goto exit_procmgr_stop_sysm3; } else { /* Register this heap with MessageQ */ status = MessageQ_registerHeap (heapHandle, RCM_MSGQ_TILER_HEAPID); if (status < 0) { Osal_printf ("MessageQ_registerHeap failed!\n"); goto exit_procmgr_stop_sysm3; } } } } } if (status >= 0) { HeapBufMP_Params_init (&heapbufmpParams); heapbufmpParams.sharedAddr = NULL; heapbufmpParams.align = RCM_MSGQ_DOMX_HEAP_ALIGN; heapbufmpParams.numBlocks = RCM_MSGQ_DOMX_HEAP_BLOCKS; heapbufmpParams.blockSize = RCM_MSGQ_DOMX_MSGSIZE; heapSize1 = HeapBufMP_sharedMemReq (&heapbufmpParams); Osal_printf ("heapSize1 = 0x%x\n", heapSize1); heapBufPtr1 = Memory_alloc (srHeap, heapSize1, 0); if (heapBufPtr1 == NULL) { status = MEMORYOS_E_MEMORY; Osal_printf ("Memory_alloc failed for ptr: [0x%x]\n", heapBufPtr1); goto exit_procmgr_stop_sysm3; } else { heapbufmpParams.name = RCM_MSGQ_DOMX_HEAPNAME; heapbufmpParams.sharedAddr = heapBufPtr1; Osal_printf ("Before HeapBufMP_Create: [0x%x]\n", heapBufPtr1); heapHandle1 = HeapBufMP_create (&heapbufmpParams); if (heapHandle1 == NULL) { status = HeapBufMP_E_FAIL; Osal_printf ("HeapBufMP_create failed for Handle:" "[0x%x]\n", heapHandle1); goto exit_procmgr_stop_sysm3; } else { /* Register this heap with MessageQ */ status = MessageQ_registerHeap (heapHandle1, RCM_MSGQ_DOMX_HEAPID); if (status < 0) { Osal_printf ("MessageQ_registerHeap failed!\n"); goto exit_procmgr_stop_sysm3; } } } } Osal_printf ("=== SysLink-IPC setup completed successfully!===\n"); return 0; exit_procmgr_stop_sysm3: stopParams.proc_id = remoteIdSysM3; status = ProcMgr_stop (procMgrHandleSysM3, &stopParams); if (status < 0) { Osal_printf ("Error in ProcMgr_stop(%d): status = 0x%x\n", stopParams.proc_id, status); } exit_procmgr_close_sysm3: status = ProcMgr_close (&procMgrHandleSysM3); if (status < 0) { Osal_printf ("Error in ProcMgr_close: status = 0x%x\n", status); } exit_ipc_destroy: status = Ipc_destroy (); if (status < 0) { Osal_printf ("Error in Ipc_destroy: status = 0x%x\n", status); } exit: return (-1); }
/* * ======== 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); }
/* * ======== procCreate ======== */ static Bool procCreate(Processor_Handle proc, String coreName) { Bool retVal; HeapBufMP_Params heapP; Char heapName[32]; /* big enough? */ UInt16 coreId; Int16 heapId = 0; UInt16 regionId; UInt32 numMsgs; UInt32 msgSize; Bool createAndRegisterHeap; Log_print1(Diags_ENTRY, "[+E] Processor_create_d> Enter(proc=0x%x)", (IArg)proc); /* used later */ coreId = Processor_getCoreId(coreName); if (coreId == Processor_INVALIDID) { Log_print1(Diags_USER7, "[+7] Processor_create_d> Invalid core: %s", (IArg)coreName); goto fail; } heapId = perCoreHeapId(coreId); createAndRegisterHeap = FALSE; if (heapId == Processor_INVALID) { /* runtime validation of user configuration */ if (perCoreUserCreatedHeapFlag(coreId) == TRUE || perCoreNumMsgs(coreId) != Processor_INVALID || perCoreMsgSize(coreId) != Processor_INVALID || perCoreSharedRegionId(coreId) != Processor_INVALID) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "Invalid heap configuration for core %d: " "attempting to set other Processor_CommDesc " "elements while Processor_CommDesc.heapId is " "undefined", coreId); goto fail; } /* will return default heapId since user didn't specify */ heapId = Processor_getHeapId(coreId); if (defaultHeapRefCount++ == 0) { createAndRegisterHeap = TRUE; /* tell code below to record hHeap in defaultHeapH */ defaultHeapH = (HeapBufMP_Handle)-1; } } else { if (perCoreUserCreatedHeapFlag(coreId) == FALSE) { createAndRegisterHeap = TRUE; } } if (createAndRegisterHeap) { /* create a heap for message queue usage */ /* get either user-config'ed or module default */ numMsgs = Processor_getNumMsgs(coreId); msgSize = Processor_getMsgSize(coreId); regionId = Processor_getSharedRegionId(coreId); /* create a heap for message queue usage */ HeapBufMP_Params_init(&heapP); heapP.numBlocks = numMsgs; heapP.blockSize = msgSize; heapP.sharedAddr = NULL; heapP.regionId = regionId; if (defaultHeapH == (HeapBufMP_Handle)-1) { sprintf(heapName, "CE-default"); } else { sprintf(heapName, "CE<->Svr%d", coreId); } heapP.name = heapName; Log_print2(Diags_USER1, "[+2] Processor_create_d> " "calling HeapBufMP_create(): nblocks %d, blocksize %d", heapP.numBlocks, heapP.blockSize); proc->hHeap = HeapBufMP_create(&heapP); if (proc->hHeap == NULL) { Log_print0(Diags_USER7, "[+7] Processor_create_d> " "HeapBufMP_create failed"); goto fail; } if (defaultHeapH == (HeapBufMP_Handle)-1) { /* we've just created the module default heap singleton */ defaultHeapH = proc->hHeap; } /* register this heap with MessageQ */ Log_print2(Diags_USER1, "[+2] Processor_create_d> " "MessageQ_registerHeap(hHeap: 0x%x, heapId: %d)", (IArg)(proc->hHeap), (IArg)heapId); if (MessageQ_registerHeap((Ptr)(proc->hHeap), heapId) != MessageQ_S_SUCCESS) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "MessageQ_registerHeap() failed for heapId %d", heapId); goto fail; } } proc->heapId = heapId; retVal = TRUE; goto procCreate_return; fail: Log_print0(Diags_USER7, "[+7] Processor_create_d> " "Initializing DSP server FAILED"); procDelete(proc); retVal = FALSE; procCreate_return: Log_print1(Diags_USER2, "[+2] Processor_create_d> return (%d)", (IArg)retVal); return (retVal); }
/* * ======== 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; Ptr buf; HeapBuf_Handle heapHandle; HeapBuf_Params hbparams; SizeT blockSize; UInt numBlocks; /* Compute the blockSize & numBlocks for the HeapBuf */ numBlocks = 2; blockSize = sizeof(MessageQ_MsgHeader); /* Alloc a buffer from the default heap */ buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL); /* * Create the heap that is used for allocating MessageQ messages. */ HeapBuf_Params_init(&hbparams); hbparams.align = 0; hbparams.numBlocks = numBlocks; hbparams.blockSize = blockSize; hbparams.bufSize = numBlocks * blockSize; hbparams.buf = buf; heapHandle = HeapBuf_create(&hbparams, NULL); if (heapHandle == NULL) { System_abort("HeapBuf_create failed\n" ); } /* Register default system 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(remoteQueueName, &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 remote 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, remoteQueueName); /* 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 remote 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), remoteQueueName); /* 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); }
/* * ======== Hello_start ======== * * 1. create semaphore object * 2. register notify callback * 3. wait until remote core has also registered notify callback * 4. create local & shared resources * 5. send resource ready event * 6. wait for remote resource ready event * 7. open remote resources * 8. handshake the ready event */ Int Hello_start(UInt16 remoteProcId) { Int status; UInt32 event; SemThread_Params semParams; HeapBufMP_Params heapParams; Error_Block eb; Error_init(&eb); Module.remoteProcId = remoteProcId; /* * 1. create semaphore object */ SemThread_Params_init(&semParams); semParams.mode = SemThread_Mode_COUNTING; SemThread_construct(&Module.semS, 0, &semParams, &eb); if (Error_check(&eb)) { status = -15; goto leave; } Module.semH = SemThread_handle(&Module.semS); /* * 2. register notify callback */ status = Notify_registerEventSingle(Module.remoteProcId, Module.lineId, Module.eventId, Hello_notifyCB, (UArg)&Module); if (status < 0) { goto leave; } /* * 3. wait until remote core has also registered notify callback */ do { status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_NOP, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Thread_sleep(1000, &eb); /* microseconds */ } } while (status == Notify_E_EVTNOTREGISTERED); if (status < 0) { goto leave; } /* * 4. create local & shared resources (to be opened by remote processor) */ /* create heap for rcm messages */ HeapBufMP_Params_init(&heapParams); heapParams.name = Global_RcmClientHeapName; heapParams.regionId = 0; heapParams.blockSize = 0x200; /* 512 B */ heapParams.numBlocks = 8; Module.msgHeap = HeapBufMP_create(&heapParams); if (Module.msgHeap == NULL) { Log_error0("Hello_start: HeapBuf_create() failed"); status = -1; goto leave; } /* register heap with MessageQ */ status = MessageQ_registerHeap((Ptr)(Module.msgHeap), Global_RcmClientHeapId); if (status < 0) { goto leave; } /* * 5. send resource ready event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_RESRDY, TRUE); if (status < 0) { goto leave; } /* * 6. wait for remote resource ready event */ do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_RESRDY); /* * 7. open remote resources */ /* * 8. handshake the ready event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_READY, TRUE); if (status < 0) { goto leave; } do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_READY); leave: return(status); }