15uint8_t pc_hart_checksum(
const uint8_t *bytes,
size_t len)
18 for (
size_t i = 0; i < len; i++)
25size_t pc_hart_build(uint8_t delimiter,
const uint8_t *addr,
size_t addr_len, uint8_t command,
const uint8_t *data,
26 size_t data_len, uint8_t *out,
size_t cap)
28 if (addr_len != 1 && addr_len != 5)
32 if (!addr || (data_len && !data))
37 size_t n = 1 + addr_len + 1 + 1 + data_len + 1;
38 if (n > cap || data_len > 0xFF)
45 memcpy(out + i, addr, addr_len);
48 out[i++] = (uint8_t)data_len;
51 memcpy(out + i, data, data_len);
54 out[i] = pc_hart_checksum(out, i);
59bool pc_hart_parse(
const uint8_t *frame,
size_t len, HartFrame *out)
65 size_t addr_len = (frame[0] & HartDelim::HART_DELIM_LONG_ADDR) ? 5 : 1;
67 size_t min = 1 + addr_len + 1 + 1 + 1;
73 size_t bc_idx = 1 + addr_len + 1;
74 uint8_t byte_count = frame[bc_idx];
75 size_t expect = 1 + addr_len + 1 + 1 + byte_count + 1;
81 uint8_t want = pc_hart_checksum(frame, expect - 1);
82 if (want != frame[expect - 1])
87 out->delimiter = frame[0];
88 out->addr = frame + 1;
89 out->addr_len = addr_len;
90 out->command = frame[1 + addr_len];
91 out->byte_count = byte_count;
92 out->data = byte_count ? (frame + bc_idx + 1) : nullptr;
93 out->data_len = byte_count;
97size_t pc_hartip_build_header(uint8_t msg_type, uint8_t msg_id, uint8_t status, uint16_t seq, uint16_t total_len,
98 uint8_t *out,
size_t cap)
100 if (cap < HartIp::HARTIP_HEADER_LEN || !out)
108 out[4] = (uint8_t)(seq >> 8);
109 out[5] = (uint8_t)seq;
110 out[6] = (uint8_t)(total_len >> 8);
111 out[7] = (uint8_t)total_len;
112 return HartIp::HARTIP_HEADER_LEN;
115bool pc_hartip_parse_header(
const uint8_t *buf,
size_t len, HartIpHeader *out)
117 if (!buf || !out || len < HartIp::HARTIP_HEADER_LEN)
121 uint16_t total = (uint16_t)((buf[6] << 8) | buf[7]);
122 if (total < HartIp::HARTIP_HEADER_LEN || total > len)
126 out->version = buf[0];
127 out->msg_type = buf[1];
128 out->msg_id = buf[2];
129 out->status = buf[3];
130 out->seq = (uint16_t)((buf[4] << 8) | buf[5]);
131 out->total_len = total;
132 out->payload_len = (size_t)(total - HartIp::HARTIP_HEADER_LEN);
133 out->payload = out->payload_len ? buf + HartIp::HARTIP_HEADER_LEN :
nullptr;
HART / HART-IP process-instrument protocol codec (PC_ENABLE_HART).