Hi mingyee,
I think you would be best to adopt a fixed header character, say ASCII <STX>.
Then you need either of the following:
1. fixed length messages, shorter ones are padded, like leading zeroes
2. a termination character, say ASCII <ETX>
3. a length byte, probably straight behind the header.
This not only improves the robustness of the protocol, but makes it easier to implement.
If the messages are very short fixed length can be best/more efficient.
Doing this also speeds recovery from a dropped or garbled byte. Generally without proper framing like this the following good message will be lost as well as it will be needed to re-sync. Having a header means every message re-syncs the comms.
There are so many ways to do this that you will get a different answer from all you ask. However I believe this is the minimum for a simple protocol.
header, address, command, data, checksum, terminator.
or
header, length, address, command, data, checksum.
Is this system single master?
If single will it have an address like a slave, say 0, or will the format be different for master messages.
This affects how the response is structured, but possibly:
header, master address, slave address, <ACK> or data, checksum, terminator
or
header, master address, slave address, length, <ACK> or data, checksum
your RXDEV could be added in front of the ack/data
Multi-master has many other issues not addressed here.