问题
I have a two boards:
- Master board (M board)
- Slave board (S board)
M board shall send a request to S board and the latter shall answer.
The answer of the slave is a struct:
typedef struct{
uint8_t userID;
uint8_t userPass;
uint16_t userData;
}UserTypeDef;
UserTypeDef User;
Example:
M board asks for user's information (struct) by sending the command GET_USER_INFO. S board shall return a data structure to M board.
M Board(Tx) --> GET_USER_INFO --> (Rx)S Board
S Board(Tx) --> User --> (Rx)M Board
The question is how to send such a struct using UART ?
回答1:
Write a protocol document that explicitly defines how the contents of the structure should be transmitted over the network media. Then write code to implement the protocol.
The code that transmits the structure/object is "serializing" the data. The code that receives the structure/object is "deserializing". You can Google for lots of advice and examples about a variety of serialization protocols and techniques.
If you're using a binary protocol then you could serialize a C struct, by defining a uint8_t pointer to point to the the first byte in the structure and then transmit the bytes until you've transmitted the entire sizeof(struct)
. But this method has some pitfalls, especially if your transmitting and receiving devices use different microcontrollers and/or C compilers. If one microcontroller uses a different endianness than the other, or if one C compiler uses different struct padding rules than the other, then the deserialized data could be corrupted.
This is why you have to write a protocol document that explicitly defines the order and meaning of each byte. And you shouldn't rely on your C compiler to organize the struct exactly like your protocol. The C compiler may insert padding or may use the wrong endianness. So instead of simply incrementing a pointer through the struct, you should write serialization and deserialization routines that parse out each byte from the network protocol message and copy it to/from the appropriate byte in the struct.
回答2:
The easiest way would be to just send it in binary. As long as the receiving side knows what the endianness of the sender is (and adjusts for it), you can just send the whole struct in one go. The downside here is a human looking at the serial port will just see gibberish, and it won't work if your serial port is 7 bits instead of 8.
Second easiest would be to convert the struct to hex, but still send it as one chunk of data (so for instance if your struct is {25, 54, 16745}
, you could send 19364169
, and have the receiver split it into fields. The downside of this method is it uses twice as many bytes as the first method.
Most difficult, but most robust would be to send the name of the field followed by the value. This is good because a human looking at the serial would easily be able to tell what's going on, and if you add a field to the struct later, the receiving software could throw an error when it sees a name it doesn't recognize. So from the example data above, you might have:
userID: 0x19, userPass: 0x36, userData: 0x4169
. The downside here is it wastes a lot of bytes sending names, so if you're constrained by the speed of your serial link, you might not want to do this.
回答3:
The best way to maintain readability is to encode it in a readable form.
This can be as simple as encoding the values as a string with sprintf
.
char buffer[BUFFER_LEN];
sprintf(buffer, "%i:%i:%i", user.userId, user.userPass, user.userData);
send_over_uart(buffer);
来源:https://stackoverflow.com/questions/48828851/send-a-structure-using-uart