I am writing firmware for a device in C. The Software allows the PC to communicate with this device over the serial interface (UART). The firmware contains multiple layers as following:
- Communication layer to send and receive data over UART.
- Block layer: This layer enables/disables certain blocks on the device by writing data to the device over UART.
- API layer: This contains a sequence of calls to the routines in the block layer. It is used to enable or disable a set of blocks on the device.
My problem is the error handling since in C there are no exceptions. Here is how I've implemented my firmware and I am trying to see if there is a more efficient and compact way to build it while still handling errors efficiently. I want to avoid checking at each layer the status of the call of the lower layer. The code below is very compact and in reality, I have a long sequence of send_uart_commands in the block layer.
// Communication layer
operation_status_t send_uart_command(command_id_t id, command_value_t value)
{
// Send data over UART
// Return success if the operation is successful; otherwise failure
}
// Block layer
operation_status_t enable_block1(void)
{
if (send_uart_command(BLOCK1_COMMAND_1, 10) != operation_success)
return operation_failure;
if (send_uart_command(BLOCK1_COMMAND_2, 20) != operation_success)
return operation_failure;
// A list of sequences
if (send_uart_command(BLOCK1_COMMAND_N, 15) != operation_success)
return operation_failure;
return operation_success;
}
operation_status_t enable_block2(void)
{
if (send_uart_command(BLOCK2_COMMAND_1, 1) != operation_success)
return operation_failure;
if (send_uart_command(BLOCK2_COMMAND_2, 8) != operation_success)
return operation_failure;
return operation_success;
}
// API layer
operation_status_t initialize(void)
{
if (enable_block1() != operation_success)
return operation_failure;
if (enable_block2() != operation_success)
return operation_failure;
// A list of calls to the functions in the block layer
return operation_success;
}