The field type bytes may contain any type of uint8_t data. It is an uniform data container. It works similar to String and Repeated fields in that the FieldBytes class requires you to specify the maximum number of bytes which will be stored in the array using a template parameter or custom option. The bytes class has the same type of access functions compared to String fields. Lets take a look at an example:

message raw_bytes
  bytes b = 1;
// Declare the message object stating the bytes array 
// should hold ten bytes.
raw_bytes<10> msg;

// Set some elements, others are by default zero.
msg.mutable_b()[0] = 1;
msg.mutable_b()[9] = 10;

// There is no index out of bound exception as they 
// are not possible on small mcu's. Instead the last 
// element of the array will be returned and changes!
msg.mutable_b()[10] = 11;

// Assign the content of a std array.
const std::array<uint8_t, 10> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
msg.mutable_b().set(, 10);

// Loopoing over the array could be done like this
for(uint8_t i = 0; i < 10; ++i) {
  const auto x = msg.get_b()[i];

// And you can clear the whole array with the clear function.