Migration Guide from S810-MP-SDK2N (CAN/CAN FD)
This page is a migration guide for replacing existing applications created with S810-MP-SDK2N to S810-MX-ADL2N.
Target protocol is CAN/CAN FD only (LIN is out of scope).
Related Links
- Troubleshooting during migration: Common Issues and Solutions
- Migration from other products: Migration from ADL1N, Migration from SDK3N
Migration Overview
The following five points affect implementation when migrating from SDK2N to ADL2N.
- API naming scheme changes (
MPCAN*->MPX*/MPXCAN*) - Device selection model changes (
MPCANOpensingle target ->MPXOpenenumeration +Serialselection) - CAN parameter setting unified (Simple/Detail ->
StMPXCANParam) - Data structure extension (8-byte CAN assumption -> 64-byte CAN FD support)
- Log acquisition redesign (
MPXSetGetLogMode+MPXGetLog/MPXCANGetLogEx)
Preconditions to Confirm First
- Old DLL:
MPCANCtrl.DLL/MPCANCtrl_x64.DLL - New DLL:
MPXCtrlFree.DLL/MPXCtrlFree_x64.DLL - Some return code (
ER) values changed, so numeric comparison code must be updated
API Specification Differences (Old -> New)
Common APIs (Replacement from old CAN-only APIs)
| Old SDK2N (Signature) | New ADL2N (Signature) | Compatibility Impact |
|---|---|---|
ER MPCANGetVersion(StMPCANVersion* Version) | ER MPXGetAPIVersion(StMPXAPIVersion* Version) | Structure type name changed |
ER MPCANOpen(long* Serial) | ER MPXOpen(StMPXDeviceInfo* Devices, unsigned char Num, unsigned char* Count) | Arguments significantly changed (enumeration model) |
ER MPCANClose(void) | ER MPXClose(void) | Name changed |
ER MPCANSetLED(unsigned char Red, unsigned char Green, unsigned char GreenBlink) | ER MPXSetLED(unsigned long Serial, unsigned char LEDRed, unsigned char LEDGreen, unsigned char LEDGreenBlink, unsigned char LEDYellow, unsigned char LEDYellowBlink) | Serial added, more arguments |
ER MPCANGetStatus(unsigned short* Status) | ER MPXGetStatus(unsigned long Serial, unsigned short* StatusCh1, unsigned short* StatusCh2) | Serial added, per-channel status |
ER MPCANMonitorStart(void) | ER MPXMonitorStart(unsigned long Serial, unsigned char SyncMode) | Serial + SyncMode added |
ER MPCANMonitorStop(unsigned long* mSec, unsigned short* uSec) | ER MPXMonitorStop(unsigned long Serial, unsigned long* mSec, unsigned short* uSec) | Serial added |
ER MPCANGetTimeStamp(unsigned long* mSec, unsigned short* uSec) | ER MPXGetTimeStamp(unsigned long Serial, unsigned long* mSec, unsigned short* uSec) | Serial added |
ER MPCANGetLog(StMPCANLog** LogPointer, unsigned long* Count, unsigned char* BufferOver) | ER MPXGetLog(unsigned long Serial, unsigned char InnerCh, StMPXLog** Log, unsigned short* Count, unsigned char* BufferOver) | Serial/InnerCh added, Count type changed |
| - | ER MPXSetGetLogMode(unsigned long Serial, unsigned char InnerCh, unsigned char Mode) | Must be added in migration |
| - | ER MPXSetLogCallBack(...) | Use when operating callback mode |
CAN/CAN FD APIs
| Old SDK2N (Signature) | New ADL2N (Signature) | Difference |
|---|---|---|
ER MPCANSetParamSimple(unsigned char Mode, unsigned char RecvRemote, unsigned char Baudrate, unsigned char SamplePoint) | ER MPXCANSetParam(unsigned long Serial, unsigned char InnerCh, StMPXCANParam* Param) | Simple removed, unified into structure |
ER MPCANSetParamDetail(unsigned char Mode, unsigned char RecvRemote, unsigned short Brg, unsigned char TSeg1, unsigned char TSeg2, unsigned char Sjw, unsigned char Clock) | ER MPXCANSetParam(unsigned long Serial, unsigned char InnerCh, StMPXCANParam* Param) | Detail removed, unified into structure |
ER MPCANGetLogEx(StMPCANLog* Log, unsigned long* Num, unsigned long* Count, unsigned char* BufferOver) | ER MPXCANGetLogEx(unsigned long Serial, unsigned char InnerCh, StMPXCANLog* Log, unsigned short Num, unsigned short* Count, unsigned char* BufferOver) | Serial/InnerCh added, Num/Count type changed |
ER MPCANSetSlot(StMPCANSlot* Slot, unsigned char Num) | ER MPXCANSetSlot(unsigned long Serial, unsigned char InnerCh, StMPXCANSlot* Slots, unsigned char SlotCount) | Slot structure expanded |
ER MPCANChangeSlotData(unsigned char SlotNo, unsigned char Ena, unsigned char* Data) | ER MPXCANChangeSlot(unsigned long Serial, unsigned char InnerCh, unsigned char SlotNo, unsigned char SlotEnabled, unsigned char ReqInfo, StMPXCANFrame* Frame) | Scope changed from data-only to request type + full frame |
ER MPCANSendSlot(unsigned char SlotNo) | ER MPXCANSendSlot(unsigned long Serial, unsigned char InnerCh, unsigned char SlotNo) | Serial/InnerCh added |
ER MPCANSendDirect(StMPCANFrame Frame) / ER MPCANSendDirectEx(StMPCANFrame* Frame) | ER MPXCANDirectSend(unsigned long Serial, unsigned char InnerCh, StMPXCANDirect* Frame) | Send info now includes Protocol/BRS |
Structure-Level Migration Points
Frame Structure
- Old:
StMPCANFrameId,IdFormat,Rtr,Dlc,Data[8]
- New:
StMPXCANFrame+StMPXCANFrameTypeID(StMPXCANID)DL(0..8,12,16,20,24,32,48,64)Data[64]FrameType.Option.Protocol(CAN/CAN FD)FrameType.Option.BRS(for CAN FD)
Parameter Structure
SDK2N SetParamSimple/Detail settings are consolidated into StMPXCANParam in ADL2N.
| Old Setting | New Field |
|---|---|
Mode | StMPXCANParam.Mode |
Baudrate | StMPXCANParam.ArbitrationBaudrate |
SamplePoint | StMPXCANParam.ArbitrationSamplepoint |
RecvRemote | No direct counterpart (review behavior under new spec) |
Brg/TSeg1/TSeg2/Sjw/Clock | Direct value setting not supported; redesign with predefined parameters |
| - | EnableTerminate (termination resistor) |
| - | DataBaudrate / DataSamplepoint (CAN FD) |
If you used MPCANSetParamDetail, first migrate to SetParamSimple-equivalent operation (predefined baudrate/samplepoint) for safer transition.
Exact direct porting of Brg/TSeg1/TSeg2/Sjw/Clock is not possible. Use this approach:
- Select the closest
MPX_CAN_PARAM_ABR_*to old effective baudrate - Select the closest
MPX_CAN_PARAM_SP_*to old sample point - Validate acceptable tolerance on real hardware
If strict bit timing match is required, contact support.
Slot Structure (StMPCANSlot -> StMPXCANSlot)
Old StMPCANSlot | New StMPXCANSlot | Notes |
|---|---|---|
Enabled | FrameType.Enabled | Hierarchized |
EventKind | FrameType.FrameType | Hierarchized |
Delay (unsigned short) | msSendDelay (unsigned long) | Type expanded |
Cycle (unsigned short) | msSendCycle (unsigned long) | Type expanded |
Offset (unsigned short) | msSendOffset (unsigned long) | Type expanded |
Count (unsigned short) | SendCounter (unsigned short) | Name changed |
Increment (unsigned char) | Increment[64] | Changed from bit flag to array |
| - | SlotNo | Added (1 to 28) |
| - | TriggerType / TriggerID | Added (receive trigger) |
| - | msMinTransInterval / usMinTransInterval | Added (minimum interval) |
| - | usSendDelay / usSendOffset / usSendCycle | Added (microsecond fields) |
Slot limit in ADL2N is expanded from 24 -> 28.
EventKind (Frame Type) Value Changes
| SDK2N | Value | ADL2N | Value |
|---|---|---|---|
CAN_EVENT_PERIODIC | 0 | MPX_CAN_FRAME_TYPE_PERIODIC | 0 |
| - | - | MPX_CAN_FRAME_TYPE_PERIODIC_TRIGGER | 1 |
CAN_EVENT_EVENT | 1 | MPX_CAN_FRAME_TYPE_EVENT | 2 |
CAN_EVENT_EVENTPERIODIC | 2 | MPX_CAN_FRAME_TYPE_EVENTPERIODIC | 3 |
If old code hard-codes numeric values for EVENT=1 and EVENTPERIODIC=2, be sure to replace them with constants.
Keeping old values causes different frame-type behavior in ADL2N.
Key Points for StMPXCANFrameType / StMPXCANFrame
SDK2N set Enabled / EventKind / Frame as flat fields, while ADL2N uses nested fields.
// SDK2N
slot.Enabled = CAN_SLOT_ENA;
slot.EventKind = CAN_EVENT_PERIODIC;
slot.Frame.Id = 0x100;
slot.Frame.IdFormat = CAN_ID_STD;
slot.Frame.Rtr = CAN_RTR_DATA;
slot.Frame.Dlc = 8;
// ADL2N
slot.FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slot.FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC;
slot.FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN; // Use MPX_CAN_PROTOCOL_CANFD for CAN FD
slot.FrameType.Option.BRS = MPX_CAN_BRS_DISABLE; // Valid for CAN FD
slot.FrameType.Option.ErrorAction = MPX_CAN_ERR_BEHAVIOR_ACTIVE;
slot.Frame.ID.ID = 0x100;
slot.Frame.ID.IDE = MPX_CAN_IDE_STD;
slot.Frame.ID.RTR = MPX_CAN_RTR_DATA;
slot.Frame.DL = 8;
Increment Field Migration
Old SDK2N used 8-bit bit flags, ADL2N uses Increment[64] array.
// SDK2N: bit-flag format (example: increment Data1 and Data3)
// slot.Increment = 0x05;
// ADL2N: array format
for (int i = 0; i < 64; i++) {
slot.Increment[i] = MPX_CAN_SIM_INC_FALSE;
}
slot.Increment[0] = MPX_CAN_SIM_INC_TRUE; // D1
slot.Increment[2] = MPX_CAN_SIM_INC_TRUE; // D3
Log Structure (StMPCANLog -> StMPXCANLog)
Old StMPCANLog | New StMPXCANLog | Notes |
|---|---|---|
mSec | mSec | Equivalent |
uSec | uSec | Equivalent |
Dir | Dir | Equivalent |
Err | Error + ErrorInfo | Detailed |
Frame.Id | ID | Flattened |
Frame.IdFormat | IDE | Name changed |
Frame.Rtr | RTR | Flattened |
Frame.Dlc | DL | CAN FD support |
Frame.Data[8] | Data[64] | Size expanded |
| - | Protocol | Added (CAN/CAN FD identification) |
Revisit buffer design previously based on 8-byte data.
Return Code (ER) Differences
| Old SDK2N | New ADL2N | Notes |
|---|---|---|
E_OK=0 | E_OK=0 | Same |
E_PARAM=1 | E_PARAM=1 | Same |
E_DEVICE=2 | E_DEVICE=2 | Same |
E_COMM=3 | E_COMM=3 | Same |
E_TGT=4 | E_TGT=4 | Same |
E_SLT_BUSY=5 | - | Removed |
| - | E_TRG_BUSY=11 | Added |
E_DCT_FULL=6 | E_DCT_FULL=12 | Value changed |
E_STS=7 | E_STATUS=105 | Value changed |
E_OTHER=8 | E_OTHER=255 | Value changed |
| - | E_TIMEOUT=202 | Added |
Implementation Procedure (Replacement Flow)
- Update DLL references (
MPCANCtrl*->MPXCtrlFree*) - Replace
MPCANOpenwithMPXOpenand addSerialmanagement - Consolidate old
MPCANSetParamSimple/Detailcalls intoMPXCANSetParam - Replace frame/slot structures to
StMPXCAN* - Replace
MPCANGetLogExwithMPXCANGetLogEx, and reviewNum/Counttypes - Reflect intent of old
MPCANChangeSlotDataintoReqInfoofMPXCANChangeSlot - Update
ERbranch conditions to new definitions
Language-Specific Replacement Examples
C/C++ Replacement Example
// SDK2N
long serial = 0;
ER er = MPCANOpen(&serial);
er = MPCANSetParamSimple(CAN_MODE_MONITOR, CAN_REMOTE_DIS, CAN_PARAM_BR_500K, CAN_PARAM_SP_80P);
// ADL2N
StMPXDeviceInfo devices[8] = {};
unsigned char count = 0;
ER er = MPXOpen(devices, 8, &count);
unsigned long serial = (count > 0) ? devices[0].Serial : 0;
StMPXCANParam param = {};
param.EnableTerminate = MPX_CAN_TERMINATE_ENABLE;
param.Mode = MPX_CAN_MODE_MONITOR;
param.ArbitrationBaudrate = MPX_CAN_PARAM_ABR_500K;
param.ArbitrationSamplepoint = MPX_CAN_PARAM_SP_80P;
param.DataBaudrate = MPX_CAN_PARAM_DBR_2M; // set appropriate value when not using CAN FD
param.DataSamplepoint = MPX_CAN_PARAM_SP_80P;
unsigned char innerCh = 1; // target CH (set according to product specification)
er = MPXCANSetParam(serial, innerCh, ¶m);
er = MPXSetGetLogMode(serial, innerCh, MPX_GETLOGMODE_GETLOGAPI); // newly required in migration
C/C++ CAN Simulation Replacement Example (SetSlot to Start)
// SDK2N (example)
StMPCANSlot oldSlots[2] = {};
oldSlots[0].Enabled = CAN_SLOT_ENA;
oldSlots[0].EventKind = CAN_EVENT_PERIODIC;
oldSlots[0].Frame.Id = 0x100;
oldSlots[0].Frame.IdFormat = CAN_ID_STD;
oldSlots[0].Frame.Rtr = CAN_RTR_DATA;
oldSlots[0].Frame.Dlc = 8;
oldSlots[0].Cycle = 100;
MPCANSetSlot(oldSlots, 2);
MPCANMonitorStart();
// ADL2N (example)
StMPXCANParam simParam = {};
simParam.EnableTerminate = MPX_CAN_TERMINATE_ENABLE;
simParam.Mode = MPX_CAN_MODE_SIM;
simParam.ArbitrationBaudrate = MPX_CAN_PARAM_ABR_500K;
simParam.ArbitrationSamplepoint = MPX_CAN_PARAM_SP_80P;
simParam.DataBaudrate = MPX_CAN_PARAM_DBR_2M;
simParam.DataSamplepoint = MPX_CAN_PARAM_SP_80P;
MPXCANSetParam(serial, innerCh, &simParam);
StMPXCANSlot slots[2] = {};
slots[0].FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slots[0].FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC;
slots[0].FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN;
slots[0].FrameType.Option.BRS = MPX_CAN_BRS_DISABLE;
slots[0].FrameType.Option.ErrorAction = MPX_CAN_ERR_BEHAVIOR_ACTIVE;
slots[0].msSendCycle = 100;
slots[0].SendCounter = 0; // unlimited
slots[0].Frame.ID.ID = 0x100;
slots[0].Frame.ID.IDE = MPX_CAN_IDE_STD;
slots[0].Frame.ID.RTR = MPX_CAN_RTR_DATA;
slots[0].Frame.DL = 8;
slots[0].Frame.Data[0] = 0x01;
for (int i = 0; i < 64; i++) {
slots[0].Increment[i] = MPX_CAN_SIM_INC_FALSE;
}
slots[0].Increment[0] = MPX_CAN_SIM_INC_TRUE; // increment only D1
slots[1].FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slots[1].FrameType.FrameType = MPX_CAN_FRAME_TYPE_EVENT;
slots[1].FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN;
slots[1].FrameType.Option.BRS = MPX_CAN_BRS_DISABLE;
slots[1].FrameType.Option.ErrorAction = MPX_CAN_ERR_BEHAVIOR_ACTIVE;
slots[1].Frame.ID.ID = 0x200;
slots[1].Frame.ID.IDE = MPX_CAN_IDE_STD;
slots[1].Frame.ID.RTR = MPX_CAN_RTR_DATA;
slots[1].Frame.DL = 8;
MPXCANSetSlot(serial, innerCh, slots, 2);
MPXMonitorStart(serial, MPX_SYNC_MASTER);
C# (P/Invoke) Replacement Example
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct StMPXDeviceInfo
{
public uint Serial;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] Model;
}
[DllImport("MPXCtrlFree.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MPXOpen(
[In, Out] StMPXDeviceInfo[] devices,
byte num,
ref byte count);
[DllImport("MPXCtrlFree.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MPXCANSetParam(
uint serial,
byte innerCh,
ref StMPXCANParam param);
[DllImport("MPXCtrlFree.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MPXSetGetLogMode(
uint serial,
byte innerCh,
byte mode);
// SDK2N MPCANOpen/MPCANSetParamSimple replacement image
var devices = new StMPXDeviceInfo[8];
byte count = 0;
int er = MPXOpen(devices, (byte)devices.Length, ref count);
uint serial = count > 0 ? devices[0].Serial : 0;
byte innerCh = 1;
er = MPXSetGetLogMode(serial, innerCh, 1); // MPX_GETLOGMODE_GETLOGAPI
Key Points for C# CAN Simulation Replacement
// 1) Set Param in SIM mode
param.Mode = MPX_CAN_MODE_SIM;
er = MPXCANSetParam(serial, innerCh, ref param);
// 2) Set Slot (nested FrameType and Frame.ID)
slots[0].FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slots[0].FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC;
slots[0].FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN;
slots[0].Frame.ID.ID = 0x100;
slots[0].Frame.ID.IDE = MPX_CAN_IDE_STD;
slots[0].Frame.ID.RTR = MPX_CAN_RTR_DATA;
slots[0].Frame.DL = 8;
slots[0].Increment[0] = MPX_CAN_SIM_INC_TRUE;
er = MPXCANSetSlot(serial, innerCh, slots, (byte)slots.Length);
// 3) Start monitoring (slot transmission starts)
er = MPXMonitorStart(serial, MPX_SYNC_MASTER);
Concept is the same when using .NET wrapper DLL (MPXCtrldotNET40Free*.dll).
Excel VBA Replacement Example
' SDK2N
Declare PtrSafe Function MPCANOpen Lib "MPCANCtrl_x64.DLL" (ByRef Serial As Long) As Long
Declare PtrSafe Function MPCANSetParamSimple Lib "MPCANCtrl_x64.DLL" (ByVal Mode As Byte, ByVal RcvRemote As Byte, ByVal Baudrate As Byte, ByVal SamplePoint As Byte) As Long
' ADL2N
Declare PtrSafe Function MPXOpen Lib "MPXCtrlFree_x64.DLL" (ByRef Devices As StMPXDeviceInfo, ByVal Num As Byte, ByRef Count As Byte) As Long
Declare PtrSafe Function MPXCANSetParam Lib "MPXCtrlFree_x64.DLL" (ByVal Serial As Long, ByVal InnerCh As Byte, ByRef Param As StMPXCANParam) As Long
Declare PtrSafe Function MPXSetGetLogMode Lib "MPXCtrlFree_x64.DLL" (ByVal Serial As Long, ByVal InnerCh As Byte, ByVal Mode As Byte) As Long
In VBA, same as old version, it is recommended not to use MPXGetLog / MPXSetLogCallBack directly.
Use MPXCANGetLogEx for log acquisition.
Key Points for Excel VBA CAN Simulation Replacement
' 1) Set SIM mode
Param.Mode = MPX_CAN_MODE_SIM
Ret = MPXCANSetParam(Serial, InnerCh, Param)
' 2) Set slot
Slots(0).FrameType.Enabled = MPX_CAN_SLOT_ENABLE
Slots(0).FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC
Slots(0).FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN
Slots(0).Frame.ID.ID = &H100
Slots(0).Frame.ID.IDE = MPX_CAN_IDE_STD
Slots(0).Frame.ID.RTR = MPX_CAN_RTR_DATA
Slots(0).Frame.DL = 8
Slots(0).Increment(0) = MPX_CAN_SIM_INC_TRUE
Ret = MPXCANSetSlot(Serial, InnerCh, Slots(0), 2)
' 3) Start
Ret = MPXMonitorStart(Serial, MPX_SYNC_MASTER)
Replacement Guidance for APIs with Large Differences
MPCANChangeSlotData -> MPXCANChangeSlot
Old API mainly updated slot data only.
New API explicitly specifies request type with ReqInfo:
MPX_CAN_SLOT_REQ_NONEMPX_CAN_SLOT_REQ_DATAMPX_CAN_SLOT_REQ_TRGMPX_CAN_SLOT_REQ_DATA_TRG
Choose ReqInfo according to original behavior intention.
MPCANSendDirect/Ex -> MPXCANDirectSend
In new API, build StMPXCANDirect and explicitly set:
Protocol(CAN / CAN FD)BRS(for CAN FD)DL(0..8,12..64)
Do not directly reuse old StMPCANFrame; construct both StMPXCANFrameType and StMPXCANFrame.
Migration Checklist
- DLL names changed from
MPCANCtrl*toMPXCtrlFree* -
MPCANOpenreplaced withMPXOpen(Devices/Num/Count) -
SerialandInnerChare correctly specified in all new API calls -
MPCANSetParamSimple/Detailconsolidated intoMPXCANSetParam -
StMPCANFrame/Slot/Logreplaced withStMPXCAN* -
EventKindnumeric dependencies are replaced withMPX_CAN_FRAME_TYPE_* - CAN simulation start flow replaced to
SetParam(SIM) -> SetSlot -> MonitorStart -
MPCANGetLogExreplaced withMPXCANGetLogEx, buffer design updated forunsigned short -
MPCANChangeSlotDatareplaced withMPXCANChangeSlot,ReqInfodesigned - Old ER numeric branch logic updated to new definitions
-
Protocol/BRS/DL/Data[64]verified for CAN FD usage
Related Pages
- Common API list: /S810-MX-ADL2N/Common/api_list_common
- Common API details: /S810-MX-ADL2N/Common/api_detail_common
- CAN API list: /S810-MX-ADL2N/CAN/api_list_can
- CAN API details: /S810-MX-ADL2N/CAN/api_detail_can
- CAN structure definitions: /S810-MX-ADL2N/CAN/struct_can
- Notes for .NET: /S810-MX-ADL2N/Common/dotnet