MAVLink协议的移植

        mavlink协议被大众知晓应该是PX4项目发起之后,随着开源飞控神器PX项目进入国内。本次就只分析移植过程中的问题,协议具体内容及其他知识只稍作带过,有时间再更新。

        mavlink的源码有官方的代码生成器,或者从开源的px4或者px4flow(光流)的源代码中获得。目前版本只有v0.9和v1.0,0.9已经逐渐不更新了。要用1.0的。

  1.如果从mavlink官网下载的生成器生成代码的话,需要额外的一些改动,下载的文件如下,需要py环境,歪果仁好像很喜欢py。

        

  运行后的效果是这样的,通过xml文件定义数据结构,语言选C语言,就能生成标准的c代码了。

       

  不大推荐这种方式,不过需要新的数据帧结构的话,用这种方式可以保证代码比较规矩一致。

  2.px4或者光流的源码里的,和生成器的代码差别很小,要修改的地方只有一处。


  简单分析一下代码文件的功能和结构。代码在A/mavlink/include/mavlink/v1.0下,A是源代码的位置。

  checksum:校验和,用来在数据帧结尾加一个16bits校验码检查通讯出错。不需要改。

  mavlink_conversions:一些常用的转换函数方法,四元数、矩阵、欧拉等等的转换,不用改。

  mavlink_helpers:需要修改,翻到文件最下面,有注释说明了需要根据你使用的MCU重写字符发送的底层函数,常见的就是用串口,重写个串口发送单个字符函数就行。

       
MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len)
{
#ifdef MAVLINK_SEND_UART_BYTES
	/* this is the more efficient approach, if the platform
	   defines it */
	MAVLINK_SEND_UART_BYTES(chan, (const uint8_t *)buf, len);
#else
	/* fallback to one byte at a time */
	uint16_t i;
	for (i = 0; i < len; i++) {
		comm_send_ch(chan, (uint8_t)buf[i]);
	}
#endif
}

  可以在其他函数中定义宏#define MAVLINK_SEND_UART_BYTES mavlink_send_uart_bytes,并重写mavlink_send_uart_bytes为自己的函数就行。

  mavlink_types:定义了用到的各种数据结构,方法1生成的代码片段是这样的

  
MAVPACKED(
typedef struct __mavlink_message {
	uint16_t checksum; ///< sent at end of packet
	uint8_t magic;   ///< protocol magic marker
	uint8_t len;     ///< Length of payload
	uint8_t seq;     ///< Sequence of packet
	uint8_t sysid;   ///< ID of message sender system/aircraft
	uint8_t compid;  ///< ID of the message sender component
	uint8_t msgid;   ///< ID of message in payload
	uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];
}) mavlink_message_t;

  需要改成 

  
typedef struct __mavlink_message {
	uint16_t checksum; ///< sent at end of packet
	uint8_t magic;   ///< protocol magic marker
	uint8_t len;     ///< Length of payload
	uint8_t seq;     ///< Sequence of packet
	uint8_t sysid;   ///< ID of message sender system/aircraft
	uint8_t compid;  ///< ID of the message sender component
	uint8_t msgid;   ///< ID of message in payload
	uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];
} mavlink_message_t;
  从px源码得到的该函数就是已经修改好的了,结构体字节对齐在嵌入式编程里基本用不到,嵌入式基本都是单字节寻址,加上编译器优化,不会出现一个数据需要两次寻址的情况。
  protocol:处理大端小端什么的,没具体看,用不上改。
  common文件下的各种头文件就是定义了具体的数据结构的数据帧,包含发送接收等等编码译码函数等等。

  完成移植还需要解决过程中的各种小问题,可以参照px4flow的源代码里Flow-master/src/communication以及settings文件进行与main函数的关联。


  想要理解mavlink的设计思路的话,参照CANopen协议就行,后者的资料多,二者的思路我认为是极其类似的。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值