Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Overview

For the Bootloader, the following operations will be carried through datagrams. For some operations like querying, update ID/name, and flash application code, the data will first be serialized through protobufs. To generate protobuf files, run make bootloader_protos.

Datagram Format

Please check over the format for a datagram (https://uwmidsun.atlassian.net/wiki/spaces/ELEC/pages/2030895112/Bootloader%2BFlash%2Bover%2BCAN#Transport-layer-(Datagrams)). Below, the id and type of data will be specified. Status return functions will share the same datagram ID of 0. The number of node IDs addressed through the client is arbitrary, and the special value 0 means every controller board is addressed. Every response datagram will have a value of 0 for the list of node IDs parameter, as 0 is the ID of the client.

Querying

In the querying function, the client sends out a datagram containing the pattern-matching information: controller board IDs, name, current project name, project info, and/or git version information. The client message can target one, several, or zero projects from the information. An example of this would be id=5, project=bms_carrier, name=curiosity to match controller board 5 running BMS carrier named curiosity.

The client → boards datagram should have the following format:

uint8 id = 1 // Use 1 here as the datagram ID to avoid conflicts 
uint8 ids_addressed = 0 // The special value 0 means every controller board is addressed
uint16 data_size // Size of the protobuf (in n bytes)
uint8[n] data // The protobuf (located in the protos folder in the bootloader project: querying_bootloader.proto)

The response datagram will have the following format:

uint8 id = 2 // Use 2 here as the datagram ID to avoid conflicts 
uint16 data_size // Size of the protobuf (in n bytes)
uint8[n] data // The protobuf (located in the protos folder in the bootloader project: querying_response_bootloader.proto)

Ping

The ping function sends out a list of node IDs or none to ping all boards. Each board will send back a message with its ID if it is in the bootloader and ready to receive commands.

The client → boards datagram should have the following format:

uint8 id = 3 // Use 3 here as the datagram ID to avoid conflicts 
uint8 ids_addressed // The number(m) of nodes on the network that should receive the datagram. The special value 0 means every controller board is addressed
uint8[m] node_id // The different node IDs. Keep this blank if ids_addressed = 0

Note: This function has no data

The response datagram will have the following format:

uint8 id = 4 // Use 4 here as the datagram ID to avoid conflicts 
uint16 data_size = 1 // This is the size of the ID of the controller board in n bytes
uint8 data // The id of the controller board

Jump to application

Direct the matched boards to jump to the application code. The client sends out a list of IDs it wants to jump; each matched controller board computes the CRC of the application code, checks it, responds with a status code, and jumps to the application. (Actually doing this is super tricky: info here https://interrupt.memfault.com/blog/how-to-write-a-bootloader-from-scratch .)

Depending on how the design works out, we might be able to skip the CRC.

The client → boards datagram should have the following format:

uint8 id = 5 // Use 5 here as the datagram ID to avoid conflicts 
uint8 ids_addressed // The number(m) of nodes on the network that should receive the datagram. The special value 0 means every controller board is addressed
uint8[m] node_id // The different node IDs. Keep this blank if ids_addressed = 0

Note: This function has no data

The response datagram will have the following format:

uint8 id = 0 // Use 0 here as the datagram ID to avoid conflicts 
uint16 data_size = 1 // This is the size of the status code in n bytes
uint8 data // The status code

Update ID / Update name

This function will be split into two different commands, update ID and update name. These functions update the name or ID of a single controller board. The client sends out an ID to update and the new ID or name. The controller board overwrites the config (being careful to write one page, check it, and then write the other), and responds back with a status code. The protobuf used will change based on which function is used (name vs ID).

The client → boards datagram should have the following format:

uint8 id = 6 // Use 6 here as the datagram ID to avoid conflicts 
uint16 data_size // Size of the protobuf (in n bytes)
uint8[n] data // The protobuf (located in the protos folder in the bootloader project: update_id.proto or update_name.proto)

The response datagram will have the following format:

uint8 id = 0 // Use 0 here as the datagram ID to avoid conflicts 
uint16 data_size = 1 // This is the size of the status code in n bytes
uint8 data // The status code

Flash application code

The client sends out IDs of the boards to flash to, metadata like project name, git version (+branch?) info, and application CRC and size, then the application code itself. The controller boards write the application code to flash (making sure not to keep it all in memory at once to avoid overflows) and compute their own CRC of the application code. If it matches, they overwrite the project name/git version info/application CRC/application size in the config and clear the project info (being careful to write one page, check it, and then write the other), then respond back with an “OK” status code message. If it doesn’t match, they mark their config as “no project” (again being careful) and respond back with an appropriate status code.

The client → boards datagram should have the following format:

uint8 id = 7 // Use 7 here as the datagram ID to avoid conflicts 
uint16 data_size // Size of the protobuf (in n bytes)
uint8[n] data // The protobuf (located in the protos folder in the bootloader project: flash_application_code.proto)

The response datagram will have the following format:

uint8 id = 0 // Use 0 here as the datagram ID to avoid conflicts 
uint16 data_size = 1 // This is the size of the status code in n bytes
uint8 data // The status code

Note: The application code is to be transmitted in 2048-byte chunks in separate datagrams as raw data

  • No labels