Context
Arm.license() reads the licence block from the firmware. It waits with:
_, p = arm.expect(P.RSP_LICENSE, timeout, "get_license")
expect() (src/litearm/arm.py:668) routes replies by the (uplink id, echo code) pair, and its docstring states the rule:
want 是 RSP_ACK/RSP_ERR 时 echo_cmd 必填(见 _wait_keys)
license() asks for RSP_LICENSE, not for ACK/ERR, so it passes no echo_cmd and waits on the (RSP_LICENSE, kNoEcho) queue.
Expected
On firmware that does not implement the licence command, the firmware's refusal reaches the caller as a rejection naming the command, in the same way every other command's refusal does.
Actual
Firmware below 1.8.0 has no licence command, so it answers the unrecognised opcode through its default branch with ERR{0x2F, 0x00}. That reply is routed under (RSP_ERR, 0x2F), while this call is waiting on (RSP_LICENSE, kNoEcho). The two never meet, the wait runs out, and the caller is told the link did not answer:
MotionTimeoutError: get_license 无应答 (超时 1.0s)
The message points at the serial link or at a silent firmware. The actual situation is that the firmware answered immediately and said it does not know the command. Anyone debugging this will reach for the cable first.
Reproduce
By inspection of expect's queue keying against license()'s call, on a board running firmware below 1.8.0.
I have not run it against this implementation. The behaviour was characterised on real hardware in the C++ port, and src/litearm/arm.py line for license() plus expect at :668 is where it comes from.
Suggested direction
Either pass echo_cmd=P.CMD_LICENSE and make expect accept it for non-ACK/ERR wants, or explicitly wait on both queues so a matching ERR{0x2F, ...} ends the wait with the firmware's reason. The second keeps _wait_keys unchanged.
Context
Arm.license()reads the licence block from the firmware. It waits with:expect()(src/litearm/arm.py:668) routes replies by the(uplink id, echo code)pair, and its docstring states the rule:license()asks forRSP_LICENSE, not forACK/ERR, so it passes noecho_cmdand waits on the(RSP_LICENSE, kNoEcho)queue.Expected
On firmware that does not implement the licence command, the firmware's refusal reaches the caller as a rejection naming the command, in the same way every other command's refusal does.
Actual
Firmware below 1.8.0 has no licence command, so it answers the unrecognised opcode through its
defaultbranch withERR{0x2F, 0x00}. That reply is routed under(RSP_ERR, 0x2F), while this call is waiting on(RSP_LICENSE, kNoEcho). The two never meet, the wait runs out, and the caller is told the link did not answer:The message points at the serial link or at a silent firmware. The actual situation is that the firmware answered immediately and said it does not know the command. Anyone debugging this will reach for the cable first.
Reproduce
By inspection of
expect's queue keying againstlicense()'s call, on a board running firmware below 1.8.0.I have not run it against this implementation. The behaviour was characterised on real hardware in the C++ port, and
src/litearm/arm.pyline forlicense()plusexpectat:668is where it comes from.Suggested direction
Either pass
echo_cmd=P.CMD_LICENSEand makeexpectaccept it for non-ACK/ERRwants, or explicitly wait on both queues so a matchingERR{0x2F, ...}ends the wait with the firmware's reason. The second keeps_wait_keysunchanged.