Avr-GCC with Arduino
Asked Answered
J

2

8

How can I program my Arduino in C on Ubuntu. I've heard of avr-gcc but all online tutorials seem extremely tedious and don't have options for an AVR chip with the Arduino bootloader. Can anyone help me with an easier way to install avr-gcc on Ubuntu and get started programming in C for the Arduino?

Judiciary answered 5/9, 2015 at 14:5 Comment(10)
Why would you want that? You're already programming in C in the Arduino IDE. Is there anything you can only achieve by compiling C code manually? I would suggest sticking with the Arduino IDE.Doc
@adam10603 for example, if someone dislikes the Arduino IDE, its dependence of Java; maybe he wants to integrate the project with another build system (e.g. Make), etc. There are various reasons why you want to do that.Kyanize
@adam10603 The Arduino language most closely resembles C++, but I'm trying to program it in C, because I'd like to get started with embedded C.Judiciary
@adam10603 Also, I like the manual memory control that C provides on all platforms.Judiciary
You can still use malloc and free as well as pointers in the Arduino IDE, they work the same way.Doc
@adam10603 Thank you. I didn't know that, but I also plan to work with embedded C on other architectures and I feel that this will help with experience.Judiciary
Writing code manually for any microcontroller is very hard and requires very low-level knowledge of your platform. This is the reason why Arduino was born actually. People who know that stuff very well write libraries that enable you to take advantage of features which would otherwise require multiple pages of low-level C code (which is a pain in the ass to write, even for professional programmers) with just a few lines of library calls. That's Arduino in a nutshell. I'd say that you only makes things worse for yourself by abandoning all this. But if that's what you need, good luck with itDoc
@adam10603 I appreciate the advice but yes I am trying to challenge myself to see what extremely low level development is truly like. I appreciate the quick responses also.Judiciary
@adam10603 the Arduino libraries are actually horribly-organized and painfully slow. You need to omit them if you want to do anything non-trivial with your MCU. Most of the stuff isn't even painful to write. You have to read data sheets, yeah, but you need to read the documentation anyway. And the AVR-GCC "standard library" already provides abstractions (intrinsic functions, macros, constants), you don't have to dig deep in address spaces and bit-twiddling.Kyanize
For the stuff that I use my Arduino for, the Arduino library is perfectly fine. I wanted to program it with my own C code too, but after looking up a few things, I realized that it would take way more effort than using the Arduino IDE, and benefits (for me at least) are non. If you find it beneficial to code it completely by hand, then sure, it might be worth a try. But if you want to completely abandon the Arduino library, I don't think you need the bootloader either. You should just program the chip directly through SPI.Doc
K
18

I recommend the following set of command line options for compiling:

avr-gcc -c
        -std=gnu99
        -Os
        -Wall
        -ffunction-sections -fdata-sections
        -mmcu=m328p
        -DF_CPU=16000000

And for linking:

avr-gcc -Os
        -mmcu=m328p
        -ffunction-sections -fdata-sections
        -Wl,--gc-sections

Where…

  • -c means "compile to object file only, do not link"
  • -std=gnu99 means "My code conforms to C99 and I use GNU extensions"
  • -Os means "optimize for executable size rather than code speed"
  • -Wall means "turn on (almost) all warnings"
  • -ffunction-sections -fdata-sections is necessary for the -Wl,--gc-sections optimization
  • -mmcu=m328p means "the MCU part number is ATmega 328P"
  • -DF_CPU=16000000 means "the clock frequency is 16 MHz" (adjust for your actual clock frequency)
  • -Wl,--gc-sections means "tell the linker to drop unused function and data sections" (this helps reduce code size).

In order to actually compile your code, you would first issue the avr-gcc command with the "compile only flags", like this:

avr-gcc -c -std=gnu99 <etc.> MyProgram.c -o MyProgram.o

Then you would repeat this for all of your source files. Finally, you would link the resulting object files together by invoking AVR-GCC in link mode:

avr-gcc -Os <etc.> MyProgram.o SomeUtility.o -o TheExecutable.elf

This generates an ELF file, which isn't directly executable by your MCU. Thus, you'll need to extract the useful part (the raw machine code) from it in the Intel Hex format:

avr-objcopy -O ihex -R .eeprom TheExecutable.elf TheExecutable.ihex

Finally, you will need AVRdude to upload the contents of the hex file to the MCU:

avrdude -C /path/to/avrdude.conf
        -p m328p
        -c PROGRAMMER_NAME
        -b 19600
        -P PORT_NAME
        -U flash:w:TheExecutable.ihex:i

Where…

  • -C /path/to/avrdude.conf means "use this file as the configuration file"
  • -c PROGRAMMER_NAME means "I am using a programmer of type PROGRAMMER_NAME" (you will need to fill this in yourself depending on what kind of programmer you use).
  • -b 19600 is the baud rate (you may need to adjust this depending on the baud rate you set or have pre-programmed into the bootloader)
  • -P PORT_NAME means "the programmer is connected to port PORT_NAME". On Linux, it will most often be something like /dev/ttyusbN, where N is some number.
  • -U flash:w:TheExecutable.ihex:i means "write to the Flash memory the contents of TheExecutable.ihex which is in Intel Hex format".
Kyanize answered 5/9, 2015 at 14:14 Comment(3)
Thank you very much. However, I must ask where to download and install a functioning avr-gcc version. What is the difference between compiling and linking? Also, will this setup work with an Atmega chip with the Arduino bootloader pre-installed?Judiciary
@ApplicationDeveloper "where to download and install a functioning avr-gcc version" – just google it. "What is the difference between compiling and linking?" – that's a long story, just google it. "will this setup work with an Atmega chip with the Arduino bootloader pre-installed?" – yes.Kyanize
Thanks for everything.Judiciary
D
6

If you just want to use C code with an Arduino that already has a boot loader installed. You can literally write the code in C in the Arduino IDE and compile it as usual. Sketch is effectively a bunch of header files and Macros.

Here's the blink sketch written in C:

#include <avr/io.h> //defines pins, ports etc
#include<util/delay.h> //functions for wasting time

int main (void) {
//init
DDRB |= (1<<PB5); //Data Direction Register B:
//writing a 1 to the Pin B5 bit enables output
//Event loop
  while (1) {
    PORTB = 0b00100000; //turn on 5th LED bit/pin in PORT B (Pin13 in Arduino)
    _delay_ms (1000); //wait

    PORTB = 0b00000000; //turn off all bits/pins on PB    
    _delay_ms (1000); //wait
  } //end loop
  return(0); //end program. This never happens.
}

Paste this into the IDE and try it for yourself.

If you want to move away from the Arduino to programming AVR's without a bootloader, may I recommend an excellent webcast by Elliot Williams as an introduction. - https://www.youtube.com/watch?v=ERY7d7W-6nA

Good luck and have fun :)

Dillingham answered 20/1, 2017 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.