移植mavlink协议到STM32详细教程
1准备材料,
首先准备一个带串口的stm32程序(这里选用整点原子的官方串口例程这里自己去找不讲),然后去mavlink官网下载mavlink源码,这里重点讲解这里 







a.进入mavlink官网(http://qgroundcontrol.org/mavlink/start),下拉到MAVLink Code and Generator如下图,得到mavlink源码有多种途径,这里选取用python生成。即点击MAVLink Generator (C/C++, Python)

b.然后进入如下界面,点击网址,下面是生成的方法和步骤都写有

c.然后点击clone and downed里面的download zip 即可下载
下载好后解压,然后直接运行mavlink-master里面的mavgenerate.py(python环境自己安装,这里不讲)
然后进入如下界面

点击第一个browse选择message_definitions文件夹里面的v1.0里面的common.xml
然后自己选择输出路径我这里选的新建文件夹
language选择C
protocol选择1.0
然后直接点generate生成

到此材料准备完毕。
2开始真正的移植工作
a.在串口实验里新建一个MAVLINK文件夹,并将刚才生成的文件拷贝过来,如图

打开工程新建分组,将所有拷贝过来的文件和头文件目录添加好,具体这里就不讲了,添加好后如图

b.在main函数中添加#include "mavlink.h"如下

然后编译
"..\OBJ\USART.axf" - 30 Error(s), 17 Warning(s).
一个一个解决。
错误一:
..\MAVLINK\common\../mavlink_types.h(53): error: #20: identifier "pack" is undefined
解决方法:
将mavlink_types.h中
#define MAVPACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
改为
#define MAVPACKED( __Declaration__ ) __Declaration__

这里不使用对齐字节了,直接用也是一样的。
编译后:
"..\OBJ\USART.axf" - 30 Error(s), 7 Warning(s).
错误二:
..\MAVLINK\common\../mavlink_types.h(54): error: #3092: anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions
解决方法:
根据提示信息在mavlink_types.h的前面加入#pragma anon_unions

编译后:
"..\OBJ\USART.axf" - 30 Error(s), 8 Warning(s).
错误三:
..\MAVLINK\common\../checksum.h(34): warning: #260-D: explicit type is missing ("int" assumed)
包括后面很多错误都有共同点,指向有inline的行,这里是因为mdk中无法识别inline
解决方法:
在checksum.h加入一行代码定义inline
#define inline __INLINE

编译后:
"..\OBJ\USART.axf" - 4 Error(s), 195 Warning(s).
错误四:
..\MAVLINK\common\../mavlink_conversions.h(167): error: #268: declaration may not appear after executable statement in block
解决方法:
指向定义的变量,将变量的定义放到函数的最前端(四个错误都是这种错误)
以前mavlink_conversions.h的代码
MAVLINK_HELPER void mavlink_dcm_to_quaternion(const float dcm[3][3], float quaternion[4])
{
float tr = dcm[0][0] + dcm[1][1] + dcm[2][2];
if (tr > 0.0f) {
float s = sqrtf(tr + 1.0f);
quaternion[0] = s * 0.5f;
s = 0.5f / s;
quaternion[1] = (dcm[2][1] - dcm[1][2]) * s;
quaternion[2] = (dcm[0][2] - dcm[2][0]) * s;
quaternion[3] = (dcm[1][0] - dcm[0][1]) * s;
} else {
/* Find maximum diagonal element in dcm
* store index in dcm_i */
int dcm_i = 0;
int i;
for (i = 1; i < 3; i++) {
if (dcm[i][i] > dcm[dcm_i][dcm_i]) {
dcm_i = i;
}
}
int dcm_j = (dcm_i + 1) % 3;
int dcm_k = (dcm_i + 2) % 3;
float s = sqrtf((dcm[dcm_i][dcm_i] - dcm[dcm_j][dcm_j] -
dcm[dcm_k][dcm_k]) + 1.0f);
quaternion[dcm_i + 1] = s * 0.5f;
s = 0.5f / s;
quaternion[dcm_j + 1] = (dcm[dcm_i][dcm_j] + dcm[dcm_j][dcm_i]) * s;
quaternion[dcm_k + 1] = (dcm[dcm_k][dcm_i] + dcm[dcm_i][dcm_k]) * s;
quaternion[0] = (dcm[dcm_k][dcm_j] - dcm[dcm_j][dcm_k]) * s;
}
}
更改后mavlink_conversions.h的代码
MAVLINK_HELPER void mavlink_dcm_to_quaternion(const float dcm[3][3], float quaternion[4])
{
int dcm_j,dcm_k;
float s;
float tr = dcm[0][0] + dcm[1][1] + dcm[2][2];
if (tr > 0.0f) {
float s = sqrtf(tr + 1.0f);
quaternion[0] = s * 0.5f;
s = 0.5f / s;
quaternion[1] = (dcm[2][1] - dcm[1][2]) * s;
quaternion[2] = (dcm[0][2] - dcm[2][0]) * s;
quaternion[3] = (dcm[1][0] - dcm[0][1]) * s;
} else {
/* Find maximum diagonal element in dcm
* store index in dcm_i */
int dcm_i = 0;
int i;
for (i = 1; i < 3; i++) {
if (dcm[i][i] > dcm[dcm_i][dcm_i]) {
dcm_i = i;
}
}
dcm_j = (dcm_i + 1) % 3;
dcm_k = (dcm_i + 2) % 3;
s = sqrtf((dcm[dcm_i][dcm_i] - dcm[dcm_j][dcm_j] -
dcm[dcm_k][dcm_k]) + 1.0f);
quaternion[dcm_i + 1] = s * 0.5f;
s = 0.5f / s;
quaternion[dcm_j + 1] = (dcm[dcm_i][dcm_j] + dcm[dcm_j][dcm_i]) * s;
quaternion[dcm_k + 1] = (dcm[dcm_k][dcm_i] + dcm[dcm_i][dcm_k]) * s;
quaternion[0] = (dcm[dcm_k][dcm_j] - dcm[dcm_j][dcm_k]) * s;
}
}
以前mavlink_helpers.h的代码
MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg)
{
memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
uint8_t *ck = buffer + (MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
ck[0] = (uint8_t)(msg->checksum & 0xFF);
ck[1] = (uint8_t)(msg->checksum >> 8);
return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len;
}
更改后mavlink_helpers.h的代码
MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg)
{
uint8_t *ck;
memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
ck = buffer + (MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
ck[0] = (uint8_t)(msg->checksum & 0xFF);
ck[1] = (uint8_t)(msg->checksum >> 8);
return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len;
}
编译后:
"..\OBJ\USART.axf" - 0 Error(s), 195 Warning(s).
解决所有警告的方法:
将protocol.h里面的旧代码
#define _MAV_RETURN_char(msg, wire_offset) (const char)_MAV_PAYLOAD(msg)[wire_offset]
#define _MAV_RETURN_int8_t(msg, wire_offset) (const int8_t)_MAV_PAYLOAD(msg)[wire_offset]
#define _MAV_RETURN_uint8_t(msg, wire_offset) (const uint8_t)_MAV_PAYLOAD(msg)[wire_offset]
去掉const,改为
#define _MAV_RETURN_char(msg, wire_offset) (const char)_MAV_PAYLOAD(msg)[wire_offset]
#define _MAV_RETURN_int8_t(msg, wire_offset) (int8_t)_MAV_PAYLOAD(msg)[wire_offset]
#define _MAV_RETURN_uint8_t(msg, wire_offset) (uint8_t)_MAV_PAYLOAD(msg)[wire_offset]
编译后:
"..\OBJ\USART.axf" - 0 Error(s), 0 Warning(s).
3开始更改底层串口代码
待续。。。
文章来自:http://www.cnblogs.com/lovechen/p/5801679.html