error in bootloader code for mega328.

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

*******after all the topic conversation the actual errors points to the source code. See post 52 on page 2. *******

 

 

 

 

I'm using a 328p chip with a USB bootloader from the v-usb project.  Today I had an issue loading my hex I have not ran in to yet. Avr studio says my chip is not full but I'm getting error during my boot flash that implies I'm out of space.  The bootloader says it failed at 0x7080.

 

Avr studio build says I have room left (see below).

I though the calculation included the boatloader space?

  Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)

 

 

If I remove a line of code and compile it flashes fine. Why would the size be reported incorrectly (if that is even my issue)?

 

 

        Size before:
        AVR Memory Usage
        ----------------
        Device: atmega328p
        Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)
        Data:       1227 bytes (59.9% Full)
        (.data + .bss + .noinit)
        Size after:
        AVR Memory Usage
        ----------------
        Device: atmega328p
        Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)
        Data:       1227 bytes (59.9% Full)
        (.data + .bss + .noinit)
        -------- end --------      

 

 

 

 

 

Last Edited: Thu. May 11, 2017 - 01:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Send me an email. bobgardner at aol dot com. I'm in Edgewood/Pinecastle area. Maybe we can collaborate on some problem solving?

 

Imagecraft compiler user

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

If you are writing a bootloader why on earth would you have a memory section called ".bootloader"? A bootloader just moves the entire .text to the BLS

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

I'm not really sure, it was a a open source project I started with. There are 3 parts to this

 

Boot loader

USB driver firmware

Code

 

The USB driver firmware and Code are really one in the same. Maybe the driver is label bootloader, I dont see where this bootloader is defined. I figure it was in the MAKE file but its not there? - I'm using AS6

Last Edited: Mon. Dec 12, 2016 - 03:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was simply referring to:


        AVR Memory Usage
        ----------------
        Device: atmega328p
        Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)

But that all seems very odd. 28K of code? It's clearly not just a bootloader. It looks like a bootloader AND and application being built together - recipe for total disaster if you ask me!

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

right, that  is how I understood your first post.  I agree but what in as6 would be adding this "bootloader". Is that specified in the make file or setting somewhere?  I'm not really sure why that is there but do agree it looks strange. It has always been there. Is there a place to define the memory sections?

Last Edited: Tue. Dec 13, 2016 - 02:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The way you build applications and bootloaders is separately. They should be two totally unrelated projects, each with their own main() and each with their own base address. You only use techniques like ".bootloader" when you simply want to add some flash writing code to an app and so that small part of it needs to be lifted to high addresses so that the SPM opcode can be used. For a true bootloader it's just like a normal app. They both have a ".text" section and the only difference is that the base address of the bootloader is lifted high.

 

If this isn't your own project code it sounds like the original author did not understand this concept.

 

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

The way you build applications and bootloaders is separately. They should be two totally unrelated projects, each with their own main() and each with their own base address. 

and I have precisely  that. I'm not 100% sure on what the addresses are but I do remember having to put that in the the project somewhere. The bootlaoder is at the higher start address and the main part of the application is in a lower address. Avr studio has a habit of moving stuff..

 

You only use techniques like ".bootloader" when you simply want to add some flash writing code to an app and so that small part of it needs to be lifted to high addresses so that the SPM opcode can be used.

From what I have always understood about my project is that the bootloader code (project 1 with its own main) gets put in the higher area and project 2 (also with its own main and the build out put at the top of this post ) gets put in to a specific area on the chip loaded by the bootloader. When I make a chip I load my bootloader then I use the flash tool to upload my project. 

 

This seem to match what you just said? 

 

but you raised a concern about this code

 AVR Memory Usage
        ----------------
        Device: atmega328p
        Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)

 

So is there a concern any longer?

 

The issue I'm having is when I build my project two it calculate this 87% full.  I know for a fact the bootloader is not %23 percent of my chip, more like %8.  but when I use my flash tool it complains. 

 

 

The things that are not clear to me.

This 87%, does that take in to account the boot loader? I say that because there is no way project 2 could know anything about my boot loader (I think). 

I'm not sure I need this .bootloader, I'm pretty sure I use a true bootloader. Both are their own projects. 

How do set this .bootloader, where did it come from, if its not needed could that be my issue. 

 

 

I can not past my output from the bootloader but it says this

device size -00032768

data (28674) exceeds flash size!

flashing 28800 (0x7080) bytes  start at 0

and obviously fails at 0x07000

 

 

If this isn't your own project code it sounds like the original author did not understand this concept.

That or maybe it get mixed up in the shuffle. The original code goes back to 07. I have gone from as4 to 5 to now 6. I would have gone to 7, but I came to the realization there is no point in update so why bother.  Every time AS comes out with a new version it changes stuff. 6 is working ok enough that I'll leave it be. The bootloader is compiled in as4 and the main app in as6 but I dont think that is an issue. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Last Edited: Tue. Dec 13, 2016 - 10:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, here is an extremely simple example to show what I think may be wrong here:

$ cat avr.c
#include <avr/io.h>

__attribute__((section(".bootloader"))) void foo(void) {
    PORTB = 0x55;
}

int main(void) {
    DDRB = 0xFF;
    foo();
}
$ avr-gcc -mmcu=atmega328p -Os -Wl,-section-start=.bootloader=0x7F00 avr.c -o avr.elf
$ avr-objcopy -O binary -j .text -j .bootloader avr.elf avr.bin
$ ls -lh avr.bin
-rwxr-xr-x 1 uid23021 domain_users 32K Dec 14 09:12 avr.bin
$ 

It couldn't get much simpler than this. It's an AVR program with two functions in it. One is main() which will be built, along with the interrupt vectors and other CRT stuff down near location 0. Then there is one function (foo()) which is put into a memory section called .bootloader. The function itself will only be about 8 bytes but when I build I tell the linker to base .bootloader up at a bootloader like address (0x7F00 in this case). Finally I extract a complete program consisting of .text and .bootloader into a binary file. That file on disk is 32K ! In fact:

-rwxr-xr-x 1 uid23021 domain_users 32518 Dec 14 09:12 avr.bin

So I have managed to build something that occupies almost the entire flash of the AVR (admittedly with a big "hole" in the middle) using 2 C functions.

 

I imagine your "87"%" is actually a much smaller app size and then something tagged on "up high" at the end that extends the entire thing to look like it is occupying most of the flash. If, as you say, the AVR already has a bootloader then clearly you cannot have the app using .bootloader too if that really means some SPM routines lifted to the same address space that the bootloader already tries to occupy.

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

Now I don't know your bootloader , the settings programmed etc.

 

But max bootloader size is 2048 Words = 0x1000 bytes that mean starting at 0x7000 !

 

Perhaps the limit is in the setting in the bootloader (how big it could be!)  

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

In the Makefile for the bootloader firmware downloaded from the V-USB link in Post1 there is a configuration section that you are meant to customise for your target AVR.

# Name: Makefile
# Project: bootloadHID
# Author: Christian Starkjohann
# Creation Date: 2007-03-19
# Tabsize: 4
# Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
# License: GNU GPL v2 (see License.txt)
# This Revision: $Id$

###############################################################################
# Configure the following variables according to your AVR. The example below
# is for an ATMega8. Program the device with
#     make fuse    # to set the clock generator, boot section size etc.
#     make flash   # to load the boot loader into flash
#     make lock    # to protect the boot loader from overwriting

DEVICE = atmega328p
BOOTLOADER_ADDRESS = 7800
F_CPU = 12000000
FUSEH = 0xc0
FUSEL = 0x9f

I've had a go at guessing what you should have entered, do you concur ?

 

The makefile contains a couple of silly errors:

1 The ELF file linker output is ELF format but is named main.bin

2. avr-size is run on the hex file and not the ELF giving less info than it could if it were run on the ELF.

 

After fixing those I get this build:

nigel@E3510:~/Project/freaks/bootloadHID.2012-12-08/firmware$ make all
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -Iusbdrv -I. -mmcu=atmega328p -DF_CPU=12000000 -DDEBUG_LEVEL=0  -x assembler-with-cpp -c usbdrv/usbdrvasm.S -o usbdrv/usbdrvasm.o
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -Iusbdrv -I. -mmcu=atmega328p -DF_CPU=12000000 -DDEBUG_LEVEL=0  -c usbdrv/oddebug.c -o usbdrv/oddebug.o
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -Iusbdrv -I. -mmcu=atmega328p -DF_CPU=12000000 -DDEBUG_LEVEL=0  -c main.c -o main.o
In file included from usbdrv/usbdrv.c:10:0,
                 from main.c:22:
usbdrv/usbdrv.h:223:24: warning: 'usbFunctionDescriptor' used but never defined
 USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq);
                        ^
usbdrv/usbdrv.h:230:17: warning: 'usbSetInterrupt' declared 'static' but never defined [-Wunused-function]
 USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len);
                 ^
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -Iusbdrv -I. -mmcu=atmega328p -DF_CPU=12000000 -DDEBUG_LEVEL=0  -o main.elf usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o -Wl,--relax,--gc-sections -Wl,--section-start=.text=7800
rm -f main.hex main.eep.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size main.elf
   text	   data	    bss	    dec	    hex	filename
   1806	     10	     49	   1865	    749	main.elf

As you can see there should be no problem fitting this into the 2K bootloader section.

 

{Captcha: BMSRMPP "Bugger Me, Someone's Reset My Posting Privileges"}

 

 

Last Edited: Wed. Dec 14, 2016 - 06:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

{Captcha: BMSRMPP "Bugger Me, Well Bless My Soul! Someone's Reset My Posting Privileges"}

 The website software settings are being globally adjusted/fine tuned in an attempt to eliminate the spammers who have lately represented more than 50% of new registrations. Everyone is affected.... moderators included. Please be patient while adjustments are being made to everyone's benefit.

 

Thanks,

 

Ross

Ross McKenzie ValuSoft Melbourne Australia

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

IIRC you could get the same effect putting everything in .bootloader :

Binary format is just bytes starting from address zero.

Again, IIRC one can use the .elf to produce a .hex file which does have gaps.

Iluvatar is the better part of Valar.

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

Ok yes my bootloader make file looks identical, all of your guesses are correct. The bootloader is also flashed to a SMD board and changing it is really out at this point since the product is in the main stream. 

 

This is my output  from the bootloader build.

   ^
		Finished building: .././main.c
		Building file: ../usbdrv/usbdrvasm.S
		Invoking: AVR32/GNU Assembler : 4.8.1
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-gcc.exe" -Wa,-gdwarf2 -x assembler-with-cpp -c -mmcu=atmega328p -Wall -gdwarf-2 -std=gnu99                       -DF_CPU=12000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -I "..\usbdrv" -I "..\."  -MD -MP -MF "usbdrv/usbdrvasm.d" -MT"usbdrv/usbdrvasm.d" -MT"usbdrv/usbdrvasm.o"   -o "usbdrv/usbdrvasm.o" "../usbdrv/usbdrvasm.S"
		Finished building: ../usbdrv/usbdrvasm.S
		Building target: main.elf
		Invoking: AVR/GNU Linker : 4.8.1
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-gcc.exe" -o main.elf  main.o usbdrv/usbdrvasm.o   -Wl,-Map="main.map" -Wl,--start-group  -Wl,--end-group -Wl,--gc-sections -Wl,-section-start=.text=0x7800  -mmcu=atmega328p
		Finished building target: main.elf
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "main.elf" "main.hex"
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "main.elf" "main.eep" || exit 0
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "main.elf" > "main.lss"
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "main.elf" "main.srec"
		"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-size.exe" "main.elf"
		   text	   data	    bss	    dec	    hex	filename
		   1900	     10	     49	   1959	    7a7	main.elf
	Done executing task "RunCompilerTask".
	Task "RunOutputFileVerifyTask"
				Program Memory Usage 	:	1910 bytes   5.8 % Full
				Data Memory Usage 		:	59 bytes   2.9 % Full

 

5.8 + 87  is not 100

but    5.8 + 5.8  +  87 is over 100

 

so I still agree my code is building a second bootloader in to my project.

 

 

So now, I'm down to trying to understand what clawson is explaining.

 

It's an AVR program with two functions in it. One is main() which will be built, along with the interrupt vectors and other CRT stuff down near location 0. Then there is one function (foo()) which is put into a memory section called .bootloader.

Great I follow this but I only have one application main(); yet two are being compiled (text + bootloader)? I do not have any attributes in my code that do that, so why is /bootlaoder even showing up?

The function itself will only be about 8 bytes but when I build I tell the linker to base .bootloader up at a bootloader like address (0x7F00 in this case).

This is very helpful,  I certainly do not do this. I also do not compile my project,  As5 does, and I only use a MAKE file. The Make file knows not of this bootloader.

 

Finally I extract a complete program consisting of .text and .bootloader into a binary file. That file on disk is 32K ! In fact:

I also do not do this.  It is not my intention to do any of that, I have a bootlaoder, I just want to compile the main (.text) and that is all. Where is this .bootloader compiler variable/directive/memory/app  coming from? The best I can tell is it would come from that attribute example you shows me. I search my entire project, in files for bootloader and it is not there. 

 


 

 

 

Last Edited: Sun. Dec 18, 2016 - 01:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So coming back to this a bit with what I feel learned info.

 

Looking at my OP

 

 Size before:
        AVR Memory Usage
        ----------------
        Device: atmega328p
        Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)
        Data:       1227 bytes (59.9% Full)
        (.data + .bss + .noinit)
        Size after:
        AVR Memory Usage
        ----------------
        Device: atmega328p
        Program:   28704 bytes (87.6% Full)
        (.text + .data + .bootloader)
        Data:       1227 bytes (59.9% Full)
        (.data + .bss + .noinit)
        -------- end --------      

 

 

I see this in my make file

COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000

 

Still completely unclear what this (.text + .data + .bootloader) is coming from though i see the  (.data + .bss + .noinit) in the makefile. but, nnder a the debug: area that is never called.

 

This is the makefile as I have it, guessing its a huge mess or overkill.

 

MCU = atmega328p
F_CPU = 12000000
DEBUG_LEVEL=0
FORMAT = ihex
TARGET = main
OBJDIR =  .
SOURCEDIR = ../BASE_2.0/
# List C source files here. (C dependencies are automatically generated.)
SRC =  /usbdrv/usbdrv.c main.c $(SOURCEDIR)gamepad.c $(SOURCEDIR)gcn64_protocol.c $(SOURCEDIR)i2c.c $(SOURCEDIR)gc.c $(SOURCEDIR)db9.c $(SOURCEDIR)snes.c $(SOURCEDIR)saturn.c $(SOURCEDIR)twelve.c $(SOURCEDIR)jaguar.c $(SOURCEDIR)intellivision.c  $(SOURCEDIR)wii.c $(SOURCEDIR)psx.c $(SOURCEDIR)dreamCast.c $(SOURCEDIR)psx.c $(SOURCEDIR)n64.c $(SOURCEDIR)wii.c $(SOURCEDIR)atmark.c $(SOURCEDIR)gameport.c
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# List Assembler source files here.
ASRC = /usbdrv/usbdrvasm.S $(SOURCEDIR)dcRead.S
# 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
#s %80.07
#1 %86.9
#2 %85.5
#3 %110.4

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

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

# 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

# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)L
#-DDEBUG_LEVEL=$(DEBUG_LEVEL)


# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)

# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS

#---------------- Compiler Options C ----------------
#  -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
#CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -Wall

#force smaller size!
CFLAGS += -fno-inline-small-functions
CFLAGS += -ffunction-sections
CFLAGS += --save-temps
#LDFLAGS += -Wl,--relax
#LDFLAGS += -Wl,--gc-sections
# causes issues ---    CFLAGS += -fwhole-program --combine

CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)


#---------------- Assembler Options ----------------
#  -Wa,...:   tell GCC to pass this to the assembler.
#  -adhlns:   create listing
#  -gstabs:   have the assembler create line number information; note that
#             for use in COFF files, additional information about filenames
#             and function names needs to be present in the assembler source
#             files -- see avr-libc docs [FIXME: not yet described there]
#  -listing-cont-lines: Sets the maximum number of continuation lines of hex
#       dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100

#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)

# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)


MATH_LIB = -lm


# List any extra directories to look for libraries 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.
EXTRALIBDIRS =

#---------------- External Memory Options ----------------

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff

EXTMEMOPTS =

#---------------- Linker Options ----------------
#  -Wl,...:     tell GCC to pass this to linker.
#    -Map:      create map file
#    --cref:    add cross reference to  map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x


#---------------- Programming Options (avrdude) ----------------

# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500

# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb

AVRDUDE_WRITE_FLASH = -Uflash:w:$(TARGET).hex -B 1.0

AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)


# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd


# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = --------  end  --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:

# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)

# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)

# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d

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


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

# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib


elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)


# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
    @echo
    @echo $(MSG_BEGIN)
    
end:
    @echo $(MSG_END)
    @echo


# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf

sizebefore:

    @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
    2>/dev/null; echo; fi

sizeafter:
    @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
    2>/dev/null; echo; fi


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


# Program the device.  
program: $(TARGET).hex $(TARGET).eep
    $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)


# Generate avr-gdb config/init file which does the following:
#     define the reset signal, load the target file, connect to target, and set
#     a breakpoint at main().
gdb-config:
    @$(REMOVE) $(GDBINIT_FILE)
    @echo define reset >> $(GDBINIT_FILE)
    @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
    @echo end >> $(GDBINIT_FILE)
    @echo file $(TARGET).elf >> $(GDBINIT_FILE)
    @echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
    @echo load  >> $(GDBINIT_FILE)
endif
    @echo break main >> $(GDBINIT_FILE)


coff: $(TARGET).elf
    @echo
    @echo $(MSG_COFF) $(TARGET).cof
    $(COFFCONVERT) -O coff-avr $< $(TARGET).cof


extcoff: $(TARGET).elf
    @echo
    @echo $(MSG_EXTENDED_COFF) $(TARGET).cof
    $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof


# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
    @echo
    @echo $(MSG_FLASH) $@
    $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@

%.eep: %.elf
    @echo
    @echo $(MSG_EEPROM) $@
    -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
    --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0

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

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


# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
    @echo
    @echo $(MSG_CREATING_LIBRARY) $@
    $(AR) $@ $(OBJ)


# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
    @echo
    @echo $(MSG_LINKING) $@
    $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)


# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
    @echo

    @echo $(MSG_COMPILING) $<
                
    $(CC) -c $(ALL_CFLAGS) $< -o $@


# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
    @echo
    @echo $(MSG_COMPILING_CPP) $<
    $(CC) -c $(ALL_CPPFLAGS) $< -o $@


Compile: create assembler files from C source files.
%.s : %.c
    $(CC) -S $(ALL_CFLAGS) $< -o $@


# Compile: create assembler files from C++ source files.
%.s : %.cpp
    $(CC) -S $(ALL_CPPFLAGS) $< -o $@


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


# Create preprocessed source for use in sending a bug report.
%.i : %.c
    $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@


# Target: clean project.
clean: begin clean_list end

clean_list :
    @echo
    @echo $(MSG_CLEANING)
    $(REMOVE) $(TARGET).hex
    $(REMOVE) $(TARGET).eep
    $(REMOVE) $(TARGET).cof
    $(REMOVE) $(TARGET).elf
    $(REMOVE) $(TARGET).map
    $(REMOVE) $(TARGET).sym
    $(REMOVE) $(TARGET).lss
    $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
    $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
    $(REMOVE) $(SRC:.c=.s)
    $(REMOVE) $(SRC:.c=.d)
    $(REMOVE) $(SRC:.c=.i)
    $(REMOVEDIR) .dep


# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)


# 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 eep lss sym coff extcoff \
clean clean_list program debug gdb-config



 

 

Last Edited: Wed. Apr 26, 2017 - 12:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:

I see this in my make file

COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000

S_K_U_N_X wrote:
but, nnder a the debug: area that is never called.

S_K_U_N_X wrote:
This is the makefile as I have it

Are you talking about two different makefiles? Neither do I see the COFFCONVERT lines in there, nor a debug target.

Anyway!

 

I read the other posts and Cliff (clawson) was misleading you. No need to worry about the .bootloader in "(.text + .data + .bootloader)", it is always there. The program avr-size lists the sections that are added up if existent. That doesn't mean that .bootloader is actually existent.

 

S_K_U_N_X wrote:
5.8 + 87 is not 100
Not necessarily. Whether 87% application and 5.8% bootloader fit into the memory depends on where the bootloader is actually located.

S_K_U_N_X wrote:
The bootloader says it failed at 0x7080.
This is a hint that you may have selected the biggest possible bootloader section size for an Mega328.

Stefan Ernst

Last Edited: Wed. Apr 26, 2017 - 08:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
was misleading you
Apologies - clearly having a bad day that particular day so try to read this thread ignoring any posts from me! blush

 

.bootloader is a complete red herring. The point is that a Bootloader Program is simply a "normal" program that has its .text section relocated. That is what you are achieving here when you use:

-Wl,-section-start=.text=0x7800

 

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

Ok Cliff LOL, take a break.

 

sternst, yes this is two projects.

 

looks like the makefile I attached was the stripped down version where I remove the debug call. So those COFFCONVERT 's are missing, sorry about that.

 

I'm still putting together how all of this works so I do apologize in advance here. I was scratching my head trying to find this reported boot loader. I knew this info is above but sometimes it's annoying to read thru it all, but.  In a very simple sense I build a bootloader (I didn't write it) for a 328 chip. The size of that build and make file is on line #11 and #14. This then is used to load my main code. That reports as seen on post #15 and is also built for a 328.

 

So how can I determine the exact limit of the size. I'm just not certain how to calculate that. The number are all here. The complete source for the bootloader is available on line as pointed out in post #11. Is 7800 the lowest for 328?

 

 

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

S_K_U_N_X wrote:
The number are all here.
Nope. One information is missing, the size of the bootloader area selected by the fuses. It is only my guess based on the error message that it may be 4k.

S_K_U_N_X wrote:
Is 7800 the lowest for 328?
You don't need the lowest, you need the one fitting your bootloader. And that is indeed 0x7800. ;-)

Stefan Ernst

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

Ah, that maybe it. The fuses were for a 168 originally and I moved to a 328. I'll report back with fuses.

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

Bootloader

Fuses used FD:ex 5A:hi DF:lo (bit is set for bootloader address)

make file says 7800 for bootloader address.

chip mega 328

 

 

If I need to add more info let me know.

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

Fuse values look OK and the BOOTSZ setting does pick 3C00/7800 entry.

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

ok but 

So how can I determine the exact limit of the size. I'm just not certain how to calculate that. The number are all here. The complete source for the bootloader is available on line as pointed out in post #11. Is 7800 the lowest for 328?

 

I'm still not certain how this all adds up. With the data above I should be able to say max program size is x = b + p.

x= chip size (32k) 

b=botlaoder ( I think I can get this from post #11 with the new provided details)

p=program size (what is the size this needs to be under)

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

b = 0x8000 - 0x7800 = 0x800 = 2K

p = 32K - b = 30K

 

As soon as you set BOOTSZ[1:0] to the 0x7800 position all these numbers become set in stone.

 

Your other options are:

 

BOOTSZ1 BOOTSZ0  BLS(word) BLS(byte)  b   p

   0       0      0x3800    0x7000   4K  28K

   0       1      0x3C00    0x7800   2K  30K   <<<<<<<<< using this now

   1       0      0x3E00    0x7C00   1K  31K

   1       1      0x3F00    0x7E00  0.5K 31.5K

 

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

ok but my bootloader is 2k, so I must use at lease 01. And that is how its being used at the moment. 

 

so I see it this way

 

x= chip size (32k) 

b=botlaoder 2k

p=application must be less then or equal to 30k but its building at 28704 (see first post) Unless I missed something?

 

so I still have room but it says full when load with the bootloader. 

 

device size -00032768

data (28674) exceeds flash size!

flashing 28800 (0x7080) bytes  start at 0

 

 

 

Last Edited: Wed. May 3, 2017 - 01:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
but it says full when load
What is saying "full"?

 

Either the PC tool that produces this message is in error or, more likely, the PC tool asks the AVR bootloader "what is the maximum size you can accept" and the answer that gives is in error.

 

Is the bootloader AVR109 protocol or something? I'm pretty sure that protocol includes a command for the bootloader to report the maximum size it thinks it can accept. Either the bootloader has 4K or 28K "burnt in" when it is supposed to be 2K or 30K (depending on which way round it reports the boundary).

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

Ok then I think we are getting close to the issue. So I use this. 

http://vusb.wikidot.com/project:...

maybe the code in this tool is set for a 4k assumption? - ill try to dig up the source. 

 

Last Edited: Wed. May 3, 2017 - 01:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK so I went back to post #1 and followed the link to the bootloader code. It has both PC and AVR sides of the code. In the PC (commandline) code one sees:

        if(endAddr > deviceSize - 2048){
            fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr);
            err = -1;
            goto errorOccurred;
        }

So that's where your:

data (28674) exceeds flash size!

is coming from. The hard coded 2048 there would seem to suggest that it is assumed that the bootloader is 2K and the code is therefore 32K (deviceSize) - 2K = 30K.

 

So it's a bit of mystery why this would report 28674 (28K) as failing the test? Have you modified this PC code in some way?

 

On the other hand maybe deviceSize is in error? Immediately before that error is displayed it does:

        deviceSize = getUsbInt(buffer.info.flashSize, 4);
        printf("Page size   = %d (0x%x)\n", pageSize, pageSize);
        printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);

So what do you actually see output for "Page Size = " and "Device Size = " ?

 

The deviceSize itself appears to be reported back from the AVR and collected with:

        deviceSize = getUsbInt(buffer.info.flashSize, 4);

so maybe the fault is in the AVR code itself - perhaps it is not reporting 32K here ?

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

I was not very clear on the code when I started this but I now know that I have two flashing apps. 

bootloadflash and FW updater.

The source you see is FW updater. The code I'm using is bootloadflash. It is possible bootloadflash does not have that 2k limit but the source is tied up ATM. I can try to build from source and try the FW updater and see it that flashes. 

 

I'll also get the "Page Size = " and "Device Size = " output and report back. Thx for the help so far I'm getting closer here. 

Last Edited: Wed. May 3, 2017 - 02:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This has me intrigued. So the page/device size seem to come as a result of:

    if(endAddr > startAddr){    // we need to upload data
        if((err = usbGetReport(dev, USB_HID_REPORT_TYPE_FEATURE, 1, buffer.bytes, &len)) != 0){
            fprintf(stderr, "Error reading page size: %s\n", usbErrorMessage(err));
            goto errorOccurred;
        }

which then made me wonder how the AVR side would receive/handle the USB_HID_REPORT_TYPE_FEATURE. So on the PC side I see:

int usbGetReport(usbDevice_t *device, int reportType, int reportNumber, char *buffer, int *len)
{
HANDLE  handle = (HANDLE)device;
BOOLEAN rval = 0;
DWORD   bytesRead;

    switch(reportType){
    case USB_HID_REPORT_TYPE_INPUT:
        buffer[0] = reportNumber;
        rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
        if(rval)
            *len = bytesRead;
        break;
    case USB_HID_REPORT_TYPE_OUTPUT:
        break;
    case USB_HID_REPORT_TYPE_FEATURE:
        buffer[0] = reportNumber;
        rval = HidD_GetFeature(handle, buffer, *len);
        break;
    }
    return rval == 0 ? USB_ERROR_IO : 0;
}

The final case there is handling this call for data. But the function it calls only gets mentioned in .h files. I don't see an implementation so it's presumably in a linked library and a "standard" call:

BOOLEAN __stdcall   HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen);

so the trail goes kind of cold at this stage except that Microsoft ARE good at documenting their own code...

 

https://msdn.microsoft.com/en-us/library/windows/hardware/ff538910(v=vs.85).aspx

 

What can be seen is that:

        buffer[0] = reportNumber;

is setting the byte to 1. So this is making a HID request for "report 1".

 

I guess it's then just a question of understanding how this is handled on the V-USB side of things. So if I just grep for "report" in the USBdrv code I find:

C:\bootloadHID.2012-12-08\firmware\usbdrv>grep -i report *
Changelog.txt:    always zero sized. This fixes a bug where the host reports an error after
Changelog.txt:  - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length
usbconfig-prototype.h:/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    42 */
usbconfig-prototype.h:/* Define this to the length of the HID report descriptor, if you implement
usbconfig-prototype.h: * "usbHidReportDescriptor" to your code which contains the report descriptor.
usbconfig-prototype.h: *   char usbDescriptorHidReport[];
usbconfig-prototype.h: *   USB_CFG_DESCR_PROPS_HID_REPORT
usbconfig-prototype.h:#define USB_CFG_DESCR_PROPS_HID_REPORT              0
usbdrv.c:#if USB_CFG_DESCR_PROPS_HID_REPORT != 0 && USB_CFG_DESCR_PROPS_HID == 0
usbdrv.c:    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */
usbdrv.c:    0x22,       /* descriptor type: report */
usbdrv.c:    USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0,  /* total length of report descriptor */
usbdrv.c:#if USB_CFG_DESCR_PROPS_HID_REPORT  /* only support HID descriptors if enabled */
usbdrv.c:    SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */
usbdrv.c:        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport)
usbdrv.c: * code and report errors back to the host. Since the ACK was already sent,
usbdrv.h:#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    /* simplified interface for backward compatibility */
usbdrv.h:#define usbHidReportDescriptor  usbDescriptorHidReport
usbdrv.h:/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */
usbdrv.h:/* If you implement an HID device, you need to provide a report descriptor.
usbdrv.h: * The HID report descriptor syntax is a bit complex. If you understand how
usbdrv.h: * report descriptors are constructed, we recommend that you use the HID
usbdrv.h:#endif  /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */
usbdrv.h:#if !(USB_CFG_DESCR_PROPS_HID_REPORT)
usbdrv.h:#   undef USB_CFG_DESCR_PROPS_HID_REPORT
usbdrv.h:#   if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* do some backward compatibility tricks */
usbdrv.h:#       define USB_CFG_DESCR_PROPS_HID_REPORT       USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
usbdrv.h:#       define USB_CFG_DESCR_PROPS_HID_REPORT       0
usbdrv.h:#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
usbdrv.h:char usbDescriptorHidReport[];
usbdrv.h:#   if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
usbdrv.h:#define USBDESCR_HID_REPORT     0x22
usbdrv.h:#define USBRQ_HID_GET_REPORT    0x01
usbdrv.h:#define USBRQ_HID_SET_REPORT    0x09

Of all that the most likely candidate looks like usbdrv.c but try as I might I cannot spot anything there that is saying "28K"

Last Edited: Wed. May 3, 2017 - 02:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Turns out the source forbootloadflash is gone lost forever according to the author. The main issue with FW updater is really hard to compile so I may not be able to make it work as things have changed so much over the years. 

 

So you are pretty sure the code is using something from the v-usb protect to determine the size? That I may be able to get answered. I'll contact Christian. But, from what I know this is a HID feature that sends data to the device. The feature report is how the usb sends the data. I think that like may just be a check for end of file or maybe an initial check for size 0. 

 

 

Last Edited: Wed. May 3, 2017 - 02:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What it appears is that the PC software "asks" the AVR code for a "report" and that report comes back with both SPM page size and also actual device size.

 

I'll bet your AVR code is saying it's a 16K mega168 or something like that. The PC app would then not be able to send more than 14K as it gives the error at "reportedSize - 2K". Certainly 28K would be too much.

 

I guess it's just a case of working out where in the AVR side of things it actually reports "16K" or whatever it is.

 

Now I just had a thought. It appears to report both SPM_PAGESIZE and the device size. So if one looked for references to the SPM pagesize in the AVR code one might also find the nearby code that might be saying something like "16K".

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

And that was the lead I needed. The main.c for the AVR code has:

static uchar    replyBuffer[7] = {
        1,                              /* report ID */
        SPM_PAGESIZE & 0xff,
        SPM_PAGESIZE >> 8,
        ((long)FLASHEND + 1) & 0xff,
        (((long)FLASHEND + 1) >> 8) & 0xff,
        (((long)FLASHEND + 1) >> 16) & 0xff,
        (((long)FLASHEND + 1) >> 24) & 0xff
    };

    if(rq->bRequest == USBRQ_HID_SET_REPORT){
        if(rq->wValue.bytes[0] == 2){
            offset = 0;
            return USB_NO_MSG;
        }

This is the return for that call to

HidD_GetFeature()

in the PC code. So clearly it sends the SPM page size first:

        SPM_PAGESIZE & 0xff,
        SPM_PAGESIZE >> 8,

and then the size of the device as:

        ((long)FLASHEND + 1) & 0xff,
        (((long)FLASHEND + 1) >> 8) & 0xff,
        (((long)FLASHEND + 1) >> 16) & 0xff,
        (((long)FLASHEND + 1) >> 24) & 0xff

It's actually quite tricky to see how that could have been built with the "wrong answer" because "FLASHEND" comes via <avr/io.h> and for a 328 is:

C:\SysGCC\avr\avr\include\avr>grep FLASH iom328*
#define FLASHEND     0x7FFF

So FLASHEND+1 is 0x8000 and that is effectively the value being conveyed back from the AVR to the PC. We know that in the PC code it then has a fixed subtraction of 2048 (2K) so it should get 32K-2K = 30K as the boundary.

 

HOWEVER if you are saying that the PC app you use is not built from the visible source (that definitely has "- 2048") but is a pre-built EXE then I can well imagine a scenario where, before some optimisation, this bootloader maybe spilled slightly over 2K in size and it would have necessitated a 4K BOOTSZ being used and in that case maybe the previous PC software contained a fixed "- 4096" ? So for a 32K device it might reject anything over 28K. Which is what you are seeing.

 

Is there some reason you cannot simply rebuild the PC application code then? Copies of Visual Studio ("Express") are free to access and should allow you to build the code I think. Actually the Makefile they supply suggests the use of MinGW which is the GCC compiler for Windows.

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

avr as in my projects firmware I make with avr studio?

Last Edited: Wed. May 3, 2017 - 03:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes.

 

The acrhive contains two components. firmware and firmware/usbdrv together are the AVR code of the bootloader. The commandline directory contains the source of the PC application (and a prebuilt bootloadHID.exe)

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

 can try to use the bootloader of the source you looked at and see if it works. 

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

clawson wrote:
I guess it's just a case of working out where in the AVR side of things it actually reports "16K" or whatever it is.
But ...

S_K_U_N_X wrote:
device size -00032768

data (28674) exceeds flash size!

flashing 28800 (0x7080) bytes start at 0

What puzzles me is the '-' there. Would be interesting to know wether the OP is able to upload anything at all. If it is really a minus then even the upload of a very small application should fail. And then the cause is very likely an unwanted sign extension somewhere.

Stefan Ernst

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

I think its a dash. Anything lower then 85% or so flashes fine. 

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

Stefan. If the source is to be believed the PC app does this:

printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);

so I know it's a pedantic detail but that is a capital 'D' and the "Device size" is followed by " = " so either this is not the active source or the

device size -00032768

is possibly a retype job that went a bit wrong. Perhaps "-" was supposed to be typed as " = " ??

 

Actually, assuming the tool being used is the prebuilt EXE in the archive then...

C:\bootloadHID.2012-12-08\commandline>strings bootloadHID.exe | grep size
Error reading page size: %s
Page size   = %d (0x%x)
Device size = %d (0x%x); %d bytes remaining
Data (%d bytes) exceeds remaining flash size!

Also:

flashing 28800 (0x7080) bytes start at 0

seems unlikely when:

C:\bootloadHID.2012-12-08\commandline>strings bootloadHID.exe | grep start
Uploading %d (0x%x) bytes starting at %d (0x%x)

So I think what he really saw was:

Device size = 32768 (0x8000); ?????? bytes remaining
Data (28674 bytes) exceeds remaining flash size!
Uploading 28800 (0x7080) bytes starting at 0 (0x0)

The ????? may be the key thing here. The question is whether it is 32768 - 2048 0r 32768 - 4096. My money on the latter.

 

(actually, just thought, I can disassemble this prebuilt EXE and see whether it is 2048 or 4096 that is being subtracted).

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

clawson wrote:
Stefan. If the source is to be believed the PC app does this:

printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);

so I know it's a pedantic detail but that is a capital 'D' and the "Device size" is followed by " = " so either this is not the active source or the

device size -00032768

is possibly a retype job that went a bit wrong. Perhaps "-" was supposed to be typed as " = " ??

Not only typing 'd' instead of 'D' and '-' instead of '=', but also adding three '0'???

Doesn't your code come from the command line app while he is using the GUI app?

Perhaps the GUI app uses a slightly different output.

Anyway, the OP can easily clarify that. ;-)

Stefan Ernst

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

OK so disassembler says:

 

 

The printf() it's about to call there is:

 

printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);

and the FFFFF800 in the LEA is a -2048. So ???? is going to be 30720 in fact.

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

Cliff, I think you are not looking at the sources of the PC app he is actually using. In #27 he gave a link and there you can read:

HIDBootFlash is a GUI and command line tool used to download firmware to a controller with BootloadHID or AVRUSBBoot equivalent boot loader. It is quite similar to the FW Uploader (www.bootloader.nm.ru/) but not taking advantage of the Fischl BootloadHID.exe.

Stefan Ernst

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

That link seems to take me to some kind of Russian "Instagram"! No thanks.

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

clawson wrote:
That link seems to take me to some kind of Russian "Instagram"! No thanks.
The link is not the interesting part, but the "not taking advantage of the Fischl BootloadHID.exe".

Stefan Ernst

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

There is no way to get the source to the app I'm using.  If you want to disassemble it use this exe http://vusb.wikidot.com/project:...

 

Going to try using the bootloadhid now (source you are looking at). and see if I get the error.

 

 

good flash

Page size   = 128 (0x80)
Device size = 32768 (0x8000); 30720 bytes remaining
Uploading 28672 (0x7000) bytes starting at 0 (0x0)
0x06f80 ... 0x07000

 

 

bad flash

Page size   = 128 (0x80)
Device size = 32768 (0x8000); 30720 bytes remaining
Uploading 28800 (0x7080) bytes starting at 0 (0x0)
0x07000 ... 0x07080Error uploading data block: Communication error with device

 

Last Edited: Wed. May 3, 2017 - 10:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Previously you said you were getting an error such as:

data (28674) exceeds flash size!

Neither your good nor your bad case has any such message about the size exceeding some limit?!?

 

The error is about communications.

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

clawson wrote:
Previously you said you were getting an error such as:
He is using a different PC tool now (the one you inspected).

Stefan Ernst

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

Right as sternst has been saying as I tried to illustrate. 

 

initial issue program 1) gave result A

You were looking at the source to program 2)

So I used program 2) and got result B

 

Either way I get the same "kinda" of error on both programs, I just figured it was best to use the program you are seeing the source for. Trying to make things easier here, though looks like I just made them more confusing.

 

From my latest tests the good flash is with a hex size of under %85 full from AVR studio. The bad I added a few lines of code to make it greater then 87 in AVR to show that it fails. The "Communication error with device" is obviously an incorrect error (or just throwing another after the data block error).  It still communicates fine, just fails because of the hex size. I see it flashing just like the flash that succeeded, only it stops with that errors towards the end of the flashing. I think the real error is "Error uploading data block:" The issue here is that is throws a fit when it tries uploading and gets to  28800 (0x7080) 

 

I think program 1 is derived from program 2. I think the program 1 was just a gui version of 2. Though he wrote his own errors for the gui. I may just have to open the damn source compile it and debug from with in. That or set a file size constant limit of 30k. 

 

 

Last Edited: Thu. May 4, 2017 - 01:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure I can follow the problem (-.-)a

Just asking

So the OP needs PC tools for downloading Hex via bootloader? or the bootloader itself?

I'm using improved AVRUSBBoot and my selfmade Windows PC tool GUI

I've tried Fischl BootloadHID with HIDBootFlash too, but I like mine better :)

I don't know why I'm still doing this hobby

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

So the OP needs PC tools for downloading Hex via bootloader? or the bootloader itself?

I need a PC tool that works. Mine seems to be limited to a 4k bootloader and I need it to allow for a  2k.

 

The device I have uses a hid data transfer

https://github.com/obdev/v-usb/t...

 

It sounds like your tool may do the same? Can I try it?

 

Last Edited: Fri. May 5, 2017 - 01:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My GUI tool looks like this

 

 

My bootloader was AVRUSBBoot with some added task.

The bootloader size is about 2K

I'm still working on it for improvement. 

The schematics is USBASP, and the speed jumper is use for bootloader switch.

 

Do you have device with USBASP schematics?

I'll try to compile the bootloader for you so you can try to program it for yourself and test it with the GUI above.

 

ATmega 8 at 12 MHz (USBASP)

https://www.4shared.com/rar/OKW0hYCCei/zip.html

 

I don't know why I'm still doing this hobby

Last Edited: Fri. May 5, 2017 - 02:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No I didn't use the ASP set up and my device is already manufactured so changes are out.  My device is based from this. 

I use a 12 mhz instead but that usb set up is the same. From what I know about usbASP is that its pretty much the same thing (This boot loader is similar to Thomas Fischl's avrusbboot, except that it is built on top of the HID device ) but I never worked with it. I think some changes may be needed to make your gui work but that really is nice. I plan to write my own firmware uploader so source code would be invaluable to me. Though again, not sure how USBASP does its bootloader, may be very different. I could not get that 4share to work kept bugging my about fackbook or something?

 

 

 

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

S_K_U_N_X wrote:
not sure how USBASP does its bootloader

Does it have a bootloader then? I doubt that. It is is simply an ISP "data pipe". On the PC facing side it looks like a USB device (software simulated) and on the target AVR facing side it is an ISP programmer.

 

Your device appears to be "stand alone". The bootloader is there so it can program itself, not other AVR so it's nothing like a USBAsp is it (apart from the fact that both happen to use software simulated USB).

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

Then what is the avrusbboot for? a non avr studio application? anyone can download avr studio and program via isp. Seems like an over kill to me? Also he said he wrote a boatloader. ISP software would write the entire chip right? 

Last Edited: Fri. May 5, 2017 - 03:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fischl is a very clever bloke. He recognized how useful Objective Development software implementation of USB was.

 

One project he used it for was USBasp. That (as I say above) uses the USB to interface to a PC then it uses the data channel to deliver data that is immediately programmed on the other side into a second AVR using ISP

 

A completely separate use for the software-USB he made was to make a standalone program that you can put into the top of an AVR so that it can not only program itself but it can receive the data to achieve that over USB - that project is called avrusbboot.

 

In fact when you look at:

 

http://www.fischl.de/projects/

 

You see USBAsp and avrusbboot listed as just two of quite a number of projects he has done. In the list there are several using soft-USB. I guess once you have use a great library like that you want to use it in as many different ways as you can think of!

 

USBasp is arguably the most important 3rd party piece of AVR development electronics/software there is (apart from Arduino). Via ebay I imagine the Chinese have now sold millions and millions of USBAsp to people all over the world who are now able to program their AVR projects with a $2 piece of electronics and a free copy of avrdude.exe. The cheapest offering from Atmel to "get started" has always been around the $50 mark. Sure that $50 thing may give you the luxury of being able to drive it from within Studio but loads of folks are happy to run avrdude separately or, as you can these days, set it up as a "tool" inside Studio so when you execute it, it just feels like it's working "inside" Studio anwyay.

Last Edited: Fri. May 5, 2017 - 04:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, I  had no idea, very insightful. So no,  this will not work for me as I do plan to use a stand alone HID based bootloader.

 

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

My refer to USBASP is for the schematics only, not the USBASP itself, many of them have use it, so it's easier to start with, without making new hardware.

The point is, it can download the full application firmware size minus 2K bootloader, I believe that's what you're looking for.

 

 

S_K_U_N_X wrote:
Though again, not sure how USBASP does its bootloader, may be very different.

 

Of course it's very different, it's bootloader not ISP programmer.

So USBASP cannot be bootloader except you flash it with bootloader firmware. Then re-program the USBASP firmware in it using bootloader. And you got 2 USB device in a single device.

But that's is useless thing to do with bootloader.

 

I'm not sure using HID, the bootloader needs how much flash size.

There's BootloaderHID from Christian's with simple GUI. I'm not sure what's your problem with that.

I'm curious to find out making my own HID bootloader using your schematics enlightened

 

S_K_U_N_X wrote:
I could not get that 4share to work kept bugging my about fackbook or something?

 

Not sure with that, any suggestion for other site?

 

 

 

 

 

 

I don't know why I'm still doing this hobby

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

Of course it's very different, it's bootloader not ISP programmer.\

I was never talking about ISP. I said "Though again, not sure how USBASP does its bootloader, may be very different." - meaning different from usbboothid.

 

I'm not sure what's your problem with that.

This is the entire point to my topic, the issue is that my bootloaders "seems" to be assuming I have a 4k boot. I have a 2k boot. No need to explain that you can read thru all the posts. I didn't really follow much of what you said here but more on point your last comment is what drives my curiosity.

I'm curious to find out making my own HID bootloader using your schematics 

This is also what I'm curios about. At home here I was able to get your download. I selected my chip and put in the vid/pid but it was not detected.

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

I'm sorry, I forgot to include the inf files for windows driver in the zip file, my bad.

I'll fix it as soon as when I get home.

I'm still working on the HID bootloader with your schematics, it still in progress.
Hope it will finish in few days.

But I had to add a boot switch in your schematics to make the device selectable.
And few leds to show the transaction progress.

Cheers

I don't know why I'm still doing this hobby

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

Here is the new zip

https://www.4shared.com/zip/u7Dxr5Joei/AVRboot.html

 

Good luck

I don't know why I'm still doing this hobby

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

Hi, thx for the interest to help me. So this latest zip with the ini. I'm not sure I'm using it right since there is no find button. I put my device in bootloader mode and I put in the vip/pid but it always says no device found. When the right id is put it does it just say found? Or do I have to hit enter or something?

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

Here is the device manager looks like 

 

 

 

And the apps after device detected by windows

 

 

No need to change VID / PID, it detected automatically and ready to use.

I've been using it for years now and had no problem.

 

To enter the bootloader mode you have to connect jumper PINC3 to ground then plug in the device. (USBASP speed select)

No need to take off the jumper, if you done with bootloader, unplug the device and remove the jumper.

The device will execute application section when it's powered.

 

Do not use external supply, use together with USB supply instead, so when you plug / unplug the device it will on/off accordingly.

 

Good luck

 

I don't know why I'm still doing this hobby

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

Hi ok I'm following what you are saying a bit better now. At this time I don't wish to try USBbootAVR. I want to stay focused on the bootloader I have and getting this source to compile. If you ever finish what you said here.

 

I'm still working on the HID bootloader with your schematics, it still in progress.
Hope it will finish in few days.

I'd be very interested to try it.

 

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

Here is the app

 

 

The schematic still using USBASP schematic because I don't want to make the new one.

The purpose of making this is my curiosity making HID device using VUSB.

It's my first try, so I need you to try it to help me find my mistake in it. I hope you don't mind.

Please don't ask for the source code, like another VUSB projects I had shared, I only intended to help people who interested in VUSB, not to do their job.

 

Good luck

 

 

Here is the zip file

https://www.4shared.com/zip/Qo9ZBIeHca/USBHIDBootAVR.html

I don't know why I'm still doing this hobby

Last Edited: Mon. May 8, 2017 - 12:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is too bad about source, I'd like to use that idea in my code. Would you consider helping me with my code at a later point? I'm not home right now but happy to test later.

Last Edited: Mon. May 8, 2017 - 12:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok so the hid app, there are two issues.
 

1) no 328 option any longer

2) no way to specify the pid.vid.

 

I tried anyways no luck.

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

 

The bootloader hex is for mega 8 (USBASP schematic), you cannot just program it to mega 328, very different size and setting.

And I don't have mega 328 at the moment.

 

As I said it's my first HID app so I haven't completed the device list and changeable VID/PID yet.

I haven't test it for some other chips either.

Still long way to go. I must buy all the chips and make the board to test. I can only do it when I got spare time and budget.

It's only to test the implementing of VUSB for HID bootloader device, not a real product. 

 

I had provided you two working example above.

It's up to you either you want to try it or not.

 

May the Force be with you angel

 

 

 

 

I don't know why I'm still doing this hobby

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

I dont have any mega8 projects or v-usb code around at the moment. Thx for the candor though.

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

I know the topic went a bit off here but I'm back on topic. Hope I still have a few watchers out there?

 

So I have the source compiled and now I see there is some type of issue here. At first look the error thrown is

 fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));  - err says communication error...

but it should be

fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr);

or at least that makes more sense to me. But really I should not have any errors....

 

 

The endaddr is 28800 minus the bootloader size that's  26752 (6880)hex.

 

so I'm guessing the size is not the issue here... Looking closer at the error.

when  startAddr = 0x07000 and  startAddr + (int)sizeof(buffer.data.data) = 0x7080 It throws the comm error.

so I added a print above the error

[buffer.bytes]         [sizeof(buffer.data)]

2553172 ..................... 132

 

if usbSetReport is trowing this error I think the issue is in the bootloader hid code, no? If so my guess would be the usbFunctionWrite section because the set up is done.

 

setup looks like this

uchar   usbFunctionSetup(uchar data[8])
{
usbRequest_t    *rq = (void *)data;
static uchar    replyBuffer[7] = {
        1,                              /* report ID */
        SPM_PAGESIZE & 0xff,
        SPM_PAGESIZE >> 8,
        ((long)FLASHEND + 1) & 0xff,
        (((long)FLASHEND + 1) >> 8) & 0xff,
        (((long)FLASHEND + 1) >> 16) & 0xff,
        (((long)FLASHEND + 1) >> 24) & 0xff
    };

    if(rq->bRequest == USBRQ_HID_SET_REPORT){
        if(rq->wValue.bytes[0] == 2){
            offset = 0;
            return USB_NO_MSG;
        }
#if BOOTLOADER_CAN_EXIT
        else{
            exitMainloop = 1;
        }
#endif
    }else if(rq->bRequest == USBRQ_HID_GET_REPORT){
        usbMsgPtr = replyBuffer;
        return 7;
    }
    return 0;
}

 

while it sends data it will use the write function.

 

 


uchar usbFunctionWrite(uchar *data, uchar len)
{
union {
    addr_t  l;
    uint    s[sizeof(addr_t)/2];
    uchar   c[sizeof(addr_t)];
}       address;
uchar   isLast;

    address.l = currentAddress;
    if(offset == 0){
        DBG1(0x30, data, 3);
        address.c[0] = data[1];
        address.c[1] = data[2];
#if (FLASHEND) > 0xffff /* we need long addressing */
        address.c[2] = data[3];
        address.c[3] = 0;
#endif
        data += 4;
        len -= 4;
    }
    DBG1(0x31, (void *)&currentAddress, 4);
    offset += len;
    isLast = offset & 0x80; /* != 0 if last block received */
    do{
        addr_t prevAddr;
#if SPM_PAGESIZE > 256
        uint pageAddr;
#else
        uchar pageAddr;
#endif
        DBG1(0x32, 0, 0);
        pageAddr = address.s[0] & (SPM_PAGESIZE - 1);
        if(pageAddr == 0){              /* if page start: erase */
            DBG1(0x33, 0, 0);
#ifndef TEST_MODE
            cli();
            boot_page_erase(address.l); /* erase page */
            sei();
            boot_spm_busy_wait();       /* wait until page is erased */
#endif
        }
        cli();
        boot_page_fill(address.l, *(short *)data);
        sei();
        prevAddr = address.l;
        address.l += 2;
        data += 2;
        /* write page when we cross page boundary */
        pageAddr = address.s[0] & (SPM_PAGESIZE - 1);
        if(pageAddr == 0){
            DBG1(0x34, 0, 0);
#ifndef TEST_MODE
            cli();
            boot_page_write(prevAddr);
            sei();
            boot_spm_busy_wait();
#endif
        }
        len -= 2;
    }while(len);
    currentAddress = address.l;
    DBG1(0x35, (void *)&currentAddress, 4);
    return isLast;
}

nothing stands out? Only a guess here but maybe the usb descriptor is expecting a smaller size chip? Though I do see this comment about timers. /* compatibility with ATMega88 and other new devices: */ So I have to assume the author expects 328's here.

 

Also I see a few cli's in the bootload code, I wonder if its taking too long and dropping? - doubtful.

 

interestingly changing  to  if(endAddr > deviceSize - 1024) didnt change a thing, so I'm sure this it not a size issue. Really confused at this point.

 

Two more additional points of interest.  I tried adding a loop to slow it down and it still failed at the same point. Also if I interrupt the usb transfer I can the same error. The failing at the same point every time is what makes thing confusing. Though this is a clue to what is causing the issue and should be easier to track down and fix as its religiously repeatable. 

 

 

 

 

 

 

 

Last Edited: Thu. May 11, 2017 - 01:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After doing some research of HIDBoot with 328p (thanks to my curiosity) , here's what I found:

 

First, I'm not really sure what's going on so I hope someone can explained to me.

 

Erasing page before writing task...

With page erase function:

boot_page_erase(address.l);

will stuck at address.l = 0x7000 which give error report.

0x7000 is the address of bootloader size 4K.

It's related or not I don't know.

 

When I use this

boot_page_erase((address.l >> 8) || address.l);

It's working until the last page of 328p which is 0x7780, no error thrown.

My guess is the matter of casting?

 

 

Now we are talking about writing the flash...

     do{
        ... 
         
        cli();
        boot_page_fill(address.l, *(short *)data);
        sei();
        prevAddr = address.l; <-- here is the problem!
        address.l += 2;       
        data += 2;

        ...
        
        if(pageAddr == 0){
        cli();
        boot_page_write(prevAddr); <-- use in here
        sei();      
       
        ...
        
       }while(len);

                 

With above prevAddr setup,  "boot_page_write(prevAddr)"  will always write to the next page of  "boot_page_erase(address.l)".

So erase page 1 but writing at page 2, that's ridicuolus is it?.

Then I moved prevAddr setup right after "boot_page_erase(address.l)".

Now everything goes smoothly.

 

 

Here I tried to write 0x81 at entire last page of 328p which at 0x7780 with above setup, and it succeeded. No complain thrown.

 

 

Hope someone correct me if I done something wrong.

 

Good luck.

 

 

I don't know why I'm still doing this hobby

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

Ok, I feel like the most stupid people in the world because ignoring datasheet sad

 

 

Ignore my above post about erase and writing at 0x7000 and above it. It was not suppose to happen!

 

As the datasheet clearly written:

 

 

 

The max rww is 224 pages, which mean 224 * 128 = 28672 bytes !!! Case closed !

 

So better use 4K bootloader than 2K, same result anyway smiley

 

After 70 post frown

 

 

BTW, the "prevAddr setup" is still a good progress. Ignoring that will sometimes cause getting garbage data if the application size is changed less than previous size.

And as datasheet said: erase and write at the same page!

 

 

May the Force be with you enlightened

Cheers

 

I don't know why I'm still doing this hobby

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

But you are wrong. SPM can write to ALL the pages in the device. It's just a question of whether the page data remains readable during the operation. In the first 28K it does not (while sector writes are happening the page reads back as 0xFFs) but in the top section the code remains visible even while the write occurs.

 

In fact most bootloaders have an address check to ensure that there is not a rogue record in the data or that it is too long so that it might inadvertently write over the bootloader itself.

 

In fact in the preceding 70 posts the question has been whether the limit being used in such a check has used the wrong boundary.

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

clawson wrote:
In fact in the preceding 70 posts the question has been whether the limit being used in such a check has used the wrong boundary.

Then I must be misinterpret the question. My bad english.

 

clawson wrote:
SPM can write to ALL the pages in the device.

I'm aware of that. But looking at the datasheet I asume the last 32 pages is not suppose to touch because it is bootloader boundary.

And yet I am wrong. Bootloader can also being updated using SPM.

Have to dig deeper then.

 

 

Thank you mr Clawson.

 

And forgive my bad english :)

 

I don't know why I'm still doing this hobby

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

Hi MicroGyro, thx again for helping... The "bad English" ( as you said) and my limited experience is not helping me follow easily at all. I thinking I have surmised that you are implying using a 4k boot would help me in my case? Your last post implies you're not %100 and you are looking further in to it? In that case may the force be with you ;) i'll remain a padawan for now.

 

Clawson, what do you make of all of this? I gather your experience to v-usb is only relevant in the preceding 70 posts? Though you have helped me thru so many battle in the last 7 years... Is my confusion shared? Does it make sense to receive a com error because of a hex size? Is the problem still possibly within the bootlaod code and not the v-usb HID data code? I know Christian well enough to say he generally does not make a mistake. Though I have found a pretty significant bug in his firmware only usb code so he is not infallible. :) What confuses things yet a bit further is that the two apps bootloadhid(command line) and boothidflash(gui) produce the same error. But it is very possible the gui was copped from the command tool. In that case it makes sense. 

Last Edited: Fri. May 12, 2017 - 01:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
What confuses things yet a bit further is that the two apps bootloadhid(command line) and boothidflash(gui) produce the same error.
No, they do not produce the same error.

S_K_U_N_X wrote:
But it is very possible the gui was copped from the command tool.
The GUI tool you used first explicitly states that it is "not taking advantage of the Fischl BootloadHID.exe".

Stefan Ernst

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

Sorry didn't mean to say same error, but both error out based on the same cause. Hex file too big. 

 

The GUI tool you used first explicitly states that it is "not taking advantage of the Fischl BootloadHID.exe".

Ah very good then. 

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

Hi I'm back

 

Here is what my conclusion stick to datasheet:

 

 

The first 224 pages is RWW section, so using Christian HIDBoot code no problem will exist.

His code sequence doing:  "Erase Page" then fill page buffer and after SPM_PAGESIZE achived execute "Write Page".

This sequence don't give error because doing RWW section do not cause CPU halting.

That section is 0 to 0x7000.

 

 

The diagram shows better

 

 

Now how about NRWW section...

 

 

With HIDBoot code, this CPU halt will give error while the CPU doing "Erase Page" task, because HIDBoot code expect return value every 8 bytes data processed by usbfunctionwrite().

With CPU halt, the return value will never return or return USB_Stall thus the code can't continue to do fill buffer and writing flash, so this was how the error start. 

 

What to do then?

The previous sequence not suitable for this 16 pages in NRWW section.

To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value.

This can be done for 16 times or one at a time follow by set_request for page write.

According to datasheet doing erase and write causing CPU halt, so erasing and writing this 16 pages needs 32 set_request with ignored return value.

 

So HIDBoot needs adjustment to cover this. And so the GUI. But if only the NRWW section need.

If not, HIDBoot  prety good.

 

Regarding the HEX size error, I never use debug from Christian. I prefer return the value I suspect using get_request.

So my explaination related to the OP question or not I don't know.

 

What I spotted is 32K-2K is 30K, not 28K.

224*128 + 16*128 = 30720 bytes.

 

 

May the ...

Good luck

 

 

 

I don't know why I'm still doing this hobby

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

I'll have to go over this a few times but I think I follow you here.

 

This is the relevant code

 

 

 

/* Name: main.c
 * Project: AVR bootloader HID
 * Author: Christian Starkjohann
 * Creation Date: 2007-03-19
 * Tabsize: 4
 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
 * License: Proprietary, free under certain conditions. See Documentation.
 * This Revision: $Id$
 */


static int uploadData(char *dataBuffer, int startAddr, int endAddr)
{
usbDevice_t *dev = NULL;
int         err = 0, len, mask, pageSize, deviceSize;
union{
    char            bytes[1];
    deviceInfo_t    info;
    deviceData_t    data;
}           buffer;

    if((err = usbOpenDevice(&dev, IDENT_VENDOR_NUM, IDENT_VENDOR_STRING, IDENT_PRODUCT_NUM, IDENT_PRODUCT_STRING, 1)) != 0){
        fprintf(stderr, "Error opening HIDBoot device: %s\n", usbErrorMessage(err));
        goto errorOccurred;
    }
    len = sizeof(buffer);
    if(endAddr > startAddr){    // we need to upload data
        if((err = usbGetReport(dev, USB_HID_REPORT_TYPE_FEATURE, 1, buffer.bytes, &len)) != 0){
            fprintf(stderr, "Error reading page size: %s\n", usbErrorMessage(err));
            goto errorOccurred;
        }
        if(len < sizeof(buffer.info)){
            fprintf(stderr, "Not enough bytes in device info report (%d instead of %d)\n", len, (int)sizeof(buffer.info));
            err = -1;
            goto errorOccurred;
        }
        pageSize = getUsbInt(buffer.info.pageSize, 2);
        deviceSize = getUsbInt(buffer.info.flashSize, 4);
        printf("Page size   = %d (0x%x)\n", pageSize, pageSize);
        printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);
        if(endAddr > deviceSize - 2048){
            fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr);
            err = -1;
            goto errorOccurred;
        }
        if(pageSize < 128){
            mask = 127;
        }else{
            mask = pageSize - 1;
        }
        startAddr &= ~mask;                  /* round down */
        endAddr = (endAddr + mask) & ~mask;  /* round up */
        printf("Uploading %d (0x%x) bytes starting at %d (0x%x)\n", endAddr - startAddr, endAddr - startAddr, startAddr, startAddr);
        while(startAddr < endAddr){
            buffer.data.reportId = 2;
            memcpy(buffer.data.data, dataBuffer + startAddr, 128);
            setUsbInt(buffer.data.address, startAddr, 3);
            printf("\r0x%05x ... 0x%05x", startAddr, startAddr + (int)sizeof(buffer.data.data));
            fflush(stdout);
            if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;
            }
            startAddr += sizeof(buffer.data.data);
        }
        printf("\n");
    }
    if(leaveBootLoader){
        /* and now leave boot loader: */
        buffer.info.reportId = 1;
        usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.info));
        /* Ignore errors here. If the device reboots before we poll the response,
         * this request fails.
         */
    }
errorOccurred:
    if(dev != NULL)
        usbCloseDevice(dev);
    return err;
}

this is the error session that hauls.

 

if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;

 

If I understand you correctly I need to deny the code sending the error on some condition?

 

if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0 && someCondition ){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;
Last Edited: Fri. May 12, 2017 - 03:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0 && someCondition ){ fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err)); goto errorOccurred;

 

Adding "someCondition " like that won't solve your problem. 

while(startAddr < endAddr)

Will executed with no error, but you only "erase the page" (16 pages in NRWW section) not follow by "writing the page" (16 pages in NRWW section).

It will give you 0xFF result inside those pages.

 

 

I'll try to give you brief explanation how the VUSB works, hope it helps.

 

Once this code excecute

if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){
                fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;

The 328p device will get into this sequence:

Erase page + (16+1) times loop to fill page buffer + writing page.  All of it done in usbfunctionwrite().

 

 

16+1 loop got from :

 

usbfunctionwrite() only process 8 bytes at each call, then give the return value back as the result.

 

The "Report length" setup in the device is 131 bytes as you can see in HID Descriptor setup (at above part of HIDBoot.c)

So this 131 bytes will be divide by 8 which is 16 times usbfunctionwrite() call + 1 call to process the remaining 3 bytes. 131= 16*8 + 3.

 

Again: once usbSetReport executed, 131 bytes will transfered to device (which will trigger 16 times usbfunctionwrite() call + 1 extra call for remaining 3 bytes).

 

 

 

Now back to the error part:

 

As I said when usbSetReport get into address which is at NRWW section(7000~7800), the driver will get into CPU halt condition while "erasing page" at the given address.

 

 above line I wrote:

 The 328p device will get into this sequence:

 Erase page + (16+1) times loop to fill page buffer + writing page.  All of it done in usbfunctionwrite().

 

That page will indeed being erase by SPM, but halting condition makes  usbfunctionwrite() get into error result.

 

So  usbfunctionwrite() which should be call for 16 times, now only called once because usbfunctionwrite() returns error and all the loop canceled.

 

That's the reason why at above line of this post I wrote  only "erase the page" (in NRWW section). The next sequence after "erase part" won't be executed!

 

MicroGyro wrote:
What to do then? The previous sequence not suitable for this 16 pages in NRWW section. To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value. This can be done for 16 times or one at a time follow by set_request for page write. According to datasheet doing erase and write causing CPU halt, so erasing and writing this 16 pages needs 32 set_request with ignored return value.

 

 

Cheers

 

 

 

 

I don't know why I'm still doing this hobby

Last Edited: Sat. May 13, 2017 - 01:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I feel I have a better understanding now. 

 

This is the issue

Erase page + (16+1) times loop to fill page buffer + writing page.  All of it done in usbfunctionwrite().​ does not return 

 

 

this is the solution. 

The previous sequence not suitable for this 16 pages in NRWW section.

To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value.

This can be done for 16 times or one at a time follow by set_request for page write.

 

 

So I loop  while(startAddr < endAddr) I need to add a for loop (16 oscillation) ignore return + page write.

 

 

I tried this code and it worked, feel like it was too easy. the flash succeeded without err and the code it running. I guess ill make a change in the hex  code to verify. 

 

Device size = 32768 (0x8000); 30720 bytes remaining
Uploading 28800 (0x7080) bytes starting at 0 (0x0)
0x07000 ... 0x07080

D:\bootloadHID.2012-12-08\commandline\bootloadhid\Debug>

 

 

 while(startAddr < endAddr){
            buffer.data.reportId = 2;
            memcpy(buffer.data.data, dataBuffer + startAddr, 128);
            setUsbInt(buffer.data.address, startAddr, 3);
            printf("\r0x%05x ... 0x%05x", startAddr, startAddr + (int)sizeof(buffer.data.data));
            fflush(stdout);

            for (i=0;i<16;i++)//do 16 sets ???(step size may need startAddr += (sizeof(buffer.data.data) / 16);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));startAddr += sizeof(buffer.data.data);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));//page write

            if(0){

                //fprintf(stderr, "---Error uploading data block: %s\n", usbErrorMessage(err));
                goto errorOccurred;
            }
            startAddr += sizeof(buffer.data.data);
        }

Side effect, takes 16 times as long to flash, but I don't see a way around this because I have to wait for HID to finish. Going to cause many issue for users. 

 

No, my conclusion is that is didn't work. My planted change didn't show up.  I think it just flashed over one scion of code, over and over. Still really surprised the device still works. I'll look over it again.

 

 

Last Edited: Sat. May 13, 2017 - 08:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
No, my conclusion is that is didn't work.

 

Of course it didn't work as expected ! 

 

 

S_K_U_N_X wrote:
while(startAddr < endAddr){

 

Above code execute 240 pages loops for full flash size;

 

And inside that each loops you do:

 

for (i=0;i<16;i++)//do 16 sets ???(step size may need startAddr += (sizeof(buffer.data.data) / 16);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));startAddr += sizeof(buffer.data.data);
                usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data));//page write

 

Another 16 loops ?

That means...  each loops *16 ? It will takes forever for those 240 pages ! Are you serious ?surprise

 

 

You can't just change only your command line code to do this nrww task, because the problem was also inside HIDBoot.c too.

The sequence inside it is always "Page erase + Fillbuffer + Write page".

 

MicroGyro wrote:
The previous sequence not suitable for this 16 pages in NRWW section.
 

So that sequence task need to be split up for "Page erase" task and "Fillbuffer + Write page" task while entering nrww section.

I guess you misunderstanding what this "sequence" point to. smiley Sorry for my unclear explanation. 

 

 

And your command line code changing should follow it.

 

MicroGyro wrote:
To erase one page, send one set_request, let the CPU halt while doing page erase, don't expect return value. This can be done for 16 times or one at a time follow by set_request for page write.
 

 

 

So with your "planted change", it  do nothing beside erasing nrww section again and again + burning those innocent rww section. indecision

Ignore above comment, I just want to scare you devil

 

 

 

Good luck

 

 

 

 

 

I don't know why I'm still doing this hobby

Last Edited: Sun. May 14, 2017 - 04:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figured tiring it was the only way for you to explain what I needed to know. This last post did just hat.  Since the device is already in production there is no way I can change the HID code. So all hope is lost.