How to make a script for AVR programming on Ubuntu?

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found a script like this:

avr-gcc -g -Os -mmcu=“microcontroller” -c “filename”.c<br>avr-gcc -g -mmcu=“microcontroller” -o “filename”.elf “filename”.o<br>avr-objcopy -j .text -j .data -O ihex “filename”.elf “filename”.hex<br>avr-size --format=avr --mcu=“microcontroller” “filename”.elf ​Here the filename that we want to compile is: led.c and the microcontroller is: atmega32​So the code becomes- avr-gcc -g -Os -mmcu=atmega32 -c led.c<br>avr-gcc -g -mmcu=atmega32 -o led.elf led.o<br>avr-objcopy -j .text -j .data -O ihex led.elf led.hex<br>avr-size --format=avr --mcu=atmega32 led.elf 

Should I write it this way, or I could add a "Enter" at every "<br>"?

This topic has a solution.
Last Edited: Fri. Jan 29, 2021 - 08:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

replace <br> with enter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MianQi wrote:
I found a script like this

Where did you find it?

 

<br> is HTML for "new line" - so, as  MattRW said, you need to replace each <br> with a new line:

avr-gcc     -g -Os -mmcu=“microcontroller” -c “filename”.c
avr-gcc     -g -mmcu=“microcontroller” -o “filename”.elf “filename”.o
avr-objcopy -j .text -j .data -O ihex “filename”.elf “filename”.hex
avr-size    --format=avr --mcu=“microcontroller” “filename”.elf 

​Here the filename that we want to compile is: led.c and the microcontroller is: atmega32​ So the code becomes

avr-gcc     -g -Os -mmcu=atmega32 -c led.c
avr-gcc     -g -mmcu=atmega32 -o led.elf led.o
avr-objcopy -j .text -j .data -O ihex led.elf led.hex
avr-size    --format=avr --mcu=atmega32 led.elf 

 

 

EDIT

 

On the HTML <br> tag: 

 

https://www.w3schools.com/tags/tag_br.asp

 

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Jan 28, 2021 - 09:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

If you are building in Linux then this kind of "home brew" build sequence is all very well but it likely omits a lot of the subtleties found in a Makefile that has been developed by experts over time.

 

If you do want to continue to build on the command line go here:

 

https://www.sax.de/~joerg/mfile/

 

and get "Mfile". It has a template Makefile and a GUI editor for it that allows you to customise the template for the specific AVR you use (and other options). That then creates a new Makefile. You just put that with your other .c and .h files and then building can be as simple as typing "make".

 

Of course in this day and age most people use an IDE like Eclipse, Netbeans, Code::Blocks. You will find internet articles/videos showing how to set them up to build for AVR. When you use those things like the choice of AVR model are nothing more than a menu/dialog choice within the IDE and when you click "Build" behind the scenes it automatically creates a Makefile then launches make in the right way.

 

So if I were you I would "audition" a few IDE. Find one you like (initially you can just use it for building native "Hello world" programs in Linux). When you find one you think you can get on with then do the extra to add AVR building support to it.

 

PS forgot to say I notice your build instructions using:

avr-objcopy -j .text -j .data -O ihex led.elf led.hex

There is an argument to be had as to whether it is best to use -j's here or -R's. Most IDEs that auto generate Makefile seem to opt for -R in fact (so user sections will automatically make it to the .hex).

Last Edited: Thu. Jan 28, 2021 - 09:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
"audition" a few IDE.

+1

 

The Microchip one says it works on linux: 

 

https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh yeah, silly me - I forgot about the multi-platform MPLABX. That is almost certainly going to be the preferred choice. Apart from the fact that it'll be the only one that allows access to the simulator it's going to become the most widely used/supported on Linux.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found my Atmel ICE by :lsusb

the info is: Bus 001 Device 005: ID 03eb:2141 Atmel Corp. ICE debugger

 

How to connect it with tty? I mean how could I know it was which tty. Since I need this info in avrdude script:

 

avrdude

-c atmelice_isp

-p m328p

-P(here, i need it)

-b 19200

-U flash:w:led_blink_atmega328p.hex

Last Edited: Fri. Jan 29, 2021 - 04:10 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

-Pusb

:: Morten

 

(yes, I work for Microchip, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use WinAVR Sample makefile for almost every my project for many years.

# WinAVR Sample makefile written 1;2by Eric B. Weddington, J.rg Wunsch, et al.
# Released to the Public Domain
# Please read the make user manual!
#
# Additional material for this makefile was submitted by:
#  Tim Henigan
#  Peter Fleury
#  Reiner Patommel
#  Sander Pool
#  Frederik Rouleau
#  Markus Pfaff

It's very well documented and easy to modify to fit all requirements.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could you present detailed? I downloaded this file this morning and haven't unzip it now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It has its own page on Github: https://gist.github.com/bradfordbarr/9182992. You can look on it directly in www browser. If You want any detailed information I will answer for Your questions if I can.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


MianQi

 

The template Makefile awit is talking about is the very "Mfile" I talked about in post #4.

 

When you get that you will have these files:

D:\WinAVR-20100110\mfile>dir
 Volume in drive D is DATA
 Volume Serial Number is 1CF4-86D6

 Directory of D:\WinAVR-20100110\mfile

20/09/2018  15:14    <DIR>          .
20/09/2018  15:14    <DIR>          ..
08/01/2010  05:02             8,580 help.html
08/01/2010  05:02            16,792 htmlview.tcl
08/01/2010  05:02               956 htmlview.xbm
08/01/2010  05:02            16,887 makefile_template
08/01/2010  05:02            44,949 mfile.tcl
08/01/2010  05:02               944 mfile.xbm
08/01/2010  05:02             4,753 README
               7 File(s)         93,861 bytes

This is Windows but the Linux version is pretty much the same.  To run this you need "tcl". That's actually much easier to get/install in Linux than it is in Windows. In fact there's a pretty strong chance you Linux may already have it installed by default anyway.

 

When Mfile is run you should see a GUI editor that pre-loads "makefile_template":

 

 

This is a generic template so then you have to use the entries on the menu to select details specific to your project like which model of AVR you are building for and so on:

 

 

Finally you "file-Save As" a new Makefile in the directory where your .c and .h files are located.

 

But really, it would be FAR easier to just use an IDE !!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awit wrote:

It has its own page on Github: https://gist.github.com/bradfordbarr/9182992. You can look on it directly in www browser. If You want any detailed information I will answer for Your questions if I can.

 

I have installed make, and I  have unziped the tarball downloaded from here:https://www.sax.de/~joerg/mfile/, I just don't know how to use it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It looks nice, but I have installed make on Ubuntu, and I have unziped the tarball from here:https://www.sax.de/~joerg/mfile/, and I viewed the several files unziped, but I don't know how to use it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't write about mfile because I don't use it. But when You has ready makefile file (it must have this name) generated by the mfile or manually, You must put it in folder with source code of Your project and run make command in it. That's all.

 

If You want make makefile manually, You must copy template to folder with source code of Your program, open it in editor, and change value of variables that are placed in the begin of this file.
If this is Your first project, You must set directories witch avr compiler, library and other utilities . All variables are very well documented.

In attachment is an makefile made for one from my projects. It works on Mint thus it should work on Ubuntu too. See differences between original and my makefile to see which variables You must change.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I unzipped it, I haven't found your makefile, just a makefile template.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yes because the program reads the template - you make some menu selections to customize it and then it writes out a new Makefile based on your selections.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awit wrote:
to see which variables You must change

 

I saw no change. Or it was a changed template itself?

Last Edited: Wed. Feb 10, 2021 - 01:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I compared your "makefile" with the makefile template(attachment) , your "makefile" has 418 lines, and the template was only 223 lines, did all the added lines changed by you?

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This time I tried mfile on Ubuntu not WinAVR, so there was no menus.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You started this thread on Jan 28. It is now Feb 18. If you had simply installed an IDE for AVR you would now have been writing you AVR code rather than worrying about makefiles/mfile since Jan 29.

 

I simply suggested Mfile as it makes a good makefile but you do need to get the TCL to work. The alternative is simply to manually copy makefile_template to your own project then hand edited it. (which is what the TCL GUI would have done automatically)

 

If you manually edited it the lines you probably need to change are:

# MCU name
MCU = atmega128

unless you really do happen to be using a mega128 you need to change this to the model of AVR you want to build for.

 

Also look at:

# Target file name (without extension).
TARGET = main


# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c

Well "TARGET" is the name of the project. So you might want to use something like:

# Target file name (without extension).
TARGET = LED_flasher

or whatever describes the overall intent of the project. When it finally builds the output ELF (and HEX) file they will be called whatever you put here so LED_flasher.elf, LED_flasher.hex and so on.

 

On the line:

# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c

this is going to take the TARGET name and assume you have a .c file of that name (in my example LED_flasher.c) but perhaps this is not the case. Perhaps you just have files called main.c uart.c, timer.c and adc.c in which case you list them all on this line:

SRC = main.c adc.c timer.c uart.c

or perhaps it is as simple as one file?

SRC = main.c

In the unlikely case that the project includes some assembler code in .S file then edit that onto the:

# List Assembler source files here.
#     Make them always end in a capital .S.  Files ending in a lowercase .s
#     will not be considered source files but generated files (assembler
#     output from the compiler), and will be deleted upon "make clean"!
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
#     it will preserve the spelling of the filenames, and gcc itself does
#     care about how the name is spelled on its command-line.
ASRC = 

but you probably don't need to do anything there.

 

One more that you might need to edit is:

# List any extra directories to look for include files here.
#     Each directory must be seperated by a space.
#     Use forward slashes for directory separators.
#     For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS = 

If you have "library code" that has .h files that are not in the main project directory then you need to tell the preprocessor where to look by adding the other directory names on this line.

 

Other than this you don't really need to change anything (at least at first). Also note that every important "XXX =" line in that file that you might need to change has a few lines of comment before it saying what it is for and how to set the value.

 

But you really would be better off using an IDE - have you looked at MPLABX ?

 

(also when I go to the main Mfile site and download the makefile_template currently there has 506 lines).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
But you really would be better off using an IDE - have you looked at MPLABX ?

 

I have tried several IDE - Atmel Studio, Arduino IDE, MPLABX, STM32CubeIDE,  and now eclipse, I found that using makefile + avr-libc + Linux such a recipe would be professional, so I stick to understand it, and I have read a lot on net about makefile, now I think I have some feeling of it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Eh? All professional engineers use IDEs these days. Sure it's an idea to understand what they generate in the makefile but the days of creating Makefile from scratch are long since passed. If you do want to learn about "command line scripting" learn about CMake or Scons.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If it helps, a more minimal example of a Makefile.

Only has rule for c files, would need extending for asm files.

It should be petty obvious what you need to change (C_SRC, MCU, F_CPU, maybe AVR_TOOLS_PATH and AVRDUDE, CFLAGS for whatever optimisation setting, warnings etc. you want))

#############################################################################

C_SRC = main.c uart.c uart_print_int.c

MCU = atmega328p
F_CPU = 8000000UL

#############################################################################

# This is the stem name to use on the output files
# eg. prog.hex, prog.elf
TARGET = prog

# All built files get placed under this directory
# eg. build/prog.hex, build/prog.elf
OBJDIR = build

#############################################################################

# Object files
OBJS = $(C_SRC:%.c=$(OBJDIR)/%.o)

# Dependeny files
DEPS = $(C_SRC:%.c=$(OBJDIR)/%.d)

# The name of the main targets
TARGET_HEX = $(OBJDIR)/$(TARGET).hex
TARGET_ELF = $(OBJDIR)/$(TARGET).elf
TARGET_LSS = $(OBJDIR)/$(TARGET).lss
TARGET_SYM = $(OBJDIR)/$(TARGET).sym
# Linker map
TARGET_MAP = $(OBJDIR)/$(TARGET).map

#############################################################################

AVRDUDE = /usr/bin/avrdude
AVRDUDE_CONF = /etc/avrdude.conf
# Using usbasp for programming
AVRDUDE_OPTS = -v -p $(MCU) -C $(AVRDUDE_CONF) -c usbasp

#############################################################################

AVR_TOOLS_PATH = /usr/bin

CC      = $(AVR_TOOLS_PATH)/avr-gcc
CXX     = $(AVR_TOOLS_PATH)/avr-g++
OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
AR      = $(AVR_TOOLS_PATH)/avr-ar
SIZE    = $(AVR_TOOLS_PATH)/avr-size
NM      = $(AVR_TOOLS_PATH)/avr-nm

CPPFLAGS      = -DF_CPU=$(F_CPU) -mmcu=$(MCU) -MMD -MP
CFLAGS        = -g -std=c99 -pedantic-errors -Os -Wall -Wextra -Wmissing-prototypes
LDFLAGS       = -mmcu=$(MCU)
# to generate a linker map file
LDMAP         = -Wl,-Map=$(TARGET_MAP)

#CFLAGS += -save-temps=obj

#CFLAGS  += -ffunction-sections
#CFLAGS  += -fdata-sections
#LDFLAGS += -Wl,-gc-sections

#############################################################################
#
# Implicit (pattern) rules
#

$(OBJDIR)/%.o: %.c $(OBJDIR)/%.d
	$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@

#############################################################################
#
# Explicit targets start here
#

all: $(TARGET_HEX) $(TARGET_LSS) $(TARGET_SYM)

$(TARGET_HEX): $(TARGET_ELF)
	$(OBJCOPY) -O ihex -R .eeprom -R .fuse -R .lock $(TARGET_ELF) $(TARGET_HEX)

$(TARGET_LSS): $(TARGET_ELF)
	$(OBJDUMP) -h -S $(TARGET_ELF) > $(TARGET_LSS)

$(TARGET_SYM): $(TARGET_ELF)
	$(NM) -n --print-size $(TARGET_ELF) > $(TARGET_SYM)

$(TARGET_ELF): $(OBJS)
	$(CC) $(LDMAP) $(LDFLAGS) -o $(TARGET_ELF) $(OBJS)

# The order-only prerequisite on OBJDIR, cause OBJDIR to be created
# if it doesn't exist, but don't rebuild objects just because timestamp
# on OBJDIR is more recent.
$(OBJS): | $(OBJDIR)

$(OBJDIR):
	mkdir $(OBJDIR)

upload: $(TARGET_HEX)
	$(AVRDUDE) $(AVRDUDE_OPTS) -U flash:w:$(TARGET_HEX):i

clean:
	rm -f $(OBJS)
	rm -f $(DEPS)
	rm -f $(TARGET_ELF)
	rm -f $(TARGET_HEX)
	rm -f $(TARGET_SYM)
	rm -f $(TARGET_LSS)
	rm -f $(TARGET_MAP)

# deliberately don't rebuild for 'make size', if it fails, fine.
size:
	$(SIZE) $(TARGET_ELF)

# dependency file is a prerequisite of the .o, this empty rule prevents
# getting an error if the dependency file doesn't exist.
$(DEPS):

# the effect of wildcard is to include only dependency files that exist
include  $(wildcard $(DEPS))

.PHONY: all upload clean size

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:


  CMake or Scons 

Excellent!

Last Edited: Mon. Feb 22, 2021 - 10:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you very much, so clear codes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I list the object files for Make to build; it has built-in rules that work fine to create the objects from the C files. A list of objects and where they need to be constructed helps to prevent surprises. After the objects are linked into the final object (elf), the previous objects are removed.

 

TARGET = BlinkLED
LIBDIR = ../lib
OBJECTS = main.o \
	$(LIBDIR)/twi0_bsd.o \
	$(LIBDIR)/uart0_bsd.o \
	$(LIBDIR)/timers_bsd.o

# Chip and project-specific global definitions
MCU = avr128da28
F_CPU = 16000000UL
CPPFLAGS = -DF_CPU=$(F_CPU) -I. 

# Cross-compilation
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size

# Compiler/linker options https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
CFLAGS = -Os -g -std=gnu99 -Wall
# CFLAGS += -funsigned-char -funsigned-bitfields
# CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -ffunction-sections -fdata-sections 

# avr128da28 is not in the avr-gcc packaged for my OS
TARGET_ARCH = -mmcu=$(MCU) \
-B $(LIBDIR)/AVR-Dx_DFP/gcc/dev/avr128da28/ \
-I $(LIBDIR)/AVR-Dx_DFP/include/
## if someday it is in mainline use
##TARGET_ARCH = -mmcu=$(MCU)

LDFLAGS = -Wl,-Map,$(TARGET).map
LDFLAGS += -Wl,--gc-sections 

.PHONY: help

# some help for the make impaired
# https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
help:
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

all: $(TARGET).hex $(TARGET).lst ## build the image and its related files

$(TARGET): $(TARGET).hex

$(TARGET).hex: $(TARGET).elf
	$(OBJCOPY) -j .text -j .data -O ihex $< $@

$(TARGET).elf: $(OBJECTS)
	$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ -o $@
	$(SIZE) $@
	rm -f $(TARGET).o $(OBJECTS)

clean: ## remove the image and its related files
	rm -f $(TARGET).hex $(TARGET).map $(TARGET).elf $(TARGET).lst

%.lst: %.elf
	$(OBJDUMP) -h -S $< > $@

builtin: ## show list of builtin (hidden) defines, some may need to be added to VScode c_cpp_properties.json
	$(CC) $(LDFLAGS) $(TARGET_ARCH) -E -dM - < /dev/null

 

Make can unencumber you from the IDE. Now you can discover the editor you prefer (for me, that is VSCode). If you find yourself employed, you will have to use the tools they use, so it may be worth figuring out commonly used editors. Makefiles also help with continuous integration (CI) testing and can even play a role in hardware production (e.g., first-self-test, burn-in, final-test, load-application).

Last Edited: Mon. Feb 22, 2021 - 11:53 PM