EmbDev.net

Forum: ARM programming with GCC/GNU tools "Better" Makefile for FreeRTOS SAM7X demo under WinARM


von Joe D. (jdupre)


Rate this post
useful
not useful
Thanks to Sven Koop for the concise instructions on compiling the SAM7X
FreeRTOS demo in WinARM.  (See topic 67145)

I have made a WinARM/WinAVR style make file for use under command line
or Eclipse.  In doing so I discovered that my new Makefile creates a
smaller binary file and I do not know why.

The FreeRTOS Makefile (with optimization set to -Os) creates a 70K
rtosdemo.bin.
This new Makefile creates 62K rtosdemo.bin

My Makefile generates a lot more warnings, but the resulting binary
appears to run exactly like the original from what I can tell.


- jmd



To replicate:

1. Extract the FreeRTOS source tree (I used v4.0.4)

2. Copy syscalls.c from the WinARM AT91SAM7S-BasicUSB example to the
lwIP_Demo_Rowley_ARM7 directory.

3. Edit syscalls.c to add the following two lines:
  #include "board.h"
  #define __inline static inline  /* Add this line */
  #include "lib_AT91SAM7X256.h"  /* Add this line */

4. Edit freertos\source\portable\gcc\arm7_at91sam7s\lib_at91sam7x256.h:
Change the "AT91F_AIC_ConfigureIt" to "AT91F_AIC_ConfigureItH" (2
places)

5. Use this Makefile:


# Hey Emacs, this is a -*- makefile -*-
#
# WinARM template makefile
# by Martin Thomas, Kaiserslautern, Germany
# <eversmith@heizung-thomas.de>
#
# based on the WinAVR makefile written by Eric B. Weddington, Jörg
Wunsch, et al.
# Released to the Public Domain
# Please read the make user manual!
#
#
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make program = Download the hex file to the device
#
# (TODO: make filename.s = Just compile filename.c into the assembler
code only)
#
# To rebuild project do "make clean" then "make all".
#
# Changelog:
# - 17. Feb. 2005  - added thumb-interwork support (mth)
# - 28. Apr. 2005  - added C++ support (mth)
# - 29. Arp. 2005  - changed handling for lst-Filename (mth)
# -  1. Nov. 2005  - exception-vector placement options (mth)
# - 15. Nov. 2005  - added library-search-path (EXTRA_LIB...) (mth)
# -  2. Dec. 2005  - fixed ihex and binary file extensions (mth)
# - 22. Feb. 2006  - added AT91LIBNOWARN setting (mth)
# - 19. Apr. 2006  - option FLASH_TOOL (default lpc21isp); variable
IMGEXT (mth)
#

# Modified 27 July 2006 for FreeRTOS 4.0.4 lwIP_Demo_Rowley_ARM7 demo
project
# The FreeRTOS Makefile generates a 70K binary (with -0s flag)
# This Makefile generates a 62K binary.  WHY???
# -jmd


#FLASH_TOOL = UVISION
#FLASH_TOOL = OPENOCD

# MCU name and submodel
MCU      = arm7tdmi
#FreeRTOS demo uses "atmel-rom.ld" for linker script, not
"AT91SAM7S-rom.ld"
#SUBMDL   = AT91SAM7S64
SUBMDL = atmel
THUMB    = -mthumb
THUMB_IW = -mthumb-interwork

## This setting chooses which linker script to use
## Create ROM-Image (final)
RUN_MODE=ROM_RUN
## Create RAM-Image (debugging) - not used in this example
#RUN_MODE=RAM_RUN


## Exception vectors not used in the FreeRTOS demo -jmd
## Exception-Vector placement only supported for "ROM_RUN"
## (placement settings ignored when using "RAM_RUN")
## - Exception vectors in ROM:
#VECTOR_LOCATION=VECTORS_IN_ROM
## - Exception vectors in RAM:
#VECTOR_LOCATION=VECTORS_IN_RAM


# Target file name (without extension).
# This only specifies the name of the output file(s),
# not used to define any source files. -jmd
TARGET = rtosdemo

# List C source files here. (C dependencies are automatically
generated.)
# use file-extension c for "c-only"-files
#SRC = $(TARGET).c

# Cut & paste from FreeRTOS Makefile, but added syscalls.c
FREERTOS_THUMB_SRC= \
  ../../Source/tasks.c \
  ../../Source/queue.c \
  ../../Source/list.c \
  ../../Source/portable/GCC/ARM7_AT91SAM7S/port.c \
  syscalls.c

DEMO_APP_THUMB_SRC= \
  ../../Source/portable/MemMang/heap_2.c \
  ParTest/ParTest.c \
  main.c \
  ../Common/Minimal/flash.c \
  ../Common/Minimal/BlockQ.c \
  ../Common/Minimal/integer.c \
  ../Common/Minimal/PollQ.c \
  ../Common/Minimal/semtest.c \
  BasicWEB.c \
  USB/USB-CDC.c

LWIP_THUMB_SRC= \
  lwip-1.1.0/src/core/tcp_out.c \
  lwip-1.1.0/src/core/inet.c \
  lwip-1.1.0/src/core/mem.c \
  lwip-1.1.0/src/core/memp.c \
  lwip-1.1.0/src/core/netif.c \
  lwip-1.1.0/src/core/pbuf.c \
  lwip-1.1.0/src/core/raw.c \
  lwip-1.1.0/src/core/stats.c \
  lwip-1.1.0/src/core/sys.c \
  lwip-1.1.0/src/core/tcp.c \
  lwip-1.1.0/src/core/tcp_in.c \
  lwip-1.1.0/src/core/ipv4/ip.c \
  lwip-1.1.0/src/core/ipv4/ip_addr.c \
  lwip-1.1.0/src/core/ipv4/icmp.c \
  lwip-1.1.0/src/api/tcpip.c \
  lwip-1.1.0/src/api/api_msg.c \
  lwip-1.1.0/src/api/err.c \
  lwip-1.1.0/src/api/api_lib.c \
  lwip-1.1.0/src/netif/etharp.c \
  lwip-1.1.0/contrib/port/FreeRTOS/AT91SAM7X/sys_arch.c \
  lwip-1.1.0/src/netif/ethernetif.c \
  EMAC/SAM7_EMAC.c \
  lwip-1.1.0/src/core/udp.c \
  lwip-1.1.0/src/core/ipv4/ip_frag.c

SRC = $(FREERTOS_THUMB_SRC) $(DEMO_APP_THUMB_SRC) $(LWIP_THUMB_SRC)

# List C source files here which must be compiled in ARM-Mode.
# use file-extension c for "c-only"-files
#SRCARM  = common/Cstartup_SAM7.c

SRCARM = \
  ../../Source/portable/GCC/ARM7_AT91SAM7S/portISR.c \
  EMAC/SAM7_EMAC_ISR.c \
  USB/USBIsr.c \
  Cstartup_SAM7.c

# List C++ source files here.
# use file-extension cpp for C++-files (use extension .cpp)
CPPSRC =

# List C++ source files here which must be compiled in ARM-Mode.
# use file-extension cpp for C++-files (use extension .cpp)
#CPPSRCARM = $(TARGET).cpp
CPPSRCARM =

# 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 =

# List Assembler source files here which must be assembled in ARM-Mode..
#ASRCARM  = common/Cstartup.S
#ASRCARM += common/swi_handler.S
ASRCARM = boot.S


## Output format. (can be ihex or binary)
## (binary i.e. for openocd and SAM-BA, hex i.e. for lpc21isp and
uVision)
#FORMAT = ihex
FORMAT = binary

# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s

# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
#DEBUG = stabs
DEBUG = dwarf-2

# List any extra directories to look for include files here.
#     Each directory must be seperated by a space.
#EXTRAINCDIRS = ./common
EXTRAINCDIRS =

# List any extra directories to look for library files here.
#     Each directory must be seperated by a space.
#EXTRA_LIBDIRS = ../arm7_efsl_0_2_4
EXTRA_LIBDIRS =

## Using the Atmel AT91_lib produces warning with
## the default warning-levels.
## yes - disable these warnings; no - keep default settings
AT91LIBNOWARN = yes
#AT91LIBNOWARN = no

# Compiler flag to set the C Standard level.
# c89   - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99   - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99

## -D adds preprocessor defines (like #define within a source file)
## No need to pass RUN_MODE.  (Not used in AT91SAM7 samples) -jmd
# Place -D or -U options for C here
#CDEFS =  -D$(RUN_MODE)
CDEFS =

# Place -D or -U options for ASM here
#ADEFS =  -D$(RUN_MODE)
ADEFS =

ifdef VECTOR_LOCATION
CDEFS += -D$(VECTOR_LOCATION)
ADEFS += -D$(VECTOR_LOCATION)
endif

CDEFS += -D__WinARM__
ADEFS += -D__WinARM__

# Add definitions required by FreeRTOS
CDEFS += -DSAM7_GCC -DTHUMB_INTERWORK


# Place -I options here (include directories)
CINCS= \
-I.  \
-I./EMAC  \
-I../Common/include  \
-I./USB  \
-I./lwip-1.1.0/src/include  \
-I./lwip-1.1.0/contrib/port/FreeRTOS/AT91SAM7X  \
-I../../Source/include  \
-I../../Source/portable/GCC/ARM7_AT91SAM7S  \
-I./lwip-1.1.0/src/include/ipv4 \


# Compiler flags.
#  -g*:          generate debugging information
#  -O*:          optimization level
#  -f...:        tuning, see GCC manual and avr-libc documentation
#  -Wall...:     warning level
#  -Wa,...:      tell GCC to pass this to the assembler.
#    -adhlns...: create assembler listing
#
# Flags for C and C++ (arm-elf-gcc/arm-elf-g++)
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -Wall -Wcast-align -Wimplicit
CFLAGS += -Wpointer-arith -Wswitch
CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused
CFLAGS += -Wa,-adhlns=$(subst $(suffix $<),.lst,$<)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))

# flags only for C
CONLYFLAGS += -Wnested-externs
CONLYFLAGS += $(CSTANDARD)

ifneq ($(AT91LIBNOWARN),yes)
#AT91-lib warnings with:
CFLAGS += -Wcast-qual
CONLYFLAGS += -Wmissing-prototypes
CONLYFLAGS += -Wstrict-prototypes
CONLYFLAGS += -Wmissing-declarations
endif

# flags only for C++ (arm-elf-g++)
# CPPFLAGS = -fno-rtti -fno-exceptions
CPPFLAGS =

# Assembler flags.
#  -Wa,...:    tell GCC to pass this to the assembler.
#  -ahlns:     create listing
#  -g$(DEBUG): have the assembler create line number information
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:.S=.lst),--g$(DEBUG)


#Additional libraries.

# Extra libraries
#    Each library-name must be seperated by a space.
#    To add libxyz.a, libabc.a and libefsl.a:
#    EXTRA_LIBS = xyz abc efsl
#EXTRA_LIBS = efsl
EXTRA_LIBS =

#Support for newlibc-lpc (file: libnewlibc-lpc.a)
NEWLIBLPC = -lnewlib-lpc

MATH_LIB = -lm

# CPLUSPLUS_LIB = -lstdc++


# Linker flags.
#  -Wl,...:     tell GCC to pass this to linker.
#    -Map:      create map file
#    --cref:    add cross reference to  map file
LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref
#-jmd #LDFLAGS += -lc
#-jmd #LDFLAGS += $(NEWLIBLPC) $(MATH_LIB)
#-jmd #LDFLAGS += -lc -lgcc
#-jmd #LDFLAGS += $(CPLUSPLUS_LIB)
#-jmd #LDFLAGS += $(patsubst %,-L%,$(EXTRA_LIBDIRS))
#-jmd #LDFLAGS += $(patsubst %,-l%,$(EXTRA_LIBS))

# Set Linker-Script Depending On Selected Memory and Controller
ifeq ($(RUN_MODE),RAM_RUN)
LDFLAGS +=-T$(SUBMDL)-RAM.ld
else
LDFLAGS +=-T$(SUBMDL)-ROM.ld
endif


#
------------------------------------------------------------------------ 
---
# Flash-Programming support using lpc21isp by Martin Maurer
# only for Philips LPC and Analog ADuC ARMs
#
# Settings and variables:
#LPC21ISP = lpc21isp
#LPC21ISP = lpc21isp
#LPC21ISP_PORT = com1
#LPC21ISP_BAUD = 38400
#LPC21ISP_XTAL = 12000
#LPC21ISP_FLASHFILE = $(TARGET).hex
# verbose output:
#LPC21ISP_DEBUG = -debug
# enter bootloader via RS232 DTR/RTS (only if hardware supports this
# feature - see Philips AppNote):
#LPC21ISP_CONTROL = -control
#
------------------------------------------------------------------------ 
---


# Define directories, if needed.
## DIRARM = c:/WinARM/
## DIRARMBIN = $(DIRAVR)/bin/
## DIRAVRUTILS = $(DIRAVR)/utils/bin/

# Define programs and commands.
SHELL = sh
CC = arm-elf-gcc
CPP = arm-elf-g++
OBJCOPY = arm-elf-objcopy
OBJDUMP = arm-elf-objdump
SIZE = arm-elf-size
NM = arm-elf-nm
REMOVE = rm -f
COPY = cp

# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = "-------- begin (mode: $(RUN_MODE)) --------"
MSG_END = --------  end  --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_FLASH = Creating load file for Flash:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_ARM = "Compiling C (ARM-only):"
MSG_COMPILINGCPP = Compiling C++:
MSG_COMPILINGCPP_ARM = "Compiling C++ (ARM-only):"
MSG_ASSEMBLING = Assembling:
MSG_ASSEMBLING_ARM = "Assembling (ARM-only):"
MSG_CLEANING = Cleaning project:
MSG_FORMATERROR = Can not handle output-format
MSG_LPC21_RESETREMINDER = You may have to bring the target in
bootloader-mode now.

# Define all object files.
COBJ      = $(SRC:.c=.o)
AOBJ      = $(ASRC:.S=.o)
COBJARM   = $(SRCARM:.c=.o)
AOBJARM   = $(ASRCARM:.S=.o)
CPPOBJ    = $(CPPSRC:.cpp=.o)
CPPOBJARM = $(CPPSRCARM:.cpp=.o)

# Define all listing files.
LST = $(ASRC:.S=.lst) $(ASRCARM:.S=.lst) $(SRC:.c=.lst)
$(SRCARM:.c=.lst)
LST += $(CPPSRC:.cpp=.lst) $(CPPSRCARM:.cpp=.lst)

# Compiler flags to generate dependency files.
### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d

# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS  = -mcpu=$(MCU) $(THUMB_IW) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. -x assembler-with-cpp
$(ASFLAGS)


# Default target.
all: begin gccversion sizebefore build sizeafter finished end

ifeq ($(FORMAT),ihex)
build: elf hex lss sym
hex: $(TARGET).hex
IMGEXT=hex
else
ifeq ($(FORMAT),binary)
build: elf bin lss sym
bin: $(TARGET).bin
IMGEXT=bin
else
$(error "$(MSG_FORMATERROR) $(FORMAT)")
endif
endif

elf: $(TARGET).elf
lss: $(TARGET).lss
sym: $(TARGET).sym

# Eye candy.
begin:
  @echo
  @echo $(MSG_BEGIN)

finished:
  @echo $(MSG_ERRORS_NONE)

end:
  @echo $(MSG_END)
  @echo


# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
sizebefore:
  @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE);
$(ELFSIZE); echo; fi

sizeafter:
  @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER);
$(ELFSIZE); echo; fi


# Display compiler version information.
gccversion :
  @$(CC) --version


# Program the device.
ifeq ($(FLASH_TOOL),UVISION)
# Program the device with Keil's uVision (needs configured
uVision-Workspace).
program: $(TARGET).$(IMGEXT)
  @echo
  @echo "Programming with uVision"
  C:\Keil\uv3\Uv3.exe -f uvisionflash.Uv2 -ouvisionflash.txt
#  $(REMOVE) ../Common_WinARM/$(TARGET).hex
#  $(COPY) $(TARGET).hex ../Common_WinARM/
#  C:\Keil\uv3\Uv3.exe -f ..\Common_WinARM\uvisionflash.Uv2
else
ifeq ($(FLASH_TOOL),OPENOCD)
# Program the device with Dominic Rath's OPENOCD in "batch-mode", needs
cfg and

"reset-script".
program: $(TARGET).$(IMGEXT)
  @echo
  @echo "Programming with OPENOCD"
  C:\WinARM\utils\openocd\openocd_svn59\openocd.exe -f
oocd_sam7_flash.cfg
else
# Program the device.  - lpc21isp will not work for SAM7
program: $(TARGET).$(IMGEXT)
  @echo
  @echo $(MSG_LPC21_RESETREMINDER)
  $(LPC21ISP) $(LPC21ISP_OPTIONS) $(LPC21ISP_DEBUG) 
$(LPC21ISP_FLASHFILE)

$(LPC21ISP_PORT) $(LPC21ISP_BAUD) $(LPC21ISP_XTAL)
endif
endif


# Create final output file (.hex) from ELF output file.
%.hex: %.elf
  @echo
  @echo $(MSG_FLASH) $@
  $(OBJCOPY) -O $(FORMAT) $< $@

# Create final output file (.bin) from ELF output file.
%.bin: %.elf
  @echo
  @echo $(MSG_FLASH) $@
  $(OBJCOPY) -O $(FORMAT) $< $@


# Create extended listing file from ELF output file.
# testing: option -C
%.lss: %.elf
  @echo
  @echo $(MSG_EXTENDED_LISTING) $@
  $(OBJDUMP) -h -S -C $< > $@


# Create a symbol table from ELF output file.
%.sym: %.elf
  @echo
  @echo $(MSG_SYMBOL_TABLE) $@
  $(NM) -n $< > $@


# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ) $(CPPOBJ) $(CPPOBJARM)
%.elf:  $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ) $(CPPOBJ) $(CPPOBJARM)
  @echo
  @echo $(MSG_LINKING) $@
  $(CC) $(THUMB) $(ALL_CFLAGS) $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ)
$(CPPOBJ)

$(CPPOBJARM) --output $@ $(LDFLAGS)
#  $(CPP) $(THUMB) $(ALL_CFLAGS) $(AOBJARM) $(AOBJ) $(COBJARM) $(COBJ)
$(CPPOBJ)

$(CPPOBJARM) --output $@ $(LDFLAGS)

# Compile: create object files from C source files. ARM/Thumb
$(COBJ) : %.o : %.c
  @echo
  @echo $(MSG_COMPILING) $<
  $(CC) -c $(THUMB) $(ALL_CFLAGS) $(CONLYFLAGS) $< -o $@

# Compile: create object files from C source files. ARM-only
$(COBJARM) : %.o : %.c
  @echo
  @echo $(MSG_COMPILING_ARM) $<
  $(CC) -c $(ALL_CFLAGS) $(CONLYFLAGS) $< -o $@

# Compile: create object files from C++ source files. ARM/Thumb
$(CPPOBJ) : %.o : %.cpp
  @echo
  @echo $(MSG_COMPILINGCPP) $<
  $(CPP) -c $(THUMB) $(ALL_CFLAGS) $(CPPFLAGS) $< -o $@

# Compile: create object files from C++ source files. ARM-only
$(CPPOBJARM) : %.o : %.cpp
  @echo
  @echo $(MSG_COMPILINGCPP_ARM) $<
  $(CPP) -c $(ALL_CFLAGS) $(CPPFLAGS) $< -o $@


# Compile: create assembler files from C source files. ARM/Thumb
## does not work - TODO - hints welcome
##$(COBJ) : %.s : %.c
##  $(CC) $(THUMB) -S $(ALL_CFLAGS) $< -o $@


# Assemble: create object files from assembler source files. ARM/Thumb
$(AOBJ) : %.o : %.S
  @echo
  @echo $(MSG_ASSEMBLING) $<
  $(CC) -c $(THUMB) $(ALL_ASFLAGS) $< -o $@


# Assemble: create object files from assembler source files. ARM-only
$(AOBJARM) : %.o : %.S
  @echo
  @echo $(MSG_ASSEMBLING_ARM) $<
  $(CC) -c $(ALL_ASFLAGS) $< -o $@


# Target: clean project.
clean: begin clean_list finished end


clean_list :
  @echo
  @echo $(MSG_CLEANING)
  $(REMOVE) ../Common_WinARM/$(TARGET).hex
  $(REMOVE) $(TARGET).hex
  $(REMOVE) $(TARGET).bin
  $(REMOVE) $(TARGET).obj
  $(REMOVE) $(TARGET).elf
  $(REMOVE) $(TARGET).map
  $(REMOVE) $(TARGET).obj
  $(REMOVE) $(TARGET).a90
  $(REMOVE) $(TARGET).sym
  $(REMOVE) $(TARGET).lnk
  $(REMOVE) $(TARGET).lss
  $(REMOVE) $(COBJ)
  $(REMOVE) $(CPPOBJ)
  $(REMOVE) $(AOBJ)
  $(REMOVE) $(COBJARM)
  $(REMOVE) $(CPPOBJARM)
  $(REMOVE) $(AOBJARM)
  $(REMOVE) $(LST)
#  $(REMOVE) $(SRC:.c=.s)
  $(REMOVE) $(SRC:.c=.d)
#  $(REMOVE) $(SRCARM:.c=.s)
  $(REMOVE) $(SRCARM:.c=.d)
#  $(REMOVE) $(CPPSRC:.cpp=.s)
  $(REMOVE) $(CPPSRC:.cpp=.d)
#  $(REMOVE) $(CPPSRCARM:.cpp=.s)
  $(REMOVE) $(CPPSRCARM:.cpp=.d)
  $(REMOVE) .dep/*


# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)


# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex bin lss sym clean clean_list program

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.