To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.nxt.nxthackingOpen lugnet.robotics.nxt.nxthacking in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / NXT / NXT Firmware Hacking / 14
13  |  15
Subject: 
Enhanced standard NXT firmware
Newsgroups: 
lugnet.robotics.nxt.nxthacking, lugnet.robotics, lugnet.robotics.nxt
Date: 
Fri, 16 Mar 2007 23:41:15 GMT
Highlighted: 
(details)
Viewed: 
20653 times
  
Over the past couple days I have used the IAR Embedded Workbench to implement
some enhancements and bug fixes for the standard NXT firmware.

The bug fixes are as follows:

1. RIC drawing code incorrectly checked the size of the OP_LINE structure for
OP_PIXEL operations making it impossible to use the pixel operation without a
workaround.

2. RIC drawing code left out the case for the OP_CIRCLE operation making it
impossible to use circle operations in RIC files.

3. RIC drawing code was limiting the user arguments to 0xF (16 entries) via a
mask which should have been 0xFF (allowing for 256 entries).

4. Internal IOMapWrite and IOMapRead calls were unnecessarily limited to 64
bytes.  This limit has been raised to 800 bytes (which is the number of bytes of
normal and popup display memory).

The enhancements are as follows:

1. New syscall functions

  a. IOMapReadByID and IOMapWriteByID.  These two syscall functions use a ULONG
module id rather than a module name to read or write to the module IOMAP.  This
eliminates the overhead of a FINDFIRSTMODULE call (which does several string
comparisons) and a CLOSEMODULEHANDLE call.

The syscall function ID values are IOMapReadByID = 34, IOMapWriteByID = 35.  The
structures for calling these syscall functions are:

TIOMapReadByID struct
  Result    sbyte
  ModuleID  long
  Offset    word
  Count     word
  Buffer    byte[]
TIOMapReadByID ends

TIOMapWriteByID struct
  Result   sbyte
  ModuleID long
  Offset   word
  Buffer   byte[]
TIOMapWriteByID ends

The module IDs are:
CommandModuleID  = 0x00010001
OutputModuleID   = 0x00020001
InputModuleID    = 0x00030001
ButtonModuleID   = 0x00040001
CommModuleID     = 0x00050001
IOCtrlModuleID   = 0x00060001
SoundModuleID    = 0x00080001
LoaderModuleID   = 0x00090001
DisplayModuleID  = 0x000A0001
LowSpeedModuleID = 0x000B0001
UIModuleID       = 0x000C0001


Here are my test results of calling IOMapRead and IOMapReadByID with each test
executing 10000 iterations.  Times are in milliseconds:

Test                   | IOMapRead  | IOMapReadByID |
-----------------------|------------|---------------|
UI Module Battery Lvl  |    3252    |     1206      |
Loader Module Free Mem |    2408    |     1183      |
-----------------------------------------------------

  c. DisplayExecuteFunction.  This system call exposes the Display module
function pointer and lets you execute any of the supported drawing functions via
that pointer.  The supported functions are

  0 DISPLAY_ERASE_ALL()
  1 DISPLAY_PIXEL(On, X1, Y1)
  2 DISPLAY_HORIZONTAL_LINE(On, X1, Y1, X2)
  3 DISPLAY_VERTICAL_LINE(On, X1, Y1, Y2)
  4 DISPLAY_CHAR(On, X1, Y1, Y1) (Y1 is the Char ascii value)
  5 DISPLAY_ERASE_LINE(X1) (X1 is line number, 0-7)
  6 DISPLAY_FILL_REGION(On, X1, Y1, X2, Y2) (X2 & Y2 are width & height
downward; 63-Y1 & Y2 must be multiples of 8)
  7 DISPLAY_FRAME(On, X1, Y1, X2, Y2) (X2 & Y2 are width & height downward)

The ability to set or clear a pixel via the *_LINE functions using the On
parameter is also an enhancement (they used to only support set).

The syscall function ID is DisplayExecuteFunction = 36.  The structure used to
execute this syscall function is:

TDisplayExecuteFunction struct
  Status byte
  Cmd    byte
  On     byte
  X1     byte
  Y1     byte
  X2     byte
  Y2     byte
TDisplayExecuteFunction ends

Here are my test results of calling DisplayExecuteFunction with each test
executing 10000 iterations.  Times are in milliseconds:

Test                    |   Timing   |
------------------------|------------|
DISPLAY_ERASE_ALL       |    2881    |
DISPLAY_PIXEL           |    1165    |
DISPLAY_HORIZONTAL_LINE |    1490    |
DISPLAY_VERTICAL_LINE   |    1237    |
DISPLAY_CHAR            |    2234    |
DISPLAY_ERASE_LINE      |    1410    |
DISPLAY_FILL_REGION     |    1537    |
DISPLAY_FRAME           |    1474    |
--------------------------------------


  d. CommExecuteFunction.  This system call exposes the Comm module function
pointer and lets you execute any of the supported communication functions via
that pointer.  The supported functions are

   0 SENDFILE(Param1, Name)
   1 SEARCH()
   2 STOPSEARCH()
   3 CONNECT(Param1, Param2)
   4 DISCONNECT(Param1)
   5 DISCONNECTALL()
   6 REMOVEDEVICE(Param1)
   7 VISIBILITY(Param1)
   8 SETCMDMODE()
   9 OPENSTREAM(Param2)
  10 SENDDATA(Param1, Param2, Param3, Name) (length, port, ?, buffer)
  11 FACTORYRESET()
  12 BTON()
  13 BTOFF()
  14 SETBTNAME()
  15 EXTREAD()
  16 PINREQ()
  17 CONNECTREQ()

The syscall function ID is CommExecuteFunction = 37.  The structure used to
execute this syscall function is:

TCommExecuteFunction struct
  Result word
  Cmd    byte
  Param1 byte
  Param2 byte
  Param3 byte
  Name   byte[]
  RetVal word
TCommExecuteFunction ends

  d. LoaderExecuteFunction.  This system call exposes the Loader module function
pointer and lets you execute any of the supported file system functions via that
pointer.  The supported functions are

  0x80 OPENREAD(FileName, Length)
  0x81 OPENWRITE(FileName, Length)
  0x82 READ(FileName, Buffer, Length)
  0x83 WRITE(FileName, Buffer, Length)
  0x84 CLOSE(FileName)
  0x85 DELETE(FileName)
  0x86 FINDFIRST(FileName, Buffer, Length)
  0x87 FINDNEXT(FileName, Buffer, Length)
  0x89 OPENWRITELINEAR(FileName, Length)
  0x8A OPENREADLINEAR(FileName, Buffer, Length)
  0x8B OPENWRITEDATA(FileName, Length)
  0x8C OPENAPPENDDATA(FileName, Length)
  0x90 FINDFIRSTMODULE(FileName, Buffer)
  0x91 FINDNEXTMODULE(Buffer)
  0x92 CLOSEMODHANDLE()
  0x94 IOMAPREAD(FileName, Buffer, Length)
  0x95 IOMAPWRITE(FileName, Buffer, Length)
  0xA0 DELETEUSERFLASH()
  0xA3 RENAMEFILE(FileName, Buffer, Length)

The syscall function ID is LoaderExecuteFunction = 38.  The structure used to
execute this syscall function is:

TLoaderExecuteFunction struct
  Result   word
  Cmd      byte
  FileName byte[]
  Buffer   byte[]
  Length   long
TLoaderExecuteFunction ends

2. Set or Clear when drawing.  Not only is this exposed via the new
DisplayExecuteFunction syscall function, but it is also exposed via the existing
display syscall functions.  With DrawPoint, DrawLine, DrawRect, and DrawCircle
you can set the 0x04 bit (DRAW_OPT_CLEAR_PIXELS) in the Options field of the
arguments structure then instead of setting the pixels on, these functions will
turn off (clear) the affected pixels.  Additionally, in RIC files the various
opcode structures within the file can set this bit in the CopyOptions field in
order to clear rather than set the affected pixels.

3. Speed enhancements.  I have tweaked some of the drawing routines to improve
speed.  The vertical line drawing function draws a byte at a time rather than
one bit at a time now.  The erase line and erase screen functions now are
optimized to use memset rather than iterate and set a single byte at a time.
The DrawRect system function now directly uses the DRAW_HORIZONTAL_LINE and
DRAW_VERTICAL_LINE drawing commands rather than drawing one pixel at a time.
The DrawLine system function directly calls these same two drawing commands if
the line is horizontal or vertical and if the start and end points are the same
it calls the set pixel routine just once.

Here are my test results of calling the standard drawing system calls with each
test executing 10000 iterations.  Times are in milliseconds:

Test                  | JCHFirm | NXT 1.04 |
----------------------|---------|----------|
DrawRect              |  1879   |   4473   |
DrawLine (Horizontal) |  1431   |   3297   |
DrawLine (vertical)   |  1256   |   3590   |
DrawLine (Diagonal)   |  3715   |   3617   |
--------------------------------------------

So even though in each of the drawing routines there is extra logic which allows
for either setting or clearing the affected pixels the optimized routines are
significantly faster than the standard NXT firmware routines (with the exception
of the diagonal line case).

4. SetScreenMode system call function now also lets you clear the screen in
addition to its existing behavior (which was to just restore the default NXT
screen).

My goal is to persuade LEGO to incorporate these changes into the standard NXT
firmware.  The problem is they don't have the manpower to test these changes
in-house.  And pretty thorough testing with NXT-G is needed to make sure that
the baseline product doesn't experience problems due to the fixes and
enhancements I've made.  What I hope can happen is that many members of the LEGO
Robotics community can step forward and volunteer to test this enhanced firmware
using NXT-G, the LabView NXT toolkit, and NBC or NXC.  If we can together put in
hundreds of hours of testing of these fixes and enhancements then perhaps LEGO
will release these changes in a future firmware update.

Thank you in advance for your willingness to help.  You do good work!

The enhanced NXT firmware can be downloaded from
http://bricxcc.sourceforge.net/lms_arm_jch.zip

Extract the .a79 file and download it to your NXT using NeXTTool, BricxCC, the
LEGO MINDSTORMS NXT software, the ATMEL SAMBA utility, or your favorite firmware
downloader.  You may need to rename it with a .rfw extension in order to use the
standard NXT software to download it.  The firmware image does not contain any
files and its size fits into the 1.04 firmware size so any files on your NXT
should continue to work okay but it is possible that you will need to reload
your sounds, icons, and programs.

Please post here or email me if you are testing the firmware.  Also, please
report by posting on the Lugnet nxt hacking newsgroup (or by emailing me) any
problems you encounter while running with the enhanced firmware installed on
your NXT.  You can tell that you are running the enhanced firmware because it
reports 1.05 as its version number.

I can provide sample code in NBC and/or NXC which demonstrates how to use these
new features to anyone who needs it.

John Hansen



Message has 3 Replies:
  Re: Enhanced standard NXT firmware
 
(...) <snipped description> Holy crap John! You've been really busy! For anyone poking around in this forum, I can say that what John has done is pretty significant. I have written my own firmware for the brick so I know how much work must have gone (...) (17 years ago, 17-Mar-07, to lugnet.robotics.nxt.nxthacking, lugnet.robotics, lugnet.robotics.nxt)
  Re: Enhanced standard NXT firmware
 
... (...) Hi John, I just tried to load it and just tested the "Try-me" light sensor. It worked fine. Not so much help, but I can try some more another day. Good work. Rasmus (...) (17 years ago, 19-Mar-07, to lugnet.robotics.nxt.nxthacking, lugnet.robotics, lugnet.robotics.nxt)
  Re: Enhanced standard NXT firmware
 
"John Hansen" <afanofosc@comcast.net> wrote in message news:JF0sGr.M2w@lugnet.com... (...) implement (...) big snip Great job John. And thank you especially for CommExecuteFunction. I couldn't believe that Lego didn't allow a way to make a Bluetooth (...) (17 years ago, 28-Mar-07, to lugnet.robotics.nxt.nxthacking, lugnet.robotics, lugnet.robotics.nxt)

7 Messages in This Thread:



Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR