Electronic – How does AVRDUDE communicate with the programmer

avrisp

I'm trying to understand exactly how AVRDUDE communicate with the AVR Programmer, for example USBtiny or Arduino itself as a programmer, to send the firmware to the microcontroller.

As a motivation to my question, suppose that I want to build an USB In-System Programmer for an AVR microcontroller from scratch. So, using another microcontroller, I build an ISP that can load code to the AVR.

Now, what if I want to use AVRDUDE to send to my ISP some code to load into my microcontroller? What kind of protocol will AVRDUDE use to send the code via USB, so I could read it correctly and generate the correct SPI to program the AVR? How the people who created USBtiny, for example, knew (or specified) the protocol avrdude would use to send the data to USBtiny, so they could interpret it correctly?

Any help is appreciated!

Thanks!

Best Answer

This is more belongs to stackoverflow and this is more related to the device drivers. However,

Nowadays USB device drivers are written in ring3 instead of ring0. In English they are user mode drivers. Any modern operating system exposes interface level functionality of USB stack to the user mode by API. And there are libraries like libusb , winusb to access them in user mode, so in theory, you only need to study how to use a library like libusb.

So the AVR dude, with enough permissions , it can access it's endpoints and write and read from them. So that's how it works.

And from the avrdude source, this is the file which defines the how to communicate with my programmer, ( sorry I'm using usbasp ). http://svn.savannah.nongnu.org/viewvc/trunk/avrdude/usbasp.c?root=avrdude&view=markup

You can see that it's using libusb if on Linux.

void usbasp_initpgm(PROGRAMMER * pgm)
{
  strcpy(pgm->type, "usbasp");

  /*
   * mandatory functions
   */

  pgm->initialize     = usbasp_initialize;
  pgm->display        = usbasp_display;
  pgm->enable         = usbasp_enable;
  pgm->disable        = usbasp_disable;
  pgm->program_enable = usbasp_spi_program_enable;
  pgm->chip_erase     = usbasp_spi_chip_erase;
  pgm->cmd            = usbasp_spi_cmd;
  pgm->open           = usbasp_open;
  pgm->close          = usbasp_close;
  pgm->read_byte      = avr_read_byte_default;
  pgm->write_byte     = avr_write_byte_default;

  /*
   * optional functions
   */

  pgm->paged_write    = usbasp_spi_paged_write;
  pgm->paged_load     = usbasp_spi_paged_load;
  pgm->setup          = usbasp_setup;
  pgm->teardown       = usbasp_teardown;
  pgm->set_sck_period = usbasp_spi_set_sck_period;

}

You can see that each programmer supported by avrdude have to support those functions, so you can understand this abstraction and how the usbasp.c file convert them into programmer specific. I encourage you to read the source code of your programmer. Good luck.

FYI: For your programmer usbtiny, the source is here: