Resolve some const/static-able warnings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Allen Hill
2026-07-08 14:16:38 -07:00
parent b194a6df2c
commit 82884c1305
3 changed files with 50 additions and 15 deletions
+33 -9
View File
@@ -29,6 +29,7 @@
No acknowledge bits are sent for broadcast frames. No acknowledge bits are sent for broadcast frames.
*/ */
#include <concepts>
#include <cstdio> #include <cstdio>
#include "avclan.h" #include "avclan.h"
@@ -54,7 +55,12 @@ inline constexpr with_ack_t with_ack{};
namespace avclan { namespace avclan {
class Bus::Handle { class Bus::Handle {
Handle() { phy_guard_enter(); }; // A live handle exclusively borrows the Bus for the duration of a
// transaction; holding the reference is what forces `get()` (and thus
// `read`/`send`) to require a mutable Bus, even though the bus hardware
// itself is reached through free `phy_*` functions.
Bus &bus_;
explicit Handle(Bus &bus) : bus_{bus} { phy_guard_enter(); };
friend Bus; friend Bus;
public: public:
@@ -62,17 +68,19 @@ public:
Handle(const Handle &) = delete; Handle(const Handle &) = delete;
Handle(Handle &&) = delete; Handle(Handle &&) = delete;
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
Send sendstartbit() { return phy_send_startbit(); }; Send sendstartbit() { return phy_send_startbit(); };
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
Read readstartbit() { return phy_read_startbit(); }; Read readstartbit() { return phy_read_startbit(); };
template <auto N, std::unsigned_integral T, template <auto N, std::unsigned_integral T,
std::derived_from<trailer_bits_t> Trailer> std::derived_from<trailer_bits_t> Trailer>
requires(sizeof(T) < 3 && N < 16 && !std::same_as<Trailer, with_ack_t>) requires(sizeof(T) < 3 && N < 16 && !std::same_as<Trailer, with_ack_t>)
Send send(T bits, Trailer /*tag*/) { Send send(T bits, Trailer /*tag*/) {
const auto parity = sendbits<N>(bits); const Bit parity = sendbits<N>(bits);
if constexpr (std::is_same_v<Trailer, with_parity_t>) if constexpr (std::is_same_v<Trailer, with_parity_t>)
sendbits<1>(static_cast<uint8_t>(parity)); sendbits<1>(to_underlying(parity));
return Send{0}; return Send{0};
}; };
@@ -93,11 +101,11 @@ public:
std::derived_from<trailer_bits_t> Trailer> std::derived_from<trailer_bits_t> Trailer>
requires(sizeof(T) < 3 && N < 16 && !std::same_as<Trailer, with_ack_t>) requires(sizeof(T) < 3 && N < 16 && !std::same_as<Trailer, with_ack_t>)
Read read(T *bits, Trailer /*tag*/) { Read read(T *bits, Trailer /*tag*/) {
const auto calc_parity = readbits<N>(bits); const Bit calc_parity = readbits<N>(bits);
if constexpr (std::is_same_v<Trailer, with_parity_t>) { if constexpr (std::is_same_v<Trailer, with_parity_t>) {
uint8_t read_parity; uint8_t read_parity;
readbits<1>(&read_parity); readbits<1>(&read_parity);
if (static_cast<uint8_t>(calc_parity) != read_parity) if (to_underlying(calc_parity) != read_parity)
return Read::BAD_PARITY; return Read::BAD_PARITY;
} }
return Read{0}; return Read{0};
@@ -165,10 +173,23 @@ template <> inline Bit Bus::Handle::readbits<8>(uint8_t *bits) {
return phy_read_byte(bits); return phy_read_byte(bits);
}; };
void Bus::init() { phy_init(); }; void Bus::init() {
// Idempotent: the single Bus is shared by reference, so every Peripheral's
// ctor calls init() on it — but the hardware must be brought up exactly once
// (phy_init is not assumed re-entrant/idempotent).
if (inited_)
return;
phy_init();
muted_ = false; // phy_init leaves the bus TX unmuted
inited_ = true;
};
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
bool Bus::is_active() const { return phy_active(); }; bool Bus::is_active() const { return phy_active(); };
void Bus::mute(bool mute) { phy_mute(mute); }; void Bus::mute(bool mute) {
bool Bus::is_muted() const { return phy_is_muted(); }; phy_mute(mute);
muted_ = mute; // Only update muted_ *AFTER* hardware has finished muting
};
auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read { auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read {
struct errtype { struct errtype {
@@ -383,9 +404,12 @@ auto Bus::send(const Frame *out, Frame::Print print) -> Send {
return err.errno; return err.errno;
} }
Bus::Handle Bus::get() { return {}; }; Bus::Handle Bus::get() { return Handle{*this}; };
#ifndef NDEBUG #ifndef NDEBUG
// Debug bit-timing measurement on the one physical bus; instance-scoped for the
// same reason as is_active().
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
void Bus::measure() { phy_measure(); } void Bus::measure() { phy_measure(); }
#endif #endif
+15 -4
View File
@@ -47,9 +47,7 @@
#pragma once #pragma once
#include <concepts>
#include <cstdint> #include <cstdint>
#include <type_traits>
#include "avclan.h" #include "avclan.h"
#include "frame.hpp" #include "frame.hpp"
@@ -60,11 +58,20 @@ class Bus {
public: public:
using Error = detail::Error; using Error = detail::Error;
// There is exactly one physical bus (the HAL `phy_*` layer is a singleton).
// `Bus` models that single hardware instance: it is owned once and shared by
// reference (e.g. multiple `Peripheral`s hold a `Bus &`), never copied — a
// copy would fork `muted_`, which must stay coherent with the one hardware
// TX state.
Bus() = default;
Bus(const Bus &) = delete;
Bus &operator=(const Bus &) = delete;
void init(); void init();
bool is_active() const; bool is_active() const;
void mute(bool mute); void mute(bool mute);
bool is_muted() const; bool is_muted() const { return muted_; };
#ifndef NDEBUG #ifndef NDEBUG
void measure(); void measure();
@@ -75,7 +82,11 @@ public:
private: private:
class Handle; class Handle;
static Handle get(); Handle get();
// Assume mute after default ctor; only viable after init call
bool muted_ = true;
bool inited_ = false;
}; };
} // namespace avclan } // namespace avclan
+2 -2
View File
@@ -18,7 +18,7 @@ template <DeviceInterface... Devs> class Peripheral {
public: public:
using Error = detail::Error; using Error = detail::Error;
Peripheral(Bus bus, uint16_t address) : bus{bus}, address_{address} { Peripheral(Bus &bus, uint16_t address) : bus{bus}, address_{address} {
bus.init(); bus.init();
(std::get<Devs>(devices_).init(), ...); (std::get<Devs>(devices_).init(), ...);
} }
@@ -181,7 +181,7 @@ private:
dev.handle(in, out); dev.handle(in, out);
} }
Bus bus; Bus &bus;
uint16_t controller_ = 0; uint16_t controller_ = 0;
const uint16_t address_; const uint16_t address_;
std::tuple<Devs...> devices_; std::tuple<Devs...> devices_;