72 lines
2.5 KiB
C++
72 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include "line_laser_modbus/protocol.hpp"
|
|
|
|
#include <array>
|
|
|
|
namespace line_laser_modbus {
|
|
|
|
constexpr std::size_t kRegisterBankSize =
|
|
static_cast<std::size_t>(kLastMappedAddress - kModeCommandAddress + 1U);
|
|
|
|
class RegisterBank {
|
|
public:
|
|
RegisterBank();
|
|
|
|
// 地址检查集中在这里处理。V1.2 寄存器表从 0xD000 到 0xD06B 是连续区域,
|
|
// 包含预留寄存器,因此紧凑数组比 map 更快、更省内存,同时保留后续启用
|
|
// 预留寄存器的空间。
|
|
[[nodiscard]] bool contains(std::uint16_t start_address,
|
|
std::uint16_t quantity) const noexcept;
|
|
|
|
[[nodiscard]] std::optional<RegisterVector> read(
|
|
std::uint16_t start_address,
|
|
std::uint16_t quantity) const;
|
|
[[nodiscard]] bool write(std::uint16_t start_address,
|
|
const RegisterVector& registers);
|
|
|
|
[[nodiscard]] WorkMode mode() const noexcept;
|
|
[[nodiscard]] DeviceState state() const noexcept;
|
|
|
|
bool set_mode(WorkMode mode) noexcept;
|
|
void set_state(DeviceState state) noexcept;
|
|
|
|
void set_current_pose(const Pose6D& pose);
|
|
[[nodiscard]] std::optional<Pose6D> current_pose() const;
|
|
[[nodiscard]] std::optional<Pose6D> target_pose() const;
|
|
[[nodiscard]] std::optional<Pose6D> correction() const;
|
|
|
|
private:
|
|
[[nodiscard]] static std::size_t index_of(std::uint16_t address) noexcept;
|
|
void apply_mode_side_effects(WorkMode mode) noexcept;
|
|
|
|
std::array<std::uint16_t, kRegisterBankSize> registers_{};
|
|
};
|
|
|
|
// DeviceServer 是下位机/从站侧帧处理器。
|
|
//
|
|
// 固件应在 UART 收到一个完整 RTU 帧后再调用 process_request()。该类会校验
|
|
// CRC、功能码、地址范围和模式切换规则,然后返回可直接发送的完整响应帧。
|
|
// 如果返回空字节数组,表示该帧应被忽略;在共享 RS-485 总线上,错误从站
|
|
// 地址或 CRC 损坏的流量都属于这种情况。
|
|
class DeviceServer {
|
|
public:
|
|
explicit DeviceServer(std::uint8_t slave_id = kDefaultSlaveId);
|
|
|
|
[[nodiscard]] std::uint8_t slave_id() const noexcept;
|
|
[[nodiscard]] RegisterBank& bank() noexcept;
|
|
[[nodiscard]] const RegisterBank& bank() const noexcept;
|
|
|
|
[[nodiscard]] ByteVector process_request(const ByteVector& request);
|
|
|
|
private:
|
|
[[nodiscard]] ByteVector process_read_request(const ReadRequest& request) const;
|
|
[[nodiscard]] ByteVector process_write_request(const WriteRequest& request);
|
|
[[nodiscard]] bool mode_write_is_valid(const WriteRequest& request) const noexcept;
|
|
|
|
std::uint8_t slave_id_;
|
|
RegisterBank bank_;
|
|
};
|
|
|
|
} // 命名空间 line_laser_modbus
|