Communication Protocols Command Questions

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
behanius
Posts: 8
Joined: 18 May 2011, 20:05

Communication Protocols Command Questions

Post by behanius »

Hello,

I am trying to write some C functions to read and write files to the NXT Brick. However, I am not entirely sure what the difference is between commands, .e.g write vs. write linear.

Does anyone know the difference?

Btw I'm looking at 'Appendix 1-LEGO MINDSTORMS NXT Communication protocol.pdf' in the NXT Bluetooth Developers Kit.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Communication Protocols Command Questions

Post by afanofosc »

Linear files are written across contiguous 256 byte blocks of flash memory. Non-linear files can span non-contiguous blocks of flash memory. RIC files and RXE|RTM|SYS files (all executables) must be linear. Other files can (and should) be non-linear. You can look at the BricxCC source code (in FantomSpirit.pas) to see how I use these different file types to write files to the NXT.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
behanius
Posts: 8
Joined: 18 May 2011, 20:05

Re: Communication Protocols Command Questions

Post by behanius »

afanofosc wrote:Linear files are written across contiguous 256 byte blocks of flash memory. Non-linear files can span non-contiguous blocks of flash memory. RIC files and RXE|RTM|SYS files (all executables) must be linear. Other files can (and should) be non-linear. You can look at the BricxCC source code (in FantomSpirit.pas) to see how I use these different file types to write files to the NXT.

John Hansen
Thank you, John: this really helps! I'll definitely check out the source code too.
behanius
Posts: 8
Joined: 18 May 2011, 20:05

Re: Communication Protocols Command Questions

Post by behanius »

Hello John (and everyone else),

I've been able to successfully write both *.rso and *.ric files with the open write data command. I've found that the brick will return an error if *.ric files are not written using the open write data command.

Now I'm trying to write a *.rtm file, e.g. Try-Touch.rtm, using the open write linear command (followed by a write command). The file does not previously exist on the brick. The error I keep getting is 0x84, where the Lego documentation says it means "End of File expected." I'm not entirely sure what to make of this error as I only receive it for the last data packet. I've posted the following output from my program that prints the data packet received from a write command (after open write linear has been sent successfully). The data packet is of the form

02--83--StatusByte--HandleNumber--LSB_WrittenBytes--MSB_WrittenBytes

and the output is below

02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--00--00--3D--00
02--83--84--00--12--00


Any help would be most appreciated. Thanks.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Communication Protocols Command Questions

Post by afanofosc »

RIC files definitely cannot be non-linear. They will not work when they are drawn if they are not contiguous in flash memory.

Code: Select all

function NameToNXTFileType(name : string) : TNXTFileType;
var
  ext : string;
begin
  Result := nftOther;
  ext := AnsiLowercase(ExtractFileExt(name));
  if (ext = '.rso') or (ext = '.rmd') then
    Result := nftSound
  else if ext = '.rdt' then
    Result := nftData
  else if (ext = '.ric') then
    Result := nftGraphics
  else if (ext = '.rxe') or (ext = '.sys') or (ext = '.rtm') then
    Result := nftProgram
end;

  size := aStream.Size;
  if filetype in [nftProgram, nftGraphics] then
    Result := NXTOpenWriteLinear(nxtFilename, size, handle)
  else if filetype = nftData then
    Result := NXTOpenWriteData(nxtFilename, size, handle)
  else
    Result := NXTOpenWrite(nxtFilename, size, handle);
  if Result then
  begin
    // write in < 64 byte chunks
    xferred := 0;
    aStream.Position := 0; // start at the beginning
    while xferred < size do
    begin
      cnt := Min(size - xferred, kNXT_MaxBytes-3);
      // fill our buffer with the right number of bytes
      for i := 0 to cnt - 1 do
        aStream.Read(buf.Data[i], 1);
      // write these bytes to the NXT
      Result := NXTWrite(handle, buf, cnt, cnt = (size - xferred));
      if not Result then Break;
      inc(xferred, cnt);
    end;
    Result := NXTCloseFile(handle) and Result;
  end;

function TFakeSpirit.NXTWrite(var handle: FantomHandle; const buffer: NXTDataBuffer;
  var count: word; const chkResponse: boolean): boolean;
var
  cmd : TNxtCmd;
  b : byte;
  len : integer;
begin
  Result := Open;
  if not Result then Exit;
  cmd := TNxtCmd.Create;
  try
    if chkResponse then
      b := kNXT_SystemCmd
    else
      b := kNXT_SystemCmdNoReply;
    len := fLink.Send(cmd.MakeCmdWriteFile(b, kNXT_SCWrite, handle, count, buffer.Data));
    if chkResponse then
    begin
      if len <> 3 then
      begin
        Result := False;
        Exit;
      end;
      handle := fLink.GetReplyByte(0);
      count  := fLink.GetReplyWord(1);
    end;
    Result := len >= kRCX_OK;
  finally
    cmd.Free;
    if fAutoClose then Close;
  end;
end;
As you can see, I use the NoReply form of a system command for all the packets except for the last one. This code definitely works. And RIC files written as linear files draw correctly. You really should just use OpenWrite or OpenWriteLinear.

I checked the firmware source code also and the only time you get EOFEXSPECTED is if you try to write more bytes in the last packet than there is room left in the file. As you can see above, the last packet is smaller than all the other packets (assuming the size is not a multiple of 61).

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
behanius
Posts: 8
Joined: 18 May 2011, 20:05

Re: Communication Protocols Command Questions

Post by behanius »

afanofosc wrote: ...
I checked the firmware source code also and the only time you get EOFEXSPECTED is if you try to write more bytes in the last packet than there is room left in the file. As you can see above, the last packet is smaller than all the other packets (assuming the size is not a multiple of 61).

John Hansen
Thanks for your insights, John. I adjusted setting the last packet size and it works now. I've also been able to do this for reading files as well :D
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest