Where I setup the Standard C toolchain for the ATmega328P for Linux.
Test with the Arduino IDE!
After performing these steps on multiple machines, I’ve found it best to install and test using the Arduino IDE before going forward with the installation instructions below. This will reduce the errors to something more manageable and having the Arduino IDE is handy for its Serial Monitor as well it provides an easy method to which port the Uno is connected.
Linux Serial Permissions
Linux also has permissions issues with its serial ports. My recommendation is this (also shown at the bottom of this page):
Linux Setup and Tool Chain Installation
For the Linux installation, it can’t get much easier.
1. Install the tool chain
To install the tool chain, you will need to perform one simple operation:
# Bring up the command line and entersudo apt install gcc-avr binutils-avr gdb-avr avr-libc avrdude make git
CHECK AND CONFIRM
Once the installation completes, perform the following commands to confirm all applications were installed correctly. The application averdude provides a lot of output, only some is shown.
avr-gcc --version
make --version
git --version
avrdude
Now, we have the same capability as the Arduino IDE, however, we are able to use it via the command line!
2. Test the tool chain
Test Code
You will want to select the code in the box below, copy it then you will paste it into a nano editor window.
#include<avr/io.h>#include<util/delay.h>#define BLINK_DELAY_MS 100
intmain (void)
{
/* set pin 5 of PORTB for output*/ DDRB |= _BV(DDB5);
while(1) {
/* set pin 5 high to turn led on */ PORTB |= _BV(PORTB5);
_delay_ms(BLINK_DELAY_MS);
/* set pin 5 low to turn led off */ PORTB &=~_BV(PORTB5);
_delay_ms(BLINK_DELAY_MS);
}
}
Testing the Code
In this step, we’ll setup a specific folder for developing C. I called it test. We’ll add a file called main.c, the we’ll compile/link the file on to the Uno.
cdmkdir testcdtest# copy the file from above and we'll call it main.cnano main.c
# paste the file, save it and exit
Notes on the steps
I’m using nano as my editor to keep this simple, this will be a copy and paste from code above into a file on your system.
Using the command cd without folder descriptor, will take you to your Linux home folder. Using cd test will take you to the new folder test you just created.
nano main.c will open a file called main.c in the nano editor. The window will be empty as main.c is a new file. Once you paste the file into nano, it will look like this:
To save and exit nano, press Ctrl-X, y (to confirm saving) and Return (to confirm file name). Once you have saved the file, you will be back at the WSL prompt. Enter the commands below to compile/link your file.
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o main.o main.c
avr-gcc -mmcu=atmega328p main.o -o main
avr-objcopy -O ihex -R .eeprom main main.hex
Your window will now look similar to this (both sets of operations shown:
Notice the "/dev/ttyACM0"? You will want to change the “ttyACM0” to the port name that you wrote down in the Arduino IDE port assignment in the earlier step Install the Arduino IDE.
When you run the averdude command above successfully, you will see the following:
Is the Arduino IDE installed, have you tested it, and it worked?
Have you closed the Arduino IDE?
Are you sure you are using the right port? Double check the number using the Arduino IDE and make sure the port name matches the port name on your averdude command. Ex: -P /dev/ttyACM0
3. Automate using a Makefile
On this GitHub site for Elliot William’s book, he has a Makefile in the folder setupProject. This Makefile is comprehensive and delivers an Arduino IDE type of simplicity with significantly increased speed. On the page for the file, click on the Raw button, just above the first line. With the raw text, select all of it then copy it. Paste it into a new file on your system in the test folder and call it Makefile. Make sure the filename is Makefile without an extension.
There are some changes that need to be made. Using the line numbers below as the line numbers in the original, change the text as reflected below. Do not add line numbers to the lines.
Line 7, change the processor type to the Uno processor, atmega328p
Line 8, change the clock speed to 16MHz
Line 23, we’ll be using the Arduino to program itself
Line 15, add a “#” at the beginning of the line to comment the line out
Line 25, be sure to confirm you use your serial port, which worked in step 2.
Line 48, change the name from blinkLED to main
Line 50, add a “#” at the beginning of the line to comment the line out
Line 60, remove the " -I$(LIBDIR)" text at the end of the line. This text exists for an additional library, which we won’t use right now.
Once you have made the above changes, please try the following to test your setup:
Manually delete all of the files EXCEPT the led.c and Makefile in the folder test.
Run make flash, this will perform all of the tasks required to compile/link/load the program onto the Arduino Uno.
Hopefully, it all works the first time. If not, look at the errors to discern what needs to be fixed. For me, I had not changed my serial port (line 25 -P /dev/ttyS3) to be the correct one.
Now that it is working, I noticed the complete time from pressing enter to “avrdude done.” was 2-3 times faster than what the Arduino framework would take on a similar file.
Finish up
Once you have tested the Makefile and the program main.c, the folder test is no longer required.
Linux Serial Permissions
Steps to follow: (actual steps and output below)
Run dmesg to determine idVendor and idProduct of the USB interfaces (in this case there are two.)
Use sudo and your favorite editor to create a file: “/etc/udev/rules.d/50-myusb.rules”
Using the idVendor and idProduct numbers, create two lines in the file using this format (replacing the numbers shown with your numbers):
# use dmesg to determine idVendor and idProduct# be sure to use the right USB devices (such as usb 1-1 and usb 1-2 below)dmesg
# ...[62603.487834] usb 1-1: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
...
[62603.492032] usb 1-1: FTDI USB Serial Device converter now attached to ttyUSB0
...
[62607.143187] usb 1-2: New USB device found, idVendor=2e8a, idProduct=0004, bcdDevice= 1.00
...
[62607.145394] cdc_acm 1-2:1.0: ttyACM0: USB ACM device
# ...sudo nano /etc/udev/rules.d/50-myusb.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="plugdev", MODE="0660", TAG+="uaccess"SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", GROUP="plugdev", MODE="0660", TAG+="uaccess"# save the file then reboot your system
Comments powered by Talkyard.