Skip to content

Commit

Permalink
Freerb/242 update can drivers (#322)
Browse files Browse the repository at this point in the history
* Adds missing import

* moves and removes unused files

* Reimplement CAN

* Adds message formatter

* bk work

* for review

* simplify get and pop methods

* remove unused import

* Add comments to Pop and Get

* Update headers

* Rename veh to demo

* Update scripts/cangen/cangen/templates/bus.h.jinja2

Co-authored-by: Samuel Parent <[email protected]>

* Add clang-format on

* Explain optional unpacking

* Revert to TxMessage concept

---------

Co-authored-by: Samuel Parent <[email protected]>
  • Loading branch information
BlakeFreer and samparent97 committed Nov 29, 2024
1 parent f1f34c4 commit cdc1af3
Show file tree
Hide file tree
Showing 29 changed files with 358 additions and 483 deletions.
29 changes: 11 additions & 18 deletions firmware/mcal/cli/periph/can.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
#include <string.h>
#include <unistd.h>

#include <chrono>
#include <cstring>
#include <iomanip>
#include <iostream>

#include "shared/comms/can/raw_can_msg.hpp"
#include "shared/comms/can/msg.hpp"
#include "shared/periph/can.hpp"

namespace mcal::cli::periph {
Expand All @@ -25,27 +26,19 @@ class CanBase : public shared::periph::CanBase {
std::cout << "can interface: " << iface_ << std::endl;
}

void Send(const shared::can::RawCanMsg& can_tx_msg) {
std::cout << iface_ << " [" << std::hex << std::uppercase
<< std::setfill('0') << std::setw(2) << can_tx_msg.header.id
<< "] ";

// Loop through each data byte and print it in uppercase hex with
// leading zeros
for (int i = 0; i < sizeof(can_tx_msg.data); ++i) {
std::cout << std::hex << std::uppercase << std::setfill('0')
<< std::setw(2) << static_cast<int>(can_tx_msg.data[i])
<< " ";
}

std::cout << std::endl;
void Send(const shared::can::RawMessage& msg) {
std::cout << std::format("{} {}", iface_, msg) << std::endl;
}

void ReadQueue(shared::can::RawCanMsg can_rx_msgs[], size_t len) {}

private:
using RawCanMsg = shared::can::RawCanMsg;
std::string iface_;

uint32_t GetTimestamp() const override {
using namespace std::chrono;
auto t = system_clock::now().time_since_epoch();
auto ms = duration_cast<milliseconds>(t).count();
return ms;
}
};

} // namespace mcal::cli::periph
73 changes: 21 additions & 52 deletions firmware/mcal/linux/periph/can.cc
Original file line number Diff line number Diff line change
@@ -1,44 +1,25 @@
#include <linux/can.h>
#include <sys/types.h>

#include <chrono>
#include <cstring>
#include <format>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>

#include "can.h"
#include "shared/comms/can/raw_can_msg.hpp"
#include "shared/comms/can/msg.hpp"
#include "vcan/vcan.h"

static std::string message_to_string(const shared::can::RawCanMsg& msg) {
std::string str = std::format("[{:02X}]", msg.header.id);
for (int i = 0; i < sizeof(msg.header.data_len); ++i) {
str += std::format(" {:02X}", msg.data[i]);
}
return str;
}

static can_frame to_can_frame(const shared::can::RawCanMsg& msg) {
struct can_frame frame{.can_id = msg.header.id,
.can_dlc = msg.header.data_len};
std::memcpy(&frame.data, msg.data, 8);
return frame;
}

static shared::can::RawCanMsg from_can_frame(const can_frame& frame) {
shared::can::RawCanMsg msg;
msg.header = {
.id = frame.can_id,
.data_len = frame.can_dlc,
.is_extended_frame = static_cast<bool>(frame.can_id & CAN_EFF_FLAG),
static can_frame to_can_frame(const shared::can::RawMessage& msg) {
struct can_frame frame{
.can_id = msg.id,
.can_dlc = msg.data_length,
};
msg.tick_timestamp = 0;

std::copy(frame.data, frame.data + 8, msg.data);

return msg;
std::memcpy(&frame.data, msg.data, msg.data_length);
return frame;
}

namespace mcal::lnx::periph {
Expand All @@ -52,34 +33,17 @@ void CanBase::Setup() {
reader_thread_ = std::thread(&CanBase::StartReading, this);
}

void CanBase::Send(const shared::can::RawCanMsg& can_tx_msg) {
void CanBase::Send(const shared::can::RawMessage& can_tx_msg) {
std::cout << std::format("CanBase {}: Sending\n| {}", socket_.GetIface(),
message_to_string(can_tx_msg))
can_tx_msg)
<< std::endl;

auto frame = to_can_frame(can_tx_msg);
socket_.Write(&frame);
}

void CanBase::ReadQueue(shared::can::RawCanMsg can_rx_msgs[], size_t len) {
uint16_t msg_idx = 0;
std::lock_guard<std::mutex> lock(queue_access_);
while (!can_queue_.empty() && msg_idx < len) {
can_rx_msgs[msg_idx] = can_queue_.front();

std::cout << std::format("CanBase {}: Received\n| {}",
socket_.GetIface(),
message_to_string(can_rx_msgs[msg_idx]))
<< std::endl;

can_queue_.pop();
msg_idx++;
}
}

void CanBase::StartReading() {
struct can_frame frame;
shared::can::RawCanMsg raw_msg;

while (true) {
// Block until a frame arrives
Expand All @@ -89,13 +53,18 @@ void CanBase::StartReading() {
exit(1);
}

raw_msg = from_can_frame(frame);
shared::can::RawMessage raw_msg(frame.can_id, frame.can_dlc,
frame.data);

{ // push RawCanMsg to queue
std::lock_guard<std::mutex> lock(queue_access_);
can_queue_.push(raw_msg);
}
AddToBus(raw_msg);
}
}

uint32_t CanBase::GetTimestamp() const {
using namespace std::chrono;
auto t = system_clock::now().time_since_epoch();
auto ms = duration_cast<milliseconds>(t).count();
return ms;
}

} // namespace mcal::lnx::periph
11 changes: 3 additions & 8 deletions firmware/mcal/linux/periph/can.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#pragma once

#include <mutex>
#include <queue>
#include <thread>

#include "mcal/linux/periph/vcan/vcan.hpp"
#include "shared/comms/can/raw_can_msg.hpp"
#include "shared/periph/can.hpp"
#include "vcan/vcan.h"

Expand All @@ -16,16 +13,14 @@ class CanBase : public shared::periph::CanBase {
CanBase(std::string can_iface);

void Setup();
void Send(const shared::can::RawCanMsg&);
void ReadQueue(shared::can::RawCanMsg[], size_t len);
void Send(const shared::can::RawMessage&) override;

private:
uint32_t GetTimestamp() const override;

struct vcan::VcanSocket socket_;

std::queue<shared::can::RawCanMsg> can_queue_;
std::mutex queue_access_;
std::thread reader_thread_;

void StartReading();
};
} // namespace mcal::lnx::periph
2 changes: 1 addition & 1 deletion firmware/projects/Demo/CAN/Receive/bindings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace bindings {

extern shared::periph::CanBase& veh_can_base;
extern shared::periph::CanBase& demo_can_base;
extern shared::periph::DigitalOutput& indicator;

extern void Initialize();
Expand Down
29 changes: 14 additions & 15 deletions firmware/projects/Demo/CAN/Receive/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,27 @@

#include <cstdint>

#include "bindings.hpp"
#include "generated/can/demobus_can_messages.hpp"
#include "generated/can/demobus_msg_registry.hpp"
#include "shared/comms/can/can_bus.hpp"
#include "bindings.h"
#include "generated/can/demobus_bus.pp"
#include "generated/can/demobus_messages.hpp"
#include "shared/comms/can/bus.hpp"

generated::can::DemobusMsgRegistry veh_can_registry{};
using namespace generated::can;

shared::can::CanBus veh_can_bus{
bindings::veh_can_base,
veh_can_registry,
};
DemobusBus demo_can_bus{bindings::demo_can_base};

int main(void) {
bindings::Initialize();

generated::can::ButtonStatus btn_msg{};

while (true) {
veh_can_bus.Update();
veh_can_bus.Read(btn_msg);

bindings::indicator.Set(btn_msg.state);
auto btn_msg = demo_can_bus.PopRxButtonStatus();

// We're not guaranteed to have message available, so we need to check.
if (btn_msg.has_value()) {
// Unpack the value from the optional
RxButtonStatus msg = btn_msg.value();
bindings::indicator.Set(msg.State());
}
}

return 0;
Expand Down
6 changes: 3 additions & 3 deletions firmware/projects/Demo/CAN/Receive/platforms/cli/bindings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
namespace mcal {
using namespace cli::periph;

CanBase veh_can_base{"vcan0"};
CanBase demo_can_base{"vcan0"};
DigitalOutput indicator{"Indicator"};
} // namespace mcal

namespace bindings {
shared::periph::CanBase& veh_can_base = mcal::veh_can_base;
shared::periph::CanBase& demo_can_base = mcal::demo_can_base;
shared::periph::DigitalOutput& indicator = mcal::indicator;

void Initialize() {
std::cout << "Initializing CLI..." << std::endl;
mcal::veh_can_base.Setup();
mcal::demo_can_base.Setup();
std::cerr << "The CLI platform has no way to receive messages from "
"CAN/Send. Consider using the linux platform instead."
<< std::endl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
namespace mcal {
using namespace lnx::periph;

CanBase veh_can_base{"vcan0"};
CanBase demo_can_base{"vcan0"};
DigitalOutput indicator{"Indicator"};

} // namespace mcal

namespace bindings {

shared::periph::CanBase& veh_can_base = mcal::veh_can_base;
shared::periph::CanBase& demo_can_base = mcal::demo_can_base;
shared::periph::DigitalOutput& indicator = mcal::indicator;

void Initialize() {
std::cout << "Initializing Linux" << std::endl;
mcal::veh_can_base.Setup();
mcal::demo_can_base.Setup();
}

} // namespace bindings
2 changes: 1 addition & 1 deletion firmware/projects/Demo/CAN/Send/bindings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace bindings {

extern shared::periph::CanBase& veh_can_base;
extern shared::periph::CanBase& demo_can_base;
extern shared::periph::DigitalInput& button;

extern void Initialize();
Expand Down
25 changes: 9 additions & 16 deletions firmware/projects/Demo/CAN/Send/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,23 @@

#include <cstdint>

#include "bindings.hpp"
#include "generated/can/demobus_can_messages.hpp"
#include "generated/can/demobus_msg_registry.hpp"
#include "shared/comms/can/can_bus.hpp"
#include "bindings.h"
#include "generated/can/demobus_bus.hpp"
#include "generated/can/demobus_messages.hpp"

generated::can::DemobusMsgRegistry veh_can_registry{};
using namespace generated::can;

shared::can::CanBus veh_can_bus{
bindings::veh_can_base,
veh_can_registry,
};
DemobusBus can_bus{bindings::demo_can_base};

int main(void) {
bindings::Initialize();
uint32_t interval_ms = 50;

generated::can::ButtonStatus btn_msg{};

while (true) {
veh_can_bus.Update();

btn_msg.state = bindings::button.Read();

veh_can_bus.Send(btn_msg);
TxButtonStatus msg{
.state = bindings::button.Read(),
};
can_bus.Send(msg);
bindings::TickBlocking(interval_ms);
}

Expand Down
6 changes: 3 additions & 3 deletions firmware/projects/Demo/CAN/Send/platforms/cli/bindings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
namespace mcal {
using namespace cli::periph;

CanBase veh_can_base{"vcan0"};
CanBase demo_can_base{"vcan0"};
DigitalInput button{"Button"};
} // namespace mcal

namespace bindings {
shared::periph::CanBase& veh_can_base = mcal::veh_can_base;
shared::periph::CanBase& demo_can_base = mcal::demo_can_base;
shared::periph::DigitalInput& button = mcal::button;

void TickBlocking(uint32_t ticks) {
Expand All @@ -28,7 +28,7 @@ void TickBlocking(uint32_t ticks) {
}

void Initialize() {
mcal::veh_can_base.Setup();
mcal::demo_can_base.Setup();
std::cout << "Initializing CLI..." << std::endl;
}
} // namespace bindings
6 changes: 3 additions & 3 deletions firmware/projects/Demo/CAN/Send/platforms/linux/bindings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
namespace mcal {
using namespace lnx::periph;

CanBase veh_can_base{"vcan0"};
CanBase demo_can_base{"vcan0"};
DigitalInput button{"Button"};

} // namespace mcal

namespace bindings {

shared::periph::CanBase& veh_can_base = mcal::veh_can_base;
shared::periph::CanBase& demo_can_base = mcal::demo_can_base;
shared::periph::DigitalInput& button = mcal::button;

void TickBlocking(uint32_t ms) {
Expand All @@ -25,7 +25,7 @@ void TickBlocking(uint32_t ms) {

void Initialize() {
std::cout << "Initializing Linux" << std::endl;
mcal::veh_can_base.Setup();
mcal::demo_can_base.Setup();
}

} // namespace bindings
Loading

0 comments on commit cdc1af3

Please sign in to comment.