鉴于飞控近年来发展历程及趋势
在传感器应用领域,期望更多的标准化设计,MSPv2协议在拓展v1时,就考虑了这方面的需求。
+---+---+--------+---------+--------+------+---------+------------------------------+-------------+| Multiwii Serial Protocol V2 length = 9 + payload size |+---+---+--------+---------+--------+------+---------+------------------------------+-------------+| $ | X | < ! > | flag(1) | cmd(2) | size(2) | payload(16bit len) | checksum_v2 |+---+---+--------+---------+--------+------+---------+------------------------------+-------------+
这里要注意的一个问题是网络字节序,尤其是对通信比较熟悉的朋友。常规的逻辑是这样的:
发送端CPU字节序 — Host2Network转换字节序 —> 网络传输(大端字节序) — Network2Host转换字节序 —> 接收端CPU字节序
上述两个逻辑转换:Host2Network/Network2Host来确保发送和接受CPU能根据本地的存储字节序来解析多字节变量
【但是】飞控代码上看,串口收到报文以后,直接将buffer一个指针强行变换到定义的结构体上了。
【好嘛,这么粗暴处理!!!】STM32可是小端字节序的呀,这么大胆??? 猜测这些传感模块大都是小端字节序或者8位单片机,所以整个系统都是小端的,就没有大系统这么复杂了。
iNav应用代码从main开始进入,根据配置信息使能串口;当串口收到传感器MSP v2传感报文时,将信息送到mspProcessSensorCommand进行解析。
taskHandleSerial└──> mspSerialProcess└──> mspFcProcessCommand└──> mspProcessSensorCommandmain└──> init└──> fcTasksInit //setTaskEnabled(TASK_SERIAL, true);
截止发稿日,在MSP v2协议上支持的传感器根据cmd(2),有如下几种:
src/main/msp/msp_protocol_v2_sensor.h
#define MSP2_IS_SENSOR_MESSAGE(x) ((x) >= 0x1F00 && (x) <= 0x1FFF)#define MSP2_SENSOR_RANGEFINDER 0x1F01
#define MSP2_SENSOR_OPTIC_FLOW 0x1F02
#define MSP2_SENSOR_GPS 0x1F03
#define MSP2_SENSOR_COMPASS 0x1F04
#define MSP2_SENSOR_BAROMETER 0x1F05
#define MSP2_SENSOR_AIRSPEED 0x1F06
mspSensorOpflowDataMessage_t
typedef struct __attribute__((packed)) {uint8_t quality; // [0;255]int32_t motionX;int32_t motionY;
} mspSensorOpflowDataMessage_t;
mspSensorRangefinderDataMessage_t
typedef struct __attribute__((packed)) {uint8_t quality; // [0;255]int32_t distanceMm; // Negative value for out of range
} mspSensorRangefinderDataMessage_t;
mspSensorGpsDataMessage_t
typedef struct __attribute__((packed)) {uint8_t instance; // sensor instance number to support multi-sensor setupsuint16_t gpsWeek; // GPS week, 0xFFFF if not availableuint32_t msTOW;uint8_t fixType;uint8_t satellitesInView;uint16_t horizontalPosAccuracy; // [cm]uint16_t verticalPosAccuracy; // [cm]uint16_t horizontalVelAccuracy; // [cm/s]uint16_t hdop;int32_t longitude;int32_t latitude;int32_t mslAltitude; // cmint32_t nedVelNorth; // cm/sint32_t nedVelEast;int32_t nedVelDown;uint16_t groundCourse; // deg * 100, 0..36000uint16_t trueYaw; // deg * 100, values of 0..36000 are valid. 65535 = no data availableuint16_t year;uint8_t month;uint8_t day;uint8_t hour;uint8_t min;uint8_t sec;
} mspSensorGpsDataMessage_t;
mspSensorCompassDataMessage_t
typedef struct __attribute__((packed)) {uint8_t instance;uint32_t timeMs;int16_t magX; // mGauss, frontint16_t magY; // mGauss, rightint16_t magZ; // mGauss, down
} mspSensorCompassDataMessage_t;
mspSensorBaroDataMessage_t
typedef struct __attribute__((packed)) {uint8_t instance;uint32_t timeMs;float pressurePa;int16_t temp; // centi-degrees C
} mspSensorBaroDataMessage_t;
mspSensorAirspeedDataMessage_t
typedef struct __attribute__((packed)) {uint8_t instance;uint32_t timeMs;float diffPressurePa;int16_t temp; // centi-degrees C
} mspSensorAirspeedDataMessage_t;
【1】BetaFlight模块设计之三十二:MSP协议模块分析
【2】Multiwii Serial Protocol Version 2
【3】传感模块:MATEKSYS Optical Flow & LIDAR 3901-L0X