LEGO Mindstorms EV3 |
Beside running user programs the VM is able to execute direct commands from the Communication Module. In fact direct commands are small programs that consists of regular byte codes and they are executed in parallel with a running user program.
Special care MUST be taken when writing direct commands because the decision until now is NOT to restrict the use of "dangerous" codes and constructions (loops in a direct command are allowed).
If a new direct command from the same source is going to be executed an actual running direct command is terminated.
Because of a small header objects are limited to one VMTHREAD only - SUBCALLs and BLOCKs is of course not possible.
This header contains information about number of global variables (for response), number of local variables and command size.
Direct commands that has data response can place the data in the global variable space. The global variable space is equal to the communication response buffer. The composition of the direct command defines at which offset the result is placed (global variable 0 is placed at offset 0 in the buffer).
Offset in the response buffer (global variables) must be aligned (float/32bits first and 8 bits last).
Direct Command Bytes: ,------,------,------,------,------,------,------,------, |Byte 0|Byte 1|Byte 2|Byte 3|Byte 4|Byte 5| |Byte n| '------'------'------'------'------'------'------'------' Byte 0 – 1: Command size, Little Endian\n Byte 2 – 3: Message counter, Little Endian\n Byte 4: Command type. see following defines */ #define DIRECT_COMMAND_REPLY 0x00 // Direct command, reply required #define DIRECT_COMMAND_NO_REPLY 0x80 // Direct command, reply not required /* Byte 5 - 6: Number of global and local variables (compressed). Byte 6 Byte 5 76543210 76543210 -------- -------- llllllgg gggggggg gg gggggggg Global variables [0..MAX_COMMAND_GLOBALS] llllll Local variables [0..MAX_COMMAND_LOCALS] Byte 7 - n: Byte codes Direct Command Response Bytes: ,------,------,------,------,------,------,------,------, |Byte 0|Byte 1|Byte 2|Byte 3| | | |Byte n| '------'------'------'------'------'------'------'------' Byte 0 – 1: Reply size, Little Endian\n Byte 2 – 3: Message counter, Little Endian\n Byte 4: Reply type. see following defines */ #define DIRECT_REPLY 0x02 // Direct command reply #define DIRECT_REPLY_ERROR 0x04 // Direct command reply error /* Byte 5 - n: Response buffer (global variable values)
opOUTPUT_START Example
Start motor connected to port A with speed 20: Byte codes: opOUTPUT_POWER,LC0(0),LC0(0x01),LC0(20), opOUTPUT_START,LC0(0),LC0(0x01) \ / \ / Hex values send: 0C00xxxx800000A4000114A60001
opOUTPUT_STOP Example
Stop and float motor connected to port A: Byte codes: opOUTPUT_STOP,LC0(0),LC0(0x01),LC0(0), \ / \ / Hex values send: 0900xxxx800000A3000100
opINPUT_READ Example
Read sensor connected to port 1: Byte codes: opINPUT_READ,LC0(0),LC0(0),LC0(0),LC0(0),GV0(0), \ / \ / Hex values send: 0B00xxxx0001009A0000000060 Hex values received: 0400xxxx0200 ^- | Command global variable (response buffer offset) 0=sensor value.
opINPUT_DEVICE GET_NAME Example
Read sensor name connected to port 1: Byte codes: opINPUT_DEVICE,LC0(0),LC0(0),LC0(GET_NAME),LC0(16),GV0(0), \ / \ / Hex values send: 0B00xxxx001000990000151060 Hex values received: 1300xxxx024F70656E202020202020202020202000 ^------------------------------- | Command global variable (response buffer offset) 0..15=sensor name "Open ".
opINPUT_DEVICE_LIST Example
Get all device types connected to input ports: Byte codes: opINPUT_DEVICE_LIST,LC0(4),GV0(0),GV0(4), \ / \ ------- \ / Hex values send: 0900xxxx00050098046064 Hex value received: 0800xxxx027E7E7E7D00 ^--------- | Command global variable (response buffer offset) 0=port 1 type, 1=port 2 type, 2=port 3 type, 3=port4 type, 4=change flag.
opMEMORY_WRITE Example
Write 0x01 0x02 0x03 0x04 0x05 into global variable 4..8 of user program running in slot 1: opINIT_BYTES,LV0(0),LC0(5),1,2,3,4,5, opMEMORY_WRITE,LC0(1),LC0(0),LC0(4),LC0(5),LV0(0), Bytes actually sent to brick: 1300xxxx8000142F400501020304057E0100040540 bbbbmmmmtthhhhccccccccccccccccCCCCCCCCCCCC bbbb = bytes in message, mm = message counter, tt = type of command, hhhh = header, cc/CC = byte codes. hhhh = 10 least significant bits are number of globals, 6 most significal bits are locals Bytes received from brick: 0600xxxx02 bbbbmmmmtt bbbb = bytes in message, mm = message counter, tt = type of command, rr = global variables (response).
opMEMORY_READ Example
Read global variable 4..8 from user program running in slot 1: opMEMORY_READ,LC0(1),LC0(0),LC0(4),LC0(5),GV0(0), Bytes actually sent to brick: 0B00xxxx0005007F0100040560 bbbbmmmmtthhhhcccccccccccc bbbb = bytes in message, mm = message counter, tt = type of command, hhhh = header, cc = byte codes. hhhh = 10 least significant bits are number of globals, 6 most significal bits are locals Bytes received from brick: 0800xxxx02xxxxxxxxxx bbbbmmmmttrrrrrrrrrr bbbb = bytes in message, mm = message counter, tt = type of command, rr = global variables (response).
opINFO GET_ID Example
Read 6 bytes ID from brick: opINFO,LC0(GET_ID),LC0(6),GV0(0) Bytes actually sent to brick: 0900xxxx0006007C000660 bbbbmmmmtthhhhcccccccc bbbb = bytes in message, mm = message counter, tt = type of command, hhhh = header, cc = byte codes. hhhh = 10 least significant bits are number of globals, 6 most significal bits are locals Bytes received from brick: 0900xxxx02xxxxxxxxxxxx bbbbmmmmttrrrrrrrrrrrr bbbb = bytes in message, mm = message counter, tt = type of command, rr = global variables (response).
opPROGRAM_START Example
Run app byte code file (../apps/tst/tst.rbf) in user slot (1): opFILE,LC0(LOAD_IMAGE),LC0(USER_SLOT),LCS,'.','.','/','a','p','p','s','/','t','s','t','/','t','s','t','.','r','b','f',0,LV0(0),LV0(4), opPROGRAM_START,LC0(USER_SLOT),LV0(0),LV0(4),LC0(0), Bytes actually sent to brick: 2400xxxx800020C00801802E2E2F617070732F7473742F7473742E7262660040440301404400 bbbbmmmmtthhhhccccccccccccccccccccccccccccccccccccccccccccccccccccCCCCCCCCCC bbbb = bytes in message, mm = message counter, tt = type of command, hhhh = header, cc/CC = byte codes. hhhh = 10 least significant bits are number of globals, 6 most significal bits are locals
opPROGRAM_STOP Example
Stop program in user slot (1): opPROGRAM_STOP,LC0(USER_SLOT), Bytes actually sent to brick: 0700xxxx8000000201 bbbbmmmmtthhhhcccc bbbb = bytes in message, mm = message counter, tt = type of command, hhhh = header, cc/CC = byte codes. hhhh = 10 least significant bits are number of globals, 6 most significal bits are locals