2#include "asio/use_awaitable.hpp"
10#include <sys/socket.h>
12using namespace roboctrl::io;
15struct std::formatter<
can_frame> : std::formatter<std::string> {
17 std::ostringstream
oss;
18 oss << std::hex << std::uppercase;
27 oss <<
" DLC=" << std::dec << static_cast<int>(
frame.can_dlc)
30 for (
int i = 0;
i <
frame.can_dlc; ++
i) {
31 oss << std::format(
"{:02X}",
frame.data[
i]);
36 return std::formatter<std::string>::format(
oss.str(),
ctx);
44 can_name_{info.can_name.data(),info.can_name.
length()}
48 throw std::runtime_error(
"socket() failed");
51 std::strncpy(
ifr.ifr_name, can_name_.c_str(),
IFNAMSIZ);
53 throw std::runtime_error(
"ioctl(SIOCGIFINDEX) failed");
57 addr.can_ifindex =
ifr.ifr_ifindex;
59 throw std::runtime_error(
"bind() failed");
65 log_info(
"Can io created on {}",info.can_name);
76 size_t pkg_size =
co_await stream_.async_read_some(asio::buffer(buffer_),asio::use_awaitable);
79 can_id_type
id =
cf.can_id;
89 co_await stream_.async_write_some(
98 if (data.size() > 8) {
99 throw std::invalid_argument(
"payload of can can't > 8");
103 cf_->can_dlc = data.size();
104 std::memcpy(cf_->data, data.data(), data.size());
108 co_await stream_.async_write_some(
基于 Linux SocketCAN 的 CAN 总线封装。
can(const info_type &info)
打开 CAN 设备。
awaitable< void > task()
接收循环任务。
awaitable< void > send(byte_span data)
发送裸帧。
void dispatch(const std::uint32_t &key, byte_span data)
将数据派发给对应 key 的回调。
void log_debug(std::format_string< Args... > fmt, Args &&...args) const
输出debug日志
void log_info(std::format_string< Args... > fmt, Args &&...args) const
输出info日志
std::span< std::byte > byte_span
byte span,实际上就是一个std::span<std::byte>;
auto spawn(task_context::task_type &&task)
添加一个协程任务到全局任务上下文中执行。
asio::awaitable< T > awaitable
协程任务类型。
auto & io_context()
获取全局任务上下文的io_context。