microchipboot

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2022 License: MIT Imports: 9 Imported by: 0

README

microchipboot

Go implementation of the Microchip Unified Bootloader protocol.

GoDoc

This package contains the following components:

  • Bootloader: low-level interface to the bootloader.
  • Programmer: high-level programming interface.
  • microchipboot: command line programming tool.

Supported transports:

  • Serial

Installation

To install the package and the command line tool to your GOPATH:

go get github.com/amrbekhit/microchipboot/...

Note: Remove the /... at the end if you only want to install the library, but not the command line tool.

Command Line Tool

The cmd/microchipboot directory contains the code for a command line tool that serves as both an example on how to use the library and a fully functional host program to allow HEX files to be uploaded to devices. The tool currently supports programming 8-bit PICs.

Usage

Before using the host tool, a profile file must be created that describes the memory layout of the device to be programmed. An example for the PIC18F45K20 is shown below:

profile:
  bootloaderoffset: 0x800
  flashsize: 0x8000
  eepromoffset: 0xF00000
  eepromsize: 256
  configoffset: 0x300000
  configsize: 14
  idoffset: 0x200000
  idsize: 8
options:
  programeeprom: true
  programconfig: false
  programid: false
  verifybyreading: true

To program a HEX file, run the following command:

microchipboot -port /dev/ttyUSB0 -profile profile.yaml program.hex

Individual bootloader commands can be run using the -cmd flag. See the help text for more information.

Library

Programming functionality can be integrated into exisitng programs using the Bootloader and Programmer interfaces.

The Bootloader interface provides direct access to the individual bootloader commands. It abstracts away the communication transport (serial, ethernet, i2c, USB etc) and provides a unified way of interacting with the bootloader.

The Programmer interface implements the actual algorithms for loading a HEX file, erasing, programming and verifying the device. It uses a Bootloader to then send the necessary commands to the device.

The following example demonstrates how to use these two interfaces to program a device:

// First create a bootloader using the necessary transport
bootloader, err := microchipboot.NewSerialBootloader("/dev/ttyUSB0", 115200)
if err != nil {
    log.Fatalf("failed to initialise bootloader: %v", err)
}
// Create a programmer that uses that bootloader
programmer := microchipboot.NewPIC8Programmer(bootloader, profile, options)

log.Print("connecting to device...")
if err := programmer.Connect(); err != nil {
    log.Fatal(err)
}
defer programmer.Disconnect()
log.Print("connected")

file, err := os.Open("firmware.hex")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

if err := programmer.LoadHex(file); err != nil {
    log.Fatal(err)
}
log.Print("hex file loaded")

log.Print("programming...")
if err := programmer.Program(); err != nil {
    log.Fatal(err)
}

log.Print("verifying...")
if err := programmer.Verify(); err != nil {
    log.Fatal(err)
}

log.Print("resetting...")
if err := programmer.Reset(); err != nil {
    log.Fatal(err)
}
log.Print("complete")

Documentation

Overview

Package microchipboot implements the Microchip Unified Bootloader protocol (https://www.microchip.com/promo/unified-bootloaders).

The package contains two main components: Bootloader and Programmer. Bootloader provides a transport-agnostic way of interacting with the individual bootloader commands. Programmer provides a high-level programming interface, allowing HEX files to be loaded, programmed and verified. It uses a provided Bootloader interface to communicate with the device.

Also included is a command line tool, found in the cmd/microchipboot directory, that serves as both an example on how to use the library and a fully functional host program to allow HEX files to be uploaded to devices.

Example
// First create a bootloader using the necessary transport
bootloader, err := NewSerialBootloader("/dev/ttyUSB0", 115200)
if err != nil {
	log.Fatalf("failed to initialise bootloader: %v", err)
}
// Populate the profile with the device memory map details
profile := PIC8Profile{}
// Specify programming options (such as whether EEPROM or configuration bits should be programmed)
options := PIC8Options{}

// Create a programmer that uses the previously created bootloader
programmer := NewPIC8Programmer(bootloader, profile, options)

log.Print("connecting to device...")
if err := programmer.Connect(); err != nil {
	log.Fatal(err)
}
defer programmer.Disconnect()
log.Print("connected")

file, err := os.Open("firmware.hex")
if err != nil {
	log.Fatal(err)
}
defer file.Close()

if err := programmer.LoadHex(file); err != nil {
	log.Fatal(err)
}
log.Print("hex file loaded")

log.Print("programming...")
if err := programmer.Program(); err != nil {
	log.Fatal(err)
}

log.Print("verifying...")
if err := programmer.Verify(); err != nil {
	log.Fatal(err)
}

log.Print("resetting...")
if err := programmer.Reset(); err != nil {
	log.Fatal(err)
}
log.Print("complete")

Index

Examples

Constants

View Source
const (
	ResultSuccess      = 0x01
	ResultUnsupported  = 0xFF
	ResultAddressError = 0xFE
)

Command result codes.

Variables

This section is empty.

Functions

func GetResponseCodeString

func GetResponseCodeString(code int) string

GetResponseCodeString returns the string representation of a bootloader response code.

func SetLogger added in v0.2.0

func SetLogger(l logger)

SetLogger sets the logger used internally by the package.

Types

type Bootloader

type Bootloader interface {
	Connect() error
	Disconnect()
	GetVersion() (VersionInfo, error)
	ReadFlash(address uint32, length uint16) ([]byte, error)
	WriteFlash(address uint32, data []byte) error
	EraseFlash(address uint32, numRows uint16) error
	ReadEE(address uint32, length uint16) ([]byte, error)
	WriteEE(address uint32, data []byte) error
	ReadConfig(address uint32, length uint16) ([]byte, error)
	WriteConfig(address uint32, data []byte) error
	CalculateChecksum(address uint32, length uint16) (uint16, error)
	Reset() error
}

The Bootloader interface allows low-level interaction with the bootloader in a transport-agnostic fashion. For higher level programming operations, use the Programmer interface.

func NewSerialBootloader

func NewSerialBootloader(port string, baud int) (Bootloader, error)

NewSerialBootloader creates a new bootloader using the serial transport.

type Command

type Command struct {
	Command        uint8
	UnlockSequence [2]byte
	Address        uint32
	Length         uint16
	Data           []byte
	// contains filtered or unexported fields
}

Command represents a bootloader command.

func NewCalculateChecksumCommand

func NewCalculateChecksumCommand(address uint32, length uint16) Command

NewCalculateChecksumCommand returns the representation of the CalculateChecksum command.

func NewEraseFlashCommand

func NewEraseFlashCommand(address uint32, numRows uint16) Command

NewEraseFlashCommand returns the representation of the EraseFlash command.

func NewGetVersionCommand

func NewGetVersionCommand() Command

NewGetVersionCommand returns the representation of the GetVersion command.

func NewReadConfigCommand

func NewReadConfigCommand(address uint32, length uint16) Command

NewReadConfigCommand returns the representation of the ReadConfig command.

func NewReadEECommand

func NewReadEECommand(address uint32, length uint16) Command

NewReadEECommand returns the representation of the ReadEEPROM command.

func NewReadFlashCommand

func NewReadFlashCommand(address uint32, length uint16) Command

NewReadFlashCommand returns the representation of the ReadFlash command.

func NewResetCommand

func NewResetCommand() Command

NewResetCommand returns the representation of the Reset command.

func NewWriteConfigCommand

func NewWriteConfigCommand(address uint32, data []byte) Command

NewWriteConfigCommand returns the representation of the WriteConfig command.

func NewWriteEECommand

func NewWriteEECommand(address uint32, data []byte) Command

NewWriteEECommand returns the representation of the WriteEEPROM command.

func NewWriteFlashCommand

func NewWriteFlashCommand(address uint32, data []byte) Command

NewWriteFlashCommand returns the representation of the WriteFlash command.

func (Command) ExpectsSuccessCode

func (c Command) ExpectsSuccessCode() bool

ExpectsSuccessCode returns true if the command expects a success code to be returned.

func (Command) GetBytes

func (c Command) GetBytes() []byte

GetBytes returns a byte slice containing the data for the command.

func (Command) GetResponseLength

func (c Command) GetResponseLength() int

GetResponseLength returns the expected number of response bytes.

type PIC8Options

type PIC8Options struct {
	ProgramEEPROM bool
	ProgramConfig bool
	ProgramID     bool
	// If true, then verification is done by reading back from flash memory.
	// Otherwise, checksum is used.
	VerifyByReading bool
}

PIC8Options holds programming options.

type PIC8Profile

type PIC8Profile struct {
	BootloaderOffset uint32
	FlashSize        uint32
	EEPROMOffset     uint32
	EEPROMSize       uint32
	ConfigOffset     uint32
	ConfigSize       uint32
	IDOffset         uint32
	IDSize           uint32
}

PIC8Profile defines the memory structure for 8-bit PICs.

type Programmer

type Programmer interface {
	Connect() error
	Disconnect()
	GetVersionInfo() VersionInfo
	LoadHex(data io.Reader) error
	Program() error
	Verify() error
	Reset() error
}

Programmer reprsents the high level interface that allows devices to be programmed.

func NewPIC8Programmer

func NewPIC8Programmer(bootloader Bootloader, profile PIC8Profile, options PIC8Options) Programmer

NewPIC8Programmer creates a new programmer for 8-bit PICs.

type VersionInfo

type VersionInfo struct {
	VersionMinor, VersionMajor int
	MaxPacketSize              int
	DeviceID                   int
	EraseRowSize               int
	WriteRowSize               int
	ConfigWords                [4]byte
}

VersionInfo holds the results of the Request Version command.

func ParseGetVersionResponse

func ParseGetVersionResponse(data []byte) (VersionInfo, error)

ParseGetVersionResponse parses the response of the GetVersionInfo command.

Directories

Path Synopsis
cmd
microchipboot command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL