⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ext_comm.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 3 页
字号:

			#if DEBUG_MSG_LVL >= 3
			mexPrintf("ExtRecvIncomingMsg: checking for pending data\n");
			#endif
	
			/* no telegrams are currently pending... -> check COM */
			error = ExtTargetTelPending(ES, &pending, 0, 0);
			if (error) {
				esSetError(ES, "ExtTagetTelPending() call failed while checking for message telegrams\n");
				goto EXIT_POINT;
			}
			
			#if DEBUG_MSG_LVL >= 3
			mexPrintf("ExtRecvIncomingMsg: pending = %d\n", (uint_T)pending);
			#endif

		}
		else {

			/* previously intercepted telegrams pending -> check if it was a message telegram */
			if(userData->TelType == MSG) {

				/* previously intercepted MSG telegram */
				#if DEBUG_MSG_LVL >= 2
				mexPrintf("ExtRecvIncomingMsg: previously detected MSG\n");
				#endif

				pending = TRUE;

			}
			else {

				/* previously intercepted DAT/USR telegram */
				#if DEBUG_MSG_LVL >= 2
				mexPrintf("ExtRecvIncomingMsg: previously detected DAT/USR telegram\n");
				#endif

				goto EXIT_POINT;

			}

		}


        if (!pending) {
			
			#ifdef MODELSTUCK
			if(ModelIsRunning) {
		
				if(NoDataPending++ > 10000) {

					//mexPrintf("Alarm\n");
					NoDataPending = 0;
					
					if(alarmCounter++ > 3) {

						mexPrintf("Communication stuck\n");
						alarmCounter = 0;

					}

				}

			}
			#endif
						
			goto EXIT_POINT; /* nothing to read */
		
		}
		else {

			/* check if the detected telegram is a message telegram */
			if(userData->TelType != MSG) goto EXIT_POINT;

		}


        /*
         * Process pending message.
         */
        {
            MsgHeader msgHdr;
            
            /* assume that the entire message header can be read in one shot */
            error = ExtGetTargetMsg(ES,sizeof(msgHdr),&nGot,(char_T *)&msgHdr);
            if (error || (nGot != sizeof(msgHdr))) {
				esSetError(ES, "ExtGetTargetMsg() call failed while checking target msg's\n");
                goto EXIT_POINT;
            }

			#if DEBUG_MSG_LVL >= 1
			printf("Message Received type %d size %d\n",msgHdr.type,msgHdr.size);
			#endif
            
            /* Convert the msg hdr to host format. */
            Copy32BitsFromTarget(ES, (uint32_T *)&msgHdr, (char *)&msgHdr, NUM_HDR_ELS);
            if (!esIsErrorClear(ES)) goto EXIT_POINT;
            
            nBytesNeeded = msgHdr.size * esGetHostBytesPerTargetByte(ES);
            assert(nBytesNeeded <= esGetIncomingMsgDataBufSize(ES));
            
            /*
             * We have a message pending.  Set the flag and the type.
             */
            esSetIncomingMsgPending(ES, TRUE);
            esSetIncomingMsg(ES, (ExtModeAction)msgHdr.type);
        }
    }

    
	/* we're done unless this is a message with data... */
	if (nBytesNeeded == 0) goto EXIT_POINT;
    

	/* message with data -> receive data */
    bufPtr = buf + nBytes;

	/* get message data (all in one shot) */
	error = ExtGetTargetMsg(ES, nBytesNeeded, &nGot, bufPtr);
	if(error) {
		esSetError(ES, "recv() call failed while retrieving msg data\n");
		goto EXIT_POINT;
	}

	#if DEBUG_MSG_LVL >= 2
	{
		int i;
		
		if(nBytesNeeded > 0) {
			mexPrintf("\nData Sent ... \n\t");
			for(i=0;i<nBytesNeeded;i++)
				mexPrintf("%d ",esGetCommBuf(ES)[i]);
			mexPrintf("\n");
		}
	}
	#endif

	esSetIncomingMsgPending(ES, TRUE);
        
	nBytesNeeded -= nGot;
	nBytes       += nGot;
	bufPtr       += nGot;            //* unnecessary... re-initialized upon next entry of this function  --  fw-03-05 */

	assert(nBytesNeeded >= 0);


EXIT_POINT:

	esSetIncomingMsgDataNBytesNeeded(ES, nBytesNeeded);
    esSetIncomingMsgDataNBytesInBuf (ES, nBytes      );

	#if DEBUG_MSG_LVL >= 3
	mexPrintf("ExtRecvIncomingMsg: OUT\n");
	mexPrintf("-----------------------\n");
	#endif

} /* end ExtRecvIncomingMsg */



/* Function: ExtRecvIncomingLogData ============================================
 * Abstract:
 *  Check and get upload data for 1 time point from one target tid buffer.  
 *  In order to prevent the Simulink GUI, from "locking up", this function
 *  should not block indefinately.  As such, there is no guarantee that all
 *  of the data corresponding to this time point will be retrieved via one
 *  call to this function.  In the case where only a partial buffer is
 *  available, Simulink will hold onto the partial data buffer (in the 
 *  ES data structure) and pass the partially filled buffer back into this
 *  function on the next call.  
 *
 * NOTES:
 *  o 'nBytes' will be 0 if the buffer is empty.  Otherwise, it contains
 *    the number of bytes that are currently held in the buffer (i.e., the
 *    part of the current time step that has previously arrived).
 *  o 'nBytesNeeded' will be 0 when - and only when - 'data' contains all of
 *    the data for the current time point
 *
 *  o the data that is being received from the target is of the form:
 *    [nbytes data...][nbytes data...][nbytes data...], where nbytes
 *    is the number of bytes:
 *          - including itself
 *          - representing the target interpretation of a byte (not necessarily
 *            8 bits)
 *          - in target data format (e.g., may need to be converted to host
 *            format)
 *    data is:
 *          - one time step of upload data corresponding to a given tid
 *          - in target data format (will be converted by Simulink via calls
 *            to ext_convert.c).
 */
PRIVATE void ExtRecvIncomingLogData(
    ExternalSim    *ES,
    int_T          nrhs,
    const mxArray  *prhs[])
{
    int_T          nGot;
    boolean_T      pending;
    boolean_T      error        = EXT_NO_ERROR;

    char           *buf         = esGetIncomingLogDataBuf(ES);
    int32_T        nBytesNeeded = esGetIncomingLogDataNBytesNeeded(ES);
    int            nBytes       = esGetIncomingLogDataNBytesInBuf(ES);

    UserData	   *userData	= (UserData *)esGetUserData(ES);

    (void)nrhs; /* unused */
    (void)prhs; /* unused */
    
	
	#if DEBUG_MSG_LVL >= 3
	mexPrintf("\n--------------------------\n");
	mexPrintf("ExtRecvIncomingLogData: IN\n");
	#endif

	
	/* check for new data telegrams */
    if (nBytesNeeded == UNKNOWN_BYTES_NEEDED) {
    
		assert(nBytes == 0);


        /*
         * Check for pending upload data.  If none, nothing to do.
         */
		#if DEBUG_MSG_LVL >= 3
		mexPrintf("ExtRecvIncomingLogData: userData->TelType = %d\n", (uint_T)userData->TelType);
		#endif

		if(userData->TelType == 0) {

			/* no telegrams are currently pending... -> check COM */
			error = ExtTargetTelPending(ES, &pending, 0, 0);
			if (error) {
				esSetError(ES, "ExtTagetTelPending() call failed while checking for data telegrams\n");
				goto EXIT_POINT;
			}

		}
		else {

			/* previously intercepted telegrams pending -> check if it was a data telegram */
			if(userData->TelType == MSG) {

				/* previously intercepted MSG telegram */
				#if DEBUG_MSG_LVL >= 2
				mexPrintf("ExtRecvIncomingLogData: previously detected MSG\n");
				#endif

				goto EXIT_POINT;

			}
			else {

				/* previously intercepted DAT/USR telegram */
				#if DEBUG_MSG_LVL >= 2
				mexPrintf("ExtRecvIncomingLogData: previously detected DAT/USR telegram\n");
				#endif

				pending = TRUE;

			}

		}

	
		if (!pending) {
			
			#ifdef ERASE
			/* nothing to read - request data (every 10 idle loops)  --  fw-03-05 */
			if(noRequestDataCounter++ > 10) {
				
				#if DEBUG_MSG_LVL >= 2
				mexPrintf("ExtRecvIncomingLogData: 10th idle transmission loop -> request data transmission.\n");
				#endif

				noRequestDataCounter = 0;
				RequestDataTelegram(ES);

			}
			#endif

			goto EXIT_POINT;

		}
		else {

			/* bypass remainder of this function if a message was detected */
			if(userData->TelType == MSG) goto EXIT_POINT;

		}


		/* DAT or USR have been detected -> both treated as 'data', ExtGetTargetData filters out USR data */

		/*
         * Read the nBytes field.  Assume that the entire integer
	     * is available.
		 */
        error = ExtGetTargetData(ES, sizeof(int32_T), &nGot, buf);
        if (error || (nGot != sizeof(int32_T))) {
			
			/* 'nGot == -1' signifies the receipt of a USR TEL >> no error! (FW-01-03) */
			if(nGot != -1) {
				
				esSetError(ES, "recv() call failed while checking target data\n");

			}
			else {

				/* finished uploading the USR telegram -> return */
				nBytesNeeded = UNKNOWN_BYTES_NEEDED;				/* << possibly to be 0 */
				nBytes = 0;

				/* possibly need to request next data telegram */
				//RequestDataTelegram(ES);

			}
            
			goto EXIT_POINT;

        }

		#if DEBUG_MSG_LVL >= 3
		mexPrintf("\nData received...\n\t");
		mexPrintf("%d %d %d %d \n",buf[0],buf[1],buf[2],buf[3]);
		fflush(stdout);
		#endif

        Copy32BitsFromTarget(ES, &nBytesNeeded, buf, 1);
        if (!esIsErrorClear(ES)) goto EXIT_POINT;
        
		nBytesNeeded *= esGetHostBytesPerTargetByte(ES); 
        assert(nBytesNeeded <= esGetIncomingLogDataBufSize(ES));
        
        
		nBytes        = sizeof(int32_T);		/* this is what we have so far */
        nBytesNeeded -= sizeof(int32_T);		/* this is what we still need... */

	} /*if (nBytesNeeded == UNKNOWN_BYTES_NEEDED) */
	

	/*
	 * Retrieve data (all in one shot)
     */
	error = ExtGetTargetData(ES, nBytesNeeded, &nGot, (char *)(buf + nBytes));
	if (error) {
		esSetError(ES, "recv() call failed while uploading target data\n");
		goto EXIT_POINT;
	}

	nBytesNeeded -= nGot;					/* should be 0 now */
	nBytes       += nGot;					/* should be the required size now */

	assert(nBytesNeeded >= 0);

		
	/* request next upload -- or not */
	if(nBytesNeeded == 0) {

		/* check if EXT_DISCONNECT_CONFIRMED has been received */
		if(buf[0] == 8) {

			#if DEBUG_MSG_LVL >= 2
			mexPrintf("ExtRecvIncomingLogData: Got an 8-%d-message.\n", (int_T)buf[4]);
			#endif

			if(buf[4] == 5) {
				/* received EXT_DISCONNECT_CONFIRMED -> don't request upload */
				userData->ExtDisconnectConfirmed = TRUE;
				
				#if DEBUG_MSG_LVL >= 2
				mexPrintf("ExtRecvIncomingLogData: EXT_DISCONNECT_CONFIRMED -> not sending any further upload requests\n");
				#endif

				//Sleep(2000);
			
			}
			else {
				/* request next data telegram (without acknowledgement) */
				RequestDataTelegram(ES);
			}
		}
		else {
			/* request next data telegram (without acknowledgement) */
			RequestDataTelegram(ES);
		}

	}
	else {

		#if DEBUG_MSG_LVL >= 2
		mexPrintf("ExtRecvIncomingLogData: nBytesNeeded = %d, nGot = %d\n", nBytesNeeded, nGot);
		#endif

		if(nGot == 0) {

			/* timeout occurred during reception -> discard data... */
			#if DEBUG_MSG_LVL >= 1
			mexPrintf("ExtRecvIncomingLogData: data telegram length '0' (discarded data or incoming user telegram)\n");
			mexPrintf("ExtRecvIncomingLogData: Requesting next data telegram (TXactive)\n");
			#endif

			/* enable next target data upload */
			RequestDataTelegram(ES);
			#if DEBUG_MSG_LVL >= 1
			mexPrintf("ExtRecvIncomingLogData: next telegram requested (RequestDataTelegram). Exiting...\n");
			#endif

			/* set data telegram length to zero ('esSetIncomingLogData...') */
			nBytesNeeded = UNKNOWN_BYTES_NEEDED;
			nBytes = 0;

		}
		
	} /* if(nBytesNeeded == 0) */


EXIT_POINT:

    esSetIncomingLogDataNBytesNeeded(ES, nBytesNeeded);
    esSetIncomingLogDataNBytesInBuf (ES, nBytes      );

	#if DEBUG_MSG_LVL >= 3
	mexPrintf("ExtRecvIncomingLogData: OUT\n");
	mexPrintf("---------------------------\n");
	#endif

} /* end ExtRecvIncomingLogData */



/* Function: ExtConnect ========================================================
 * Abstract:
 *  Establish communication with target.
 */
PRIVATE void ExtConnect(
    ExternalSim    *ES,
    int_T          nrhs,
    const mxArray  *prhs[])
{
    int_T          nGot;
    int_T          nSet;
    MsgHeader      msgHdr;
    int16_T        one   = 1;
    boolean_T      error = EXT_NO_ERROR;

	mexLock();

    {
        UserData *userData = ExtUserDataCreate();
        if (userData == NULL) {
            esSetError(ES, "Memory allocation error.");
            goto EXIT_POINT;
        }

        esSetUserData(ES, (void*)userData);
    }

    /*
     * Parse the arguments.
     */
    assert(esIsErrorClear(ES));
    ExtProcessArgs(ES,nrhs,prhs);
    if (!esIsErrorClear(ES)) goto EXIT_POINT;


    assert(esIsErrorClear(ES));
    ExtOpenConnection(ES);
    if (!esIsErrorClear(ES)) goto EXIT_POINT;

    /*
     * Send the EXT_CONNECT msg to the target.  This message consists
     * of the string 'ext-mode'.  The purpose of this header is to serve
     * as a flag to start the handshaking process.
     */
    #if DEBUG_MSG_LVL >= 3
	mexPrintf("ExtConnect: Sending 'ext-mode'\n");
	#endif
	
	(void)memcpy((void *)&msgHdr,"ext-mode",8);
    error = ExtSetTargetMsg(ES,sizeof(msgHdr),(char *)&msgHdr,&nSet);
    if (error || (nSet != sizeof(msgHdr))) {
        esSetError(ES, "ExtSetTargetMsg() call failed on EXT_CONNECT.\n"
	               "Ensure target is still running\n");
        goto EXIT_POINT;
    }

    /*
     * Get the first of two EXT_CONNECT_RESPONSE messages.  See the 
     * ext_conv.c/ProcessConnectResponse1() function for a description of
     * the message.
     *
     * NOTE: Until both EXT_CONNECT_RESPONSE messages are read, messages
     *       received from the target consists solely of unsigned 32 bit
     *       integers.
     */
    #if DEBUG_MSG_LVL >= 3
	mexPrintf("ExtConnect: Receiving EXT_CONNECT_RESPONSE (1/2)\n");
	#endif
    
	error = ExtGetTargetMsg(ES,sizeof(msgHdr),&nGot,(char_T *)&msgHdr);
    if (error || (nGot != sizeof(msgHdr))) {

        esSetError(ES, "ExtGetTargetMsg() call failed on 1st EXT_CONNECT_RESPONSE 1.\n");
        goto EXIT_POINT;

    }
   
	#if DEBUG_MSG_LVL >= 4
	{
		int_T	i;

		for(i=0; i<sizeof(msgHdr); i++)
			mexPrintf("ExtConnect: ExtGetTargetMsg returned [%d/%d]) %d\n", i+1, sizeof(msgHdr), (uint_T)*((char_T *)&msgHdr + i));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -