[dorkbotpdx-blabber] assembler on the arduino?
Paul Stoffregen
paul at pjrc.com
Mon Jan 28 14:06:29 EST 2008
Ultimately, your assembler is going to produce a .hex file which is an
ascii encoded copy of the raw data that needs to be programmed into the
MEGA168 chip. All you need to do is write that code into the MEGA168
chip, run it, and have some way to observe what it's doing so you can
debug it (unless you never make any mistakes!)
There are 2 ways to program code into the MEGA168 chip.
#1: if the chip already has a bootloader programmed in, you can cause
the bootloader to run and it will receive a download of code and write
it into the chip (except for the portion which already has the
bootloader, of course). This is how the arduino is normally used.
#2: by connecting to a few pins, you can directly program code into any
portion of the chip. This is the only way to initially write the
bootloader. To do this, you need to buy or build hardware that
manipulates the special programming pins. For example:
http://www.arduino.cc/en/Hacking/ParallelProgrammer This is the way I
have always programmed the Atmel AVR chips, though my custom-build
hardware is quite different, the idea is the same.
There is actually another way, pretty much the same as #2, but many more
pins are used for a small speed increase. It's pretty much only used to
program the chips in high volume production.
Usually, to observe what your code is doing, you'll send data via the
UART to your PC serial port. You can use the arduino software or any
terminal emulator to view it. You can also toggle output pins, which
gives a lot less info but also takes a lot less time. There are also
expensive in-circuit emulator products that let for more or less
directly observe stuff, but if you have the arduino, you're probably not
going to buy one of those.
Also, there are 2 different approaches to assembly language.
Most commonly, people opt to write mostly in C and code tiny pieces in
assembly. C is a lot less work than assembly, so the reasoning goes
that you can do everything "easily" in C that isn't speed critical, then
only do the "hard work" on a few little sections. This is true,
however, the compiler will impose a lot of constraints on your assembly
code. Entry and exit from functions requires parameter passing using
pre-defined registers (and the stack if more params), most other
registers have to be saved if you use them, and so on. Your freedom to
allocate the registers is severely constrained. While you don't have to
write very much assembly this way, the bits you do write have many rules
to follow. That makes it more difficult and puts a lot of limits on you
(basically the same limits the compiler has, though you're a lot smarter
than the compiler and will still do a better job, even playing by its
rules).
The other approach is to write everything in assembly. Without the
compiler's requirements, you have a lot more freedom. Some people would
say a lot more rope to hang yourself. But just to give you an idea, the
main difference (which matters most on the AVR) is that you get to
decide about register allocation on a global scale. You can, for
instance, decide to dedicate several registers to some interrupt routine
that needs a bunch of variables (quite common), rather than having to
slowly (and with lots of extra code) push the registers onto the stack,
load the variables from memory, and then to the reverse on exit from the
interrupt. All you have to do is simply not use those registers
anywhere else (or disable interrupts, but if you're coding such high
performance interrupt handlers, disabling interrupts for any length of
time is probably the last thing you'll want to do). There are a lot of
ways to achieve much faster, much smaller code than is ever possible
with the compiler, if it's never used anywhere and you don't have to
obey its rules.
So, if you really want to do an all assembly approach the "hard way" (as
Don will happily tell you I'm crazy to do), first try writing a very
simple bit of assembly code to just toggle a pin in an infinite loop.
It should be only a dozen bytes of output. Then build that parallel
port cable and try getting the MEGA168 chip to run it, using a 'scope or
multimeter (DC volts 2.5 if it's toggling high/low rapidly at 50%) or
even an LED to observe the pin. Then try sending some bytes out the
UART while watching via a terminal emulator. Once you get to that
stage, well, you'll be well on your way.
But in all likelihood, if your course is using the arduino, it may be
other approach of using C with little bits of assembly.
-Paul
More information about the dorkbotpdx-blabber
mailing list