Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue #201] CAN errors C++ implementation #314

Merged
merged 15 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions firmware/projects/Demo/CANErrors/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Luai Bashar
# November 5, 2024

# The target executable 'main' is created in the master CMakeLists. Do not change its name.
# We only need to add the source code files and include directories.

include("${CMAKE_SOURCE_DIR}/cmake/cangen.cmake")

target_sources(main
PRIVATE
main.cc
)

target_include_directories(main
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/inc
)

# Notice that we don't include any mcal/ subdirectory in this CMake file.
# The master CMakeLists handles platform selection and library linking.
32 changes: 32 additions & 0 deletions firmware/projects/Demo/CANErrors/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# CANErrors
This is the CAN Errors demo project. It defines a global system for the vehicle to send/receive errors through different subsystems. It defines:
- A 64 bit CAN error signal. Each bit represents a different error, and will be sent periodically for other systems to know if an error has occurred
- The `ErrorHandler` class, an interface to set/send different errors on the CAN signal
- Enum `Error` that defines all 64 possible errors to send through the CAN signal

## How to use `ErrorHandler`

### Defining an instance of ErrorHandler:
```
ErrorHandler error_handler{};
```

### Setting errors with ErrorHandler:
- `SetError` takes an error from the `Error` enum and sets it
```
error_handler.SetError(Error0);
error_handler.SetError(Error15);
error_handler.SetError(Error48);
```

### Sending errors with ErrorHandler:
- `SendError` takes a CAN bus and sends the errors through that bus. It resets the errors to send the next set of errors
```
error_handler.SendError(error_can_bus);
```

## Building the Project
- To build the project, run the following in the firmware directory `make PROJECT=Demo/CANErrors PLATFORM=cli`
- This should create a build file with no errors!
- This will also generate the dbc files automatically, but if you want to generate them seperately, run `cangen projects/Demo/CANErrors`
- To execute the new build, run `./build/Demo/CANErrors/cli/main.exe`
9 changes: 9 additions & 0 deletions firmware/projects/Demo/CANErrors/bindings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "shared/comms/can/can_bus.h"

namespace bindings {
extern shared::periph::CanBase& error_can_base;
extern void Initialize();
extern void TickBlocking(uint32_t);
} // namespace bindings
5 changes: 5 additions & 0 deletions firmware/projects/Demo/CANErrors/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
canGen:
busses:
- name: error
node: tms
dbcFile: errors.dbc
9 changes: 9 additions & 0 deletions firmware/projects/Demo/CANErrors/errors.dbc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
VERSION ""

BS_:

BU_: TMS

// Defines one 64 bit signal where each bit represents a different error
BO_ 390 TMS_ERROR: 8 TMS
SG_ Errors : 0|64@1+ (1,0) [0|0] "bitfield" Vector__XXX
107 changes: 107 additions & 0 deletions firmware/projects/Demo/CANErrors/inc/app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/// @author Luai Bashar
/// @date 2024-11-10
/// @brief Functions and types that will be used in CANErrors main

#pragma once

#include "../generated/can/error_can_messages.h"
#include "shared/comms/can/can_bus.h"

/***************************************************************
App-level objects
***************************************************************/

// Defines all possible errors to set
enum class Error {
kError0 = 0,
kError1 = 1,
kError2 = 2,
kError3 = 3,
kError4 = 4,
kError5 = 5,
kError6 = 6,
kError7 = 7,
kError8 = 8,
kError9 = 9,
kError10 = 10,
kError11 = 11,
kError12 = 12,
kError13 = 13,
kError14 = 14,
kError15 = 15,
kError16 = 16,
kError17 = 17,
kError18 = 18,
kError19 = 19,
kError20 = 20,
kError21 = 21,
kError22 = 22,
kError23 = 23,
kError24 = 24,
kError25 = 25,
kError26 = 26,
kError27 = 27,
kError28 = 28,
kError29 = 29,
kError30 = 30,
kError31 = 31,
kError32 = 32,
kError33 = 33,
kError34 = 34,
kError35 = 35,
kError36 = 36,
kError37 = 37,
kError38 = 38,
kError39 = 39,
kError40 = 40,
kError41 = 41,
kError42 = 42,
kError43 = 43,
kError44 = 44,
kError45 = 45,
kError46 = 46,
kError47 = 47,
kError48 = 48,
kError49 = 49,
kError50 = 50,
kError51 = 51,
kError52 = 52,
kError53 = 53,
kError54 = 54,
kError55 = 55,
kError56 = 56,
kError57 = 57,
kError58 = 58,
kError59 = 59,
kError60 = 60,
kError61 = 61,
kError62 = 62,
kError63 = 63
};

// Interface to set/send all possible errors for the system
class ErrorHandler {
luaibash marked this conversation as resolved.
Show resolved Hide resolved
public:
// Sets the error based on the error index given
void SetError(Error error) {
uint64_t error_index = static_cast<uint64_t>(error);
error_message_.errors |= (1ULL << error_index);
}

// Sends the error message through the provided CAN bus
// TODO: Error message is only for a specific bus, change this when autogen code is created
void SendError(shared::can::CanBus error_can_bus) {
error_can_bus.Send(error_message_);

// Reset after a send to not send duplicate errors
ResetError();
}
private:
// Object that holds a 64 bit int, each bit representing an error
generated::can::TMS_ERROR error_message_{};

// Resets all errors back to untriggered
void ResetError() {
error_message_.errors = 0;
}
};
49 changes: 49 additions & 0 deletions firmware/projects/Demo/CANErrors/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/// @author Luai Bashar
/// @date 2024-11-05

#include <cstdint>

#include "app.h"
#include "bindings.h"
#include "shared/comms/can/can_bus.h"
#include "generated/can/error_msg_registry.h"

// Initializing can bus that sends the error message
generated::can::ErrorMsgRegistry error_can_registry{};
shared::can::CanBus error_can_bus{
bindings::error_can_base,
error_can_registry,
};

int main(void) {
// Initialize the CLI and milliseconds to repeat by
bindings::Initialize();
uint32_t tick_duration = 100;

// Initialize the error object that sets/sends each error
ErrorHandler error_message{};

while (true) {
error_can_bus.Update();

// Test #1: Iterate through each error, setting it and sending it
for (int i = 0; i < 64; i++) {
Error error = static_cast<Error>(i);
error_message.SetError(error);
error_message.SendError(error_can_bus);
}

// Test #2: Set random errors using the enum
error_message.SetError(Error::kError0);
error_message.SetError(Error::kError5);
error_message.SetError(Error::kError10);
error_message.SetError(Error::kError15);
error_message.SetError(Error::kError20);
error_message.SendError(error_can_bus);

// Wait for 100ms before repeating the process
bindings::TickBlocking(tick_duration);
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target_sources(bindings PRIVATE bindings.cc)

target_link_libraries(bindings PUBLIC mcal-cli)
34 changes: 34 additions & 0 deletions firmware/projects/Demo/CANErrors/platforms/cli/bindings.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/// @author Luai Bashar
/// @date 2024-11-05

#include <chrono>
#include <thread>

#include "mcal/cli/periph/can.h"
#include "shared/periph/can.h"

#include "../../generated/can/error_can_messages.h"
#include "shared/comms/can/can_bus.h"

namespace mcal {
using namespace cli::periph;

CanBase error_can_base{"vcan0"};
}

namespace bindings {
shared::periph::CanBase& error_can_base = mcal::error_can_base;

// Simulates a sleep, waiting for inputted ticks ms
void TickBlocking(uint32_t ticks) {
std::chrono::milliseconds duration(ticks);

std::this_thread::sleep_for(duration);
}

// Initializes the can/CLI outputs
void Initialize() {
mcal::error_can_base.Setup();
std::cout << "Initializing CLI..." << std::endl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(MCAL cli)
Loading