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

📄 ext_serial_utils.c

📁 RT9S12 target document
💻 C
📖 第 1 页 / 共 3 页
字号:
   boolean_T   error=EXT_NO_ERROR;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="ExtGetPktBlocking";
   #endif

   PRINT_DEBUG_MSG_LVL3("IN");
   PRINT_DEBUG_MSG_NL3;

   #ifndef MATLAB_MEX_FILE
   #if DEBUG_MSG_LVL > 0
   /* nBytesAvailable = MAX_SERIAL_PKT_SIZE   ->   display up to MAX_SERIAL_PKT_SIZE bytes... */
   ExtSerialPortPeekRB(MAX_SERIAL_PKT_SIZE);
   #endif
   #endif /* MATLAB_MEX_FILE */
   
   /* Block until a packet is available from the comm line. */
   error=GetExtSerialPacket(InBuffer, portDev);

   
   PRINT_DEBUG_MSG_LVL1_Raw(">");
   PRINT_DEBUG_MSG_NL1;
        
   #if DEBUG_MSG_LVL > 0
   DisplayActualReceivedPacket(InBuffer);
   #endif
         

   if(error!=EXT_NO_ERROR) {

      /* never happens, errors caught above  --  fw-07-07 */
      abort_LED(23);    // just in case

      PRINT_DEBUG_MSG_LVL3("Error in call to GetExtSerialPacket\n\r");
      goto EXIT_POINT;

   }

   PRINT_DEBUG_MSG_LVL3("Received valid packet. Type: ");
   PRINT_DEBUG_MSG_LVL3_UDec((uint16_T)(InBuffer->PacketType));
   PRINT_DEBUG_MSG_NL3;
   PRINT_DEBUG_MSG_LVL3(debugTelTypeStrings[(uint16_T)InBuffer->PacketType]);
   PRINT_DEBUG_MSG_NL3;
   #ifdef MATLAB_MEX_FILE
   #if DEBUG_MSG_LVL > 0
   if(InBuffer->PacketType==EXTMODE_PACKET&&InBuffer->BufferSize>=4) {

      uint8_T  myAction=InBuffer->Buffer[3];     // stored in reverse order, e.g.  0  0  0  27

      PRINT_DEBUG_MSG_LVL3("Payload indicates data action (if it is an action at all...): 0x");
      PRINT_DEBUG_MSG_LVL3_UHex(myAction);
      if(myAction<numActionStrings) {

         PRINT_DEBUG_MSG_LVL3_Raw(" (");
         PRINT_DEBUG_MSG_LVL3_Raw(debugActionStrings[myAction]);
         PRINT_DEBUG_MSG_LVL3_Raw(")");
         if(InBuffer->PacketType==EXTMODE_PACKET&&InBuffer->BufferSize>=8) {

            uint8_T  mySize=InBuffer->Buffer[7];    // stored in reverse order, e.g.  0  0  0  size(<=255)

            PRINT_DEBUG_MSG_LVL3_Raw(", data size: 0x");
            PRINT_DEBUG_MSG_LVL3_UHex(mySize);
            PRINT_DEBUG_MSG_LVL3_Raw(" (");
            PRINT_DEBUG_MSG_LVL3_UDec(mySize);
            PRINT_DEBUG_MSG_LVL3_Raw(" bytes)");

         }

      }
      PRINT_DEBUG_MSG_NL3;

   }
   #endif /* DEBUG_MSG_LVL */
   #endif /* MATLAB_MEX_FILE */

   /* Process ACK packets, don't pass on to application. */
   if(InBuffer->PacketType==ACK_PACKET) {

      PRINT_DEBUG_MSG_LVL3("Received ACK_PACKET -> waitForAck = FALSE;");
      PRINT_DEBUG_MSG_NL3;

      waitForAck = FALSE;

      #ifdef HOSTALIVECHECK
      HostIsAlive = TRUE;     /* automatic target data buffer control  --  fw-07-07 */
      #endif
      
      goto EXIT_POINT;

   }

   PRINT_DEBUG_MSG_LVL3("Storing received EXTMODE_PACKET in FIFO buffer");
   PRINT_DEBUG_MSG_NL3;
   SavePkt(InBuffer->Buffer, (int_T)(InBuffer->size));

   if(!isFIFOFreeEmpty()) {

      int   bytesWritten;

      PRINT_DEBUG_MSG_LVL3("Sending ACK_PACKET to acknowledge the receipt of the received EXTMODE_PACKET");
      PRINT_DEBUG_MSG_NL3;

      error=ExtSetPkt(portDev, NULL, 0, &bytesWritten, ACK_PACKET);
      if(error!=EXT_NO_ERROR) {

         PRINT_DEBUG_MSG_LVL3("Error in call to ExtSetPkt (while sending ACK_PACKET)");
         PRINT_DEBUG_MSG_NL3;

         /* never happens, errors caught above  --  fw-07-07 */
         abort_LED(24);    // just in case

         goto EXIT_POINT;

      }

   }

EXIT_POINT:

   PRINT_DEBUG_MSG_LVL3("OUT, error status: ");
   PRINT_DEBUG_MSG_LVL3_UDec(error);
   PRINT_DEBUG_MSG_NL3;

   return error;

} /* end ExtGetPktBlocking */


/* Function: ExtSetPkt =========================================================
* Abstract:
*  Sets (sends) the specified number of bytes on the comm line.  As long as an
*  error does not occur, this function is guaranteed to set the requested
*  number of bytes.  The number of bytes set is returned via the 'nBytesSet'
*  parameter.  If a previously sent packet has not yet received an ACK, then we
*  block for the next packet which must be an ACK.
*
*  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
*/
PRIVATE boolean_T ExtSetPkt(ExtSerialPort *portDev, char *pktData, int pktSize, int *bytesWritten, PacketTypeEnum pktType) {

   int         bytesToSend;
   int         deadlockCntr;
   boolean_T   error=EXT_NO_ERROR;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="ExtSetPkt";
   #endif

   bytesToSend=(pktSize>MAX_SERIAL_PKT_SIZE)?MAX_SERIAL_PKT_SIZE:pktSize;
   *bytesWritten=bytesToSend;

   PRINT_DEBUG_MSG_LVL3("IN");
   PRINT_DEBUG_MSG_NL3;

   #if COMMSTATE_ON_PTT == 1
   /* display current state of 'waitForAck' on PTT.1 */
   if(waitForAck) {

      PTT|=0x01;

   }
   else {

      PTT&=~0x01;

   }
   #endif

   /* debug: display current 'waitForAck' state on SCI0 */
   #if DEBUG_MSG_LVL > 0
   if(pktType != ACK_PACKET) {
     if(waitForAck) {
        PRINT_DEBUG_MSG_LVL3("waitForAck = TRUE  -> need to wait for ACK_PACKET");
        PRINT_DEBUG_MSG_NL3;
     }
     /* else message is printed below... (otherwise the 'clear to send' appears twice... */
   } else {
     PRINT_DEBUG_MSG_LVL3("Sending (regular) ACK_PACKET... (always possible, regardless the state of the 'waitForAck' flag)");
     PRINT_DEBUG_MSG_NL3;
   }
   #endif

   /*
      * Wait for an ACK packet if needed. Every packet sent must be ACKed before
      * another can be sent (the only exceptions are ACK packets which are never
      * ACKed).
      */
   deadlockCntr=0;
   while(waitForAck && (pktType!=ACK_PACKET)) {

      int32_T numPending = 0;

      error=ExtSerialPortDataPending(portDev, &numPending);
      if(error!=EXT_NO_ERROR) {

         /* never happens, errors caught above  --  fw-07-07 */
         abort_LED(25);    // just in case

         goto EXIT_POINT;

      }

      /* NOTE: check for '>0' because the host sided version of 'ExtSerialPortDataPending'
       *       returns the actual number of bytes on the target instead of the number
       *       packets (on the target numPending is returned '1' if there's a full packet 
       *       in the ring buffer, '0' if not and '-1' in case of a target comms timeout) 
       * 
       * fw-07-07
       */
      if(numPending > 0) {

         PRINT_DEBUG_MSG_LVL1_Raw("<3");

         PRINT_DEBUG_MSG_LVL3("Making blocking call to fetch the data from the comms line...");
         PRINT_DEBUG_MSG_NL3;

         error=ExtGetPktBlocking(portDev);
         if(error!=EXT_NO_ERROR) {

            /* never happens, errors caught above  --  fw-07-07 */
            abort_LED(26);    // just in case

            goto EXIT_POINT;

         }

      }
      
      /* on the target only... */
      #ifndef MATLAB_MEX_FILE
      else {
        
        if(numPending == -1) {
            
            /* target timeout has been detected... */
            /* incomplete ACK_PACKET (currently only an assumption! -> perform check) packet has been removed */
            PRINT_DEBUG_MSG_LVL1("Target timeout, setting waitForAck = FALSE\n\r");
            waitForAck = false;
            break;                /* exit from the while loop */
        
        }
        
      }
      #endif /* MATLAB_MEX_FILE */

      /*
         * If we are in this loop, it means we are trying to send a pkt but
         * have not received an ACK from the other side.  If we don't get an
         * ACK after some amount of time, we may be in a deadlock condition
         * where both sides are waiting for an ACK.  In this case, allocating
         * some more free packets will break the deadlock condition.
         */
      if((++deadlockCntr>=200) && isFIFOFreeEmpty()) {

         int   temp;

         PRINT_DEBUG_MSG_LVL3("ACK deadlock situation detected (host & target might be waiting for ACK)\n\r");

         deadlockCntr=0;
         error=AddToFIFOFree();
         if(error!=EXT_NO_ERROR) {

            abort_LED(27);

            goto EXIT_POINT;

         }

         PRINT_DEBUG_MSG_LVL3("Sending ACK_PACKET to target to (hopefully) unblock communication\n\r");
         error=ExtSetPkt(portDev, NULL, 0, &temp, ACK_PACKET);
         if(error!=EXT_NO_ERROR) {

            /* never happens, errors caught above  --  fw-07-07 */
            abort_LED(28);    // just in case

            goto EXIT_POINT;

         }

      } /* if(++deadlockCntr...) */


      /*
       * THE FOLLOWING 'MESS' SEEMED NECESSARY WHEN THE TARGET GOT STUCK ON READING FROM THE 
       * SERIAL LINE - THIS TURNED OUT TO BE BECAUSE OF THE WAY FUNCTION 'ExtSerialPortDataPending'
       * (EXT_SERIAL_9S12_PORT.C) USED TO WORK... THE MODIFIED 'ExtSerialPortDataPending' NOW ONLY 
       * INDICATES PENDING DATA WHEN AT LEAST ONE "FULL DATA PACKET" HAS BEEN RECEIVED. PREVIOUSLY,
       * THE FUNCTION SIMPLY RETURNED THE NUMBER OF "BYTES"... 
       * 
       * WITH THE NEW 'ExtSerialPortDataPending' THE ARTIFICIAL BREAKING OF THE DEADLOCK ON THE 
       * TARGET HAS BECOME UNNECESSARY.
       *  
       * fw-07-07
       */
      
      /* do not define DEADLOCK_EMERGENCY_TARGET !!!  --  fw-07-07 */
      #ifdef DEADLOCK_EMERGENCY_TARGET
      else {

         #ifdef MATLAB_MEX_FILE
         if(((HostStatus == HOST_STATUS_CONNECTING) || 
             (HostStatus == HOST_STATUS_RUNNING))   && 
             (deadlockCntr > 200)) {
         //if(deadlockCntr > 200) {
         #else
         //if(startModel && deadlockCntr>200) {
         if(deadlockCntr>200) {
         #endif

            int   temp;

            deadlockCntr=0;

            /* FIFO buffer not empty but clearly there is a deadlock... 
               ... forget about it and force host to send an ACK_PACKET   --   fw-07-07 */
		        PRINT_DEBUG_MSG_LVL1("Forcing 'waitForAck = FALSE' (to break local deadlock)");
		        PRINT_DEBUG_MSG_NL1;
            waitForAck=false;

            #ifdef MATLAB_MEX_FILE
		        PRINT_DEBUG_MSG_LVL3("Sending an ACK_PACKET to the target to break the remote deadlock\n");

            //#ifdef ERASE
            error=ExtSetPkt(portDev, NULL, 0, &temp, ACK_PACKET);
            if(error!=EXT_NO_ERROR) {

               /* never happens, errors caught above  --  fw-07-07 */
               abort_LED(28);    // just in case

               goto EXIT_POINT;

            }
            //#endif
            #endif
            
         } /* deadlockCntr > 200 */

      } /* else */
      #endif /* DEADLOCK_EMERGENCY_TARGET */
      
   } /* while */


   /*
      * Write the packet to the outgoing buffer. The output buffer is
      * guaranteed to be big enough to hold the maximum size packet.
      */
   OutBuffer->size=(uint32_T)bytesToSend;
   OutBuffer->PacketType=(char)pktType;
   memcpy(OutBuffer->Buffer, pktData, (uint_T)bytesToSend);

   /*
      #if DEBUG_MSG_LVL >= 3
      {
      int i;
      for(i=0; i<bytesToSend; i++) {
      PRINT_DEBUG_MSG_LVL3("ExtSetPkt: Data to be sent: 0x");
      PRINT_DEBUG_MSG_LVL3_UHex((uint8_T)pktData[i]);
      PRINT_DEBUG_MSG_NL3;
      }
      }
      #endif
      */


   /* Finally read to send the packet over the comm line... =================================*/
   #if DEBUG_MSG_LVL > 0
   if(pktType!=ACK_PACKET) {
      PRINT_DEBUG_MSG_LVL3("waitForAck = FALSE -> clear to send");
      PRINT_DEBUG_MSG_NL3;
   }
   #endif

   PRINT_DEBUG_MSG_LVL3("Sending now...");
   PRINT_DEBUG_MSG_NL3;
   error=SetExtSerialPacket(OutBuffer, portDev);
   if(error!=EXT_NO_ERROR) {

      /* never happens, errors caught above  --  fw-07-07 */
      // temporarily disable to throw an error in the calling methods instead  --  fw-07-07
      //abort_LED(29);    // just in case

      goto EXIT_POINT;

   }

   EXIT_POINT:PRINT_DEBUG_MSG_LVL3("OUT, error status: ");
   PRINT_DEBUG_MSG_LVL3_UDec(error);
   PRINT_DEBUG_MSG_NL3;

   return error;

} /* end ExtSetPkt */


/* Function: ExtSetPktWithACK ==================================================
* Abstract:
*  Sets (sends) the specified number of bytes on the comm line and waits for a
*  return packet.  As long as an error does not occur, this function is
*  guaranteed to set the requested number of bytes.  The number of bytes set is
*  returned via the 'nBytesSet' parameter.
*
*  If the return packet is an ACK, the ACK is processed and thrown away.  If
*  the return packet is something other than an ACK, the packet is saved and
*  processed and a global flag is set to indicate we are still waiting for an
*  ACK packet.  A typical scenario where the return packet is not an ACK is
*  when both the host and target send a packet to each other simultaneously.
*
*  EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
*/
PRIVATE boolean_T ExtSetPktWithACK(ExtSerialPort *portDev, char *pktData, int pktSize, PacketTypeEnum pktType) {

   int         bytesWritten=0;
   int         totalBytesWritten=0;
   boolean_T   error=EXT_NO_ERROR;

   // local function name... debugging only
   #if DEBUG_MSG_LVL > 0
   const char  *funct_name="ExtSetPktWithACK";
   #endif

   PRINT_DEBUG_MSG_LVL3("IN");
   PRINT_DEBUG_MSG_NL3;

   /* NOTE: ExtSetPkt can only send up to MAX_SERIAL_PKT_SIZE (= FIFOBUFSIZE) at a time... this 
    *       loop spreads larger packets (theoretically up to CIRCBUFSIZE over multiple calls
    *       to ExtSetPkt      --    fw-07-07
    */
   while(totalBytesWritten<pktSize) {

      /* Send the packet. */
      error=ExtSetPkt(portDev, pktData+totalBytesWritten, pktSize-totalBytesWritten, &bytesWritten, pktType);
      if(error!=EXT_NO_ERROR) {

         /* never happens, errors caught above  --  fw-07-07 */
         abort_LED(30);    // just in case

⌨️ 快捷键说明

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