Skip to content
Rhodri James edited this page Dec 4, 2015 · 2 revisions

Protocols

Implementation Notes for New Protocols

Protocols are described as a name and a set of functions:

typedef struct up_protocol_struct {
    const char *name;
    void *(*init)(void);
    int (*prepare)(void *h, up_context_t *ctx, up_load_arg_t *arg);
    int (*transfer)(void *h, up_context_t *ctx, up_load_arg_t *arg, const uint8_t *buf, int buf_bytes);
    int (*complete)(void *h, up_context_t *ctx, up_load_arg_t *arg);
    int (*shutdown)(void *h, up_context_t *ctx);
} up_protocol_t;

A new protocol is added to the system by inserting its descriptor into the array of descriptors used for command-line parsing by the front-end.

The name field identifies the protocol to the user, and is used in command-line parsing.

A protocol's init function is called at the start of the program to do any global initialisation. It returns the handle to be passed to all future function calls for this protocol. A return value of NULL indicates an error; successful initialisation functions must return a non-NULL value, even if it's only (void *)1.

The prepare entry point is called at the start of a boot stage. This is traditionally the point where the baud rate is changed, and the utility function utils_protocol_set_baud() has the right signature to be used directly as the prepare function if appropriate. Otherwise the protocol should do any other preparation before downloading a file here. Aside from changing the baud rate, communications with the back-end should be avoided; users may need to do some work before the upload can take place, for example by stopping uboot before its automation cuts in. The function should return 0 on success, or a negative number on error.

The transfer entry point is called by the core logic to do the actual file transfer. The file to transfer will already be open, and its file descriptor will be held in the fd field of the boot state arg parameter passed in. As well as the protocol handle, the system context and the boot stage parameter, the transfer function is given a byte buffer containing any bytes that the core system has read from the back-end. These bytes have already been written to the console and logged.

The transfer function should return a negative number on error, a positive number if the upload completed, and zero if the upload has not yet started or is still ongoing. It should periodically call utils_check_critical_control() to allow keyboard interrupts.

The complete entry point is called once transfer is complete, and may be required to undo the work of the prepare function. It should return zero on success or a negative number on error.

Finally, the shutdown entry point is called at the end of the program to release any resource protocol initialisation claimed. It should return zero on success or a negative number on error.

All function entries except for transfer may be NULL if the protocol does not need to do anything at that stage. The transfer entry may only be NULL if there is no file to transfer, which only is only the case when upc2 has switched into console mode after all transfers are complete.

Procotol handler functions should only talk to the back-end using the up_bio_t object in the system context, for example through ctx->bio->write() or ctx->bio->safe_write().

Protocol handler functions should use the file descriptor ctx->ttyfd to communicate with the console. Future versions may allow for dynamically redirecting console input and output, and using ctx->ttyfd proofs the code against that. The utility function utils_safe_printf() already does this. Error messages should of course be written to stderr as usual.

Supported Protocols

upc2 currently supports two upload protocols: grouch and xmodem.

Grouch

Grouch is a very simple upload protocol that has been used in-house for years. It goes like this:

  • The target system sends the six characters *LOAD* to indicate that it is ready to upload.
  • The host system (upc2) sends a * character for synchronisation.
  • The host system sends the image length in bytes as a four byte quantity, big-endian.
  • The host system sends the image.
  • The host system sends a four byte checksum, big-endian.

The checksum is the sum of the bytes of the image only, i.e. not including the initial * and image length.

XModem

upc2 handles XMODEM and XMODEM/CRC. For more details on the protocol, see the XMODEM/YMODEM reference at http://pauillac.inria.fr/~doligez/zmodem/ymodem.txt

Clone this wiki locally