Date: 2009-05-16 12:56:00
emulino: arduino cpu emulator

About a week ago I got an Arduino board for some project ideas. Naturally, one of the things I looked for was a free, cross-platform emulator that could run AVR code on a desktop machine. I only found one on Sourceforge which was started a few months ago but development seems to have stalled. So I decided to write my own. How hard could it be?

The AVR CPU is a pretty simple 8-bit microcontroller. Instruction words are all 16 bits wide, and only a handful of instructions have an additional 16 bit data word following the instruction. Given the instruction set reference, I wrote a script to help create a big 64k table of function pointers, one for each possible instruction. The main loop looks something like this:

for (;;) {
    u16 instr = Program[PC++];
    Instr[instr](instr);
}

This loads the next instruction word into instr. Then that value is used as an index into the Instr function pointer table, and calls the function at that index with the instruction word as an argument. The instruction implementation function can then pull apart the instruction word if it needs to. For example, this is the implementation of the LDI instruction, which loads a constant value into a register:

static void do_LDI(u16 instr)
{
    // ----KKKKddddKKKK
    u16 K = (instr & 0xf) | ((instr >> 4) & 0xf0);
    u16 d = 16 + ((instr >> 4) & 0xf);
    Data.Reg[d] = K;
    Cycle++;
}

It turns out there are only 93 distinct instruction words that need to be implemented. I've got 80 of the important ones working, plus some basic peripherals like the USART for serial communications, EEPROM storage, and the simplest timer that could possibly work. With that, many of the sample programs that come with the Arduino IDE run perfectly, plus it can run simple Java code using NanoVM!

I have a long list of ideas to build around this emulator core, including:

I called the emulator emulino, which in addition to being a combination of emulator and Arduino, also happens to be an obscure conjugation (third person plural present subjunctive) of the Italian verb emulare, "to emulate".

You can find the current code on Github in the emulino project.

[info]goulo
2009-05-16T05:55:27Z
What? No mention of the Esperanto meaning of "emulino"? I'd go loosely with "a willing woman". :)
[info]ghewgill
2009-05-16T07:15:33Z
Good point, the thought had occurred to me but I'd sort of forgotten that you can form more-or-less complete words using only suffixes. Dankon por tio, tio povas esti la "enŝerco". :)
[info]pne
2009-05-16T16:51:48Z
I once saw "emigisto" glossed as "animateur" (or whatever you call the chap on cruise ships or holiday camps who tries to make sure people are having fun, or are at least occupied).
[info]paradox0220
2009-05-18T15:31:43Z
I've worked with Xilinx FPGAs at work and LOVE those things. They have everything from tiny FPGAs to almost whole computer systems in a chip depending on what you want.
(anonymous) : Nice work, dude!
2009-06-12T18:43:01Z
Nice work! I too wrote a simple simulator for the 8051 core and that was way back in 2002 when I was still learning to program, It can be downloaded from http://sf.net/gsim51.
(anonymous) : Tutorial ?
2009-10-05T10:32:18Z
Could you post a mini-tutorial ?

I got emulino compiled on Mac OS X using tools from MacPorts, but now I'm stuck with emulino looking for a binary image ...

Thanks !
[info]ext_219257 : Error while compiling
2009-12-20T14:25:29Z
Hi Greg and thank you very much for sharing your work.
I found Emulino while looking for an Arduino emulator to make some safe exercises. I've got just a little knowloedge of programming, probably not enough to make the code work since I'm unable to compile it correctly under Windows XP (32bit).
After messing a while with gcc + Cygwin (which returned a lot of errors) I tried loading and compiling the "emulino.pro" file with the Nokia QT SDK (http://qt.nokia.com/downloads) which returns 5 errors totally, the first is: "cpu.c:1169: error: avr.inc: No such file or directory".
Hoping to compile the project with the right tool, can you tell where I can retrieve the avr.inc file, please? Or else, would you suggest a better tool to compile the project?
Many thanks

Andrea
[info]logic_lj : Re: Error while compiling
2010-02-14T04:53:24Z
Install scons, and run that first. The Qdevelop project doesn't generate the avr.inc file, you need to kick off mkinst.py to do that, and the easiest way for someone to quickly get up and running is to use the provided SConstruct with scons to build it.

Short answer: install scons, run "scons" in the checked-out directory, then play with it in qdevelop. :)
[info]logic_lj
2010-02-14T04:51:16Z
Just a quick note: I built this today on a relatively recent Linux distro (Fedora 12), and one quick change was needed (aside from the hard-coded paths) to emulino-gui.cpp; you used perror() without including stdio.h. :)

If anyone else is reading this, to build on Fedora, you'll need the scons package to build the CLI version (just run "scons" in your cloned git repo), and the resulting "emulino" executable will take a compiled hex image (from the Arduino GUI) as an argument.

For the gui version, both qt-devel and qdevelop packages will be needed. Load up emulino.pro into qdevelop, and run a build; the resulting "emulino" executable will be what you're looking for. Note that, toward the end of emulino-gui.cpp, there's a bunch of Greg-specific paths that you'll want to adjust to point at the image you want to run.

Really good stuff; integration of something like this into the arduino IDE itself would be a godsend for debugging (I'm using the drag-and-drop interface like Fritzing as inspiration here). You'll never cover every conceivable use case, but being able to simulate inputs on the analog and digital pins (clickable push-buttons, pots, voltage sliders) and providing a few really common outputs (LED, maybe a piezo ;-) would get you most of the way there.
[info]mako34 : tutorial
2010-02-20T21:29:06Z
hi, this is great (more if it worked for me and the newbiees!)

how to compile this plz,
linux or win

Thanks
(anonymous) : Will you make a tarball?
2010-05-13T17:19:07Z
I really dont do good with version control systems ;)
I want a .tar or .zip file!
[info]ghewgill : Re: Will you make a tarball?
2010-05-13T19:25:44Z
Sure, just go to the github project page and click "Download Source". Github will create a tarball for you in your format of choice.
(anonymous)
2010-07-26T12:18:36Z
Hi,

i have problems to compile the emulino-gui.cpp

my system is a windos 7 ultimate 64 bit

i have installed python 2.4 in c:\python24 and scons

i copy the scons.bat from the C:\Python24\Scripts diretory to the emulino folder (c:\emulino)
i have patcht the sconstruct file
from:
env.Command("avr.inc", ["mkinst.py", "instructions.txt"], "/opt/local/bin/python2.5 mkinst.py")

to:
env.Command("avr.inc", ["mkinst.py", "instructions.txt"], "C:\python24\python mkinst.py")

for use in windows (i hope that is ok?)

when i start the scons.bat (in the emulino directory) i receive following error:

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
C:\python24\python mkinst.py
File "mkinst.py", line 78
f.write("".join([" do_%s,\n" % (x if x else "BREAK") for x in table]))
^
SyntaxError: invalid syntax
scons: *** [avr.inc] Error 1
scons: building terminated because of errors.

what is wrong?
can anyone help me?
sorry for my bad english, my origin language is german!

you can answer me here or via email to karl.walter.weller@t-online.de

thanks
karl-walter
thanks
[info]ext_248302 : Excellent work, but EEPROM doesn't seem to work as expected
2010-09-05T08:46:44Z
Hi Greg,

Excellent work there. I tried a simple Arduino sketch writing consecutive bytes (10 in a for loop) into EEPROM, and then reading them back, but while writing of first byte does seem to work, reading it back fails. Ditto for trying to write more than one byte consecutively. Basically the second EEPROM operation invariably fails.

Is there a place to report this as a bug or something, where one can expect a response ??

cheers,
Banibrata
http://bit.ly/bdutta
[info]ghewgill : Re: Excellent work, but EEPROM doesn't seem to work as expected
2010-09-05T10:21:54Z
Sure, report it on the Github project page under "Issues" and I'll see what I can do.
[info]ext_304043 : Instructions for running Emulino on OSX
2010-10-30T23:59:14Z
I just spent some time getting Emulino running on OSX. Here is how I did it, hopefully this will be useful to others.

1. Download the Emulino source code by visiting http://github.com/ghewgill/emulino, click "Downloads", select a compression format of your choice.

2. Extract the compressed file to create a directory similar to /ghewgill-emulino-c75d445.

3. Download Scons (http://www.scons.org/) and decompress it.

4. View the Scons README.txt file for instructions on how to build and install. I installed it in a separate directory using something like "python setup.py install --prefix=".

5. Go into the Emulino directory and edit SConstruct, you'll likely need to change the path to the python binary. Use "which python" to determine where Python is installed on your machine.

6. In the Emulino directory run the scons executable to compile Emulino. If you did a default install of scons it will be in the path, otherwise provide the absolute path to the /bin/scons binary.

Assuming Emulino built with no errors you can now run the emulino binary on a hex file. Ahhh... but how to get hex files out of Audino you might ask? Hold down shift and then press the verify/compile button, this will turn on verbose mode and the path to the generated hex will be displayed. You can then run "./emulino foo.hex" to run the emulator.

So far I've only run it once so I don't have much input, but a huge thanks to ghewgill for providing this tool!

[info]ext_961706
2012-01-01T01:15:00Z
Hi Greg,

In emulino.c file, line 88, you load a file named "emulino.eeprom" but it was not found ...
It is essential to the functioning of the program? If so, where can we get?

Thank you and happy new year ^^
[info]jacksnodgrass
2012-01-02T18:48:50Z
Tried to use this with fedora 15 and a arduino 1.0 hex file. I either get a seg fault or something
about a command ( epl3 ) not being implemented.

I installed scons from yum ( and change the python path in the SConstruct file ) and I told it to use
gcc34 ( gcc 4.x would not compile the cpu.c file )

Has anyone had any better luck with recent code / libs?


I'm looking for something linux based to debug some arduino code I am working on.

jack
Greg Hewgill <greg@hewgill.com>