ATmega4809 : inline string is 0xff,0xff, ... 0xff, 0x00 ??

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

I had a function :

void send2net(char * str) {
    char * p=str;
    while(*p!=0) {
        while((UCSR2A&(1<<UDRE))==0);    // wait UDR empty
        UDR2=*p++;
    }
} // end of send2net

I used it with ATmega324PB and is works well.

 

Now, I switch to ATmega4809 :

void send2net(char * str) {
	char * p=str;
	while(*p!=0) {
		while((USART1.STATUS&USART_DREIF_bm)==0);	// wait UDR empty
		USART1.TXDATAL=*p++;
	}
} // end of send2net

But it does not work a expected.

char hello1[]="Hello 1\n";
send2net(hello1);
send2net("Hello 2\n");

I get :

Hello 1␊
<0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff>

 

My questions are :

  1. why inline string does not work as before as I use the same makefile (just change what's needed) ?
  2. why all bytes of the inline string is read as 0xff except the last one (as it exits send2net) ?
  3. why 9 * 0xff as "Hello 2\n" is only 8 characters (+ null char at the end) ?
  4. How to solve this ?

 

Thanks for your lights and help.

 

Doom

 

AVR inside

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

Seems the inline string is in text section but not in hex file.

 

test short string :

send2net("Hello 2\n");

test long string ;

send2net("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHello 2\n");

 

results :

short :

-rw-r--r-- 1 doom doom  9128 juin  23 12:50 main.o
-rw-r--r-- 1 doom doom    13 juin  23 12:50 test_toolchain.ee.hex
-rw-r--r-- 1 doom doom   922 juin  23 12:50 test_toolchain.hex
-rwxr-xr-x 1 doom doom 31320 juin  23 12:50 test_toolchain.out*
disasm
avr-size test_toolchain.out
   text	   data	    bss	    dec	    hex	filename
    317	     10	      0	    327	    147	test_toolchain.out

 

long :

ll *.hex *.out *.o
-rw-r--r-- 1 doom doom  9684 juin  23 12:54 main.o
-rw-r--r-- 1 doom doom    13 juin  23 12:54 test_toolchain.ee.hex
-rw-r--r-- 1 doom doom   922 juin  23 12:54 test_toolchain.hex
-rwxr-xr-x 1 doom doom 31880 juin  23 12:54 test_toolchain.out*
disasm
avr-size test_toolchain.out
   text	   data	    bss	    dec	    hex	filename
    875	     10	      0	    885	    375	test_toolchain.out

 

So inline string is in the text section, in the .out file, in the .o file, but not in the .hex file.
And I send the .hex file to the ATmega4809. so ...

AVR inside

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

Are you running objcopy yourself? Remember on these newer AVRs that constants are in .rodata

:: Morten

 

(yes, I work for Atmel, 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 this makefile :

#########  AVR Project Makefile Template   #########
######                                        ######
######    Copyright (C) 2003-2005, 2017       ######
######            Pat Deegan,                 ######
######            Psychogenic.com             ######
######          All Rights Reserved           ######
######                                        ######
###### You are free to use this code as part  ######
###### of your own applications provided      ######
###### you keep this copyright notice intact  ######
######                                        ######
###### If you use it as part of a project     ######
###### it'd be cool to include a link to      ######
###### http://flyingcarsandstuff.com     or   ######
###### http://www.psychogenic.com             ######
######                                        ######
####################################################

##### This Makefile will make compiling Atmel AVR
##### micro controller projects simple with Linux
##### or other Unix workstations and the AVR-GCC
##### tools.
#####
##### It supports C, C++ and Assembly source files.
#####
##### Customize the values as indicated below and :
##### make
##### make disasm
##### make stats
##### make hex
##### make writeflash
##### make reset	 // Doom
##### make gdbinit
##### or make clean
#####
##### See the http://flyingcarsandstuff.com/
##### website for detailed instructions

####################################################
#####                                          #####
#####              Configuration               #####
#####                                          #####
##### Customize the values in this section for #####
##### your project. MCU, PROJECT and           #####
##### PRJSRC must be setup for all projects,   #####
##### the remaining variables are only         #####
##### relevant to those needing additional     #####
##### include dirs or libraries and those      #####
##### who wish to use the avrdude programmer   #####
#####                                          #####
##### See http://flyingcarsandstuff.com/       #####
##### for further details.                     #####
#####                                          #####
####################################################

#####         Target Specific Details          #####
#####     Customize these for your project     #####

# Name of target controller
# (e.g. 'at90s8515', see the available avr-gcc mmcu
# options for possible values)
# What you probably want is atmega328p (standardish AVR)
# but you can use anything AVR-GCC can handle.
# Just ensure you also set the corresponding PROGRAMMER_MCU,
# if you're using avrdude.
MCU?=atmega4809

# id to use with programmer
# default: PROGRAMMER_MCU=$(MCU)
# In case the programer used, e.g avrdude, doesn't
# accept the same MCU name as avr-gcc (for example
# for ATmega8s, avr-gcc expects 'atmega8' and
# avrdude requires 'm8')
PROGRAMMER_MCU?=m4809

# Name of our project
# (use a single word, e.g. 'myproject')
PROJECT?=test_toolchain

# Source files
# List C/C++/Assembly source files:
# (list all files to compile, e.g. 'a.c b.cpp as.S'):
# Use .cc, .cpp or .C suffix for C++ files, use .S
# (NOT .s !!!) for assembly source code files.
# You can do this manually, like:
#     PRJSRC=main.c myclass.cpp lowlevelstuff.S
# or you can simply let the magic of wildcards
# do their thing, if the makefile in the top
# level dir of your source
#PRJSRC=main.c myclass.cpp lowlevelstuff.S

PRJSRC=$(wildcard *.c) $(wildcard **/*.c) $(wildcard **/*/*.c) \
        $(wildcard *.cpp) $(wildcard **/*.cpp) $(wildcard **/*/*.cpp)\
	$(wildcard *.cc)  $(wildcard **/*.cc) $(wildcard **/*/*.cc)\
	$(wildcard *.S)  $(wildcard **/*.S) $(wildcard **/*/*.S)

# additional includes (e.g. -I/path/to/mydir)
INC?=-I/path/to/include

# libraries to link in (e.g. -lmylib)
LIBS?=

# Optimization level,
# use s (size opt), 1, 2, 3 or 0 (off)
OPTLEVEL=s

#####      AVR Dude 'writeflash' options       #####
#####  If you are using the avrdude program
#####  (http://www.bsdhome.com/avrdude/) to write
#####  to the MCU, you can set the following config
#####  options and use 'make writeflash' to program
#####  the device.

# programmer id--check the avrdude for complete list
# of available opts.  These should include stk500,
# avr910, avrisp, bsd, pony and more.  Set this to
# one of the valid "-c PROGRAMMER-ID" values
# described in the avrdude info page.
#
AVRDUDE_PROGRAMMERID?=atmelice_updi

# port--serial or parallel port to which your
# hardware programmer is attached
#
AVRDUDE_PORT?=/dev/avrisp

$(info ******************* AVR MAKE ******************* )
$(info **                               )
$(info **   PROJECT:       $(PROJECT))
$(info **   Compiling for MCU: $(MCU)/$(PROGRAMMER_MCU))
$(info **                               )
$(info ************************************************ )
$(info use 'make' to build or with param:)
$(info      disasm)
$(info      stats)
$(info      hex)
$(info      writeflash)
$(info      reset)
$(info      secure)
$(info      gdbinit, or)
$(info      clean)
$(info See https://flyingcarsandstuff.com/ for details)
$(info ************************************************ )

####################################################
#####                Config Done               #####
#####                                          #####
##### You shouldn't need to edit anything      #####
##### below to use the makefile but may wish   #####
##### to override a few of the flags           #####
##### nonetheless                              #####
#####                                          #####
####################################################

##### Flags ####
# HEXFORMAT -- format for .hex file output
HEXFORMAT=ihex

# compiler
CONLYFLAGS=-Wstrict-prototypes
CFLAGS=-I. $(INC) -g -mmcu=$(MCU) -O$(OPTLEVEL) \
	-fpack-struct -fshort-enums             \
	-funsigned-bitfields -funsigned-char    \
	-Wall                                   \
	-Wa,-ahlms=$(firstword                  \
	$(filter %.lst, $(<:.c=.lst)))

# c++ specific flags
CPPFLAGS=-fno-exceptions               \
	-Wa,-ahlms=$(firstword         \
	$(filter %.lst, $(<:.cpp=.lst))\
	$(filter %.lst, $(<:.cc=.lst)) \
	$(filter %.lst, $(<:.C=.lst)))

# assembler
ASMFLAGS =-I. $(INC) -mmcu=$(MCU)        \
	-x assembler-with-cpp            \
	-Wa,-gstabs,-ahlms=$(firstword   \
		$(<:.S=.lst) $(<.s=.lst))

# linker
LDFLAGS=-Wl,-Map,$(TRG).map -mmcu=$(MCU) \
	-lm $(LIBS)

##### executables ####
CC=avr-gcc
OBJCOPY=avr-objcopy
OBJDUMP=avr-objdump
SIZE=avr-size
AVRDUDE=avrdude
REMOVE=rm -f

##### automatic target names ####
TRG=$(PROJECT).out
DUMPTRG=$(PROJECT).s

HEXROMTRG=$(PROJECT).hex
HEXTRG=$(HEXROMTRG) $(PROJECT).ee.hex
GDBINITFILE=gdbinit-$(PROJECT)

# Define all object files.

# Start by splitting source files by type
#  C++
CPPFILES=$(filter %.cpp, $(PRJSRC))
CCFILES=$(filter %.cc, $(PRJSRC))
BIGCFILES=$(filter %.C, $(PRJSRC))
#  C
CFILES=$(filter %.c, $(PRJSRC))
#  Assembly
ASMFILES=$(filter %.S, $(PRJSRC))

# List all object files we need to create
OBJDEPS=$(CFILES:.c=.o)    \
	$(CPPFILES:.cpp=.o)\
	$(BIGCFILES:.C=.o) \
	$(CCFILES:.cc=.o)  \
	$(ASMFILES:.S=.o)

# Define all lst files.
LST=$(filter %.lst, $(OBJDEPS:.o=.lst))

# All the possible generated assembly
# files (.s files)
GENASMFILES=$(filter %.s, $(OBJDEPS:.o=.s)) 

.SUFFIXES : .c .cc .cpp .C .o .out .s .S \
	.hex .ee.hex .h .hh .hpp

.PHONY: writeflash clean stats gdbinit stats

# Make targets:
# all, disasm, stats, hex, writeflash/install, clean
all: $(TRG)

disasm: $(DUMPTRG) stats

stats: $(TRG)
	$(OBJDUMP) -h $(TRG)
	$(SIZE) $(TRG) 

hex: $(HEXTRG)

writeflash: hex
	$(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID)   \
	 -p $(PROGRAMMER_MCU) -e        \
	 -U flash:w:$(HEXROMTRG)
#~ 	 -p $(PROGRAMMER_MCU) -P $(AVRDUDE_PORT) -e        \

# reset the mcu with avrdude
reset:
	$(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID) -p $(PROGRAMMER_MCU)

# write lock bits to secure device
secure :
	$(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID) -p $(PROGRAMMER_MCU) -U lock:w:0xc0:m

install: writeflash

$(DUMPTRG): $(TRG)
	$(OBJDUMP) -S  $< > $@

$(TRG): $(OBJDEPS)
	$(CC) $(LDFLAGS) -o $(TRG) $(OBJDEPS)

#### Generating assembly ####
# asm from C
%.s: %.c
	$(CC) -S $(CFLAGS) $(CONLYFLAGS) $< -o $@

# asm from (hand coded) asm
%.s: %.S
	$(CC) -S $(ASMFLAGS) $< > $@

# asm from C++
.cpp.s .cc.s .C.s :
	$(CC) -S $(CFLAGS) $(CPPFLAGS) $< -o $@

#### Generating object files ####
# object from C
.c.o:
	$(CC) $(CFLAGS) $(CONLYFLAGS) -c $< -o $@

# object from C++ (.cc, .cpp, .C files)
.cc.o .cpp.o .C.o :
	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

# object from asm
.S.o :
	$(CC) $(ASMFLAGS) -c $< -o $@

#### Generating hex files ####
# hex files from elf
#####  Generating a gdb initialisation file    #####
.out.hex:
	$(OBJCOPY) -j .text                    \
		-j .data                       \
		-O $(HEXFORMAT) $< $@

.out.ee.hex:
	$(OBJCOPY) -j .eeprom                  \
		--change-section-lma .eeprom=0 \
		-O $(HEXFORMAT) $< $@

#####  Generating a gdb initialisation file    #####
##### Use by launching simulavr and avr-gdb:   #####
#####   avr-gdb -x gdbinit-myproject           #####
gdbinit: $(GDBINITFILE)

$(GDBINITFILE): $(TRG)
	@echo "file $(TRG)" > $(GDBINITFILE)

	@echo "target remote localhost:1212" \
		                >> $(GDBINITFILE)

	@echo "load"        >> $(GDBINITFILE)
	@echo "break main"  >> $(GDBINITFILE)
	@echo "continue"    >> $(GDBINITFILE)
	@echo
	@echo "Use 'avr-gdb -x $(GDBINITFILE)'"

#### Cleanup ####
clean:
	$(REMOVE) $(TRG) $(TRG).map $(DUMPTRG)
	$(REMOVE) $(OBJDEPS)
	$(REMOVE) $(LST) $(GDBINITFILE)
	$(REMOVE) $(GENASMFILES)
	$(REMOVE) $(HEXTRG)

#####                    EOF                   #####

 

AVR inside

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
.out.hex:
	$(OBJCOPY) -j .text                    \
		-j .data                       \
		-O $(HEXFORMAT) $< $@

Then Morten is suggesting:

.out.hex:
	$(OBJCOPY) -j .text                    \
		-j .data                       \
                -j .rodata                     \
		-O $(HEXFORMAT) $< $@

with the addition of .rodata

 

PS most build systems choose to use -R not -j these days. That way you list what you want to remove not what you want to include and by implication everything else is included. So if this had been more like:

.out.hex:
	$(OBJCOPY) -R .fuse                    \
		-R .lock                       \
                -R .eeprom                     \
		-O $(HEXFORMAT) $< $@

then it would have worked immediately when .rodata was populated.

Last Edited: Tue. Jun 23, 2020 - 11:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Many thanks !  First works and second also.

As suggested, I finally keep the -R version.

AVR inside