|
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:
7 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|