GithubHelp home page GithubHelp logo

xboot's Introduction

XBoot Readme

See the XBoot wiki for the latest version of this information: http://alexforencich.com/wiki/en/xboot/

Also, please check the git repository on github: https://github.com/alexforencich/xboot

Table of Contents

1 Introduction
    1.1 Compatibility List
2 Using XBoot
    2.1 Configure
    2.2 Build XBoot and Program to Chip
    2.3 Write Main Application Program
    2.4 Notes for Main Application
3 Configuring XBoot
    3.1 Bootloader clock options
    3.2 AVR 1008 fixes
    3.3 Bootloader entrance options
    3.4 Bootloader exit options
    3.5 Bootloader communication
    3.6 General Options
    3.7 Bootloader features
    3.8 API Support
    3.9 Code Protection
4 XBoot API
    4.1 Using the API
    4.2 Return Values
    4.3 General API Functions
    4.4 Low-level Flash Programming API
    4.5 Firmware Update API
    4.6 Offsets defined in xbootapi.h
    4.7 Using the Firmware Update API

1 Introduction

XBoot is an extensible, modular bootloader for the ATMEL AVR processor series, compatible with both AVR ATMEGA and AVR XMEGA devices with sufficient memory. It is compatible with the AVR109 (butterfly) bootloader protocol with a few XMEGA specific extensions for access to the user and production signature rows. XBoot includes several advanced features including multiple serial busses and an API providing the ability for the running application to update itself without the need for external programming hardware. Many bootloaders only support RS232 for programming from a PC, but XBoot's modularity allows it to support the exact same set of commands over any hardware serial port. Currently, I²C, RS485, and parallel FIFO support have been incorporated. This allows for easy in-system reconfiguration of XBoot equipped chips with little additional time investment. Also, XBoot includes support for I²C address autonegotiation for when multiple, identically configured processors sit on the same I²C bus.

Thanks for using XBoot!

Alex Forencich

1.1 Compatibility List

Currently, XBoot should work on any XMEGA processor and any ATMEGA with sufficient memory (4K boot NRWW block). The following list of processors are currently supported. An asterisk denotes the MCU has been tested and confirmed XBoot compatible.

  • XMEGA
    • atxmega8e5
    • atxmega16a4 *
    • atxmega16e5
    • atxmega32a4 *
    • atxmega32e5 *
    • atxmega64a1
    • atxmega64a3 *
    • atxmega64a4
    • atxmega128a1 *
    • atxmega128a3 *
    • atxmega128a4
    • atxmega192a1
    • atxmega192a3
    • atxmega256a1
    • atxmega256a3b
    • atxmega256a3 *
    • atxmega16d4
    • atxmega32d4
    • atxmega64d3
    • atxmega64d4
    • atxmega128d3
    • atxmega128d4
    • atxmega192d3
    • atxmega256d3
    • atxmega16a4u
    • atxmega32a4u *
    • atxmega64a3u
    • atxmega64a4u
    • atxmega128a3u
    • atxmega128a4u
    • atxmega192a3u
    • atxmega256a3u
    • atxmega256a3bu
    • atxmega64b1
    • atxmega64b3
    • atxmega128b1
    • atxmega128b3
  • ATMEGA
    • atmega324
    • atmega324pa
    • atmega325
    • atmega3250
    • atmega328p *
    • atmega329
    • atmega3290
    • atmega64
    • atmega640
    • atmega644
    • atmega644pa
    • atmega645
    • atmega6450
    • atmega649
    • atmega649p
    • atmega6490
    • atmega128
    • atmega1280
    • atmega1281
    • atmega1284p *
    • atmega2560
    • atmega2561

2 Using XBoot

2.1 Configure

Before building XBoot, please configure it so it will interface properly with your system. This will involve selecting a .conf.mk file in the conf directory and then editing some parameters. The main parameters that need to be set in the .conf.mkfile are the target chip (MCU) and the frequency (F_CPU). For ATMEGA chips, the boot size (BOOTSZ) must also be set, generally to the largest setting. All you need to do is make sure the only line that's not commented out is the one for your chip and the proper frequency. For the simplest bootloader configuration on the XMEGA, you may only choose 2000000 and 32000000 for the clock speed, corresponding to the two internal RC oscillator frequencies. For ATMEGA chips, the specific start up clock speed (based on the fuse settings and/or external crystal or other clock source) must be specifically entered manually. For the rest of the configuration, see the section 3, “Configuring XBoot”.

2.2 Build XBoot and Program to Chip

To build XBoot, select a .conf.mk file from the conf directory and make sure the settings are appropriate for your chip, programmer, and configuration. Then type “make [file].conf.mk”. This will copy [file].conf.mk to config.mk, generate config.h, compile the whole package, and generate xboot.hex, which can be downloaded with any programming cable capable of programming AVR chips. If you have an XMEGA and want to save some time and just program the boot section, type “make xboot-boot.hex” and then write the new file xboot-boot.hex to the boot section directly with avrdude. The makefile includes built-in support for avrdude, so all you need to do is modify the avrdude parameters in the .conf.mk file for the programmer you have and type “make program”.

Note that after typing “make [file].conf.mk”, the settings from [file].conf.mk will remain active until either a new .conf.mk file is selected or “make clean” is run.

2.3 Write Main Application Program

To write a program to a device with XBoot installed, use a command like this:

avrdude -p atxmega64a3 -P /dev/ttyUSB0 -c avr109 -b 115200 -U flash:w:main.hex

Or for windows:

avrdude -p atxmega64a3 -P com1 -c avr109 -b 115200 -U flash:w:main.hex

Also, feel free to re-use XBoot's makefile for your own code. Like XBoot, it is reconfigurable and can be used to compile most projects, just make sure to turn off the MAKE_BOOTLOADER flag for regular programs. It also has the configuration options for XBoot as a target built in, all you need to do is switch a couple of comments around.

NOTE: At this time, avrdude (currently 5.10) does NOT support programming the XMEGA flash boot section (see https://savannah.nongnu.org/bugs/?28744) due to the fact that a different programming command must be sent to the chip to write flash pages in the boot section. If you want to use avrdude, you will need to compile it from source with one of the patches listed on the bug report.

2.4 Notes for Main Application

Here are a few tips for your main application that will make using XBoot a much more pleasant experience.

2.4.1 Catch the "Enter Bootloader" command

When AVRDude starts programming the chip, the first character sent out is the the sync command; the “Escape” character, 0x1B. If your program transmits ASCII, or only transmits Binary during certain program states, you can monitor the UART for the escape character and cause a software reset to enter the bootloader, as shown in the following snippet on an XMEGA:

if (rx_byte == 0x1B) {
   CCPWrite( &RST.CTRL, RST_SWRST_bm );
}

Or, if CCPWrite is not available, this should also work:

if (rx_byte == 0x1B) {
   CCP = CCP_IOREG_gc;
   RST.CTRL = RST_SWRST_bm;
}

In many cases, this allows you to use the AVRDude program command without having to manually reset the AVR. Alternatively, the API call xboot_reset() will have the same effect.

2.4.2 Combine hex files

To streamline programming multiple chips for a production run, the tool srec_cat can be used to combine the hex files. Use the command as follows:

srec_cat xboot.hex -intel main.hex -intel -o mergedfile.hex -intel

This will concatenate the two hex files together with the proper offsets.
Please make sure to use xboot.hex and not xboot-boot.hex to ensure tha the correct offset is used (xboot.hex is relative to address 0 while xboot-boot.hex is relative to the start of the boot section). Note that the combined hex file cannot be programmed with xboot; it is intended to be written with an ISP programmer so both xboot and the application are written in one step.

3 Configuring XBoot

XBoot is designed to be reconfigured to suit specific needs. Out of the box, all of the standard features are turned on. Turning off features and reassigning pins is easy, just pick a .conf.mk file in the .conf folder, make a copy of it, and edit the appropriate parameters. Then build xboot with your parameters by running make [file].conf.mk.

Recommended configuration:

# Entry
USE_ENTER_DELAY = yes
USE_ENTER_UART = yes
 
# Communication
USE_LED = yes
USE_UART = yes
 
# Bootloader Features
ENABLE_BLOCK_SUPPORT = yes
ENABLE_FLASH_BYTE_SUPPORT = yes
ENABLE_EEPROM_BYTE_SUPPORT = yes
ENABLE_LOCK_BITS = yes
ENABLE_FUSE_BITS = yes

This configuration will make the bootloader work similarly to an Arduino. It will blink its light a few times, polling for a character. If none is received, it starts the application. If one shows up, it enters the bootloader and processes it.

In fact, the file arduino328p.conf.mk can be used to build XBoot for use on an atmega328p based Arduino.

3.1 Bootloader clock options

3.1.1 USE_DFLL

This will turn on the DFLL for the selected oscillator, improving its accuracy. Recommended for high serial baud rates. This option only applies to XMEGA processors.

3.1.2 USE_32MHZ_RC

This will switch to the 32MHz RC oscillator on start. In the default configuration of xboot.h, this will be defined automatically when F_CPU is set to 32000000. This option only applies to XMEGA processors.

3.2 AVR 1008 fixes

If you're using a device affected by AVR1008, then you may need to enable these for the bootloader to successfully program the chip. Affected chips are the ATXMEGA256A3 rev A, ATXMEGA256A3B rev B, ATXMEGA256A3 rev B, and possibly the ATXMEGA192A3.

3.2.1 USE_AVR1008_EEPROM

This enables the AVR1008 fix for the EEPROM controller. This option only applies to XMEGA processors.

3.3 Bootloader entrance options

3.3.1 USE_ENTER_DELAY

If this is defined, XBoot will run a loop, specified with the ENTER_BLINK_* variables, and check for an entry condition. If none is found, it jumps into the main code. (BTW, they're called ENTER_BLINK_* because they assume USE_LED is defined. If it isn't, it will still work, but the variable names don't make a whole lot of sense…)

Options

  • ENTER_BLINK_COUNT defines the number of times to blink the LED, e.g. 3
  • ENTER_BLINK_WAIT defines the number of loops to make between blinks, e.g. 30000

3.3.2 USE_ENTER_PIN

If this is defined, XBoot will check the state of a pin, specified with the ENTRY_PORT and ENTRY_PIN_* variables, when it starts (and possibly throughout the startup delay loop) to determine if it should start or just jump into the main program.

Options

  • ENTER_PORT defines the port that the in is in, e.g. PORTC
  • ENTER_PIN defines the pin in the port, an integer from 0 to 7
  • ENTER_PIN_CTRL defines the PINnCTRL register for the pin, e.g. ENTER_PORT.PIN0CTRL
  • ENTER_PIN_STATE defines the “asserted” state of the pin, 0 or 1
  • ENTER_PIN_PUEN enables a pull-up resistor on the pin if nonzero

3.3.3 USE_ENTER_UART

If this is defined, XBoot will poll for received characters over the UART. If one is received, it will enter the bootloader code. USE_UART must be defined. ENTER_UART_NEED_SYNC can also be defined to require the sync command (0x1B) in order to enter the bootloader. This can help prevent the bootloader from being started accidentally.

3.3.4 USE_ENTER_I2C

If this is defined, XBoot will poll for received characters over the I2C interface. If one is received, it will enter the bootloader code. USE_I2C must be defined.

3.3.5 USE_ENTER_FIFO

If this is defined, XBoot will poll for received characters over the FIFO. If one is received, it will enter the bootloader code. USE_FIFO must be defined. ENTER_FIFO_NEED_SYNC can also be defined to require the sync command (0x1B) in order to enter the bootloader. This can help prevent the bootloader from being started accidentally.

3.4 Bootloader exit options

3.4.1 LOCK_SPM_ON_EXIT

If this is defined, SPM instructions will be locked on bootloader exit.

3.5 Bootloader communication

3.5.1 USE_LED

If this is defined, XBoot will use an LED for feedback, specified by the LED_* variables.

Options

  • LED_PORT_NAME defines the port, e.g. A for PORTA
  • LED_PIN defines the pin, e.g. 0
  • LED_INV inverts the LED state if nonzero

3.5.2 USE_UART

If this is defined, XBoot will configure and use a UART for communication.

Options

  • UART_BAUD_RATE defines the baud rate of the UART, e.g. 19200
  • UART_PORT_NAME defines the port that the UART is connected to, e.g. D
    • Note: this only applies to XMEGA devices
  • UART_NUMBER defines number of the UART device on the port, e.g. 1 for USARTD1 (or USART1 for ATMEGA)
  • UART_U2X turns on the double-rate BRG in ATMEGA parts
    • Note: this only applies to ATMEGA devices
  • UART_RX_PUEN enables a pull-up on the UART RX pin

3.5.3 USE_UART_EN_PIN

If this is defined along with USE_UART, XBoot will configure and use a transmit enable pin. This allows configuration over a half-duplex RS485 connection.

Options

  • UART_EN_PORT_NAME defines the port, e.g. C for PORTC
  • UART_EN_PIN defines the pin, e.g. 4
  • UART_EN_INV inverts the EN pin output state if nonzero

3.5.4 USE_I2C

If this is defined, XBoot will configure and use an I2C/TWI controller in slave mode for communication.

Note: Currently only implemented on XMEGA.

Options

  • I2C_DEVICE_PORT defines the port the I2C interface is on, e.g. E for TWIE
  • I2C_MATCH_ANY will enable the I2C controller promiscuous mode (match any address) if nonzero
  • I2C_ADDRESS defines the default I2C address 0x10
  • I2C_GC_ENABLE enables the I2C bus general call capability (address 0) if nonzero

3.5.5 USE_I2C_ADDRESS_NEGOTIATION

Enables I2C address autonegotiation if defined. Requires USE_I2C.

Note: Currently only implemented on XMEGA due to the presence of the Production Signature Row with a signature unique to each chip produced. A suitable workaround for ATMEGA has not yet been implemented.

Options

  • I2C_AUTONEG_DIS_PROMISC will disable I2C promiscuous mode after completion of autonegotiation routine if nonzero
  • I2C_AUTONEG_DIS_GC will disable I2C general call detection after completion of autonegotiation routine if nonzero
  • I2C_AUTONEG_PORT_NAME defines the port in which the autonegotiation pin is located, e.g. A
  • I2C_AUTONEG_PIN defines the pin, e.g. 2

3.5.6 USE_ATTACH_LED

Enables the autonegotiation code to turn on a light when a new I2C address is received.

Options

  • ATTACH_LED_PORT_NAME defines the port, e.g. A for PORTA
  • ATTACH_LED_PIN defines the pin, e.g. 1
  • ATTACH_LED_INV inverts the LED state if nonzero

3.5.7 USE_FIFO

If this is defined, XBoot will talk to an external parallel FIFO for communication.

Options

  • FIFO_DATA_PORT_NAME defines the FIFO data port, e.g. C for PORTC
  • FIFO_CTL_PORT_NAME defines the FIFO control port, e.g. D for PORTD
  • FIFO_RXF_N_bm defines the receive flag pin mask on the control port, e.g. (1 << 3) for pin 3
  • FIFO_TXE_N_bm defines the transmit enable pin mask on the control port
  • FIFO_RD_N_bm defines the read strobe pin mask on the control port
  • FIFO_WR_N_bm defines the write strobe pin mask on the control port
  • FIFO_BIT_REVERSE will reverse the data bits

3.6 General Options

3.6.1 USE_INTERRUPTS

Defining this will configure XBoot to use interrupts instead of polled I/O for serial communications. This will increase code size and won't offer much advantage at the time being, so only use if you know what you're doing.

3.6.2 USE_WATCHDOG

Defining this will enable the watchdog timer during operation of the bootloader. This can reduce the overhead caused by failed programming attempts by resetting the chip if the bootloader and host get out of sync.

Options

  • WATCHDOG_TIMEOUT determines the watchdog timeout period; leave only one of the listed lines uncommented (see XMEGA A series datasheet for details)

3.7 Bootloader features

Generally, these are all enabled, but they can be disabled to save code space.

3.7.1 ENABLE_BLOCK_SUPPORT

Enables flash block access support

3.7.2 ENABLE_FLASH_BYTE_SUPPORT

Enables flash byte access support

3.7.3 ENABLE_EEPROM_BYTE_SUPPORT

Enables EEPROM byte access support

3.7.4 ENABLE_LOCK_BITS

Enables lock bit read and write support (note: cannot clear lock bits to 1, complete chip erase from external programmer needed to do that)

Note: only supported on XMEGA

3.7.5 ENABLE_FUSE_BITS

Enables fuse bit read support (cannot write fuse bits outside of hardware programming)

Note: only supported on XMEGA

3.7.6 ENABLE_FLASH_ERASE_WRITE

Erase each page before writing. This allows the device to be reprogrammed without a complete erase sequence.

3.7.7 ENABLE_CRC_SUPPORT

Enables commands for computing the CRC of various sections of Flash memory.

3.8 API Support

3.8.1 ENABLE_API

Enable API functionality. This functionality can be completely disabled to save space.

3.8.2 USE_API_VERSION

Select API version to implement. Currently the only legal value is 1.

3.8.3 ENABLE_API_LOW_LEVEL_FLASH

Enable low level flash access APIs. Turns on the following API calls:

  • xboot_spm_wrapper (can be separately disabled)
  • xboot_erase_application_page
  • xboot_write_application_page
  • xboot_write_user_signature_row (XMEGA specific)

3.8.4 ENABLE_API_SPM_WRAPPER

Enable SPM wrapper API. Requires ENABLE_API_LOW_LEVEL_FLASH to be defined.

3.8.5 ENABLE_API_FIRMWARE_UPDATE

Enable firmware update APIs. Turns on the following API calls in addition to enabling the firmware upgrade code in xboot:

  • xboot_app_temp_erase
  • xboot_app_temp_write_page

3.9 Code Protection

The code protection features built into xboot keep your code safe from reverse engineering. Protected areas will read the same as unprogrammed flash or EEPROM (0xff).

3.9.1 ENABLE_CODE_PROTECTION

Enable basic code protection. Code protection prevents reading of the flash memory via xboot's interface. Code protection is temporarily disabled by an erase command, allowing verification of newly written firmware. Code protection does not disable CRC commands.

3.9.2 ENABLE_EEPROM_PROTECTION

Enable EEPROM protection. EEPROM protection prevents reading of the EEPROM memory via xboot's interface. Like code protection, EEPROM protection is temporarily disabled by an erase command, allowing verification of newly written firmware.

3.9.3 ENABLE_BOOTLOADER_PROTECTION

Enable bootloader protection. Bootloader protection prevents reading of the boot block via xboot's interface. Unlike code protection, bootloader protection is not disabled by an erase command.

4 XBoot API

XBoot provides several hooks to enable flash reprogramming by the application. Since the SPM instruction is disabled when executing in the application section (Read-While-Write, RWW), it is not possible for an application to write to any location in flash memory without being able to use code located in the boot (Non-Read-While-Write, NRWW) section.

XBoot provides three different types of API calls. The first type are informational and are required for operation of the API. The second type are for low-level Flash programming access. The third are for controlled firmware updating. The low-level Flash programming calls and the firmware update calls can be selectively disabled separately.

Note: XBoot automatically disables interrupts during Flash programming operations. This is necessary because, despite the name, RWW flash cannot be read and written at the same time (NRWW can be read while RWW is written, though). The interrupt bit will be automatically restored on return from an API call.

4.1 Using the API

The API requires some loader code to find and execute the APIs. This code is fully contained within xbootapi.c and xbootapi.h. Include these files in your application to use all of the xboot API calls.

The loader must also know the size of the boot section on the chip in order to calculate all of its offsets and find the jump table. This is defined in the header files for XMEGA chips as BOOT_SECTION_SIZE since it is constant. Since ATMEGA chips are generally reconfigurable, it is not constant and therefore must be defined manually in xbootapi.h or passed to avr-gcc with -DBOOT_SECTION_SIZE=0x…. The xboot makefile does this automatically when it builds xboot for many ATMEGA chips and the makefile can be freely reused for your application, simplifying this process.

Note: All the page-based flash access commands work on Flash pages SPM_PAGESIZE bytes in size, located at addresses of multiples of SPM_PAGESIZE.

4.2 Return Values

All of the API calls except for xboot_reset return a value indicating success or an error code, defined in xbootapi.h.

#define XB_SUCCESS 0
#define XB_ERR_NO_API 1
#define XB_ERR_NOT_FOUND 2
#define XB_INVALID_ADDRESS 3
  • XB_SUCCESS is returned when the call succeeds
  • XB_ERR_NO_API is returned when the loader cannot find the API calls in xboot (either the APIs are disabled, xboot is not installed, or the loader is not looking at the right address)
  • XB_ERR_NOT_FOUND is returned when the particular API call is not found because it is disabled in xboot
  • XB_INVALID_ADDRESS is returned when an invalid address is passed to an API call

4.3 General API Functions

The general API functions are informational only.

uint8_t xboot_get_version(uint16_t *ver);
uint8_t xboot_get_api_version(uint8_t *ver);

4.3.1 xboot_get_version

uint8_t xboot_get_version(uint16_t *ver);

Returns the version of xboot in ver, MSB is major version and LSB is minor version.

4.3.2 xboot_get_api_version

uint8_t xboot_get_api_version(uint8_t *ver);

Returns the API version in ver. Currently the only legal value is 1.

4.4 Low-level Flash Programming API

The low-level Flash programming API provides low-level access to the Flash memory. Can be disabled in xboot via ENABLE_API_LOW_LEVEL_FLASH

uint8_t xboot_spm_wrapper(void);
uint8_t xboot_erase_application_page(uint32_t address);
uint8_t xboot_write_application_page(uint32_t address, uint8_t *data, uint8_t erase);
uint8_t xboot_write_user_signature_row(uint8_t *data);

4.4.1 xboot_spm_wrapper

uint8_t xboot_spm_wrapper(void);

Not currently implemented. Will eventually be used to execute any valid SPM command. Use with caution. Can be independently disabled in xboot via ENABLE_API_SPM_WRAPPER

4.4.2 xboot_erase_application_page

uint8_t xboot_erase_application_page(uint32_t address);

Erase the page in application memory (SPM_PAGESIZE bytes) pointed to by address.

4.4.3 xboot_write_application_page

uint8_t xboot_write_application_page(uint32_t address, uint8_t *data, uint8_t erase);

Write SPM_PAGESIZE bytes of data to the page in application memory pointed to by address, erasing before hand if erase is nonzero.

4.4.4 xboot_write_user_signature_row

uint8_t xboot_write_user_signature_row(uint8_t *data);

XMEGA only. Write data to the user signature row, automatically erasing it beforehand.

4.5 Firmware Update API

The firmware update API allows client firmware to update itself atomically while making it difficult for the application to accidentally overwrite itself. The loader can call the underlying low level calls if these higher level calls are disabled, however, the firmware may not be updated after a reset if the actual firmware update capability in the bootloader is disabled.

Out of all the API calls listed here, the only actual API calls are xboot_app_temp_erase and xboot_app_temp_write_page. The rest do not require code running in the bootloader space, aside from xboot_install_firmware which calls xboot_app_temp_write_page internally, and so are implemented directly in xbootapi.c.

Note that for all the app_temp calls, addr = 0 is not the beggining of application flash but the beginning of the application temporary section, generally about the halfway point of the chip's memory. Hence, when using these calls, it is impossible to overwrite the application section directly.

uint8_t xboot_app_temp_erase(void);
uint8_t xboot_app_temp_write_page(uint32_t addr, uint8_t *data, uint8_t erase);
uint8_t xboot_app_temp_crc16_block(uint32_t start, uint32_t length, uint16_t *crc);
uint8_t xboot_app_temp_crc16(uint16_t *crc);
uint8_t xboot_app_crc16_block(uint32_t start, uint32_t length, uint16_t *crc);
uint8_t xboot_app_crc16(uint16_t *crc);
uint8_t xboot_install_firmware(uint16_t crc);
void __attribute__ ((noreturn)) xboot_reset(void);

4.5.1 xboot_app_temp_erase

uint8_t xboot_app_temp_erase(void);

Erase the application temporary section

4.5.2 xboot_app_temp_write_page

uint8_t xboot_app_temp_write_page(uint32_t addr, uint8_t *data, uint8_t erase);

Write SPM_PAGESIZE bytes of data to page in temporary section pointed to by addr, erasing beforehand if erase is nonzero. Note that addr = 0 is not the beggining of application flash but the beginning of the application temporary section.

Equivalent to:

xboot_write_application_page(address + XB_APP_TEMP_START, data, erase);

4.5.3 xboot_app_temp_crc16_block

uint8_t xboot_app_temp_crc16_block(uint32_t start, uint32_t length, uint16_t *crc);

Compute the crc hash of length bytes, starting at start in the application temporary section and return in crc. Note that start = 0 is not the beggining of application flash but the beginning of the application temporary section.

Equivalent to:

xboot_app_crc16_block(start + XB_APP_TEMP_START, length, crc);

4.5.4 xboot_app_temp_crc16

uint8_t xboot_app_temp_crc16(uint16_t *crc);

Computer the crc hash of the complete application temporary section and return in crc.

Equivalent to:

xboot_app_temp_crc16_block(0, XB_APP_TEMP_SIZE, crc);

4.5.5 xboot_app_crc16_block

uint8_t xboot_app_crc16_block(uint32_t start, uint32_t length, uint16_t *crc);

Compute the crc hash of length bytes, starting at start in the application section and return in crc. Note that start = 0 is actually address 0 in flash, the beginning of the application section.

xboot_app_crc16_block uses _crc16_update from avr-libc <util/crc16.h> with an initial value of 0 internally to compute the crc.

4.5.6 xboot_app_crc16

uint8_t xboot_app_crc16(uint16_t *crc);

Computer the crc hash of the complete application section and return in crc.

Equivalent to:

xboot_app_crc16_block(0, XB_APP_SIZE, crc);

4.5.7 xboot_install_firmware

uint8_t xboot_install_firmware(uint16_t crc);

Write the install firmware command to the end of application temporary flash, along with the crc of the section passed in crc. This crc must be calculated when the firmware update is built to ensure its correctness, not calculated with xboot_app_temp_crc16 on the fly.

This command does not actually install the firmware. It simply goes to the highest location in application flash and writes “XBIF” followed by the CRC. After XBoot starts (and if firmware update is enabled), it will look for this sequence, calculate the crc, install the firmware (if the crc matches), and erase the application temporary section. Since the command is stored in the flash memory, if XBoot is interrupted by a reset during the copy operation, it will simply restart the copy operation from the beginning when it starts up again, making the update operation atomic.

As this command will return, it is possible to perform clean-up and perhaps post a message that the device is going down for a firmware update before the actual update occurs. To reset the chip for the update, call xboot_reset. Note that the firmware install process can be cancelled by erasing the last page of the application temporary section (or the whole section) before resetting the chip.

The crc functions all use _crc16_update from avr-libc <util/crc16.h> with an initial crc of 0. The equivalent C code is:

uint16_t crc16_update(uint16_t crc, uint8_t a)
{
    int i;
 
    crc ^= a;
    for (i = 0; i < 8; ++i)
    {
        if (crc & 1)
            crc = (crc >> 1) ^ 0xA001;
        else
            crc = (crc >> 1);
    }
 
    return crc;
}

Calculating the crc for a new firmware must be done before it is sent to the chip for an update. As the crc passed to xboot_install_firmware must match the crc that XBoot calculates over the entire application temporary section, the firmware must be padded to the size of the application temporary section (XB_APP_TEMP_SIZE) with 0xff when the crc is calculated beforehand.

This checksum will be the same as the one calculated by xboot_app_temp_crc16. The temptation to simply pass the output of this function back to xboot_install_firmware is great. However, this is where a device can be bricked with ease if the firmware is copied into the application section incorrectly. Therefore, make sure the precalculated crc is the one passed to xboot_install_firmware.

4.5.8 xboot_reset

void __attribute__ ((noreturn)) xboot_reset(void);

This call will trigger a device reset and will not return. In XMEGA devices, it is done via the RST.CTRL register. In ATMEGA devices, it uses the watchdog timer, which XBoot will disable automatically after the reset.

4.6 Offsets defined in xbootapi.h

Several offsets and addresses are defined in xbootapi.h. They are detailed in the following table, along with example values (XMEGA with 64K application flash and 8K boot flash, 72K total flash):

Name                    Value           Description

PROGMEM_SIZE            0x012000        Size of entire program memory

BOOT_SECTION_START      0x010000        Offset of boot section

APP_SECTION_START       0x000000        Offset of entire application section

APP_SECTION_SIZE        0x010000        Size of entire application section

APP_SECTION_END         0x00FFFF        End address of entire application
                                        section

JUMP_TABLE_LOCATION     0x0101E8        Location of jump table in bootloader

XB_APP_START            0x000000        Offset of application section for
                                        firmware updates

XB_APP_SIZE             0x008000        Size of application section for
                                        firmware updates

XB_APP_END              0x007FFF        End address of application section for
                                        firmware updates

XB_APP_TEMP_START       0x008000        Offset of application temporary
                                        section for firmware updates

XB_APP_TEMP_SIZE        0x008000        Size of application temporary section
                                        for firmware updates

XB_APP_TEMP_END         0x00FFFF        End address of application temporary
                                        section for firmware updates

4.7 Using the Firmware Update API

The firmware update API allows client firmware to update itself. The process is not entirely foolproof, but with sufficient testing it is very difficult to 'brick' a device with the firmware upgrade API.

The memory map of a device using the firmware update API looks something like the following (XMEGA with 64K application flash and 8K boot flash, 72K total flash):

Section                 Address
--------------------------------------------
                        0x000000
                        XB_APP_START

Application
32K
  
                        XB_APP_END
                        0x007FFF
--------------------------------------------
                        0x008000
                        XB_APP_TEMP_START

Temporary Storage
32K

                        XB_APP_TEMP_END
                        0x00FFFF
--------------------------------------------
                        0x010000
XBoot
8K
                        0x011FFF
--------------------------------------------

To successfully use the firmware update API, the application must fit completely inside the application section.

Updating is performed by writing the firmware one page of SPM_PAGESIZE bytes at a time to the temporary storage section with xboot_app_temp_write_page, then calling xboot_install_firmware to schedule the firmware update, and finally calling xboot_reset to enter XBoot to reset the chip and actually install the firmware.

When the firmware is not being updated, the temporary storage section can be used for storing application data.

4.7.1 Firmware update example

The follwing example assumes get_new_firmware_crc, read_new_firmware, and cleanup are functions with appropriate parameters defined elsewhere in the client firmware. This routine calls get_new_firmware_crc to get the crc of the firmware update followed by a call to xboot_app_temp_erase to erase the temporary section. Then it calls read_new_firmware to read bytes into read_data, writing accumulated pages to the temporary section until it has no more bytes to read. The last page is padded with 0xff so as to not affect the crc calculation. Then it computes the crc of the application temporary section. If it matches the crc it fetched earlier, it initializes the firmware install process, cleans up, and resets the chip.

void upgrade_firmware()
{
    uint8_t page_buffer[SPM_PAGESIZE];
    uint8_t read_data[1024];
    uint8_t *read_ptr;
 
    uint32_t addr = 0;
    uint16_t page_addr = 0;
    uint16_t read_bytes;
 
    uint16_t target_crc = get_new_firmware_crc();
    uint16_t crc;
 
    if (xboot_app_temp_erase() != XB_SUCCESS)
        return;
 
    while (read_bytes = read_new_firmware(read_data, 1024))
    {
        read_ptr = read_data;
 
        while (read_bytes > 0)
        {
            page_buffer[page_addr++] = *read_ptr++;
            read_bytes--;
            if (page_addr >= SPM_PAGESIZE)
            {
                if (xboot_app_temp_write_page(addr, page_buffer, 0) != XB_SUCCESS)
                    return;
                addr += SPM_PAGESIZE;
                page_addr = 0;
            }
        }
    }
 
    if (page_addr > 0)
    {
        while (page_addr < SPM_PAGESIZE)
        {
            page_buffer[page_addr++] = 0xff;
        }
        if (xboot_app_temp_write_page(addr, page_buffer, 0) != XB_SUCCESS)
            return;
    }
 
    xboot_app_temp_crc16(&crc);
 
    if (crc != target_crc)
        return;
 
    if (xboot_install_firmware(target_crc) != XB_SUCCESS)
        return;

    cleanup();
 
    xboot_reset();
}

xboot's People

Contributors

alexforencich avatar awozniak avatar bradnelson avatar hkleen avatar karlbackstrom avatar neonquill avatar nickdademo avatar stevemarple avatar tasssadar avatar thefork avatar uwebonnes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xboot's Issues

Problem compiling non modified source in AS 7.0

Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe -C "C:\atmel\xboot-master\xboot-master" -f "Makefile" clean
make: Entering directory 'C:/atmel/xboot-master/
xboot-master' The system cannot find the path specified.

Noticing the SLASH instead of BACKSLASH in the path but have no clue how to fix it..
So probably not a code problem but thought someone have had this problem before.

make arduino328p fails if i2c is enabled in config file

hi,

if i enable the i2c-option(s) in the arduino328p.conf.mk i'm getting an odd output on the make command. i've no clue what went wrong... when setting back e.g. to UART bus, everything goes fine.

unfortunately, i'm very new to the raspi and all the linux stuff, so i would really appreciate any hints and support also in terms of posting issues here.

i hope it is okay to post all the stuff in this form of presentation...
first, the enabled lines of the conf.mk, after that i've pasted the mentioned output of the make-command.

resulting switches in the conf.mk:

USE_CONFIG_H = yes
MCU = atmega328p
BOOTSZ=0
F_CPU = 16000000
USE_DFLL = yes
OVERRIDE_AVRDUDE_PROGRAMMER = yes
AVRDUDE_PROGRAMMER = avrispmkII
AVRDUDE_PORT = usb
AVRDUDE_FUSES =
USE_ENTER_DELAY = yes
USE_ENTER_PIN = no
USE_ENTER_UART = no
USE_ENTER_I2C = yes
USE_ENTER_FIFO = no
USE_ENTER_EEPROM = no
LOCK_SPM_ON_EXIT = no
USE_LED = yes
USE_UART = no
USE_UART_EN_PIN = no
USE_I2C = yes
USE_I2C_ADDRESS_NEGOTIATION = no
USE_ATTACH_LED = no
USE_FIFO = no
USE_INTERRUPTS = no
USE_WATCHDOG = no
ENABLE_BLOCK_SUPPORT = yes
ENABLE_FLASH_BYTE_SUPPORT = yes
ENABLE_EEPROM_BYTE_SUPPORT = yes
ENABLE_LOCK_BITS = yes
ENABLE_FUSE_BITS = yes
ENABLE_FLASH_ERASE_WRITE = yes
ENABLE_CRC_SUPPORT = yes
ENABLE_API = yes
USE_API_VERSION = 1
ENABLE_API_LOW_LEVEL_FLASH = yes
ENABLE_API_SPM_WRAPPER = yes
ENABLE_API_FIRMWARE_UPDATE = yes
ENABLE_CODE_PROTECTION = no
ENABLE_EEPROM_PROTECTION = no
ENABLE_BOOTLOADER_PROTECTION = no
ENTER_PORT_NAME = C
ENTER_PIN = 0
ENTER_PIN_STATE = 0
ENTER_PIN_PUEN = 1
ENTER_BLINK_COUNT = 3
ENTER_BLINK_WAIT = 300000
ENTER_EEPROM_ADDR = 0x3f8;
WATCHDOG_TIMEOUT = WDT_PER_1KCLK_gc
LED_PORT_NAME = B
LED_PIN = 5
LED_INV = 1
UART_BAUD_RATE = 115200
UART_NUMBER = 0
UART_U2X = yes
UART_RX_PUEN = yes
UART_REMAP = no
UART_EN_PORT_NAME = C
UART_EN_PIN = 4
UART_EN_PIN_INV = 0
FIFO_DATA_PORT_NAME = C
FIFO_CTL_PORT_NAME = D
FIFO_RXF_N = 3
FIFO_TXE_N = 2
FIFO_RD_N = 1
FIFO_WR_N = 0
FIFO_BIT_REVERSE = yes
I2C_DEVICE_PORT = C
I2C_MATCH_ANY = 1
I2C_ADDRESS = 0x10
I2C_GC_ENABLE = 1

the output of the make command at prompt:

avr-gcc (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Generating config.h for atmega328p

Compiling: xboot.c
avr-gcc -c -mmcu=atmega328p -I. -gstabs -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -fno-jump-tables -Wall -Wa,-adhlns=xboot.lst -Wstrict-prototypes -std=gnu99 -MD -MP -MF .dep/xboot.o.d -DF_CPU=16000000L -DBOOT_SECTION_SIZE=0x001000 -DUSE_CONFIG_H xboot.c -o xboot.o
In file included from xboot.c:34:0:
xboot.c: In function ‘main’:
xboot.h:366:46: error: ‘TWIC’ undeclared (first use in this function)
#define I2C_DEVICE token_paste2(TWI, I2C_DEVICE_PORT)
^
xboot.h:43:32: note: in definition of macro ‘token_paste2_int’
#define token_paste2_int(x, y) x ## y
^
xboot.h:366:33: note: in expansion of macro ‘token_paste2’
#define I2C_DEVICE token_paste2(TWI, I2C_DEVICE_PORT)
^
i2c.h:45:31: note: in expansion of macro ‘I2C_DEVICE’
#define i2c_address_match() ((I2C_DEVICE.SLAVE.STATUS & TWI_SLAVE_APIF_bm) &&
^
xboot.c:388:21: note: in expansion of macro ‘i2c_address_match’
if (i2c_address_match())
^
xboot.h:366:46: note: each undeclared identifier is reported only once for each function it appears in
#define I2C_DEVICE token_paste2(TWI, I2C_DEVICE_PORT)
^
xboot.h:43:32: note: in definition of macro ‘token_paste2_int’
#define token_paste2_int(x, y) x ## y
^
xboot.h:366:33: note: in expansion of macro ‘token_paste2’
#define I2C_DEVICE token_paste2(TWI, I2C_DEVICE_PORT)
^
i2c.h:45:31: note: in expansion of macro ‘I2C_DEVICE’
#define i2c_address_match() ((I2C_DEVICE.SLAVE.STATUS & TWI_SLAVE_APIF_bm) &&
^
xboot.c:388:21: note: in expansion of macro ‘i2c_address_match’
if (i2c_address_match())
^
In file included from xboot.h:432:0,
from xboot.c:34:
i2c.h:45:57: error: ‘TWI_SLAVE_APIF_bm’ undeclared (first use in this function)
#define i2c_address_match() ((I2C_DEVICE.SLAVE.STATUS & TWI_SLAVE_APIF_bm) &&
^
xboot.c:388:21: note: in expansion of macro ‘i2c_address_match’
if (i2c_address_match())
^
i2c.h:46:36: error: ‘TWI_SLAVE_AP_bm’ undeclared (first use in this function)
(I2C_DEVICE.SLAVE.STATUS & TWI_SLAVE_AP_bm))
^
xboot.c:388:21: note: in expansion of macro ‘i2c_address_match’
if (i2c_address_match())
^
xboot.c: In function ‘get_char’:
xboot.c:1208:26: error: #error Not implemented!
#error Not implemented!
^
xboot.c: In function ‘send_char’:
xboot.c:1314:26: error: #error Not implemented!
#error Not implemented!
^
xboot.c:1233:23: warning: unused variable ‘tmp’ [-Wunused-variable]
unsigned char tmp;
^
Makefile:886: recipe for target 'xboot.o' failed
make[1]: *** [xboot.o] Error 1
make[1]: Leaving directory '/home/pi/xboot'
Makefile:779: recipe for target 'conf/arduino328p.conf.mk' failed
make: *** [conf/arduino328p.conf.mk] Error 2

thank you guys for checking this issue (if it is a real one ;o) !

regards,
richard

Enter Bootloader

Hi

How I can enter the bootloader with avrdude? I saw in your documentation that you mentioned to sniff the sync word 0x1b in the application software. But when I enter the xboot, then must send AVRDUDE again the sync word.

Support for multiple I2C

I am working with a XMEGA128A4U which supports multiple I2C connections (2). I am currently using one as a Slave and one as a Master. Is it possible to use xboot for such purpose?

UEFI Support

With more and more newer computer systems using UEFI for boot, it would be great if this tool offered the ability to create multiboot USB drives that can be booted on UEFI systems (perhaps not necessarily with SecureBoot enabled).

Compiling Issues

Hi

When I compile with the command make conf/arduino328p.conf.mk then I receive always the error:

inlining failed in call to always_inline 'uart_deinit': function body not available
 extern void __attribute__ ((always_inline)) uart_deinit(void);
                                             ^

What are I do wrong?

Start bootloader section address

I have some misunderstanding with start bootloader section address.
I use atmega644p device. According to "Atmel-8011-8-bit-AVR-Microcontroller-ATmega164P-324P-644P_datasheet" table 23-13 Boot Reset Address is 0x7000 while BOOTSZ1=0 and BOOTSZ0=0.
But in xboot Makefile BOOT_SECTION_start defined as 0xE000.
...
ifneq ($(filter $(MCU_S), m64 m640 m644 m644p m644pa m645 m6450 m649 m649p m6490),)
ifeq ($(BOOTSZ), 0)
BOOT_SECTION_START =0x00E000
BOOT_SECTION_SIZE =0x002000
endif
...
In fact, when I read chip flash after xboot flashing I see code at 0xE000 as defined in xboot Makefile.
What is wrong?

EEPROM writing problem

Hi! I've been using this bootloader for some time now without any issue. However, after updating to the latest version (current master as of 2015/12/29) I found a problem when programming the EEPROM memory:

avrdude: reading input file "robot.eep"
avrdude: input file robot.eep auto detected as Intel Hex
avrdude: writing eeprom (1835 bytes):

Writing |                                                    | 0% 0.00savrdude: butterfly_recv(): programmer is not responding

The flash is programmed successfully.

I'm using an atxmega128a3u, with this xboot configuration

This problem appeared with the commit 9829ddd up to one commit before that, I'm able to program the EEPROM.

All reset flags cleared by xboot

Clearing all reset flags in MCUSR (for ATmega devices) prevents the user application from finding out the cause of the MCU reset.

I have some hardware where an LED displays some debugging information for a few minutes following a reset, but only if the reset was caused by a human (power-on, JTAG and external resets). To preserve battery life resets caused by the watchdog timer and brown-outs do not enable the LED. Pull request #22 preserves all reset flags except the watchdog which must be cleared. However when all flags are zero the user application can deduce that the cause was the watchdog timer.

XBOOT on AS7

Hi guys,
after I installed Windows10 my only IDE was AS7. In order to compile XBOOT for atxmega384C I created a new project, added the required xboot files, changed settings accordingly and compiled it the usual way.
Seemed to work, would connect to AVRDUDE and reported that my application was being 'burnt', but in fact all I got was 0xFF. Also the programming did not finish, it got somehow stuck in the end with no error message.
The reason for it was the function get_2bytes that was written in ASM. I removed the ASM part and uncommented the C part of it like that:
unsigned int attribute ((noinline)) get_2bytes()
{
return (get_char() << 8) | get_char();
}
Also this part I reverted back to C rather than ASM:
if (val == CMD_SET_EXT_ADDRESS)
{
// Read address high then low
address = ((ADDR_T)get_char() << 16) | get_2bytes();
// acknowledge
send_char(REPLY_ACK);
}
That resolved the issue and XBOOT now programs my atxmega384C3 as expected. Maybe it helps someone. Have fun...
Thomas from Germany

update firmware with Xboot on a micro through SPI bus and micro is slave..

hello,
i have some micro Xmega128A1U connected as slaves on a SPI bus to an Allwiinner SOC.
i planned to use the SOC to update the firmware, so i was studying xboot.
do you think the xboot could be used as a firmware update code for the micros?
as far as i can see, there's no support for the SPI interface in the xboot code.
is there a known issue or it's just because the use case was missing?
i could eventually try to patch your code. do you think it's feasible easily?

ATmega32u4

Is it possible to use xboot on ATmega32u4?

blocks in erase page

Hi, Thank you for your bootloader.
I'am facing a problem using the function xboot_erase_application_page. The code blocks and don't run .. I i'am using in the same code xboot_app_temp_erase and it is working.. Do we need some extra command do to this ? Thank you
Thanks in advance

Licensing

Hi,

Is there any plans to add a LICENSE file to this? Thanks.

Build fails on windows with AS6.1.

I'm trying to build xboot on windows, using a completely stock setup (just did a fresh check-out) with AS6.1.

I have all the relevant binaries on my $PATH.

I've copied the example x32a4.conf.mk from the conf directory into the main directory.

Running make -d x32a4.conf.mk fails with

Removing child 0x0251a080 PID 39087024 from chain.
  Successfully remade target file `gccversion'.
  Considering target file `sizebefore'.
   File `sizebefore' does not exist.
   Finished prerequisites of target file `sizebefore'.
  Must remake target `sizebefore'.
Creating temporary batch file D:\NEKOPR~2\AppData\Local\Temp\make809684-1.bat
CreateProcess(D:\NEKOPR~2\AppData\Local\Temp\make809684-1.bat,D:\NEKOPR~2\AppData\Local\Temp\make809684-1.bat,...)
Putting child 0x0251a080 (sizebefore) PID 39087024 on the chain.
Live child 0x0251a080 (sizebefore) PID 39087024
-f was unexpected at this time.

I've been trying to poke around and fix things, but makefiles melt my brain, and I really don't know how to fix this.

I have cygwin installed locally, and I added SHELL=C:/cygwin/bin/sh.exe at the beginning of the makefile, but that just results in another error:

CreateProcess(C:\cygwin\bin\sh.exe,C:/cygwin/bin/sh.exe -c "echo >> config.h",...)
Live child 0x0251a260 (config.h) PID 39096208
Reaping winning child 0x0251a260 PID 39096208
CreateProcess(C:\cygwin\bin\sh.exe,C:/cygwin/bin/sh.exe -c "if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define ATTACH_LED_INV\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define ATTACH_LED_INV 1\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define ATTACH_LED_PIN\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define ATTACH_LED_PIN 1\" >> config.h ; fi ;  if [ \"A\" = \"y\" ] || [ \"A\" = \"yes\" ] ; then echo \"#define ATTACH_LED_PORT_NAME\" >> config.h ; elif [ -n \"A\" ] && [ \"A\" != \"n\" ] && [ \"A\" != \"no\" ] ; then echo \"#define ATTACH_LED_PORT_NAME A\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_API\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_API yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_API_FIRMWARE_UPDATE\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_API_FIRMWARE_UPDATE yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_API_LOW_LEVEL_FLASH\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_API_LOW_LEVEL_FLASH yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_API_SPM_WRAPPER\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_API_SPM_WRAPPER yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_BLOCK_SUPPORT\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_BLOCK_SUPPORT yes\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define ENABLE_BOOTLOADER_PROTECTION\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define  ENABLE_BOOTLOADER_PROTECTION no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define ENABLE_CODE_PROTECTION\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define ENABLE_CODE_PROTECTION no\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_CRC_SUPPORT\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_CRC_SUPPORT yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_EEPROM_BYTE_SUPPORT\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_EEPROM_BYTE_SUPPORT yes\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define ENABLE_EEPROM_PROTECTION\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define ENABLE_EEPROM_PROTECTION no\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_FLASH_BYTE_SUPPORT\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_FLASH_BYTE_SUPPORT yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_FLASH_ERASE_WRITE\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_FLASH_ERASE_WRITE yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_FUSE_BITS\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_FUSE_BITS yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define ENABLE_LOCK_BITS\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define ENABLE_LOCK_BITS yes\" >> config.h ; fi ;  if [ \"3\" = \"y\" ] || [ \"3\" = \"yes\" ] ; then echo \"#define ENTER_BLINK_COUNT\" >> config.h ; elif [ -n \"3\" ] && [ \"3\" != \"n\" ] && [ \"3\" != \"no\" ] ; then echo \"#define ENTER_BLINK_COUNT 3\" >> config.h ; fi ;  if [ \"30000\" = \"y\" ] || [ \"30000\" = \"yes\" ] ; then echo \"#define ENTER_BLINK_WAIT\" >> config.h ; elif [ -n \"30000\" ] && [ \"30000\" != \"n\" ] && [ \"30000\" != \"no\" ] ; then echo \"#define ENTER_BLINK_WAIT 30000\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define ENTER_PIN\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define ENTER_PIN 0\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define ENTER_PIN_PUEN\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define ENTER_PIN_PUEN 1\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define ENTER_PIN_STATE\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define ENTER_PIN_STATE 0\" >> config.h ; fi ;  if [ \"C\" = \"y\" ] || [ \"C\" = \"yes\" ] ; then echo \"#define ENTER_PORT_NAME\" >> config.h ; elif [ -n \"C\" ] && [ \"C\" != \"n\" ] && [ \"C\" != \"no\" ] ; then echo \"#define ENTER_PORT_NAME C\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define FIFO_BIT_REVERSE\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define FIFO_BIT_REVERSE yes\" >> config.h ; fi ;  if [ \"D\" = \"y\" ] || [ \"D\" = \"yes\" ] ; then echo \"#define FIFO_CTL_PORT_NAME\" >> config.h ; elif [ -n \"D\" ] && [ \"D\" != \"n\" ] && [ \"D\" != \"no\" ] ; then echo \"#define FIFO_CTL_PORT_NAME D\" >> config.h ; fi ;  if [ \"C\" = \"y\" ] || [ \"C\" = \"yes\" ] ; then echo \"#define FIFO_DATA_PORT_NAME\" >> config.h ; elif [ -n \"C\" ] && [ \"C\" != \"n\" ] && [ \"C\" != \"no\" ] ; then echo \"#define FIFO_DATA_PORT_NAME C\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define FIFO_RD_N\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define FIFO_RD_N 1\" >> config.h ; fi ;  if [ \"3\" = \"y\" ] || [ \"3\" = \"yes\" ] ; then echo \"#define FIFO_RXF_N\" >> config.h ; elif [ -n \"3\" ] && [ \"3\" != \"n\" ] && [ \"3\" != \"no\" ] ; then echo \"#define FIFO_RXF_N 3\" >> config.h ; fi ;  if [ \"2\" = \"y\" ] || [ \"2\" = \"yes\" ] ; then echo \"#define FIFO_TXE_N\" >> config.h ; elif [ -n \"2\" ] && [ \"2\" != \"n\" ] && [ \"2\" != \"no\" ] ; then echo \"#define FIFO_TXE_N 2\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define FIFO_WR_N\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define FIFO_WR_N 0\" >> config.h ; fi ;  if [ \"0x10\" = \"y\" ] || [ \"0x10\" = \"yes\" ] ; then echo \"#define I2C_ADDRESS\" >> config.h ; elif [ -n \"0x10\" ] && [ \"0x10\" != \"n\" ] && [ \"0x10\" != \"no\" ] ; then echo \"#define I2C_ADDRESS 0x10\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define I2C_AUTONEG_DIS_GC\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define I2C_AUTONEG_DIS_GC 0\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define I2C_AUTONEG_DIS_PROMISC\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define I2C_AUTONEG_DIS_PROMISC 1\" >> config.h ; fi ;  if [ \"2\" = \"y\" ] || [ \"2\" = \"yes\" ] ; then echo \"#define I2C_AUTONEG_PIN\" >> config.h ; elif [ -n \"2\" ] && [ \"2\" != \"n\" ] && [ \"2\" != \"no\" ] ; then echo \"#define I2C_AUTONEG_PIN 2\" >> config.h ; fi ;  if [ \"A\" = \"y\" ] || [ \"A\" = \"yes\" ] ; then echo \"#define I2C_AUTONEG_PORT_NAME\" >> config.h ; elif [ -n \"A\" ] && [ \"A\" != \"n\" ] && [ \"A\" != \"no\" ] ; then echo \"#define I2C_AUTONEG_PORT_NAME A\" >> config.h ; fi ;  if [ \"C\" = \"y\" ] || [ \"C\" = \"yes\" ] ; then echo \"#define I2C_DEVICE_PORT\" >> config.h ; elif [ -n \"C\" ] && [ \"C\" != \"n\" ] && [ \"C\" != \"no\" ] ; then echo \"#define I2C_DEVICE_PORT C\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define I2C_GC_ENABLE\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define I2C_GC_ENABLE 1\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define I2C_MATCH_ANY\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define I2C_MATCH_ANY 1\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define LED_INV\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define LED_INV 1\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define LED_PIN\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define LED_PIN 0\" >> config.h ; fi ;  if [ \"A\" = \"y\" ] || [ \"A\" = \"yes\" ] ; then echo \"#define LED_PORT_NAME\" >> config.h ; elif [ -n \"A\" ] && [ \"A\" != \"n\" ] && [ \"A\" != \"no\" ] ; then echo \"#define LED_PORT_NAME A\" >> config.h ; fi ;  if [ \"115200\" = \"y\" ] || [ \"115200\" = \"yes\" ] ; then echo \"#define UART_BAUD_RATE\" >> config.h ; elif [ -n \"115200\" ] && [ \"115200\" != \"n\" ] && [ \"115200\" != \"no\" ] ; then echo \"#define UART_BAUD_RATE 115200\" >> config.h ; fi ;  if [ \"4\" = \"y\" ] || [ \"4\" = \"yes\" ] ; then echo \"#define UART_EN_PIN\" >> config.h ; elif [ -n \"4\" ] && [ \"4\" != \"n\" ] && [ \"4\" != \"no\" ] ; then echo \"#define UART_EN_PIN 4\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define UART_EN_PIN_INV\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define UART_EN_PIN_INV 0\" >> config.h ; fi ;  if [ \"C\" = \"y\" ] || [ \"C\" = \"yes\" ] ; then echo \"#define UART_EN_PORT_NAME\" >> config.h ; elif [ -n \"C\" ] && [ \"C\" != \"n\" ] && [ \"C\" != \"no\" ] ; then echo \"#define UART_EN_PORT_NAME C\" >> config.h ; fi ;  if [ \"0\" = \"y\" ] || [ \"0\" = \"yes\" ] ; then echo \"#define UART_NUMBER\" >> config.h ; elif [ -n \"0\" ] && [ \"0\" != \"n\" ] && [ \"0\" != \"no\" ] ; then echo \"#define UART_NUMBER 0\" >> config.h ; fi ;  if [ \"C\" = \"y\" ] || [ \"C\" = \"yes\" ] ; then echo \"#define UART_PORT_NAME\" >> config.h ; elif [ -n \"C\" ] && [ \"C\" != \"n\" ] && [ \"C\" != \"no\" ] ; then echo \"#define UART_PORT_NAME C\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define UART_RX_PUEN\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define UART_RX_PUEN yes\" >> config.h ; fi ;  if [ \"1\" = \"y\" ] || [ \"1\" = \"yes\" ] ; then echo \"#define USE_API_VERSION\" >> config.h ; elif [ -n \"1\" ] && [ \"1\" != \"n\" ] && [ \"1\" != \"no\" ] ; then echo \"#define USE_API_VERSION 1\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_ATTACH_LED\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_ATTACH_LED no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_AVR1008_EEPROM\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_AVR1008_EEPROM no\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define USE_ENTER_DELAY\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define USE_ENTER_DELAY yes\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_ENTER_FIFO\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_ENTER_FIFO no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_ENTER_I2C\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_ENTER_I2C no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_ENTER_PIN\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_ENTER_PIN no\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define USE_ENTER_UART\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define USE_ENTER_UART yes\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_FIFO\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_FIFO no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_I2C\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_I2C no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_I2C_ADDRESS_NEGOTIATION\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_I2C_ADDRESS_NEGOTIATION no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_INTERRUPTS\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_INTERRUPTS no\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define USE_LED\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define USE_LED yes\" >> config.h ; fi ;  if [ \"yes\" = \"y\" ] || [ \"yes\" = \"yes\" ] ; then echo \"#define USE_UART\" >> config.h ; elif [ -n \"yes\" ] && [ \"yes\" != \"n\" ] && [ \"yes\" != \"no\" ] ; then echo \"#define USE_UART yes\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_UART_EN_PIN\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_UART_EN_PIN no\" >> config.h ; fi ;  if [ \"no\" = \"y\" ] || [ \"no\" = \"yes\" ] ; then echo \"#define USE_WATCHDOG\" >> config.h ; elif [ -n \"no\" ] && [ \"no\" != \"n\" ] && [ \"no\" != \"no\" ] ; then echo \"#define USE_WATCHDOG no\" >> config.h ; fi ;  if [ \"WDT_PER_1KCLK_gc\" = \"y\" ] || [ \"WDT_PER_1KCLK_gc\" = \"yes\" ] ; then echo \"#define WATCHDOG_TIMEOUT\" >> config.h ; elif [ -n \"WDT_PER_1KCLK_gc\" ] && [ \"WDT_PER_1KCLK_gc\" != \"n\" ] && [ \"WDT_PER_1KCLK_gc\" != \"no\" ] ; then echo \"#define WATCHDOG_TIMEOUT WDT_PER_1KCLK_gc\" >> config.h ; fi ;",...)
Live child 0x0251a260 (config.h) PID 39096208
/usr/bin/sh: -c: line 1: syntax error: unexpected end of file
Reaping losing child 0x0251a260 PID 39096208
make[1]: *** [config.h] Error 1
Removing child 0x0251a260 PID 39096208 from chain.

Which looks like a bit much to be passing on the command line. I'd guess that in this case, the command line arguments are being truncated.

I can't just install winavr as I want to eventually try to port xboot to the xmega32e5, which isn't supported by the FOSS avr-gcc, at least without building from sources, which is also a bit beyond me.

Is there any way to build xboot as an Atmel Studio project?

Thanks.

API not responding

Hi there,
I gone through the link and downloaded the code.
Im using Xmega32a4u board , Avr studio 4.18
Created Xboot.h hex file( enable UART and A LED for communication, Enable the API)
Programmed the Xboot.hex file and i can see the LED blinking and also UART responds with Xboot++ when i send 'S' through UART.

My problem is whenever i call Any API (get version) from my application code, its restarting
am i doing anything wrong?

USE_LED ... LED not lit when USE_ENTER_DELAY = no and USE_ENTER_PIN = yes

Entry
USE_ENTER_DELAY = no
USE_ENTER_PIN = yes
USE_ENTER_UART = no
USE_ENTER_I2C = no
USE_ENTER_FIFO = no

Communication
USE_LED = yes
USE_UART = yes

What appears to be happening is that the LED is lit during initialisation and then turned off when the bootloader in entered by the toggle code.
The line val = get_char(); appears to be blocking and so the LED remains off until the bootloader processes some serial input.

Suggest moving the LED toggling code below val = get_char(); so that a positive visual indication is given that the bootloader has been entered.

e.g.

// Main bootloader
while (in_bootloader) {
val = get_char();

#ifdef USE_LED
#ifdef AVR_XMEGA
LED_PORT.OUTTGL = (1 << LED_PIN);
#else // AVR_XMEGA
LED_PORT ^= (1 << LED_PIN);
#endif // AVR_XMEGA
#endif // USE_LED

....

Thanks for the work so far on this project.

`eeprom_driver.c` will not compile for xmega E devices

Basically, it seems like Atmel is trying to depreciate 'NVM_CMD_READ_EEPROM_gc', 'NVM_CMD_LOAD_EEPROM_BUFFER_gc', 'NVM_CMD_READ_EEPROM_gc' and 'NVM_CMD_LOAD_EEPROM_BUFFER_gc'.

In any event, they've removed them from the available commands for the NVM controller on xmega E devices.

Is there any reason xboot is using it's own EEPROM driver, rather then the EEPROM functions in <avr/eeprom.h>? The functions in <avr/eeprom.h> seem to be written in assembly (assuming I'm looking at the correct source files).

Is it a code-size issue?

always_inline ???????

Hi there,

thanks for the great work. One remark: all over the code I see attributes "always_inline". This causes (very recent ...) gcc's to fail, and the compiler is right: it rightly complains that it cannot inline function without the function body around, i.e. it does not make sense to label a function "always_inline" and then just provide the proto-type. What was the reason for all this "always_inline" tags?

Best regards,

Claus Heine

Trouble Flashing Application

I'm having issues flashing an application over RS485. It looks like it finds the bootloader but never is able to read the type or software version. I'm not sure what I am doing wrong here.

Here is the output of avrdude:

$ avrdude -v  -p atmega328p -P /dev/ttyS12 -c avr109 -b 9600 -U flash:w:firmware.hex

avrdude: Version 6.3
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/etc/avrdude.conf"
         User configuration file is "/home/alex/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyS12
         Using Programmer              : avr109
         Overriding Baud Rate          : 9600
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : butterfly
         Description     : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = ?
    Software Version = ?.?; No Hardware Version given.
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: error: programmer did not respond to command: leave prog mode
avrdude: error: programmer did not respond to command: exit bootloader

avrdude done.  Thank you.

Make configurations

I'm probably not understanding how this was setup. I should be able to do

make arduino328p.conf.mk

to build that target correct? It is not working for me on Linux (Ubuntu 16.04)

~/Samba/xboot$ make arduino328p.conf.mk
cp arduino328p.conf.mk config.mk
cp: cannot stat 'arduino328p.conf.mk': No such file or directory
Makefile:779: recipe for target 'arduino328p.conf.mk' failed
make: *** [arduino328p.conf.mk] Error 1

I can build when placing those setting directly into the Makefile.

Fails to flash application on xmega384D3

I crated a config file for the xmega384D3 and modified the Makefile to have the correct boot loader address.
the makefile programs the boot loader to the chip and i can enter the boot loader using a button. When trying to flash the application following your example it fails to program. avrdude says ****failed repeatedly and the verify step at the end fails also. Any idea why this might happen?

Generating config.h - syntax error: unexpected end of file

Hi all,

I am trying to build xboot with the x32a4u.conf.mk configuration by running:

$ make conf/x32a4u.conf.mk

but i get the following error:

$ make conf/x32a4u.conf.mk
cp conf/x32a4u.conf.mk config.mk
"C:/Program Files (x86)/GnuWin32/bin/make"
make[1]: Entering directory `D:/Programmeren/avr-xboot/xboot'

-------- begin --------
avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.2_1778) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Generating config.h for atxmega32a4u
/usr/bin/sh: -c: line 1: syntax error: unexpected end of file
make[1]: *** [config.h] Error 1
make[1]: Leaving directory `D:/Programmeren/avr-xboot/xboot'
make: *** [conf/x32a4u.conf.mk] Error 2

It seems something goes wrong in the config.h.mk file ( the makefile part where the config.h is created from the config.mk)
The process of creating config.mk , (just a copy of x32a4u.conf.mk) is working fine. config.mk is there in the folder.

Any idea?

Kind regards,
Corne

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.