cancel
Showing results for 
Search instead for 
Did you mean: 
SOLVED

RT SDK to read Ethercat Real Time Memory

RT SDK to read Ethercat Real Time Memory

Andrefs
Member

I have the following code to read rt memory from ethercat at each 2ms.

 

switch (event_type)
    {
    case common::scheduler::SchedEventType::SCHED_EVENT_TICK:
      // Call real-time method here
      if (m_finalStateMachineState == FinalStateMachineState::SCHED_OPERATING)
      {
        runSharedMemUser();
      }

      return common::scheduler::SchedEventResponse::SCHED_EVENT_RESP_OKAY;

(...)
(...)
(...)



void Callable::runSharedMemUser()
  {
    comm::datalayer::DlResult result;

    // // ----------------------- Write flatbuffer Output memory -----------------------

    result = outputMemUser->beginAccess(inData, revisionOut);
    if (result == comm::datalayer::DlResult::DL_RT_NOTOPEN)
    {
      outputMemUser->endAccess();
      return;
    }
    if (STATUS_FAILED(result))
    {
      TRACE_ERR("ERROR Accessing output memory failed with: %s", result.toString());
      return;
    }
    size_t size = 0;
    if (comm::datalayer::STATUS_FAILED(outputMemUser->getSize(size)))
    {
      TRACE_ERR("WARNING Can't read output memory size");
      return;
    }
    else
    {
      if (isFirstRun1) {
        outDataRead = new uint8_t[size];
        memcpy(outDataRead, inData, size);
        isFirstRun1 = false;
      }else{
        delete[] outDataRead;
        outDataRead = new uint8_t[size];
        memcpy(outDataRead, inData, size);
      }  
    }

    outputMemUser->endAccess();
    // ----------------------- Write flatbuffer Input memory -----------------------

    result = inputMemUser->beginAccess(inData, revisionIn);
    if (result == comm::datalayer::DlResult::DL_RT_NOTOPEN)
    {
      inputMemUser->endAccess();
      return;
    }

    if (STATUS_FAILED(result))
    {
      TRACE_ERR("ERROR Accessing input memory failed with: %s", result.toString());
      return;
    }

    size = 0;
    if (comm::datalayer::STATUS_FAILED(inputMemUser->getSize(size)))
    {
      TRACE_ERR("WARNING Can't read input memory size");
      return;
    }
    else
    {
      if (isFirstRun2)
      {
        inDataRead = new uint8_t[size];
        memcpy(inDataRead, inData, size);
        isFirstRun2 = false;
      }else{
        delete[] inDataRead;
        inDataRead = new uint8_t[size];
        memcpy(inDataRead, inData, size);
      }  
    }
    inputMemUser->endAccess();
    TRACE_INFO("runSharedMemUser");
  }

 

The average running time is good, but sometimes it takes more than 2ms and I have a scheduler error.

Andrefs_1-1712563976298.png

Andrefs_0-1712563945997.png

Can someone give me some help to try to solve this?

 

4 REPLIES 4

nickH
Community Moderator
Community Moderator

Hi Andrefs,

To allocate memory with "new" is not real time capable.

Dynamic memory allocation is not time deterministic. The time taken to allocate memory may not be predictable. Thats why "Avoid heap memory allocation" is also one of  NASA's "The Power of 10: Rules for Developing Safety-Critical Code".

Best regards, 

Nick

Yes, i understand. But in this case, i need to put always the size of memUser. Any suggestion? 

nickH
Community Moderator
Community Moderator

Hi @Andrefs 

Please read the size of the memory and create your arrays outside of the scheduler context. For example from the final statemachine, at the same time where you also read in the MemoryMap.

Best regards, 

Nick

Thanks for your help @nickH .

That was a part of the solution. The other part of solution was to add my callable to ctrlXAutomation Task and use syncpoints.

Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist