Skip to content

Commit

Permalink
Add state machine framework for the ping datagram types
Browse files Browse the repository at this point in the history
  • Loading branch information
Leg3ndary committed Nov 2, 2024
1 parent d54a68a commit b6e22d9
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 46 deletions.
16 changes: 14 additions & 2 deletions projects/bootloader/inc/bootloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,21 @@ typedef enum {
BOOTLOADER_JUMP_APP,
/// @brief Bootloader is in fault state
BOOTLOADER_FAULT,
/// @brief Bootloader is in ping state
BOOTLOADER_PING,
/// @brief Bootloader is ready to start receiving data
BOOTLOADER_PING_READY,
/// @brief Bootloader is receiving data
BOOTLOADER_PING_RECEIVE,
} BootloaderStates;

typedef enum {
/// @brief Bootloader should start pinging MCU's
BOOTLOADER_PING_NODES = 0,
/// @brief Bootloader ping should do branch stuff
BOOTLOADER_PING_BRANCH,
/// @brief Bootloader ping should do group stuff
BOOTLOADER_PING_PROJECT,
} BooloaderPingStates;

typedef struct {
uintptr_t application_start;
uintptr_t current_address;
Expand All @@ -34,6 +45,7 @@ typedef struct {
uint32_t packet_crc32;
uint16_t expected_sequence_number;
uint16_t buffer_index;
uint16_t ping_req;

BootloaderStates state;
BootloaderError error;
Expand Down
4 changes: 3 additions & 1 deletion projects/bootloader/inc/bootloader_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,7 @@ typedef enum {
/// @brief Bootloader time out
BOOTLOADER_TIMEOUT,
/// @brief Bootloader flash memory verification failed. Everything is still erased
BOOTLOADER_FLASH_MEMORY_VERIFY_FAILED
BOOTLOADER_FLASH_MEMORY_VERIFY_FAILED,
/// @brief Bootloader ping timeout
BOOTLOADER_PING_TIMEOUT
} BootloaderError;
1 change: 1 addition & 0 deletions projects/bootloader/inc/can_datagram.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typedef enum {
CAN_ARBITRATION_START_ID,
CAN_ARBITRATION_JUMP_BOOTLOADER,
CAN_ARBITRATION_PING,
CAN_ARBITRATION_PING_RECEIVE,
} BootloaderCanID;

typedef struct {
Expand Down
84 changes: 41 additions & 43 deletions projects/bootloader/src/bootloader.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "bootloader.h"

#include "boot_crc32.h"

// Store CAN traffic in 1024 byte buffer to write to flash
Expand All @@ -20,13 +21,14 @@ BootloaderError bootloader_init(uint8_t *buffer) {
prv_bootloader.state = BOOTLOADER_IDLE;
prv_bootloader.target_nodes = 0;
prv_bootloader.buffer_index = 0;
prv_bootloader.ping_req = 0;

boot_crc_init();

return BOOTLOADER_ERROR_NONE;
}

static BootloaderError bootloader_switch_states(const BootloaderStates new_state) {
static BootloaderError wbootloader_switch_states(const BootloaderStates new_state) {
BootloaderError return_err = BOOTLOADER_ERROR_NONE;
BootloaderStates current_state = prv_bootloader.state;
if (current_state == new_state) {
Expand Down Expand Up @@ -89,14 +91,15 @@ static BootloaderError bootloader_switch_states(const BootloaderStates new_state

case BOOTLOADER_PING:
if (new_state == BOOTLOADER_START || new_state == BOOTLOADER_JUMP_APP ||
new_state == BOOTLOADER_DATA_READY || new_state == BOOTLOADER_FAULT || new_state == BOOTLOADER_PING) {
new_state == BOOTLOADER_DATA_READY || new_state == BOOTLOADER_FAULT ||
new_state == BOOTLOADER_PING) {
prv_bootloader.state = new_state;
} else {
return_err = BOOTLOADER_INVALID_ARGS;
prv_bootloader.state = BOOTLOADER_FAULT;
}
break;

default:
return_err = BOOTLOADER_INVALID_ARGS;
prv_bootloader.state = BOOTLOADER_FAULT;
Expand All @@ -117,9 +120,11 @@ static BootloaderError bootloader_handle_arbitration_id(Boot_CanMessage *msg) {
case CAN_ARBITRATION_JUMP_ID:
return bootloader_switch_states(BOOTLOADER_JUMP_APP);
case CAN_ARBITRATION_PING:
return bootloader_switch_states(BOOTLOADER_PING);
default:
return BOOTLOADER_INVALID_ARGS;
return bootloader_switch_states(BOOTLOADER_PING_READY);
case CAN_ARBITRATION_PING_RECEIVE:
return bootloader_switch_states(BOOTLOADER_PING_RECEIVE)

default : return BOOTLOADER_INVALID_ARGS;
}
}

Expand Down Expand Up @@ -183,22 +188,25 @@ static BootloaderError bootloader_data_receive() {
if (BOOTLOADER_PAGE_BYTES - prv_bootloader.buffer_index < 8) {
bytes_to_copy = BOOTLOADER_PAGE_BYTES - prv_bootloader.buffer_index;
}
if (prv_bootloader.binary_size - (prv_bootloader.buffer_index + prv_bootloader.bytes_written) < 8) {
bytes_to_copy = prv_bootloader.binary_size - (prv_bootloader.buffer_index + prv_bootloader.bytes_written);
if (prv_bootloader.binary_size - (prv_bootloader.buffer_index + prv_bootloader.bytes_written) <
8) {
bytes_to_copy =
prv_bootloader.binary_size - (prv_bootloader.buffer_index + prv_bootloader.bytes_written);
}

memcpy(flash_buffer + prv_bootloader.buffer_index, datagram.payload.data.binary_data, bytes_to_copy);
memcpy(flash_buffer + prv_bootloader.buffer_index, datagram.payload.data.binary_data,
bytes_to_copy);
prv_bootloader.buffer_index += bytes_to_copy;

if (prv_bootloader.buffer_index == BOOTLOADER_PAGE_BYTES ||
(prv_bootloader.bytes_written + prv_bootloader.buffer_index) >= prv_bootloader.binary_size) {

uint32_t calculated_crc32 = boot_crc_calculate((const uint32_t *)flash_buffer, BYTES_TO_WORD(prv_bootloader.buffer_index));
(prv_bootloader.bytes_written + prv_bootloader.buffer_index) >= prv_bootloader.binary_size) {
uint32_t calculated_crc32 = boot_crc_calculate((const uint32_t *)flash_buffer,
BYTES_TO_WORD(prv_bootloader.buffer_index));
if (calculated_crc32 != prv_bootloader.packet_crc32) {
send_ack_datagram(NACK, BOOTLOADER_CRC_MISMATCH_BEFORE_WRITE);
return BOOTLOADER_CRC_MISMATCH_BEFORE_WRITE;
}

error |= boot_flash_erase(BOOTLOADER_ADDR_TO_PAGE(prv_bootloader.current_address));
error |= boot_flash_write(prv_bootloader.current_address, flash_buffer, BOOTLOADER_PAGE_BYTES);
error |= boot_flash_read(prv_bootloader.current_address, flash_buffer, BOOTLOADER_PAGE_BYTES);
Expand All @@ -208,7 +216,8 @@ static BootloaderError bootloader_data_receive() {
return error;
}

calculated_crc32 = boot_crc_calculate((uint32_t *)flash_buffer, BYTES_TO_WORD(prv_bootloader.buffer_index));
calculated_crc32 =
boot_crc_calculate((uint32_t *)flash_buffer, BYTES_TO_WORD(prv_bootloader.buffer_index));
if (calculated_crc32 != prv_bootloader.packet_crc32) {
send_ack_datagram(NACK, BOOTLOADER_CRC_MISMATCH_AFTER_WRITE);
return BOOTLOADER_CRC_MISMATCH_AFTER_WRITE;
Expand All @@ -235,39 +244,28 @@ static BootloaderError bootloader_fault() {
return BOOTLOADER_INTERNAL_ERR;
};

volatile uint32_t bootloader_timer = 0;
#define BOOTLOADER_TIMEOUT_MS 15000

static void ping_run(Boot_CanMessage *msg) {
//branch out into the three ID
}

static BootloaderError bootloader_ping() {
BootloaderError error = BOOTLOADER_ERROR_NONE;
/* Start handling each req
1 - Git
2 - Proj
3 - Node_ID
/* Start handling each req
1 - Node_ID
2 - Branch
3 - Project
*/

Boot_CanMessage msg = { 0 };

while (true) {
if(boot_can_receive(&msg) == BOOTLOADER_ERROR_NONE){
bootloader_timer = 0;
//bootloader_run(&msg);
ping_run(&msg);
if (prv_bootloader.ping_req == 0) {
switch (datagram.payload.ping.req) {
case BOOTLOADER_PING_NODES:
break;
case BOOTLOADER_PING_BRANCH:
break;
case BOOTLOADER_PING_PROJECT:
break;
default:
return BOOTLOADER_INTERNAL_ERR;
}

if (bootloader_timer > BOOTLOADER_TIMEOUT_MS) {
bootloader_timer = 0;
if (boot_verify_flash_memory() == BOOTLOADER_ERROR_NONE) {
send_ack_datagram(NACK, BOOTLOADER_TIMEOUT);
bootloader_jump_app();
}
send_ack_datagram(NACK, BOOTLOADER_FLASH_MEMORY_VERIFY_FAILED);
}

++prv_bootloader.ping_req; // Received the first datagram, rest will be data.
} else {
// Start handling the rest of the datagrams
}
}

Expand All @@ -291,7 +289,7 @@ static BootloaderError bootloader_run_state() {
case BOOTLOADER_FAULT:
return bootloader_fault();
case BOOTLOADER_PING:
return bootloader_ping();
return bootloader_ping();
default:
return BOOTLOADER_INTERNAL_ERR;
}
Expand Down

0 comments on commit b6e22d9

Please sign in to comment.