buserror/simavr

Cannot generate VCD file

froart opened this issue · 13 comments

Hello, dear developers. I am encountering an issue of generating the VCD file. Here is a project file timer_toggle_pin.c:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/iom644.h>
#include <stdint.h>

volatile uint8_t wait = 255;

ISR(TIMER0_COMPA_vect)
{
  --wait;
}

void main()
{

  // TCCR0A |= ( 1 <<  WGM01 ); /* enable CTC (Clear Timer on Compare) mode */
  TCCR0A |= ( 1 << WGM01  ) | ( 1 << COM0A0 ); /* enable CTC (Clear Timer on Compare) mode and toggle of OC0A on compare match */
  OCR0A   =   0xff;  /* compare match value register */
  TIMSK0 |= ( 1 << OCIE0A ); /* enable compare match interrupt */
  SREG   |= ( 1 << SREG_I ); /* enable global interrupt */
  DDRB   |= ( 1 << PINB3  ); /* set pin OC0A as an output */ 
  TCCR0B |= ( 1 << ISC00  ); /* launch timer0 */

  while(wait); /* infinite loop */

  return;
}

Here is a vcd_trace_file.c:

#include <avr/io.h>
#include "/usr/include/simavr/avr/avr_mcu_section.h"

AVR_MCU(16000000, "atmega644");
AVR_MCU_VCD_FILE("my_trace_file.vcd", 1000);

const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = {
	{ AVR_MCU_VCD_SYMBOL("OUTPUT"), .mask = (1 << PINB3 ), .what = (void*)&PORTB, },
};

I compile it this way:

avr-gcc -g -o timer_toggle_pin.elf timer_toggle_pin.c vcd_trace_file.c -mmcu=atmega644

And the compilation goes with no errors. But, now, when I try to run:

simavr timer_toggle_pin.elf

I get the following error:

ELF format is not supported by this build.
simavr: Unable to load firmware from file timer_toggle_pin.elf

I spent whole yesterday to figure out how to resolve this issue with what there is on the internet, but there is not much and it didn't help. Any suggestions?

lsb_release -a

Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy

Did you install libelf? There are build instructions in the Wiki. (They do not yet recommend also installing libdwarf, but that only really benefits the tracing option.) If you are using a Debian or Ubuntu package, there should at least be a "recommends" for libelf.

(It is possible to do without libelf: convert the ELF file to hex with avr-objcopy and run that. But debugging will be harder.)

You also need to compile the right way. This worked for me

avr-gcc -g -I../../simavr/sim -o timer_toggle_pin.elf timer_toggle_pin.c vcd_trace_file.c -mmcu=atmega644 -Wl,--undefined=_mmcu,--section-start=.mmcu=0x910000

(I needed -I and an edit to get to avr_mcu_section.h.)

The black magic at the end of that command is needed to get the correct treatment of the macro that requests VCD. It is probably best to use the same options that simavr uses for the included test and example firmware:

avr-gcc -Wall -gdwarf-2 -Os -std=gnu99 -mmcu=attiny85 -DF_CPU=8000000 -fno-inline-small-functions -ffunction-sections -fdata-sections -Wl,--relax,--gc-sections -Wl,--undefined=_mmcu,--section-start=.mmcu=0x910000 -I../simavr/sim/avr -I../../simavr/sim/avr attiny85_load_test.c -o attiny85_load_test.axf

@gatk555 Thank you for you recommendation. I compiled the way you recommended:

avr-gcc -g -I../../simavr/sim -o timer_toggle_pin.elf timer_toggle_pin.c vcd_trace_file.c -mmcu=atmega644 -Wl,--undefined=_mmcu,--section-start=.mmcu=0x910000

Yet it still hasn't change the simavr error.

According to the error message, it would seem the issue is not about how you compile the AVR program, but rather about how simavr itself was built. Specifically, it seems to be lacking the support for the ELF file format, which is provided by the libelf library.

Where did you get the simavr binary from? Does it come from a .deb package? Did you build it from sources? What is the output of the command below?

ldd $(which simavr)

Do you see “libelf” mentioned?

I have two Ubuntu 22.04 boxes, one with simavr installed from sources and the other with the .deb package. They both show simavr is linked with libelf.so.1.

@edgar-bonet hello. thanks for the reply. I downloaded simavr using apt install. As for the output of the command I get:

linux-vdso.so.1 (0x00007ffe469b6000)
libsimavr.so.1 => /usr/local/lib/libsimavr.so.1 (0x00007fb6af7ee000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb6af5a9000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb6af8e0000)

Yes, there is no libelf. Although, simavr ran my project without libelf (when I don't include the vcd_trace_file.c into avr-gcc compilation). I will install it and try again and let you know if it worked.

@edgar-bonet I have installed libelf. How should I ran commands now to make things work? Because mere libelf installation seems like hasn't made any difference.

@edgar-bonet running

ldd $(which simavr)

still doesn't include libelf -- the output is the same.

@froart: you wrote:

there is no libelf.

There is something broken in your installation. Libelf is an indirect dependency of simavr. You should not be able to install the latter without the former:

$ apt depends simavr
simavr
  Depends: libc6 (>= 2.4)
  Depends: libsimavr2 (>= 1.6)
  Recommends: gdb-avr
  Suggests: gtkwave
  Suggests: avr-libc
  Suggests: avra
  Suggests: libsimavr-dev
$ apt depends libsimavr2
libsimavr2
  Depends: libc6 (>= 2.17)
  Depends: libelf1 (>= 0.131)

Try this, and see how your output differs from mine:

$ dpkg --no-pager -l simavr
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=================================
ii  simavr         1.6+dfsg-3   amd64        lean and mean AVR simulator
$ dpkg -V simavr
$ which simavr
/usr/bin/simavr
$ md5sum /usr/bin/simavr
35c14828275fe3fb3560386a97fbdd0c  /usr/bin/simavr

You may want to apt purge, then reinstall simavr.

@edgar-bonet

apt depends libsimavr2

gave me this:

libsimavr2
Depends: libc6 (>= 2.17)
Depends: libelf1 (>= 0.131)

As for all the commands below:

$ dpkg --no-pager -l simavr
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=================================
ii  simavr         1.6+dfsg-3   amd64        lean and mean AVR simulator
$ dpkg -V simavr
$ which simavr
/usr/local/bin/simavr
$ md5sum /usr/bin/simavr
35c14828275fe3fb3560386a97fbdd0c  /usr/bin/simavr

@edgar-bonet okay, examining my outputs above, the one thing that draws attention is:

$ which simavr
/usr/local/bin/simavr

I ran:

$ /usr/bin/simavr timer_toggle_pin.elf 
Loaded 336 .text at address 0x0
Loaded 2 .data

^Csignal caught, simavr terminating

So everything started working. Thank you. The VCD file also appeared.

P. S. Can you please fast recommend how to change the /usr/local/bin/simavr to /usr/bin/simavr?

The likely explanation for /usr/local/bin/simavr is that someone (you?) built it from source and did "make install" as root.
The Ubuntu package system never touches /usr/local. So to remove it, find the build directory and do "make uninstall" as root.

But really, building from source is highly recommended, as the Ubuntu jammy package is from 2017 and much has changed. But install packages libelf-dev and libdwarf-dev before rebuilding and install again. Then purge the packaged version of simavr.

You have two versions of simavr installed:

  • one with ELF support, installed via apt in /usr/bin
  • the other one missing ELF support, presumably installed from sources, in /usr/local/bin

You could follow gatk555's advice and reinstall from sources. Alternatively, if you don't mind having a less recent version, you could remove the one you previously installed from sources. However, since it was not installed using a package manager, there is no standard and clean way to remove it (make uninstall may not work). You may have to search /usr/local for anything related to that installation of simavr. The following command should give a good starting point:

find /usr/local/ -name '*avr*'

Yes, there is no "uninstall" target, but there should be!

@edgar-bonet @gatk555 Sorry, guys, but I just copied the /usr/bin/simavr file as /usr/local/bin/simavr and it all works fine now xD Happy New Year!