嵌入式C++中的通信协议实现
Communication protocol implementation in embedded C++
我一直在用 C++ 实现基于 CAN 的专有通信协议。
该协议使用具有以下结构的消息:
1 Control packet (3 bytes header, 5 payload bytes)
0 - 124 Data packets (2 bytes header, 6 payload bytes)
1 CRC packet (2 bytes header, 4 payload bytes, 2 CRC bytes)
我在通信协议实现方面没有太多经验,所以我
想在这里讨论我的解决方案。我已经开始传输。
从顶层来看我决定分流执行
分成三个类。他们每个人都将实现单例设计模式。
类 个接口如下:
// Main interface for communication over CAN bus.
class Manager
{
public:
// initializes the CAN periphery (baud rate and reception filters)
bool init(can_baudrate_e, uint16_t*);
// creates the message, divides the message into packets and puts the
// packets into transmission queue, message description (type,
// destination node ID) and message data are stored in a structure
bool sendMsg(app_msg_data_t*);
private:
// appends unique message code to informations in app_msg_data_t
// structure
void buildMsg(app_msg_data_t*, msg_t*);
// calculates needed number of packets
uint8_t calcNoPkts(msg_t*);
// divides the message into packets
void appMsg2Pkts(msg_t*, uint8_t, pkt_t*);
// creates message Control packet
void buildAppControlPkt(msg_t*, pkt_t*, uint8_t, uint8_t);
// creates message Data packet
void buildAppDataPkt(msg_t*, pkt_t*, uint8_t);
// creates message CRC packet
void buildAppCRCPkt(msg_t*, pkt_t*, uint8_t, uint8_t);
// transform whole message into byte array
uint16_t getAppMsgBytes(pkt_t*, uint8_t, uint8_t*);
// returns the data content of the message
uint8_t* getAppMsgData(msg_t*);
// calculates the CRC for a message (message passed as array of bytes)
uint16_t calcCRC(uint8_t*, uint16_t);
}
// Transmission buffer
class TxQueue
{
public:
// puts the packet into the transmission queue
bool putPacket(Manager::pkt_t*);
// retrieves the packet from the transmission queue
bool getPacket(Manager::pkt_t*);
private:
}
// Transmits the packets onto the CAN bus
class Transmitter
{
public:
// transmits one packet per call onto the CAN bus
bool transmit(void);
private:
// transforms the packet into CAN frame
static void packet2CANFrame(Manager::pkt_t*, can_msg_t*);
}
如果有人比我更有经验可以评估我的解决方案,我将不胜感激。我怕走错路。预先感谢您的任何建议。
我建议先阅读 Guide to Implementing Communication Protocols in C++ (for Embedded Systems) 免费 e-book。书中提到的主要概念是,嵌入式系统在未来通过不同的附加 I/O 接口(例如 wifi 或蓝牙)尝试使用相同的协议消息并不少见。因此,将应用程序消息有效负载与传输帧分开,尤其是与您的 CAN 总线打包分开是有益的。
我一直在用 C++ 实现基于 CAN 的专有通信协议。 该协议使用具有以下结构的消息:
1 Control packet (3 bytes header, 5 payload bytes)
0 - 124 Data packets (2 bytes header, 6 payload bytes)
1 CRC packet (2 bytes header, 4 payload bytes, 2 CRC bytes)
我在通信协议实现方面没有太多经验,所以我 想在这里讨论我的解决方案。我已经开始传输。
从顶层来看我决定分流执行 分成三个类。他们每个人都将实现单例设计模式。 类 个接口如下:
// Main interface for communication over CAN bus.
class Manager
{
public:
// initializes the CAN periphery (baud rate and reception filters)
bool init(can_baudrate_e, uint16_t*);
// creates the message, divides the message into packets and puts the
// packets into transmission queue, message description (type,
// destination node ID) and message data are stored in a structure
bool sendMsg(app_msg_data_t*);
private:
// appends unique message code to informations in app_msg_data_t
// structure
void buildMsg(app_msg_data_t*, msg_t*);
// calculates needed number of packets
uint8_t calcNoPkts(msg_t*);
// divides the message into packets
void appMsg2Pkts(msg_t*, uint8_t, pkt_t*);
// creates message Control packet
void buildAppControlPkt(msg_t*, pkt_t*, uint8_t, uint8_t);
// creates message Data packet
void buildAppDataPkt(msg_t*, pkt_t*, uint8_t);
// creates message CRC packet
void buildAppCRCPkt(msg_t*, pkt_t*, uint8_t, uint8_t);
// transform whole message into byte array
uint16_t getAppMsgBytes(pkt_t*, uint8_t, uint8_t*);
// returns the data content of the message
uint8_t* getAppMsgData(msg_t*);
// calculates the CRC for a message (message passed as array of bytes)
uint16_t calcCRC(uint8_t*, uint16_t);
}
// Transmission buffer
class TxQueue
{
public:
// puts the packet into the transmission queue
bool putPacket(Manager::pkt_t*);
// retrieves the packet from the transmission queue
bool getPacket(Manager::pkt_t*);
private:
}
// Transmits the packets onto the CAN bus
class Transmitter
{
public:
// transmits one packet per call onto the CAN bus
bool transmit(void);
private:
// transforms the packet into CAN frame
static void packet2CANFrame(Manager::pkt_t*, can_msg_t*);
}
如果有人比我更有经验可以评估我的解决方案,我将不胜感激。我怕走错路。预先感谢您的任何建议。
我建议先阅读 Guide to Implementing Communication Protocols in C++ (for Embedded Systems) 免费 e-book。书中提到的主要概念是,嵌入式系统在未来通过不同的附加 I/O 接口(例如 wifi 或蓝牙)尝试使用相同的协议消息并不少见。因此,将应用程序消息有效负载与传输帧分开,尤其是与您的 CAN 总线打包分开是有益的。