FORUM CTRLX AUTOMATION
ctrlX World Partner Apps for ctrlX AUTOMATION
Dear Community User! We have started the migration process.
This community is now in READ ONLY mode.
Read more: Important
information on the platform change.
04-08-2024 10:14 AM - edited 04-08-2024 10:15 AM
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.
Can someone give me some help to try to solve this?
Solved! Go to Solution.
04-08-2024 01:23 PM
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
04-08-2024 04:18 PM
Yes, i understand. But in this case, i need to put always the size of memUser. Any suggestion?
04-09-2024 09:13 AM
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
04-09-2024 11:37 AM - edited 04-09-2024 11:38 AM
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.