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

📄 mod232commsprocessor.cpp

📁 mod_RSsim
💻 CPP
📖 第 1 页 / 共 3 页
字号:
         pDataPortion = responseModMsg.dataPtr; //Get offset to fill in data
         if (MAX_MOD_MEMWORDS >= modMsg.address + modMsg.byteCount)
         {
            WORD memValueTemp;

            deb.Format("Read Register from %d for %d .\n", modMsg.address, modMsg.byteCount);
            OutputDebugString(deb);
            RSDataMessage(deb);

            for (i=0; i <modMsg.byteCount;i++)
            {
               // grab the memory now
               memValueTemp = PLCMemory[requestMemArea][(seperationOffset + modMsg.address)+i];
               *(WORD*)pDataPortion =  SwapBytes( memValueTemp );
               pDataPortion += 2;
            }
         }
         else
         {
            // pack the exception code into the message
            ASSERT(0); // this is supposed to be caught in TestMessage()
            responseModMsg.buffer[1] |= 0x80;
            responseModMsg.buffer[2] = 0x02;    // exception code here (could also use 0x03)

            deb.Format("Read register past %d error x%02X!\n", MAX_MOD_MEMWORDS, (BYTE)responseModMsg.buffer[2]);
            OutputDebugString(deb);
            RSDataMessage(deb);

         }
         break;
      default :
          // Writes acks are all built in copy constructor
          // But the update is done here!
          if (MAX_MOD_MEMWORDS >= modMsg.address + modMsg.byteCount)
          {
          // lock memory for writting
          CMemWriteLock lk(PLCMemory.GetMutex());
      
              pDataPortion = responseModMsg.dataPtr; //Get offset to fill in data

              if (!lk.IsLocked())
                 //...Update
                 switch (modMsg.functionCode)
                 { 
                 case MOD_WRITE_SINGLE_COIL     :
                     {
                     CString deb;
                        deb.Format("Write single output %d.\n", modMsg.address);
                        OutputDebugString(deb);
                        RSDataMessage(deb);
                     }
                     //data gets copied in now
                     if (m_modifyThenRespond)
                        PLCMemory.SetAt(requestMemArea, seperationOffset +modMsg.address, (*(WORD*)modMsg.dataPtr?1:0));

//                     pDataPortion = responseModMsg.dataPtr; //Get offset to fill in data
                     *pDataPortion++ = (PLCMemory[requestMemArea][(seperationOffset +modMsg.address)+i] ? 0xFF : 0x00);
                     *pDataPortion++ = 0x00;
                     if (!m_modifyThenRespond)
                        PLCMemory.SetAt(requestMemArea, seperationOffset +modMsg.address, (*(WORD*)modMsg.dataPtr?1:0));
                     
                     numRegs = 1;   // repaint 1 item

                     break;
                 case MOD_WRITE_MULTIPLE_COILS  :
                    // unpack into the SIMul memory on WORD of sim memory for every BIT in the data 
                    //WORD numBytes;

                     numBytesInReq = modMsg.count/8;
                     if (modMsg.count%8)  // if we overflow a byte
                        numBytesInReq++;

                     {
                     CString deb;
                        deb.Format("Write multiple outputs from %d for %d bits.\n", modMsg.address, modMsg.count);
                        OutputDebugString(deb);
                        RSDataMessage(deb);
                     }
                     numRegs = numBytesInReq;   // repaint X bits

                     for (i=0;i<numBytesInReq;i++)
                     {
                     WORD bitOffset;
                        for (bitOffset=0;bitOffset<8;bitOffset++)
                        {
                           if ((i*8)+bitOffset <= modMsg.count)
                           {
                              if (*(BYTE*)modMsg.dataPtr & (0x01<<bitOffset))
                                 PLCMemory.SetAt(requestMemArea, seperationOffset +modMsg.address+(i*8)+bitOffset, 1);
                              else
                                 PLCMemory.SetAt(requestMemArea, seperationOffset +modMsg.address+(i*8)+bitOffset, 0);
                           }
                        }
                        modMsg.dataPtr++;
                     }
                     break;
                 case MOD_WRITE_HOLDING : //WRITE multiple holdings
                 case MOD_WRITE_EXTENDED:
                     //PLCMemory[requestMemArea][modMsg.address] = SwapBytes(*(WORD*)modMsg.dataPtr);
                     //break;

                     numRegs = modMsg.byteCount/2;

                     {
                     CString deb;
                        deb.Format("Write multiple registers from %d for %d registers.\n", modMsg.address, numRegs);
                        OutputDebugString(deb);
                        RSDataMessage(deb);
                     }
                     for (i=0;i<numRegs;i++)
                     {
                        PLCMemory.SetAt(requestMemArea, seperationOffset + modMsg.address + i, SwapBytes(*(WORD*)modMsg.dataPtr));
                        modMsg.dataPtr +=2;   // inc pointer by 2 bytes
                     }
                     break;
                 case MOD_WRITE_SINGLEHOLDING : //WRITE single holding reg.
                     {
                     CString deb;
                     WORD memValueTemp;
                        deb.Format("Write single register %d.\n", modMsg.address);
                        OutputDebugString(deb);
                        RSDataMessage(deb);

                        numRegs = 1;   //repaint 1 register

                        if (m_modifyThenRespond)
                           PLCMemory.SetAt(requestMemArea, seperationOffset + modMsg.address , SwapBytes(*(WORD*)modMsg.dataPtr));

                        memValueTemp = PLCMemory[requestMemArea][(seperationOffset +modMsg.address)];
                        *(WORD*)pDataPortion =  SwapBytes( memValueTemp );

                        if (!m_modifyThenRespond)
                           PLCMemory.SetAt(requestMemArea, seperationOffset + modMsg.address , SwapBytes(*(WORD*)modMsg.dataPtr));
                        modMsg.dataPtr +=2;   // inc pointer by 2 bytes
                        pDataPortion += 2;

                     }
                     break;
                 }
          }
          // we can only call on the GUI thread once we have un-locked
          if (pGlobalDialog)
          {
             int cols = pGlobalDialog->GetListDisplayedWidth();
             pGlobalDialog->RedrawListItems(modMsg.GetAddressArea(modMsg.functionCode), 
                                            (seperationOffset +modMsg.address)/(cols), 
                                            (seperationOffset +modMsg.address+(numRegs-1))/(cols)
                                           ); // repaint only the needed rows
          }
          break;
  
      }
   }
   else
   { // error occurred
      pDataPortion = responseModMsg.dataPtr; //Get offset to fill in data
   }
   if (0 == modMsg.stationID)   // broadcast, don't respond at all.
      return (TRUE);
   
   // finnish building the response
   responseModMsg.totalLen = (WORD)((LONG)pDataPortion-(LONG)responseModMsg.buffer);
   responseModMsg.totalLen += MODBUS_CRC_LEN;

   // 5. append the CRC
   //OutputDebugString("Calculate CRC\n");
   {
      responseModMsg.BuildMessageEnd();
   }
   
   // 6. send it back
   m_debuggerStep = 102;

#ifdef _COMMS_DEBUGGING
   sprintf(debugStr, "Send %d bytes\n", responseModMsg.totalLen);
   OutputDebugString(debugStr);
#endif
   
   RSStateChanged(RSPORTCURRENTLY_WRITTING);
   // Send it on the wire , but first kill any incomming messages as well so we don't overflow or anything
   Purge();
   if (!m_NoiseSimulator.ErrorsEnabled())
      Send(responseModMsg.totalLen, (BYTE*)responseModMsg.buffer, debugStr);
   else
   {
      m_NoiseSimulator.InjectErrors((CRS232Port*)this, (BYTE*)responseModMsg.buffer, responseModMsg.totalLen, debugStr);
      RSDataMessage("Error simulation active\n");

   }
   m_debuggerStep = 103;
   
   // inc our counter
   pGlobalDialog->PacketsSentInc();
   RSDataMessage(".\n");

   /*if (TRUE)
   {
   BOOL linesSet;
      linesSet = EscapeCommFunction(h232Port, 
      Sleep(300);
      linesSet = EscapeCommFunction(h232Port, 
   } */
   return (TRUE);
} // ProcessData

// ----------------------------- LoadRegistersIMP -----------------------------
// STATIC : implements the function to load register values from file
BOOL CMOD232CommsProcessor::LoadRegistersIMP()
{
CFileException ex;
CFile dat;
LONG area;
DWORD wordIndex;

   if (!dat.Open("MODDATA.DAT", CFile::modeRead|CFile::shareDenyRead, &ex) )
   {
      // complain if an error happened
      // no need to delete the exception object

      TCHAR szError[1024];
      ex.GetErrorMessage(szError, 1024);
      OutputDebugString( "Couldn't open source file: ");
      OutputDebugString( szError);
      
      return FALSE;
   }
   // read it in
   for (area=0;area < MAX_MOD_MEMTYPES;area++)
   {
   DWORD numRead,totalRead=0;
   WORD dataWord;
   DWORD maxIndex = PLCMemory[area].GetSize();

      // lock the memory for reading
//      CMemWriteLock lk(pGlobalDialog->m_pMemWriteSync);
      CMemWriteLock  lk(PLCMemory.GetMutex());
      // loop thru all registers (WORD)
      if (!lk.IsLocked())
      {
         for (wordIndex=0; wordIndex < maxIndex/*MAX_MOD_MEMWORDS*/; wordIndex++)
         {
            numRead = dat.Read((BYTE*)&dataWord, sizeof(WORD));
            PLCMemory.SetAt(area, wordIndex, dataWord);
            totalRead +=numRead;
            if (numRead != sizeof(WORD))
               return FALSE;
         }
         // Read past the rest of the block
         while (wordIndex < MAX_MOD_MEMWORDS)
         {
            numRead = dat.Read((BYTE*)&dataWord, sizeof(WORD));
            totalRead +=numRead;
            if (numRead != sizeof(WORD))
               return FALSE;
            wordIndex++;
         }
      }
      else
      {
      CString errorMsg;
         //error
         errorMsg.LoadString(IDS_SYNC_READING);
         AfxMessageBox(errorMsg, MB_ICONEXCLAMATION);
         return FALSE;
      }
   }
   return(TRUE);
}

// ----------------------------- LoadRegisters -----------------------------
// load binary dump of the register values from file.
BOOL CMOD232CommsProcessor::LoadRegisters()
{
BOOL ret = LoadRegistersIMP();

   if (ret)
      RSDataMessage("Register values loaded OK\n");
   return (ret);
} // LoadRegisters


// --------------------------------------- SaveRegisters ---------------------------
// save a binary dump of the values to file.
BOOL CMOD232CommsProcessor::SaveRegisters()
{
BOOL ret = SaveRegistersIMP();

   if (ret)
      RSDataMessage("Register values saved OK\n");
   return (ret);

}

// --------------------------------------- SaveRegistersIMP ---------------------------
// STATIC : save all register values to a flat file.
BOOL CMOD232CommsProcessor::SaveRegistersIMP()
{
CFileException ex;
CFile dat;
LONG area;
DWORD wordIndex;


   if (!dat.Open("MODDATA.DAT", CFile::modeWrite | CFile::shareExclusive | CFile::modeCreate, &ex) )
   {
      // complain if an error happened
      // no need to delete the ex object

      TCHAR szError[1024];
      ex.GetErrorMessage(szError, 1024);
      OutputDebugString( "Couldn't open source file: ");
      OutputDebugString( szError);
      
      return FALSE;
   }
   // read it in
   for (area=0;area < MAX_MOD_MEMTYPES;area++)
   {
   WORD wordData;
   DWORD maxIndex = PLCMemory[area].GetSize();
      // lock the memory for writting
      CMemWriteLock lk(PLCMemory.GetMutex());
      // loop thru all registers (WORD)
      if (!lk.IsLocked())
      {
         for (wordIndex=0; wordIndex < maxIndex/*MAX_MOD_MEMWORDS*/; wordIndex++)
         {
            wordData = PLCMemory[area][wordIndex];
            dat.Write((BYTE*)&wordData, sizeof(WORD));
         }
         // Fill the rest with NULLs
         while (wordIndex < MAX_MOD_MEMWORDS)
         {
            wordData = 0;
            dat.Write((BYTE*)&wordData, sizeof(WORD));
            wordIndex++;
         }
      }
      else
      {
      CString errorMsg;
         errorMsg.LoadString(IDS_SYNC_WRITTING);
         AfxMessageBox(errorMsg, MB_ICONEXCLAMATION);
         // error
         return FALSE;
      }
   }
   return TRUE;
} // SaveRegistersIMP

// ------------------------------- ActivateStation ---------------------------
void CMOD232CommsProcessor::ActivateStationLED(LONG stationID)
{
   if (stationID>0 && stationID<STATIONTICKBOXESMAX)
   {
      //start the counter for this station at the beginning
      pGlobalDialog->m_microTicksCountDown[stationID] = pGlobalDialog->GetAnimationOnPeriod();
      // it will count down untill it extinguishes
   }
} // ActivateStation

// ------------------------------- StationIsEnabled ---------------------------
// Return TRUE if station is enabled
BOOL CMOD232CommsProcessor::StationIsEnabled(LONG stationID)
{
   if (stationID>0 && stationID<STATIONTICKBOXESMAX)
   {
      return (pGlobalDialog->StationEnabled(stationID));//m_microTickState==1);
   }
   return TRUE;
} // StationIsEnabled

⌨️ 快捷键说明

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