c – 远程读取和编写结构

我正在建造一个附有传感器的机器人.机器人上的控制单元是ARM Cortex-M3,所有传感器都连接到它,它通过以太网连接到“地面站”.

现在我想通过地面站在机器人上读写设置.因此,我考虑在机器人上实施一个可由地面站操纵的“虚拟寄存器”.

它可以由结构组成,看起来像这样:

// accelerometer register
struct accel_reg {
  // accelerations
  int32_t accelX;
  int32_t accelY;
  int32_t accelZ;
};

// infrared distance sensor register 
struct ir_reg {
  uint16_t  dist; // distance
};

// robot's register table
struct {
  uint8_t     status;         // current state
  uint32_t    faultFlags;     // some fault flags
  accel_reg   accelerometer;  // accelerometer register
  ir_reg      ir_sensors[4];  // 4 IR sensors connected
} robot;

// usage example:

robot.accelerometer.accelX = -981;
robot.ir_sensors[1].dist = 1024;

在机器人上,寄存器将不断填充新值,配置设置由地面站设置并由机器人应用.

地面站和机器人将用C语言编写,因此它们都可以使用相同的struct数据类型.

我现在的问题是如何在不写大量元数据的情况下将读/写操作封装在协议中?

假设我想读寄存器robot.ir_sensors [2] .dist.我如何在协议中处理此寄存器?

我已经考虑过以字节为单位传输相对偏移量(即结构中内存中的相对位置),但我认为内存对齐和填充可能会导致问题,特别是因为地面站运行在x86_64架构上而机器人运行在32-位ARM处理器.

谢谢你的任何提示! 🙂

最佳答案 我也将建议使用Google Protocol Buffers.

在最简单的情况下,您可以像这样实现一个消息RobotState:

message RobotState {
   optional int32_t status = 1;
   optional int32_t distance = 2;
   optional int32_t accelX = 3;
   ...
}

然后,当机器人收到消息时,它将从存在的任何可选字段中获取新值.然后它将回复一条包含所有字段当前值的消息.

这样,使用大多数protobuf实现的“合并消息”功能实现字段更新非常容易.此外,您可以在开始时保持简单,因为您只有一种消息类型,但如果您稍后需要扩展,则可以添加子消息.

确实protobuf不支持int8_t或int16_t.只需使用int32_t.

点赞