То, как вы представляете команды, будет в значительной степени зависеть от последовательности команд, которую будет отправлять ваша программа.
Если ваша программа полностью универсальна и должна иметь возможность отправлять буквально любую возможную последовательностьиз байтов, тогда const unsigned char
массив (или const uint8_t
, если вы хотите быть немного более явным), вероятно, путь.
С другой стороны, если есть какие-то "правила"к вашему протоколу, который, как вы знаете, никогда не изменится или не будет нуждаться в каких-либо исключениях, чем вы можете написать свой код для включения / применения этих правил, а не просто слепой отправки необработанных предоставленных программистом последовательностей (и надеясь, что программист наберет их все правильно).
Например, если вы точно знаете, что ваше последовательное устройство всегда требует, чтобы каждая команда начиналась с префикса 0x7E, 0x01, 0x00, 0x20
, то вы можете сократить дублирование (и, следовательно, шансы созданияопечатка), удалив этот префикс из ваших последовательностей и автоматически добавив к нему функцию send, ввместо, например:
const unsigned char configurePresetDelivery[] = { 0x38, 0x0B, 0x04, 0x03, 0xF2, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3 };
const unsigned char beginPresetDelivery[] = { 0x3C, 0x01, 0x04, 0x2B };
const unsigned char configureDirectDelivery[] = { 0x37, 0x02, 0X03, 0XF2, 0xD5 };
const unsigned char prefix[] = {0x7e, 0x01, 0x00, 0x20};
void send_prefix_and_command(const unsigned char * cmdWithoutPrefix, int numBytes)
{
send(prefix, sizeof(prefix));
send(cmdWithoutPrefix, numBytes);
}
[...]
send_prefix_and_command(configurePresetDelivery, sizeof(configurePresetDelivery));
... и (продолжая это немного дальше), если вы знаете, что некоторые из ваших командных последовательностей будут изменяться в зависимости от параметров времени выполнения, а не вручную.кодируя каждую вариацию, вы можете создать функцию генератора команд, которая сделает это за вас (и, таким образом, инкапсулировать этап генерации, потенциально подверженный ошибкам, в одно место кода, поэтому вместо множества существует только одна подпрограмма для обслуживания / отладки).Например,
// This is easier to do using std::vector, so I will use it
std::vector<unsigned char> generatePresetDataCommand(unsigned char presetID, unsigned short presetValue)
{
// I'm totally making this up just to show an example
std::vector<unsigned char> ret;
ret.push_back(0x66);
ret.push_back(0x67);
ret.push_back(presetID);
ret.push_back((presetValue>>8)&0xFF); // store high-bits of 16-bit value into a byte
ret.push_back((presetValue>>0)&0xFF); // store low-bits of 16-bit value into a byte
return ret;
}
// Convenience wrapper-function so later code can send a vector with less typing
void send_prefix_and_command(const std::vector<unsigned char> & vec)
{
send_prefix_and_command(&vec[0], vec.size());
}
[...]
// The payoff -- easy one-liner sending of a command with little chance of getting it wrong
send_prefix_and_command(generatePresetDataCommand(42, 32599));