Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 127 additions & 18 deletions init_solution.ps1
Original file line number Diff line number Diff line change
@@ -1,45 +1,154 @@
Write-Host "Updating Git submodule."
git submodule update --init --recursive --quiet

# x86
Write-Host "Creating native x86 project."
$path = "$($PSScriptRoot)/artifacts/bin32"
New-Item -Force -ItemType directory -Path $path
# load .NET types
$RType = [type]::GetType('System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation')
$PType = [type]::GetType('System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation')

try
{
if (-not $RType -or -not $PType) { throw }

$R = $RType
$P = $PType

$mWindows = $R::IsOSPlatform($P::Windows)
$mLinux = $R::IsOSPlatform($P::Linux)
$mMacOS = $R::IsOSPlatform($P::OSX)
}
catch
{
# fallback for Windows PowerShell 5.1 oder missing types
$mWindows = $env:OS -eq 'Windows_NT'
$mLinux = $false
$mMacOS = $false
}

Write-Host "Windows: $mWindows, Linux: $mLinux, macOS: $mMacOS"

# detect architecture once
# try .NET Core API first (PowerShell Core on Linux/macOS)
$type = [type]::GetType('System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation')

if ($type)
{
# RuntimeInformation exists
$arch = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString()
}
else
{
# Fallback for Windows PowerShell / older .NET
switch ($env:PROCESSOR_ARCHITECTURE) {
'AMD64' { $arch = 'X64' }
'x86' { $arch = 'X86' }
'ARM64' { $arch = 'Arm64' }
'ARM' { $arch = 'Arm' }
default { $arch = $env:PROCESSOR_ARCHITECTURE }
}
}

Write-Host "Detected architecture: $arch"

# x86 / arm
if ($arch -like 'Arm*')
{
Write-Host "Creating native arm project."
$path = "$($PSScriptRoot)/artifacts/arm32"
} else
{
Write-Host "Creating native x86 project."
$path = "$($PSScriptRoot)/artifacts/bin32"
}

New-Item -Force -ItemType Directory -Path $path | Out-Null
Set-Location -Path $path

if ($IsWindows)
if ($mWindows)
{
cmake ./../../native -DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release" -G "Visual Studio 16 2019" -A "Win32"
cmake ./../../native `
-DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release" `
-G "Visual Studio 16 2019" `
-A "Win32"
}
elseif ($IsLinux)
elseif ($mLinux)
{
cmake ./../../native -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
if ($arch -like 'Arm*')
{
# For 32-bit ARM, install the following compilers:
# sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

cmake ./../../native `
-DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc `
-DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_C_FLAGS='-Wno-error=stringop-overflow -Wno-stringop-overflow' `
-DCMAKE_CXX_FLAGS='-Wno-error=stringop-overflow -Wno-stringop-overflow'
}
else
{
cmake ./../../native `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_C_FLAGS=-m32 `
-DCMAKE_CXX_FLAGS=-m32 `
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
}
}
elseif ($IsMacOS)
elseif ($mMacOS)
{
# The i386 architecture is deprecated for macOS
throw [System.PlatformNotSupportedException]
}
else
else
{
throw [System.PlatformNotSupportedException]
}

# x64
Write-Host "Creating native x64 project."
$path = "$($PSScriptRoot)/artifacts/bin64"
# x64 / arm4
if ($arch -like 'Arm*')
{
Write-Host "Creating native arm64 project."
$path = "$($PSScriptRoot)/artifacts/arm64"
} else
{
Write-Host "Creating native x64 project."
$path = "$($PSScriptRoot)/artifacts/bin64"
}

New-Item -Force -ItemType directory -Path $path
Set-Location -Path $path

if ($IsWindows)
if ($mWindows)
{
cmake ./../../native `
-DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release" `
-G "Visual Studio 16 2019" `
-A "x64"
}
elseif ($mLinux)
{
cmake ./../../native -DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release" -G "Visual Studio 16 2019" -A "x64"
if ($arch -like 'Arm*')
{
cmake ./../../native `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_C_FLAGS='-Wno-error=stringop-overflow -Wno-stringop-overflow' `
-DCMAKE_CXX_FLAGS='-Wno-error=stringop-overflow -Wno-stringop-overflow'
}
else
{
cmake ./../../native `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_C_FLAGS=-m64 `
-DCMAKE_CXX_FLAGS=-m64
}
}
elseif ($IsLinux -or $IsMacOS)
elseif ($mMacOS)
{
cmake ./../../native -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-m64 -DCMAKE_CXX_FLAGS=-m64
cmake ./../../native `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_C_FLAGS=-m64 `
-DCMAKE_CXX_FLAGS=-m64
}
else
else
{
throw [System.PlatformNotSupportedException]
}
Expand Down
56 changes: 34 additions & 22 deletions native/SOEM_wrapper/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ static void state_init_enter(struct sm_state_data_t* data);
static void state_init_run(struct sm_state_data_t* data);
static void state_idle_run(struct sm_state_data_t* data);
static void state_receive_run(struct sm_state_data_t* data);
static void state_receive_accepted(struct sm_state_data_t* data);
static void state_transmit_run(struct sm_state_data_t* data);
static void state_wait_transmit_accepted(struct sm_state_data_t* data);
static void check_requests(struct sm_state_data_t* data);
static void check_receive_request(struct sm_state_data_t* data);

// Static data containers
static int _mapping_index[MAX_SLAVES] = { 0 };
Expand Down Expand Up @@ -186,7 +187,7 @@ static void init_state_data(struct sm_state_data_t* state)
state->rx_offset = 0;
state->rx_updated = false;
state->next_state = NULL;
state->current_state = &state_init_enter;
state->current_state = NULL;
state->initialized = false;
state->receive_request_bit = 0;
state->transmit_accepted_bit = 0;
Expand All @@ -208,6 +209,7 @@ bool init_serial(uint16_t slave)
return false;

init_state_data(state);
state->current_state = &state_init_enter;

if(state->tx_cache == NULL)
state->tx_cache = (uint8_t*)malloc(TX_CACHE_SIZE);
Expand Down Expand Up @@ -345,8 +347,12 @@ void update_serial(uint16_t slave, uint8_t* tx_data, uint8_t* rx_data)
state->rx_status = (rx_status_t *)rx_data;
state->rx_buffer = rx_data + sizeof(uint16_t);

state->current_state(state);
state->current_state = state->next_state;
if(state->current_state != NULL)
{
check_receive_request(state);
state->current_state(state);
state->current_state = state->next_state;
}
}
}

Expand All @@ -355,14 +361,17 @@ void update_serial(uint16_t slave, uint8_t* tx_data, uint8_t* rx_data)
*
* data: Pointer to sm_state_data_t struct.
*/
static void check_requests(struct sm_state_data_t* data)
static void check_receive_request(struct sm_state_data_t* data)
{
uint8_t current_receive_request = data->rx_status->receive_request;

if (current_receive_request != data->receive_request_bit)
if(data->initialized)
{
data->receive_request_bit = current_receive_request;
data->receive_request = true;
const uint8_t current_receive_request = data->rx_status->receive_request;

if (current_receive_request != data->receive_request_bit)
{
data->receive_request_bit = current_receive_request;
data->receive_request = true;
}
}
}

Expand Down Expand Up @@ -397,14 +406,9 @@ static void state_init_run(struct sm_state_data_t* data)
}
else if ((data->tx_control->init_request == 0) && (data->rx_status->init_accepted == 0))
{
data->receive_request_bit = data->rx_status->receive_request;
data->initialized = true;
data->next_state = &state_idle_run;

if (data->tx_control->receive_accepted != data->rx_status->receive_request)
{
data->tx_control->receive_accepted = data->rx_status->receive_request;
data->receive_request_bit = data->rx_status->receive_request;
}
}
}

Expand All @@ -415,8 +419,6 @@ static void state_init_run(struct sm_state_data_t* data)
*/
static void state_idle_run(struct sm_state_data_t* data)
{
check_requests(data);

// check if receive request occurred
if (data->receive_request)
{
Expand Down Expand Up @@ -444,21 +446,31 @@ static void state_receive_run(struct sm_state_data_t* data)
{
data->rx_offset = 0;
}

// receive data
memcpy(data->rx_cache + data->rx_offset, data->rx_buffer, length);
data->rx_offset += length;

if(data->rx_callback != NULL)
{
data->rx_callback(data->slave, data->rx_buffer, length);
}

data->next_state = &state_receive_accepted;
}

/*
* Receive accepted state function.
*
* data: Pointer to sm_state_data_t struct.
*/
static void state_receive_accepted(struct sm_state_data_t* data)
{
data->rx_updated = true;
data->receive_request = false;
// toggle accepted bit
data->tx_control->receive_accepted = !data->tx_control->receive_accepted;

data->rx_updated = true;
data->receive_request = false;
data->next_state = &state_idle_run;
}

Expand Down
31 changes: 16 additions & 15 deletions src/EtherCAT.NET/EcMaster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public class EcMaster : IDisposable
private Task _watchdogTask;
private bool _watchDogActive = true;

// sdo callbacks
List<EcHL.PO2SOCallback> _callbacks = new List<EcHL.PO2SOCallback>();

#endregion

#region Constructors
Expand Down Expand Up @@ -118,8 +121,6 @@ private void ValidateSlaves(IList<SlaveInfo> slaves, IList<SlaveInfo> actualSlav

private void ConfigureSlaves(IList<SlaveInfo> slaves)
{
var callbacks = new List<EcHL.PO2SOCallback>();

foreach (var slave in slaves)
{
// SDO / PDO config / PDO assign
Expand All @@ -128,24 +129,22 @@ private void ConfigureSlaves(IList<SlaveInfo> slaves)

var sdoWriteRequests = slave.GetConfiguration(extensions).ToList();

EcHL.PO2SOCallback callback = slaveIndex =>
if (sdoWriteRequests.Count != 0)
{
sdoWriteRequests.ToList().ForEach(sdoWriteRequest =>
EcHL.PO2SOCallback callback = slaveIndex =>
{
EcUtilities.CheckErrorCode(this.Context, EcUtilities.SdoWrite(this.Context, slaveIndex, sdoWriteRequest.Index, sdoWriteRequest.SubIndex, sdoWriteRequest.Dataset), nameof(EcHL.SdoWrite));
});
sdoWriteRequests.ToList().ForEach(sdoWriteRequest =>
{
EcUtilities.CheckErrorCode(this.Context, EcUtilities.SdoWrite(this.Context, slaveIndex, sdoWriteRequest.Index, sdoWriteRequest.SubIndex, sdoWriteRequest.Dataset), nameof(EcHL.SdoWrite));
});

return 0;
};
return 0;
};

EcHL.RegisterCallback(this.Context, currentSlaveIndex, callback);
callbacks.Add(callback);
EcHL.RegisterCallback(this.Context, currentSlaveIndex, callback);
_callbacks.Add(callback);
}
}

callbacks.ForEach(callback =>
{
GC.KeepAlive(callback);
});
}

private void ConfigureIoMap(IList<SlaveInfo> slaves)
Expand Down Expand Up @@ -741,6 +740,8 @@ protected virtual void Dispose(bool disposing)
if (_ioMapPtr != IntPtr.Zero)
Marshal.FreeHGlobal(_ioMapPtr);

_callbacks?.Clear();

_cts?.Cancel();

try
Expand Down
Loading