This document describes how to use MMLite on the Atmel EB63 board.
If MMLite is already in FLASH the steps are:
If your board came stright from the vendor (a new board should have an Angel debug monitor in the STD half) and does not yet have MMLite in FLASH you will need to:
If there is neither Angel debug monitor nor MMLite in FLASH you will need to use Wiggler to upload MMLite to Eb63 board (see How to use Wiggler to upload MMLite to Eb63 board).
Other information is provided in the following sections:
If you have grabbed the "latest" tree this is trivial. If you are getting stuff from SSafe you need to put the tools in place first. Look at the tree in latest for the schema. And ask your friendly devs if you need more help :-)).
One environment variable is mandatory, a few others are optional.
The MMLITE_SDK envvar should be set to the top of your MMLite tree. To build outside of the source tree you should define the MMLITE_BUILD_DIR envvar appropriately.
set MMLITE_SDK=c:\MMLite
The are a few batch files that you can (per)use:
mkall.bat -- builds everything but the documentation
mkdoc.bat -- builds the documentation
You will need at least two builds, one is the ARM proper and one is for the hostfsd server (who runs on the PC under Win2k).
To build hostfsd do the following:
cd %MMLITE_SDK%
nmake -nologo TARGETCPU=i386 TARGETTYPE=release
This will also build what we call "the simulator", which infact runs at full speed under Win2k. Try something like this to get an idea:
cd %MMLITE_SDK%\build\i386\release\bin
ntu
> mmdoom.exe
You can kill NTU.EXE by hitting ^C.
To build the ARM version do the same:
cd %MMLITE_SDK%
nmake -nologo TARGETCPU=arm TARGETTYPE=release
Note that this will not give you a whole lot of symbols, just the bare minimum. For full symbols (and somewhat larger images) select the debug build instead:
cd %MMLITE_SDK%
nmake -nologo TARGETCPU=arm TARGETTYPE=debug
One option is to build MMLite as release and your own app as debug. See below for this combo.
The Atmel board needs two different cables: a cross-over and a normal. Let us call Cable-1 the
cross-over one and Cable-2 the normal one.
Cable-1 has a female connector on the PC side, and a male connector on the Atmel side.
The Atmel socket for this cable is the female one, the one furthest from the socket for the power supply.
Cable-1 can provide a host file system, a network connection (see Ethernet over serial line on
the eb63) and a console simultaneously.
Cable-2 has a female connector on both sides. Guess which socket it goes into. You can Cable-2 as the
second host file system, network connection or console as you want. By default, Cable-2 is used as provide the
second network connection.
It is a brilliant idea to check the cables first. If MMLite is already
installed in the USER half of flash memory (see How to (re)flash the MMLite base),
plug Cable-1 into your PC on COM2 and take the following steps to test Cable-1.
You can test Cable-2 in the same way.
If MMLite is not in the flash memory but the Angel debug monitor is in the STD
half (a new board got from the manufactory has an Angel debug monitor in the STD
half), you can take the following steps to test Cable-1:
Plug Cable-1 into your PC on COM2.
This server is a combination of the old hostfsd server, hostnic server and console. It will export the directory where you start it
as the filesystem "root". MMLite will see that direstory as fs if you are using a RAM version, or as srfs
if ROM version. The eb63 has no ethernet chip but it has serial lines. Serplexd
can play a network proxy (see Ethernet over serial line on
the eb63). It also provides a console. Normally you run it (assuming Cable-1
plugs into your PC on COM2):
cd %MMLITE_SDK%\build\arm_gnu\debug\bin
%MMLITE_SDK%\build\i386\release\bin\serplexd.exe COM2
If you don't need network proxy, just run:
cd %MMLITE_SDK%\build\arm_gnu\debug\bin
%MMLITE_SDK%\build\i386\release\bin\serplexd.exe COM2 -n
But in this case we want to verify that things are working, so we'll start it in a more verbose mode:
cd %MMLITE_SDK%\build\arm_gnu\debug\bin
%MMLITE_SDK%\build\i386\release\bin\serplexd.exe -verb -verb COM2
If you are using an old version (older than v0.28) MMLite, you should use hostfsd_old.exe instead of serplexd.exe on the Windows side.
This server will export the directory where you start it as the filesystem "root".
MMLite will see that directory as fs.
Normally you run it without arguments:
cd %MMLITE_SDK%\build\arm_gnu\debug\bin
%MMLITE_SDK%\build\i386\release\bin\hostfsd_old.exe
But in this case we want to verify that things are working, so we'll start it in a more verbose mode:
cd %MMLITE_SDK%\build\arm_gnu\debug\bin
%MMLITE_SDK%\build\i386\release\bin\hostfsd_old.exe -writeable -verb -verb COM1
Here we also tell the server to let the board make changes to the filesystem (-writeable), to use COM1 (see cabling above, this is the other cable we did not test), and to be rather verbose about it. This way we'll see if the cable actually works. If it doesn't, this window will show no activity. If it does, a lot of junk will scroll past.
There are a few other options like chosing the baudrate, look at the sources for details.
NB: MMLite will normally be in FLASH and the EB63 board will boot into it when the E7 jumper is set to the USER position.
This section only applies if the E7 jumper is in the STD position, and the board boots to the Angel debug monitor.
We also assume Cable-1 plugs into your PC on COM2.
This phase uses the ARM RDI protocol, implemented in the Angel boot monitor which is FLASHed on the board. Type this:
%MMLITE_SDK%\tools\arm_gnu\gdb //c/MMLite/build/arm_gnu/release/bin/eb63.exe
(gdb) target rdi com2 57600
Angel Debug Monitor.....
Serial Rate: 57600
(gdb) load
Loading section .text, .....
Transfer rate: 13186 bits/sec.
(gdb) c
This assumes the value for MMLITE_SDK we used above, change as needed.
After the last command the system is running. Since it switches to a different debug protocol, the debugger will get confused. You should just kill the gdb. A ^C sometimes works, sometimes you must resort to Win2k's task manager. After you kill the gdb, you should start serplexd immediately (see Start the serplexd server)
To avoid typing this all the times you can use debugger scripts.
For example, the commands above could be in a text file called x:
target rdi com2 57600
load
c
and you would tell GDB to "source x" or just "so x".
Normally the system proceeds directly to initializing and looking for the first app. So you are done here, move to the next step.
If you are making changes to the base system and do not like this you should change the file src\base\md\arm\eb63\_startEb63.s where it conditionally calls DebugBreak.
That function will drop it into the debugger, this time using the REMOTE protocol.
So here we go again:
%MMLITE_SDK%\tools\arm_gnu\gdb -baud 38400 //c/MMLite/build/arm_gnu/release/bin/eb63.exe
(gdb) path //c/MMLite/build/arm_gnu/debug/bin
(gdb) target remote COM2
Remote debugging using COM2
0x200801c in _start ()
Notice this time we are saying on the command line what baudrate to use. Also, we are assuming you'll be using a debug build for your own application, hence the somewhat inconsistent "path" command. You will probably put breakpoints around or whatever. Once you are satisfied you can let the system proceed without debugger:
(gdb) detach
Now we'll see if the second cable works. If MMLite has initialized correctly it will look for the first app. Hostfsd should start dumping out a lot of characters and saying it is opening the file "tzk.exe" and reading from it. It will stop by saying it did not open the file "init.tzk".. unless of course you have one laying around.
Once the debug shell tzk.exe is running it will print on COM1 something like this:
fs/init.tzk not found.
>
At this point you can type to the debug "shell" (ahem..). You should use hyperterminal (on COM1, 38400, as previously indicated) for interaction with the debug shell and your application.
This can also be done via GDB, albeit it is quite a bit crummy and pretty broken. Do not type too fast, for example. There is also a bug somewhere, and the first three character you want to be typing are ^J (line-feed) ^M (return) ^C. Then say "continue" and type away. Slowly. You will need to make changes in the base system for this to work, ask your friendly devs :-))
Say your application is called himom.exe. You can start it like this:
> himom.exe
The shell will wait until the application terminates, then regain control. You can also start your app in the background, for instance:
> start httptest.exe
Either way, hitting the SW4 pushbutton will drop you in the debugger, where you can set breakpoints, single step etc etc.
You will have symbols for any code that is loaded, not just your app.
There are a couple of other ways to start your application, which you might consider.
The first is to replace the file tzk.exe with your app.
This means that your app will be executed immediately at startup, the debug shell will not be loaded and will not take up any memory resources.
You can also edit the file src\base\md\arm\eb63\_firstEb63.c and make it start your app instead of the debug shell.
Just change the constant string FIRST_IMAGE_NAME.
This is possibly one way to setup for ship, while retaining flexible FLASH upgrade possibilities.
The second way is to link your app directly into the base MMLite image.
You can look at the file above to see what the function FirstThread() does.
You can edit the makefile conf\package\eb63.mk to select which modules to include in the building of the eb63.exe image.
The base system creates the first thread to start executing FirstThread(), it entirely up to you what you want that thread to do.
By editing or replacing src\base\md\arm\eb63\_firstEb63.c you can remove/add/replace other components as well.
What goes into the base image can and should be optimized for what your application actually requires.
If you do not need to load any images you can use the null loader src\loaders\no_ldr.c.
If you do not need any sort of filesystems just drop them from the link, after removing their initialization calls.
These are typically named InitXXXFileSystem, currently there are three filesystems to chose from.
You might not need any device drivers. If so, do not load the COBs from the FirstThread and drop their libraries from the link.
Finally, the notion of a "console" might not apply beyond debugging.
Ifso, drop the call to InitConsole/InitDebugConsole from FirstThread.
As you become more expert with the base system you can discover other ways to remove functionality that you do not require.
Look at the file src\base\baseinit.c to see what is done from the moment the system boots and before the first thread is executed.
Have fun!
The EB63 board can hold two separate boot monitors in its FLASH. It uses the E7 jumper to select between the two. When the jumper is in the STD position, the address line A20 is normally passed to the FLASH device [a 2MB AT49BV1604 chip]. Consequently, the first portion of the chip is used for booting, approximately 64KB in the first 8 sectors. The ARM Angel boot monitor resides in this portion of the chip, and we advise that you leave it alone as a safeguard.
When the jumper is in the USER position the A20 line is negated. Consequently, the second portion of the chip is used for booting, starting at sector No. 24. MMLite fits comfortably in this one 64KB sector.
It is important to note that the sectors of the FLASH chip are not of identical size. Please be careful in following the instructions provided herein, it is easy to make mistakes and render your board inoperable. Also note that the FLASH device has a relatively limited rewrite life. You do not have the patience to reflash that many times, but a program does. It is not advisable to include code that rewrites the flash in your own application, if it ever goes wild it might endup writing in the wrong place or loop too many times.
The program EB_FLASH.EXE knows how to write to the FLASH device.
It is meant for flashing MMLite into the second part of the FLASH, and/or
putting the initial application and data files in there. As provided,
it assumes the E7 jumper is set to the USER position unless you explicitly
tell it otherwise (see below).
After booting to the debug shell (tzk.exe) and assuming that hostfsd.exe is running in the proper directory on your Win2k PC, you should type the following:
eb_flash.exe 1000000 fs\eb63.bin 0The first argument is the address at which the FLASH is visible. There is some sanity checking built into the program, it will try to make sure the device is indeed one of the FLASH devices it knows about [either a 16x0 or a 16x4T]. If it does not recognize the device it will terminate.
The second argument is the name of the MMLite image. Notice how this is not the .EXE file you would feed to the debugger for downloading, but rather its .BIN brother, which is an image stripped of the ELF header.
The third argument should be zero when in USER. Leave it out when STD. The third argument tells eb_flash the offset within the flash where to write. 0 is at beginning, default middle of memory, i.e. beginning of other bank.
When the program asks "Did you make sure that Strap E7 is in the USER position?", be truthful! eb_flash will not work if it assumes wrong.
When flashing the image for the first time after booting from Angel do
eb_flash.exe -std 1000000 fs\eb63.binThe -std flag tells eb_flash.exe that it should assume E7 is STD intentionally. Once you've done this, move E7 to USER (shut off the power first). MMLite should now boot when you power the board back on (serial @38400 bauds).
The EB63 board can easily be setup with MMLite for standalone use.
The file src\base\md\arm\eb63\_firstEb63.c can either start
HostFs or RomFs, or both.
For standalone use, RomFs should be used and registered as the root filesystem.
The default arguments provided to the constructor RomFsNew()
will make it look for a filesystem image at address 0x1180000,
and sanity-check it for a maximum filesystem image size of 256KB.
To (re)place a RomFs image at that address in FLASH the following command should be used:
> eb_flash.exe -std 1000000 fs\eb63.flp 80000Make sure that the setting of the E7 jumper is the correct one. It should match what
EB_FLASH.EXE will ask you to verify.
In the example above, we assumed E7==STD, as described in
the previous section.
> eb_flash.exe 1000000 fs\eb63.flp 180000
There is an utility (in the src\tests directory) called DUMP.EXE
that can be used to inspect the content of FLASH memory before/after a rewrite.
For example, a board that came directly from Atmel should have no data in the third quarter of the FLASH. The following test (E7==STD) should therefore print
a (long!) sequence of 0xffffffff values.
> dump.exe 1080000 1081000Again, the arguments are different if E7==USER (1180000).
ROM_HEADER
in the source file src\storage\romfs\romfs.c
$(MMLITE_SDK)\tools\bin\mkmemfs.
To recap the previous two sections: The flash is divided into two halves, one megabyte each. The halves are swapped by the USER/STD dip switch. There is no way to probe the dip switch from software so you have to tell it by hand (if you get it wrong, the flash content will get corrupted). Each half is further divided into two halves each, one for the boot image, the other one for a file system.
The makefiles build three relevant images: eb63fs.flp - a file system image; eb63.bin - the base setup to run from RAM and to read files from hostfs over the serial line; and eb63big.bin - the base linked together with many cobs, set up to run straight from flash and to use the file system image on flash (RomFS, eb63fs.flp).
Once you have booted your device one time using Angel, there is no need for it anymore. You could, e.g. use the STD half for the image (eb63.bin) that boots from hostfs, making it easy to use it for further reflashing, and use the USER half for an image (eb63big.bin). If you use the USER half for an image (eb63big.bin), you must also flash the file system image (eb63fs.flp) into the USER half.
When you boot from STD, the Flash is at 0x01000000,
eb_flash.exe -std 1000000 fs/eb63big.bin
eb_flash.exe -std 1000000 fs/eb63fs.flp 180000
eb_flash.exe -std 1000000 fs/eb63.bin 0
eb_flash.exe -std 1000000 fs/eb63fs.flp 80000
When you boot from USER, the Flash is at 0x01000000,
eb_flash.exe 1000000 fs/eb63big.bin 0
eb_flash.exe 1000000 fs/eb63fs.flp 80000
eb_flash.exe 1000000 fs/eb63.bin
eb_flash.exe 1000000 fs/eb63fs.flp 180000
"$S05#b8" to appear on the debug line (COM2 in this setup).
To attach the debugger to the running system do the following:
%MMLITE_SDK%\tools\arm_gnu\gdb -baud 38400 //c/MMLite/build/arm_gnu/release/bin/eb63.exe
(gdb) path //c/MMLite/build/arm_gnu/debug/bin
(gdb) dir //c/MyApplication/src/...
(gdb) target remote COM2
The wiggler is a cheap JTAG interface. See www.ocdemon.com for ordering info and free software. We have no affiliation. We just tried it. Ask them if it doesn't work :). Here is what we had to do:
/usr/local/bin/OcdLibRemote -c ARM7 -d WIGGLER
copy build\arm_gnu\debug\bin\eb63.exe c:\cygwin\tmp\OCDemon\arm\AtmelAT91\
and run from the directory OCDemon/arm/AtmelAT91 of a second cygwin "bash" shell window:
/usr/local/arm/bin/arm-elf-gdb -nw
And then type
(arm-gdb) load
eb63.exe
Loading section .text, size 0x1d77c lma 0x2008000
Loading section .data, size 0x32c lma 0x202577c
Start address 0x2008000, load size 121512
Transfer rate: 108010 bits/sec, 510 bytes/write.
(arm-gdb) symbol-file eb63.exe
Reading symbols from eb63.exe...done.
(arm-gdb) c
Continuing.
Note: Remember to recopy eb63.exe after rebuilding it.
%MMLITE_SDK%\build\i386\debug\bin\serplexd COM2
Assume Cable-1
plugs into your PC on COM2.
bt prints a stack trace.b *0x22222222 breaks at the specified addressx/i $pc disassembles at the program counterp somevar prints the value of the specified variableb *4 makes the debugger stop at DebugBreak().symbol-file eb63big.exe loads the symbols without trying to load the image.