Resolving MotoPlus Alarms 1020, 1050, 4207 on Yaskawa Robots
When a motoPlus application fails to start on a Yaskawa Motoman robot controller (DX100, DX200, FS100, YRC1000, YRC1000micro), the controller typically reports one of three alarm groups: 1020 (application load error), 1050-[1] (HMI/teach pendant communication loss), or 4207-[1101] (unresolved application symbol). This reference covers the most common boot-time failure mode reported in the field: a motoPlus application that compiles cleanly, produces a valid .OUT file, but stops at the boot screen with the teach pendant marked as disconnected. Three independent root causes are usually stacked in the same project: a function pointer cast to an undefined or wrongly-named function, a while(1) loop without mpTaskDelay, and a leftover .OUT file from a previous build. This article details each alarm, isolates the underlying defect, and provides a verified fix sequence.
Problem Summary
The defect reproduces deterministically when the developer creates three tasks in mpUsrRoot() with mpCreateTask(...), then enters a tight receive loop of the form:
void mpOnRecvData() {
while (1) {
RecvCount = mpRecv(SockHandle, RecvBuf, 100, 0);
}
}
On first download the controller reports 1050-[1] and 4207-[1101] and stops at the boot screen. The teach pendant shows loss-of-communication with the Dx-class CPU. If the developer comments the mpRecv call but leaves the while(1) empty, the controller still fails. Only when the offending task is removed entirely does the application run. Inserting a single mpTaskDelay(1) inside the loop is sufficient to recover full operation. A separate but related fault, alarm 1020-[1], appears when more than one .OUT file is present on the controller at boot time. DX100 systems additionally exhibit sub-code 1020-[5] when the MotoPlus License Manager (MPLM) is not loaded before any other application.
Affected Controllers, Firmware, and Toolchain
All Yaskawa Motoman controllers that ship the motoPlus runtime are susceptible. The set in current field deployment includes:
| Controller | MotoPlus Runtime | IDE | Toolchain | Notes |
|---|---|---|---|---|
| DX100 | MotoPlus32 v3.x | MPLID (motoPlus IDE) | gcc for SH-2A / SH-2 | 1020-[5] sub-code observed when MPLM is not loaded first |
| DX200 | MotoPlus32 v4.x | MPLID | gcc for SH-2A | Standard successor to DX100 |
| FS100 | MotoPlus32 v3.x | MPLID | gcc for SH-2A | Common in third-party ROS/Ethernet driver deployments |
| YRC1000 | MotoPlus64 v1.x | MPLID-E (64-bit) | x86_64 cross compiler | 64-bit pointer model; default task stack differs from 32-bit SDKs |
| YRC1000micro | MotoPlus64 v1.x | MPLID-E | x86_64 cross compiler | Compact cabinet variant; documented 1020 load error in Yaskawa KB |
Where the documentation you have on hand references a specific firmware/SDK build number (for example "MotoPlus32 Ver. 3.20-00" or "YAS2.81"), use that as the local pin against which you validate register and prototype signatures; the alarm codes documented below are stable across the listed runtime versions. The Yaskawa Motoman knowledge base entries that confirm the 1020 sub-codes are YRC1000MICRO ALARM CODE 1020 MOTOPLUS (APPLICATION LOAD ERROR) and DX100 ALARM CODE 1020 [5] MOTOPLUS APPLICATION LOAD ERROR.
Root Cause #1: Function Pointer Mismatch in mpCreateTask
The mpCreateTask prototype declared in motoPlus.h requires a function pointer of type FUNCPTR that takes ten int arguments. The cast in C is unchecked at compile time when the function is declared with the extern storage class but never actually defined. The compiler accepts the build, the linker resolves the symbol from another translation unit or, more commonly, emits a 0x00000000 entry in the task descriptor. At boot the motoPlus kernel dereferences that entry and the controller reports:
4207-[1101] // APPLICATION SYMBOL NOT FOUND (MotoPlus task entry point)
The defect typically appears in projects that grew by copy/paste. A representative broken declaration is:
// header.h
extern void mpRecvData(int a1, int a2, int a3, int a4, int a5,
int a6, int a7, int a8, int a9, int a10);
// main.c
Task_id3 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE,
(FUNCPTR)mpRecvData, // BUG: function does not exist
arg1, arg2, arg3, arg4, arg5,
arg6, arg7, arg8, arg9, arg10);
The real function name in the source is mpOnRecvData, not mpRecvData. The C cast hides the prototype mismatch because FUNCPTR is a void (*)(void) typedef on most motoPlus SDKs. There is no warning, no link error, and no runtime error at task creation; the failure is deferred to the first dispatch.
The fix is to ensure the function passed to mpCreateTask exists with the documented prototype, or to wrap the user function in a thin shim. The recommended shape is:
// Always declare the entry point exactly as motoPlus requires
static void taskRecvEntry(int a1, int a2, int a3, int a4, int a5,
int a6, int a7, int a8, int a9, int a10)
{
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
(void)a6; (void)a7; (void)a8; (void)a9; (void)a10;
mpOnRecvData();
}
Task_id3 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE,
(FUNCPTR)taskRecvEntry,
arg1, arg2, arg3, arg4, arg5,
arg6, arg7, arg8, arg9, arg10);
Because the wrapper is defined in the same translation unit that calls mpCreateTask, the compiler can validate the prototype and the linker can resolve the symbol deterministically. The shim is also the cleanest place to pass user context via static state if the arg1..arg10 parameters are not sufficient.
Root Cause #2: Cooperative Scheduling and the Missing mpTaskDelay
Yaskawa Motoman motoPlus uses a non-preemptive, priority-ordered cooperative scheduler. Each task runs to completion of its current iteration, then yields. A task that contains a tight while(1) loop without any blocking primitive starves the scheduler, including the kernel-internal task that services the HMI/watchdog channel. Within a few hundred milliseconds of power-on the controller detects the missing heartbeat and trips:
1050-[1] // HMI (teach pendant) communication error; the controller cannot
// exchange I/O with the Dx-class CPU within the watchdog window.
Because alarm 1050 is also the alarm generated when the teach pendant is physically disconnected, faulted, or replaced, the symptom is initially misread as a pendant hardware issue. The motoPlus task starvation produces the same alarm code with the same sub-code. The fact that the same alarm appears after commenting the mpRecv call (but leaving the while(1)) confirms the scheduler-starvation theory: even an empty while(1) without any blocking call starves the kernel in tens of milliseconds.
The motoPlus kernel provides two cooperative blocking primitives. mpTaskDelay(int ticks) blocks the calling task for the specified number of system clock ticks, and mpTaskDelay(SYS_CLK_RATE / 50) produces a 50 ms period (one tick per millisecond on most motoPlus configurations; verify SYS_CLK_RATE in your local SDK header). mpSemTake(...) with timeout is the second option and is preferable when the receive should wake on data availability, not on a fixed period.
// Correct: cooperative receive loop
void mpOnRecvData(void)
{
while (1) {
RecvCount = mpRecv(SockHandle, RecvBuf, RECV_LEN, 0);
if (RecvCount < 0) {
mpTaskDelay(10); // back off on socket error
} else {
mpTaskDelay(1); // yield, ~1 tick
}
}
}
The single mpTaskDelay(1) call inside the loop is what restored operation in the field case. With the delay in place the controller boots cleanly, the teach pendant remains connected, and the receive task services incoming data at full Ethernet rate without impacting the kernel heartbeat.
while(1) in a motoPlus task must contain at least one of: mpTaskDelay(), mpSemTake() with timeout, mpMsgQueueReceive() with timeout, or a blocking I/O call (mpRecv with a non-zero timeout flag, mpDevRecv). A bare while(1) {} is functionally equivalent to a deadlock for every other task on the controller.Root Cause #3: Multiple .OUT Files and Load Order (Alarm 1020)
Alarm 1020 is the motoPlus application load error. It is generated at boot by the motoPlus loader when it cannot decide which .OUT file to start, when a required .OUT is missing, or when the load order of co-resident applications is wrong. The sub-codes encountered in practice are:
| Sub-code | Controller | Trigger | Resolution |
|---|---|---|---|
| 1020-[1] | DX / DX200 / FS100 / YRC1000 | More than one .OUT file present on the controller | In maintenance mode, delete all .OUT files except the intended application |
| 1020-[5] | DX100 | MotoPlus License Manager (MPLM) not loaded before the application | Load MPLM first, then load the user .OUT; reboot in the prescribed order |
| 1020 (no sub-code) | YRC1000micro / YRC1000 | Generic application load failure: file integrity, symbol resolution, .OUT size, or controller mismatch | Rebuild, confirm FTP transfer, confirm controller class match |
Sub-code 1020-[1] is by far the most common. Each MPLID build produces a .OUT that is dropped into the motoPlus application slot via FTP or the maintenance menu. If an old build is not deleted, two .OUT files coexist and the loader refuses to pick a winner. Maintenance mode is the only state from which files in the motoPlus application directory can be deleted while the controller is in a faulted state. Navigate to Main Menu → Maintenance → MotoPlus Application, list files, and delete everything except the one binary you intend to run. The Yaskawa Motoman knowledge base documents this procedure for YRC1000micro in YRC1000MICRO ALARM CODE 1020 MOTOPLUS (APPLICATION LOAD ERROR).
Sub-code 1020-[5] is specific to DX100. The MotoPlus License Manager (MPLM) is a small .OUT that arbitrates concurrent access to motoPlus features; it must be present and must be loaded before any other .OUT. If the application slot contains the user .OUT but not MPLM, or if MPLM is in a higher slot number, the loader raises 1020-[5] and aborts startup. The fix is to copy MPLM into the controller first, reboot, confirm the alarm clears, then load the user .OUT. The Yaskawa Motoman knowledge base documents this in DX100 ALARM CODE 1020 [5] MOTOPLUS APPLICATION LOAD ERROR.
Alarm Code Reference
The following table consolidates the alarm codes that surface during a motoPlus boot failure. Use the alarm history viewer (F2 → Alarm History on most DX/YRC teach pendants) to capture the exact sub-code before clearing.
| Alarm | Sub-code | Meaning | Likely Cause | First Action |
|---|---|---|---|---|
| 1020 | 1 | Multiple .OUT files on controller | Old build not deleted | Maintenance mode → delete extras |
| 1020 | 5 | MPLM not loaded first (DX100) | License manager missing or in wrong slot | Load MPLM, reboot, then user .OUT |
| 1020 | (none) | Generic .OUT load error | File corrupted, wrong controller class, file too large | Rebuild, verify controller match |
| 1050 | 1 | HMI / teach pendant communication broken | Pendant cable, pendant fault, OR motoPlus task starving the kernel | Check task loops for mpTaskDelay
|
| 4207 | 1101 | Application symbol not found | Undefined function passed to mpCreateTask via (FUNCPTR) cast |
Verify symbol name and prototype |
| 4107 | 4 | Application initialization fault |
mpUsrRoot returns before tasks are created, or a motoPlus API call in mpUsrRoot fails |
Step mpUsrRoot in the simulator and inspect return codes |
The 1050 and 4207 codes are typically reported together when the underlying cause is a function pointer mismatch: 4207 fires when the loader resolves the task entry, and 1050 fires as a secondary effect when the resulting dispatch loop starves the kernel. Resolving the function name removes both alarms in one step.
Step-by-Step Diagnosis Procedure
- Place the controller in Maintenance mode: from the teach pendant, select Main Menu → System → Security → Management and enter the maintenance password, then cycle power.
- Open Main Menu → Maintenance → MotoPlus Application. List the .OUT files present. More than one file in the slot is a 1020-[1] condition.
- Capture the alarm history (F2 → Alarm History) and write down the full sub-code for each entry. Do not clear until the cause is identified.
- Open the MPLID project. For each call to
mpCreateTask, confirm the third argument resolves to a defined function in the same project. Use the IDE's "Go to definition" on the symbol to verify. - Grep the source for
while\s*\(1\)and audit every occurrence. Each must contain a blocking motoPlus API ormpTaskDelay. - Confirm the Ethernet socket is created with
mpSocketand bound withmpBindbefore any task attempts to receive. A nullSockHandlepassed tompRecvreturns immediately with a negative code, which is enough to keep a tight loop alive without starving the kernel — the symptom then shows up later, not at boot. - Rebuild the project with full warnings enabled. MPLID's default build suppresses some warnings; enable
-Wall -Wextrain the project options to surface prototype mismatches. - Transfer the .OUT to the controller and reboot. Observe the boot screen for 60 seconds; if 1050 clears within 5 seconds of pendant handshake, the kernel heartbeat is healthy.
Step-by-Step Resolution Procedure
- Fix the function pointer. Rename the task entry function in the source so the symbol exists, or wrap it in a static shim that calls the user function. Rebuild.
-
Add a yield in every infinite loop. Insert
mpTaskDelay(1)at the bottom of everywhile(1). For the 50 ms periodic sender, usempTaskDelay(SYS_CLK_RATE / 50)or compute the tick count from your SDK'sSYS_CLK_RATEmacro. - Resolve duplicate .OUT files. In maintenance mode, delete every .OUT file in the motoPlus application slot except the intended one. Confirm the file count is exactly 1 (or 2 if MPLM is required on DX100).
- Verify the load order on DX100. If MPLM is required, confirm it is the first .OUT in the slot, then reboot, then load the user application.
- Re-build with warnings as errors. Set Project Properties → C/C++ Build → Settings → Warnings → -Werror to make prototype mismatches fail the build.
- Transfer the new .OUT via FTP (anonymous, port 21) into the motoPlus application directory, or via the maintenance menu's MotoPlus Application → Install entry.
- Cycle power on the controller. The motoPlus loader runs early in the boot sequence; a soft reset does not re-run the loader on most controller classes.
- Verify boot: the teach pendant should reach the main menu within 30 seconds with no 1050 alarm. The alarm history should be empty after a controlled reset.
- Verify the application: trigger a 50 ms send burst from the peer, confirm data on the wire, and confirm the receive callback fires. A motoCom trace (motoCom32 on 32-bit controllers, motoCom64 on YRC1000) or a packet capture on the Ethernet segment can validate the period.
Verification and Field Commissioning
After the resolution is applied, run the following verification sequence before handing the cell back to production:
- Pendant handshake. Confirm the teach pendant reaches the main menu and the controller does not report 1050. The pendant should not flash the comm-loss indicator.
- Alarm history clean. Reset the alarm history, reboot, and confirm 1020, 1050, and 4207 do not reappear.
- Task CPU budget. From the maintenance menu, view the motoPlus task load if exposed in your SDK build. A well-behaved Ethernet client should report single-digit percentage CPU. A starved kernel will report 99% on the offending task and starvation on the kernel task.
- End-to-end data path. Send a known pattern from the peer at 50 ms intervals, confirm arrival at the receive task, and confirm the response is emitted within the deadline. Latency should be bounded and stable.
- Stress test. Run the application for 24 hours. Watch for latent alarm entries in the history. Starvation defects often manifest as 1050 within 15-30 minutes of a heavy loop.
- Recovery test. Pull the pendant cable while the application is running. The controller should report 1050 (physical disconnect). Reconnect the cable; the pendant should handshake and the application should resume. If 1050 persists after reconnection, the motoPlus task is starving the kernel even on the "good" path.
MotoPlus Task Design Best Practices
These rules distill the field failures into reusable guidelines. Treat them as pre-merge checks for every motoPlus commit.
-
Always yield in
while(1). Every infinite loop must contain a blocking API ormpTaskDelay. A bare loop is a kernel-killer. -
Avoid
externdeclarations for task entry points. Define them in the same translation unit that callsmpCreateTask, or in a header with the full motoPlus prototype. This makes prototype mismatches a compile error. -
Wrap user code in a shim. The shim has the motoPlus prototype and calls into your real function. This decouples motoPlus ABI from your API and prevents the
externfoot-gun. - One task per role. A receiver task, a sender task, and a main task is a clean split. Do not run the receive loop inside the main task; the main task should set up sockets and resources, then idle or exit.
-
Bound the receive buffer and length. Hard-code the receive length to a named constant.
mpRecv(SockHandle, RecvBuf, 100, 0)with a 100-byte buffer is acceptable; a dynamically computed length is a vector for stack corruption. -
Check return codes from every motoPlus API.
mpRecv,mpSend,mpSocket,mpBind,mpConnect, andmpAcceptall return negative codes on error. Treat the error path as the hot path: log, back off withmpTaskDelay, and retry. -
Set stack size explicitly. Default
MP_STACK_SIZEis small. Recursive parsers, largeprintfbuffers, and STL-style code can overflow the default. Pass a larger literal and confirm the build accepts it. -
Use
SYS_CLK_RATEfor timing math. Hard-coded millisecond constants inmpTaskDelayassume a tick rate. Use the macro so the same source builds against SDK variants that change the rate. - Delete old .OUT files after every build transfer. Maintenance mode is fast. A 5-second delete is cheaper than a 30-minute debug of 1020-[1].
- Keep MPLM in the lowest slot on DX100. The loader expects it first. If a developer tool has reordered slots, move MPLM back to slot 0 before rebooting.
- Distinguish motoPlus from motoCom. motoPlus is the on-controller C runtime; motoCom32 / motoCom64 is the off-controller PC-side SDK that talks to the controller over Ethernet. A peer that cannot connect is almost always a motoCom configuration problem, not a motoPlus alarm.
- Confirm controller class at build time. YRC1000/YRC1000micro require the 64-bit motoPlus SDK; DX/DX200/FS100 require the 32-bit SDK. A 32-bit .OUT loaded on a YRC1000 raises a generic 1020 with no sub-code.
Troubleshooting Matrix
| Symptom | First Alarm | Likely Cause | Verify | Fix |
|---|---|---|---|---|
| Robot stuck at boot, pendant dark | 1050-[1] | Kernel starvation by motoPlus task | Grep while(1) for missing mpTaskDelay
|
Add mpTaskDelay(1) at loop bottom |
| Boot alarm, .OUT not loaded | 1020-[1] | Multiple .OUT files | Maintenance menu → file count | Delete extras, reboot |
| Boot alarm, .OUT not loaded (DX100) | 1020-[5] | MPLM not first | Maintenance menu → slot order | Move MPLM to slot 0, reboot |
| Alarm during first task dispatch | 4207-[1101] | Function pointer to undefined symbol | IDE "Go to definition" on cast target | Define symbol, rebuild |
| Pendant works, app crashes on socket open | 4107-[4] | Socket creation failed in mpUsrRoot
|
Check mpSocket return code |
Validate socket handle before passing to task |
| Pendant comm error after a long idle | 1050-[1] | Receive task loop on error path | Check error branch of while(1)
|
Yield on negative return from mpRecv
|
| 1020 with no sub-code, fresh .OUT | 1020 | File corruption or wrong controller class | Re-build for exact controller model | Re-build, re-transfer, confirm SDK match |
| Pendant works, peer cannot connect | (none) | motoCom / Ethernet server config, not motoPlus | Confirm TCP port and server mode | Re-check peer SDK; no motoPlus code change needed |
FAQ
What does alarm 1050-[1] mean on a DX or YRC controller?
Alarm 1050-[1] is the HMI (teach pendant) communication error. It fires when the controller does not exchange I/O with the teach pendant within the watchdog window. The cause can be a physical pendant fault, a cable issue, or a motoPlus task that starves the kernel because its while(1) loop contains no mpTaskDelay or other blocking call.
Why does my .OUT file fail to load with alarm 1020-[1]?
Alarm 1020-[1] is raised when more than one .OUT file is present in the motoPlus application directory at boot. The loader cannot pick a winner. Enter maintenance mode, navigate to Main Menu → Maintenance → MotoPlus Application, and delete every .OUT file except the one you intend to run, then cycle power.
How do I fix alarm 1020-[5] on a DX100 controller?
Alarm 1020-[5] is specific to DX100 and indicates that the MotoPlus License Manager (MPLM) is not loaded before the user application. Copy MPLM into the motoPlus application slot first, reboot, confirm the alarm clears, and only then load the user .OUT. The Yaskawa Motoman knowledge base documents this in DX100 ALARM CODE 1020 [5] MOTOPLUS APPLICATION LOAD ERROR.
What causes alarm 4207-[1101]?
Alarm 4207-[1101] is the motoPlus application symbol-not-found alarm. It fires at task dispatch when a function pointer passed to mpCreateTask resolves to an undefined or wrongly-named symbol. The C cast (FUNCPTR) suppresses the prototype check at compile time, so the defect only manifests at runtime. Define the entry function in the same translation unit, or wrap it in a shim that has the documented motoPlus prototype, then rebuild.
Why does adding mpTaskDelay(1) in a while(1) loop fix the boot alarm?
The motoPlus scheduler is cooperative. A while(1) loop with no blocking call pegs the calling task at 100% CPU and starves the kernel task that services the teach pendant heartbeat. Within a few hundred milliseconds the controller misses the heartbeat and trips 1050-[1]. Inserting mpTaskDelay(1) yields the scheduler once per loop iteration, restoring heartbeat timing and clearing the alarm.
Can I keep the receive loop tight to get lower latency?
No. A tight receive loop in motoPlus always produces a 1050 alarm once it runs long enough to starve the kernel. For lower latency, use mpRecv with a non-zero timeout flag (the documented blocking mode for your SDK) so the call blocks on the socket and wakes when data is available, then yields automatically. This achieves the latency of a tight loop without starving the kernel.