我正在建造一个附有传感器的机器人.机器人上的控制单元是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.